Convert chtmlview to chtmlctrl

Source: Internet
Author: User

Convert chtmlview to chtmlctrl
View and frame Separation

Download source code

Wow !! There are several articles that let people take the case. After the competition, I was so addicted! Can't you think that Microsoft is also so proficient in Windows Programming ?! At this moment, I think of sharing it with the brothers in kbase! No, applause !!!!

[Note]:

Luo Tou said, it is best not to split the frame/doc/view into different couples. Yes. Who would be so cruel to be a good family !? Hey, I just gave them a distant relative. :)

Now, stop talk ing !! Let's go on the stuff...
First, there are two difficulties to solve! First, since chtmlctrl is the final product, how can I randomly drop it into the dialog box like other controls (such as buttons? Com-> ActiveX ?? You said, do it yourself! I am confused about com !! Even more lazy than you think (encourage programmers to exercise this inertia! Benefits ). I wonder, why don't you give me a try? By the way, isn't cstatic allowed to be processed by the hacker at will? Well, just put subclassdlgitem on it and we can use it as our chtmlctrl! That makes sense !! Then, the view is indeed closely related to the frame. MFC is a semi-customized framework. Microsoft has already done a lot of work. Maybe you click a few clicks in the view and several messages similar to wm_microspace are transmitted to the frame. However, there is no frame for controls, and the controls never need to know which container they are placed in !!

So, in order not to let the compiler do anything, we have to be careful! :)

Before proceeding, You need to clarify the differences between the chtmlview and the chtmlctrl generated?

In fact, the difference is that they are used differently. A control is usually a subwindow in a dialog box. Of course, you can use it as a subwindow of any window. However, view is designed specifically to implement the view structure of the MFC Document. A view has a pointer to the document and is fixed in a special window-called: Framework Window (cframewnd ). For document, cview is a field that can be expressed in form. However, the pointer m_pdocument to the document may be null, so it is wise to do so whenever we process the document in the View:

