Use the wtl Wizard to create a program wtlhtml and display the HTML page. In fact, it is also a webbrowser control of the host. We plan to do some customization work.
1. first, you must specify the external idispatch interface. we can add an ATL object to the project. or, simply implement it directly on the existing class. I plan to use the second method. implemented on cwtlhtmlview. add two parent classes to cwtlhtmlview:
Class cwtlhtmlview:
Public cwindowimpl <cwtlhtmlview, caxwindow>,
Public ccomobjectrootex <ccomsinglethreadmodel>, // provides the iunknown Interface
Public idispatchimpl <iwtlhtml, & iid_iwtlhtml, & libid_wtlhtmllib> // implement idispatch
{..}
Since idispatchimpl is used, you must have your own Type Library. create an IDL. copy one copy from another project. name. you can change the guid. after compilation, TLB (libid_wtlhtmllib) is generated ).
You must add com map to the class declaration:
Begin_com_map (cwtlhtmlview)
Com_interface_entry (idispatch)
End_com_map ()
Now cwtlhtmlview is a pure virtual class. It cannot be instantiated. Therefore, modify the definition of m_view in cmainframe:
Ccomobject <cwtlhtmlview> m_view;
Because m_view is not created on the stack, you do not need to consider the life cycle issue. Of course, it cannot be deleted from the delete in release (). We can first go to the cmainframe: oncreate () addref () next, set external.
M_view.addref ();
M_view.setexternaldispatch (static_cast <iwtlhtml *> (& m_view ));
Now you can call methods in the iwtlhtml interface in HTML.
2. to enable visual style for buttons on the webpage, you need to set dochostuiflag_theme. the general method is to implement idochostuihandler, and there is a ready-made idochostuihandlerdispatch interface in ATL. it is relatively simple to implement this function. Continue to add the parent class to the cwtlhtmlview.
Class cwtlhtmlview:
..
Public idispatchimpl <idochostuihandlerdispatch, & iid_idochostuihandlerdispatch, & libid_atllib>
{..}
Here, libid_atllib is The TLB that comes with ATL. dll. You can use oleview to see that there are only two interfaces in it. idochostuihandlerdispatch.
Iaxwinambientdispatch;
Added the iid_idochostuihandlerdispatch. we have to implement it. fortunately, e_notimpl can be directly returned; a relatively simple method is from atliface. in the H file, all method declarations are attached. all implementations are written as {return e_notimpl;}. Do not forget to implement gethostinfo (). This is the purpose of implementing the idochostuihandlerdispatch:
Virtual hresult stdmethodcalltype gethostinfo (
/* [Out] [in] */DWORD _ rpc_far * pdwflags,
/* [Out] [in] */DWORD _ rpc_far * pdwdoubleclick)
{
Atltrace ("called gethostinfo/N ");
* Pdwflags = dochostuiflag_theme | dochostuiflag_scroll_no | dochostuiflag_no3douterborder;
Return s_ OK;
}
Here we also set the dochostuiflag_scroll_no flag to remove the scroll bar on the right. dochostuiflag_no3douterborder to remove unnecessary border.
Add the following to cmainframe: oncreate:
M_view.setexternaluihandler (static_cast <idochostuihandlerdispatch *> (& m_view ));
It should be similar. Compilation. Does not work? The external implemented in the first step is also unavailable. I checked idochostuihandlerdispatch and found a getexternal method. check that you have implemented the idochostuihandlerdispatch in webbrowser. It will call getexternal () to obtain the idispatch as needed. because we directly returned e_notimpl. so external is unavailable. the modification is also simple:
Virtual hresult stdmethodcalltype getexternal (
/* [Out] */idispatch _ rpc_far * ppdispatch)
{
* Ppdispatch = static_cast <iwtlhtml *> (this );
Return s_ OK;
}
The new problem has been solved. But we still have no visual style. There is no way. Google. I found a post on codeguru:
Http://www.codeguru.com/forum/archive/index.php/t-164752.html
It turns out that when m_view.create () is called, the control is created and the HTML page is loaded. however, our setexternaluihandler () call is after this. therefore, the current page does not have visual style. however, if you call navigate2 () to a new page, you can see that the flag settings take effect. the most direct method is to first go to "about: blank" at "CREATE ()", set the attribute, and then go to the desired page at "navigate2. but codeguru's post mentioned another method: Calling iolecontrol: onambientpropertychange () notifies webbrowser that the property has changed. after webbrowser is notified, new attributes will be re-applied. the code is like this:
Ccomptr <iolecontrol> SPOC;
Hresult hR = m_view.querycontrol (iid_iolecontrol, (void **) & SPOC );
If (succeeded (HR ))
SPOC-> onambientpropertychange (dispid_unknown );
Dispid_unknown indicates that all attributes of webbrowser must be re-applied. running the program now is the expected result.
3. We often need to remove the right-click menu, but now it's just a breeze. idochostuihandlerdispatch also has a showcontextmenu (), and reload this method:
Virtual hresult stdmethodcalltype showcontextmenu (
/* [In] */DWORD dwid,
/* [In] */dword x,
/* [In] */DWORD y,
/* [In] */iunknown _ rpc_far * pcmdtreserved,
/* [In] */idispatch _ rpc_far * pdispreserved,
/* [Retval] [out] */hresult _ rpc_far * dwretval)
{* Dwretval = s_ OK; return s_ OK ;}
* Dwretval = s_ OK tells the webbrowser menu not to worry about it. Let's do it ourselves.