Big |
Medium |
Aurora Borealis Movie Posted in 2008-06-25 17:59 Microsoft Web Browser ActiveX control is an IE kernel-based browser control that allows you to embed tiny browsers in your application interface. By implementing various interfaces, you can even use it to build a powerful browser like Maxthon. Of course, as a general simple application, the CWebBrowser class generated using the MFC ActiveX Control class Generation Wizard is sufficient.
There is a strange need in recent work: When a user clicks a hyperlink in a Microsoft Web Browser control, the hyperlink is opened with the default browser (not necessarily IE) on the user's machine. As we all know, by default, when you click a hyperlink from the Microsoft Web Browser control, IE will download the page that the into hyperspace link points to in this window or in the new IE window/ The tab page opens this link (depending on the user's configuration and the target parameter of the A element in HTML), so to achieve the above requirements, you must do two things:
View Source print?
1 |
1. If you specify to load new content in the current window, then you should block this load and then open the content in the default browser according to the URL you want to load. |
3 |
2, if it is specified in the new Window/tab page loading, then to prevent this open, and then based on the loaded URL in the default browser to open the corresponding content |
The question now is how to get the URLs that will be loaded or opened.
When some behavior occurs, the Microsoft Web Browser control sends some event messages to the top-level parent window where it is located. The parent window listens to these events to know what the Microsoft Web Browser control is about to do and what it has done. The two events, Dispid_beforenavigate2 and dispid_newwindow2, are useful for the requirements that this article will implement. The former indicates that the control is about to load the Web page, which indicates that the control is about to open a new window.
For the above Case 1, we can simply listen to the dispid_beforenavigate2 to solve, because the control will tell us it to load the URL:
View Source print?
1 |
This is to add an MFC message map for the Idc_mywebctrl control in the Cmyhtmlwnd class |
3 |
Begin_eventsink_map (Cmyhtmlwnd, CWnd) |
4 |
On_event (Cmyhtmlwnd, Idc_mywebctrl, Dispid_beforenavigate2, OnBeforeNavigate2, Vts_dispatch ts_pvariant VTS_PVARIANT Vts_pvariant vts_pvariant vts_pvariant Vts_pbool) |
7 |
This is the definition of the DISPID_BEFORENAVIGATE2 processing function. |
9 |
void OnBeforeNavigate2 (Lpdispatch pdisp, Variant far* URL, Variant far* Flags, Variant far* Targetframename, Variant far* PostData, VARIANT far* Headers, BOOL far* Cancel); |
Notice that the URL parameter in the OnBeforeNavigate2 function is the URL to be loaded. and the content setting of the Cancel parameter to set TRUE allows us to undo this load successfully.
So how do you deal with the situation?
We listened to the Dispid_newwindow2 event, but found that this event only allowed us to undo this opening or to specify which IDispatch instance (you can simply think of as the browser control) to open the URL without telling us what URL to open.
View Source print?
1 |
On_event (Cmyhtmlwnd, Idc_mywebctrl, Dispid_newwindow2, OnNewWindow2, Vts_pdispatch Vts_pbool) |
3 |
void OnNewWindow2 (Lpdispatch far* ppdisp, BOOL far* Cancel); |
programmers are always smart, and in front of smart programmers, all the difficulties are paper Tigers .:-)
Look at the code that the seniors left behind, and find out how they handled it: When dispid_newwindow2 occurs, set a flag flag, then redirect this turn to another hidden Microsoft Web Browser control, and then in that control's The flag is viewed in the Dispid_beforenavigate2 event handler, and if flag is opened, it means that it is an open window operation, which is revoked, and the URL is also obtained. Because there is no multithreaded UI problem, these events occur serially, so this method is correct.
However, I think this method, although it achieves the goal, looks very disgusting. So I tried to find another way. After looking at Microsoft's documentation, I finally found a relatively superior approach. My approach is this: Implement the IDocHostUIHandler::TranslateUrl interface, through this interface to save the URL of the Web page being processed, while listening to the Dispid_newwindow2 event, once Dispid_newwindow2 event occurs, this event is blocked by the Cancel parameter, and TranslateUrl is sure to be called first before the Dispid_newwindow2 event occurs, so the URL that is now saved is the URL of the window to be opened, because again, The occurrences of these events are serial.
Another: By looking at Microsoft's documentation, there is actually a very good event dispid_newwindow3. This event brought back a very comprehensive message, including the URL we crave, but unfortunately, this event is not supported by Windows XP SP2 or more.