If (m_pdocument! = NULL)
{
// Do something here!
}
Therefore, the view does not really need a document, and the chtmlview does not. You may think that the document in chtmlview is an HTML file, but in fact, chtmlview is implemented using iwebbrowser2, and it has no idea about the document view structure of MFC.
So do you need a frame? If you have carefully studied the relevant code, you will find that: in a few places, View
Know that you belong to a frame. Most document view structures are implemented in higher-level classes, such as frame and cdoctemplate. They closely stick frame, view, and document together. View does not know what is going on outside, so the document view system designed in this way has many advantages. Theoretically, a view is passively controlled by a frame, and there is no other way, so it is wrong to think that the view knows its own parent window. There are two cviews (also the parent class of chtmlview) that assume they are in a frame. The first part is cview: onmouseactive, which is the processing function of the wm_mouseactive message. When you click the mouse in the view, it will do a lot of meticulous work. These meticulous work is not important, but it is important that view calls getparentframe to get its parent window framework, and then cframewnd :: getactiveview activates the current active view-all of which are based on the assumption that view is a subwindow of cframewnd.
The other is in cview: ondestroy:
Void cview: ondestroy ()
{
Cframewnd * pframe = getparentframe ();
If (pframe! = NULL & pframe-> getactiveview = This)
// Deactive during death
Pframe-> setactiveview (null );
Cwnd: ondestroy ();
}
Here, the view is inactive first. From another point of view, we can send a notification message (notification) to the parent window instead of calling the C ++ method to avoid the view dependency on the frame !! Getparentframe can return a cwnd instead of a cframewnd, because this function only emphasizes the parent window, rather than returning a specific class. View can replace the cframewnd method call by sending a notification message similar to wm_microspace. These notifications will be correctly responded to by "frame" (or cframewnd or cfoownd. However, you must be clear that when a view is activated or inactive, the frame determines how to respond, not the view itself. This is true for any system. The function is called down (from parent to child), and the event is passed up (from child to parent ). A subclass never knows its own container !! Life itself is not perfect! Fortunately, we will easily overcome the difficulties that MFC brings to us! Chtmlctrl class (here! ) Is exactly what we need: an HTML "View", which can be used in a dialog box or any window. Chtmlctrl reloads onmouseactive and ondestroy to avoid the code that troubles us.
Int chtmlctrl: onmouseactive (...)
{
// Bypass cview DOC/frame stuff
Return cwnd: onmouseactive (...);
}
Void chtmlctrl: ondestroy ()
{
// Bypass cview DOC/frame stuff
Cwnd: ondestroy ();
}
In addition, chtmlctrl also reloads postncdestroy
Void chtmlctrl: postncdestroy ()
{
// Do nothing
}
The normal postncdestroy Implementation of cview is to use Delete this to destroy the view. For views, this is a normal processing method, because the view is directly created in the heap. However, controls generally exist as members of another window object. In this case, you should not delete it. It will be deleted by the parent object. With the above modifications (onmouseactive, ondestroy and postncdestroy), chtmlctrl can work smoothly in the dialog box !! For this reason, I wrote a small program: abouthtml (see the source code) to display an about box (1 ). It is completely written in HTML. HTML resources: images and audio files (right! Can even have sound) are stored in the EXE file.
// In abouthtml. RC
About. html HTML discardable "res // about.htm"
Vckbcom. gif HTML discardable "res // vckcom.gif"
Okup. gif HTML discardable "res // okup.gif"
Okdn. gif HTML discardable "res // okdn.gif"
Mozart. wav HTML discardable "res // mozart.wav"
On a general web page, if you do this: put vckcom.gif in the current directory. This is also true for accessing resources stored in an EXE file. In this case, you must use the following code to help your browser find your HTML elements:
<Base url = "res: // abouthtml.exe/about.htm">
The browser will know that the current "directory" is res: // abouthtml.exe, so when it encounters , it will automatically find the Res: // abouthtml.exe/vckcom.gif; otherwise, it will be searched in the current directory where the HTML file is located.

 
Figure 1

Generally, you can use Res: // modulename to access any resources stored in EXE and DLL. Res: is a protocol similar to http:, ftp:, file:, or mailto. It tells the path and name of the browser resource, and the details work. The browser knows how to do it! :) For the implementation of the about dialog box, a class, caboutdialog, has a member of The chtmlctrl type m_page. Let's take a look at the initialization process of caboutdialog:
Bool caboutdialog: oninitdialog ()
{
Verify (cdialog: oninitdialog ());
Verify (m_page.createfromstatic (idc_htmlview, this ));
M_page.loadfromresource (_ T ("about.htm "));
Return true;
}

You may be confused about chtmlctrl: createfromstatic. Do you remember the cstatic we just talked about? We intend to use it to represent the chtmlctrl control. It will create a chtmlctrl control object from cstatic. This is a subclass process, and the object will have the same ID, size, and position as cstatic. This is very convenient and effective! :)
Bool chtmlctrl: createfromstatic (uint NID, cwnd * pparent)
{
Cstatic wndstatic;
If (! Wndstatic. subclassdlgitem (NID, pparent ))
Return false;
// Get static control rect
Crect RC;
Wndstatic. getwindowrect (& rc );
Pparent-> screentoclient (& rc );
Wndstatic. destroywindow ();
// Create HTML control (chtmlview)
Return create (null, // Class Name
Null, // Title
(Ws_child | ws_visible), // Style
RC, // rectangle
Pparent, // parent
NID, // Control ID
Null); // frame/DOC context not used
}
Then, use chtmlctrl: loadfromresource to open the page, which is inherited from chtmlview. Of course, you can also open the page like this: Res: // abouthtml.exe/about.html OK! I have already shown you how chtmlctrl can successfully display the frame in the dialog by avoiding cview !. I also introduced how to locate HTML files and image files in resource files. It also shows you how to open a Web page. But there is another amazing solution that I didn't tell you! :), Can you guess what it is? Wow, haha !!! Can I see the OK button in the about dialog box? It is not a button !! It's just an image in an HTML file! Even Javascript is used to make it up and down when it is clicked. But how does it communicate with our Dialog Box program ??? Do you mean fun?
If you have engaged in DHTML, you may think that the DHTML document layer can use com to discover the IMG element and then listen to its onclick event. But that's a tough and troublesome job for even such com semi-illiterate people !! :( In fact, there is a simpler method. Suppose you want this "button" to link to a document named OK: Now, When you click it, the browser will go to the OK file. But before doing so, the control is handed over to chtmlctrl: onbeforenavigate2. At this time, chtmlctrl can do anything legal:
<A href = "OK"> </A>
Void cmyhtmlctrl: onbeforenavigate2 (
Lpctstr lpszurl ,..., Bool * pbcancel)
{
If (_ tcscmp (lpszurl, _ T ("OK") = 0)
{
// "OK" clicked
* Pbcancle = true; // abort
// Will close Dialog
Getparent ()-> sendmessage (wm_command, idok );
}
}
[How exciting is this ?? Think about it. We can let the dialog box do almost everything we can do! In addition, we can make web pages more beautiful !! :] So, OK is not really another file, and chtmlctrl uses it to explain the OK button !! Perfect! To make this idea more compact, a pseudo-protocol is introduced! Called: APP :. Use tokens to replace oks. In about.htm, the link is actually app: OK. When chtmlctrl finds that the browser tries to navigate to app: somewhere, it calls a new virtual function, chtmlctrl: onappcmd. It uses somewhere as the parameter and cancels navigation ), therefore, cmyhtmlctrl does not overload onnavigate2, but overload onappcmd:
Void cmyhtmlctrl: onappcmd (lpctstr lpszwhere)
{
If (_ tcsicmp (lpszwhere, _ T ("OK") = 0)
{
Getparent ()-> sendmessage (wm_command, idok );
}
}
You can use other links in HTML files, such as APP: Cancel, APP: refresh, or app: whatever! :) Use the onappcmd function to find the corresponding strings, such as "cancel", "refresh", and "whatever ". Okay !! You can do what you want to do !... Before your crazy code, I would like to remind you that loading ie DLLs requires a very short wait, but if the loading of the about dialog box exceeds 10 seconds and the box is moved out, the user will feel very uncomfortable! :). Finally, when you right-click the about dialog box, a standard browser shortcut menu will pop up. You may think this is redundant, or for the purpose of protecting your source code, you will be able to block the right-click function. In fact, this is very simple. You just need to add a script code to the HTML tag ...... But after all, we are playing VC. So despite the trouble, we are happy to try it. This is not difficult !! We can also achieve this by using the subclass principle. But not now, but some time in the future !!

 

 

Latest comment [Post comment] [Post contribution] view all comments recommended to friends

Same as above. It cannot be used in vc7. Why can I help you analyze the cause? (Superw was published on 19:56:00)
 
Why is an error in vs2003 compilation? XP SP1

I:/My Documents/1-code/view2ctrl/Sun/abouthtml/htmlctrl. CPP (55): Error c2248: "ATL: _ noaddrefreleaseonccomptr <t>: Release": Private Members cannot be accessed (in "ATL :: _ noaddrefreleaseonccomptr <t> "class declaration)
With
[
T = iwebbrowser2
]
And
[
T = iwebbrowser2
]
(Bborn was published on 15:14:00)
 
Http://www.vckbase.com/document/viewdoc.asp? Id = 566
Is another translation version of the original text. Well, good.
// From http://webdigest.myrice.com/index.html (webdigest posted on 20:59:00)
 
98 OK, great. I also failed to use vc6 compilation in Windows 2 K, prompting that the memory was read illegally. Ask how to solve the problem. (W_yu1231 was published on 11:06:00)
 
It seems that I failed to use vc6 for compiling and using Windows 2 K. When I opened the dialog box, the message "Invalid Memory read" was prompted (hugeant was published on 5:01:00)
 
It is best to mention the original author's name during translation.
Paul dilascia is the author of Windows ++: Writing reusable code in C ++ (Addison-Wesley, 1992) and a freelance consultant and writer-at-large. he can be reached at askpd@pobox.com or http://pobox.com /~ Askpd.
BTW, Paul dilascia is not from Ms. He is a freelance writer.

(Alhawk was published on 21:59:00)
 
This chtmlctrl can only be used on cdialog.
It cannot be used on cformview.
Is there any way?

<Body oncontextmenu = "Return false"> Hey
(Published on 15:03:00)
 
OK
Yes. Thank you! (Funyfuyu was published on 11:21:00)
 
You can directly put the GIF file under the Resource Directory and edit the resource file in the file mode:
// In abouthtml. RC
......
Okdn. gif HTML discardable "res // okdn.gif"
Xxx. gif HTML discardable "res // xxx.gif"
...... (Microspace was published on 0:26:00)
 
Wow, it's amazing!
However, I have a small question to ask:
It is how to import GIF image files to resources. Once they are imported into the program, they will not respond and will die.
Is there any special method, or is it wrong? (Funyfuyu was published on 19:25:00)

 
 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.