(转)续 WebBrowser 的扩展

上次写了WebBrowser这个容器( 详细参看: http://blog.csdn.net/norsd/archive/2008/09/13/2921389.aspx )

今天来说说如何在 WebBrowser的基础上扩展更多的功能.
 WebBrowserEx : public WebBrowser , public IDocHostUIHandler
1.实现 IDocHostUIHandler接口
WebBrowserEx 继承了WebBrowser ,并且加入了IDocHostUIHandler, 该接口可以个性化WB控件, 同样的必须事先实现IDocHostUIHandle
WebBrowserEx .h 部分
  1. //IDocHostUIHandler
  2.     virtual HRESULT STDMETHODCALLTYPE ShowContextMenu( 
  3.          DWORD dwID,
  4.          POINT *ppt,
  5.          IUnknown *pcmdtReserved,
  6.          IDispatch *pdispReserved);
  7.     virtual HRESULT STDMETHODCALLTYPE GetHostInfo( 
  8.          DOCHOSTUIINFO *pInfo);
  9.     virtual HRESULT STDMETHODCALLTYPE ShowUI( 
  10.          DWORD dwID,
  11.          IOleInPlaceActiveObject *pActiveObject,
  12.          IOleCommandTarget *pCommandTarget,
  13.          IOleInPlaceFrame *pFrame,
  14.          IOleInPlaceUIWindow *pDoc);
  15.     virtual HRESULT STDMETHODCALLTYPE HideUI( void);
  16.     virtual HRESULT STDMETHODCALLTYPE UpdateUI( void);
  17.     //IOleInPlaceFrame已经包含了这个方法 , IOleInPlaceFrame接口在WebBrowser中实现,所以不必要再次实现
  18.     //virtual HRESULT STDMETHODCALLTYPE EnableModeless( 
  19.     //   BOOL fEnable);
  20.     virtual HRESULT STDMETHODCALLTYPE OnDocWindowActivate( 
  21.          BOOL fActivate);
  22.     virtual HRESULT STDMETHODCALLTYPE OnFrameWindowActivate( 
  23.          BOOL fActivate);
  24.     virtual HRESULT STDMETHODCALLTYPE ResizeBorder( 
  25.          LPCRECT prcBorder,
  26.          IOleInPlaceUIWindow *pUIWindow,
  27.          BOOL fRameWindow);
  28.     virtual HRESULT STDMETHODCALLTYPE TranslateAccelerator( 
  29.          LPMSG lpMsg,
  30.          const GUID *pguidCmdGroup,
  31.          DWORD nCmdID);
  32.     virtual HRESULT STDMETHODCALLTYPE GetOptionKeyPath( 
  33.          LPOLESTR *pchKey,
  34.          DWORD dw);
  35.     virtual HRESULT STDMETHODCALLTYPE GetDropTarget( 
  36.          IDropTarget *pDropTarget,
  37.          IDropTarget **ppDropTarget);
  38.     virtual HRESULT STDMETHODCALLTYPE GetExternal( 
  39.          IDispatch **ppDispatch);
  40.     virtual HRESULT STDMETHODCALLTYPE TranslateUrl( 
  41.          DWORD dwTranslate,
  42.          OLECHAR *pchURLIn,
  43.          OLECHAR **ppchURLOut);
  44.     virtual HRESULT STDMETHODCALLTYPE FilterDataObject( 
  45.          IDataObject *pDO,
  46.          IDataObject **ppDORet);
WebBrowserEx.cpp 部分
  1. /*
  2. =====================
  3. | IDocHostUIHandler |
  4. =====================
  5. */
  6. HRESULT WebBrowser:: ShowContextMenu( 
  7.     DWORD dwID,
  8.     POINT *ppt,
  9.     IUnknown *pcmdtReserved,
  10.     IDispatch *pdispReserved){return E_NOTIMPL;}
  11. HRESULT WebBrowser:: GetHostInfo( 
  12.                                         DOCHOSTUIINFO *pInfo){return E_NOTIMPL;}
  13. HRESULT WebBrowser:: ShowUI( 
  14.                                    DWORD dwID,
  15.                                    IOleInPlaceActiveObject *pActiveObject,
  16.                                    IOleCommandTarget *pCommandTarget,
  17.                                    IOleInPlaceFrame *pFrame,
  18.                                    IOleInPlaceUIWindow *pDoc){return E_NOTIMPL;}
  19. HRESULT WebBrowser:: HideUI( void){return E_NOTIMPL;}
  20. HRESULT WebBrowser:: UpdateUI( void){return E_NOTIMPL;}
  21. //HRESULT WebBrowser:: EnableModeless( 
  22. //  BOOL fEnable){return E_NOTIMPL;}
  23. HRESULT WebBrowser:: OnDocWindowActivate( 
  24.     BOOL fActivate){return E_NOTIMPL;}
  25. HRESULT WebBrowser:: OnFrameWindowActivate( 
  26.     BOOL fActivate){return E_NOTIMPL;}
  27. HRESULT WebBrowser:: ResizeBorder( 
  28.     LPCRECT prcBorder,
  29.     IOleInPlaceUIWindow *pUIWindow,
  30.     BOOL fRameWindow){return E_NOTIMPL;}
  31. HRESULT WebBrowser:: TranslateAccelerator( 
  32.     LPMSG lpMsg,
  33.     const GUID *pguidCmdGroup,
  34.     DWORD nCmdID){return E_NOTIMPL;}
  35. HRESULT WebBrowser:: GetOptionKeyPath( 
  36.     LPOLESTR *pchKey,
  37.     DWORD dw){return E_NOTIMPL;}
  38. HRESULT WebBrowser:: GetDropTarget( 
  39.     IDropTarget *pDropTarget,
  40.     IDropTarget **ppDropTarget)
  41. {
  42.     return E_NOTIMPL;//使用默认拖拽
  43.     //return S_OK;//自定义拖拽
  44. }
  45. HRESULT WebBrowser:: GetExternal( IDispatch **ppDispatch)
  46. {
  47.     return E_NOTIMPL;
  48. }
  49. HRESULT WebBrowser:: TranslateUrl( 
  50.     DWORD dwTranslate,
  51.     OLECHAR *pchURLIn,
  52.     OLECHAR **ppchURLOut){return E_NOTIMPL;}
  53. HRESULT WebBrowser:: FilterDataObject( 
  54.     IDataObject *pDO,
  55.     IDataObject **ppDORet){return E_NOTIMPL;}
关于如何个性化IDocHostUIHandler 可以看这个: http://www.vckbase.com/document/viewdoc/?id=1486
很多人在那篇提问如何在SDK的模式下支持 IDocHostUIHandler, 我的这篇文章就是一个答案了, 你会慢慢爱上SDK的. 
2.拖拽的处理
那篇文章:  http://www.vckbase.com/document/viewdoc/?id=1486 中由于是MFC的实现, 对于SDK实现来说缺少了一点东西,
3.处理HTML的众多Event
在MFC的 HTMLDialog 中, 可以实现诸如 MouseMove 之类的消息, 让我们用SDK实现之.
下面实现了一个简单的事件onmousemove
WebBrowserEx.h 部分:
  1. virtual STDMETHODIMP_(void) DocumentComplete( IDispatch *pDisp,VARIANT *URL);//其实是: virtual void __stdcall DocumentComplete(...)
WebBrowserEx.cpp部分
  1. void
  2. WebBrowserEx::DocumentComplete( IDispatch *pDisp,VARIANT *URL)
  3. {
  4.     //  装载Event 响应函数
  5.     IHTMLDocument3* pHtmlDoc3 = GetHTMLDocument3();
  6.     BSTR bsMouseMoveEvent = ::SysAllocString(L"onmousemove");
  7.     pHtmlDoc3->attachEvent(
  8.                                                  bsMouseMoveEvent,
  9.                             CHtmlEvents::CreateEventObject( (EVENT_FUNCTION) WebBrowserEx::OnHtmlMouseMove, 0, this ));
  10.     ::SysFreeString(bsMouseMoveEvent);
  11.      //  注意在卸载的时候要调用detachEvent
  12.     WebBrowser::DocumentComplete( pDisp, URL );//  掉哦那个基类
  13.     return;
  14. }
关于 CHtmlEvents 这是一个独立的类, CreateEventObject 返回一个IDispatch的实例, 来响应 onmousemove.
其实现类似于MSDN中的相关类.
HtmlEvents.h
  1. //EVENT_FUNCTION 函数指针定义  被应用于:CreateEventObject;
  2. typedef HRESULT (*EVENT_FUNCTION)(LPVOID);
  3. class CHtmlEvents:
  4.     public IDispatch
  5. {
  6. public:
  7.     CHtmlEvents();
  8.     virtual ~CHtmlEvents(void);
  9.     // IUnknown methods
  10.     virtual STDMETHODIMP QueryInterface(REFIID iid,void**ppvObject);
  11.     virtual STDMETHODIMP_(ULONG) AddRef();
  12.     virtual STDMETHODIMP_(ULONG) Release();
  13.     // IDispatch Methods
  14.     HRESULT _stdcall GetTypeInfoCount(unsigned int * pctinfo);
  15.     HRESULT _stdcall GetTypeInfo(unsigned int iTInfo,LCID lcid,ITypeInfo FAR* FAR* ppTInfo);
  16.     HRESULT _stdcall GetIDsOfNames(REFIID riid,OLECHAR FAR* FAR* rgszNames,unsigned int cNames,LCID lcid,DISPID FAR* rgDispId);
  17.     HRESULT _stdcall Invoke(DISPID dispIdMember,REFIID riid,LCID lcid,WORD wFlags,DISPPARAMS FAR* pDispParams,VARIANT FAR* pVarResult,EXCEPINFO FAR* pExcepInfo,unsigned int FAR* puArgErr);
  18.     //Other Method
  19.     static LPDISPATCH CreateEventObject(EVENT_FUNCTION pFunc, DISPID id, LPVOID lpUserData);
  20. private:
  21.     long _lRef;
  22.     EVENT_FUNCTION _fnEvent;
  23.     DISPID _id;
  24.     LPVOID _pUserData;
  25. };
HtmlEvents.cpp
  1. #include "HtmlEvents.h"
  2. // CHtmlEvents class
  3. CHtmlEvents::CHtmlEvents()
  4. {
  5. }
  6. CHtmlEvents::~CHtmlEvents()
  7. {
  8. }
  9. /*
  10. ==================
  11. |IUnknown methods|
  12. ==================
  13. */
  14. STDMETHODIMP CHtmlEvents::QueryInterface(REFIID iid,void**ppvObject)
  15. {
  16.     if( iid == IID_IUnknown || iid == IID_IDispatch )
  17.     {
  18.         *ppvObject = this;
  19.         AddRef();
  20.         return S_OK;
  21.     }
  22.     return E_NOTIMPL;
  23. }
  24. STDMETHODIMP_(ULONG)  CHtmlEvents::AddRef()
  25. {
  26.     return InterlockedIncrement(&_lRef);
  27. }
  28. STDMETHODIMP_(ULONG)  CHtmlEvents::Release()
  29. {
  30.     return ::InterlockedDecrement(&_lRef);
  31. }
  32. /*
  33. =====================
  34. | IDispatch Methods |
  35. =====================
  36. */
  37. HRESULT _stdcall CHtmlEvents::GetTypeInfoCount(
  38.     unsigned int * pctinfo) 
  39. {
  40.     return E_NOTIMPL;
  41. }
  42. HRESULT _stdcall CHtmlEvents::GetTypeInfo(
  43.     unsigned int iTInfo,
  44.     LCID lcid,
  45.     ITypeInfo FAR* FAR* ppTInfo) 
  46. {
  47.     return E_NOTIMPL;
  48. }
  49. HRESULT _stdcall CHtmlEvents::GetIDsOfNames(REFIID riid, 
  50.   OLECHAR FAR* FAR* rgszNames, 
  51.   unsigned int cNames, 
  52.   LCID lcid, 
  53.   DISPID FAR* rgDispId 
  54. )
  55. {
  56.     return E_NOTIMPL;
  57. }
  58. HRESULT _stdcall CHtmlEvents::Invoke(
  59.     DISPID dispIdMember,
  60.     REFIID riid,
  61.     LCID lcid,
  62.     WORD wFlags,
  63.     DISPPARAMS* pDispParams,
  64.     VARIANT* pVarResult,
  65.     EXCEPINFO* pExcepInfo,
  66.     unsigned int* puArgErr)
  67. {
  68.     if( DISPID_VALUE == dispIdMember )
  69.     {
  70.         (_fnEvent)( _pUserData );
  71.         return S_OK;
  72.     }
  73.     return E_NOTIMPL;
  74. }
  75. //返回一个CHtmlEvents的实例
  76. //pFunc 表示当相关消息发生时, CHtmlEvents的实例调用pFunc这个函数, 同时参数是lpUserData,MSDN上有相关实现.
  77. //他的注销可以通过Detach 后 delete
  78. //或者 Release() 自动销毁,这里我们用了 Detach后delete
  79. LPDISPATCH CHtmlEvents::CreateEventObject(EVENT_FUNCTION pFunc, DISPID id, LPVOID lpUserData)
  80. {
  81.     CHtmlEvents* npHE = new CHtmlEvents;
  82.     npHE->_fnEvent = pFunc;
  83.     npHE->_id = id;
  84.     npHE->_pUserData = lpUserData;
  85.     return reinterpret_cast<LPDISPATCH>(npHE);
  86. };
还有一些诸如window.external 接口的实现因为已经有人说的很详细了,所以不再谈论了.

转自:http://blog.csdn.net/norsd/article/details/2934253

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
WebbrowserEx模仿IE实例源码 Private WithEvents mobjWebDoc As MSHTML.HTMLDocument Private WithEvents MouseEvent As CMouseHook Private WithEvents KeyboardEvent As CKeyboardHook Private WithEvents frmTopParent As VB.Form Private m_Documents As Collection 'HTML Documents collection Private m_Frames As Collection 'HTML Frames collection '------------------------------------------------------------------------------- ' Webbrowser naviagtion events '------------------------------------------------------------------------------- ' Event IntializeBeforeGoHome(Cancel As Boolean) Event StatusTextChange(ByVal Text As String) Event TitleChange(ByVal Text As String) Event NewDocumentStart(ByVal WebDoc As HTMLDocument, ByVal URL As String, ByVal IsTargetedToFrame As Boolean, ByVal TargetFrameName As String, Cancel As Boolean) Event NewDocumentComplete(ByVal WebDoc As HTMLDocument, ByVal URL As String, ByVal IsTargetedToFrame As Boolean, ByVal TargetFrameName As String) Event BeforeNavigate2(ByVal WebDoc As HTMLDocument, ByVal URL As String, Flags As Variant, TargetFrameName As Variant, PostData As Variant, Headers As Variant, Cancel As Boolean) Event NavigateComplete2(ByVal WebDoc As HTMLDocument, ByVal URL As String) Event DocumentComplete(ByVal WebDoc As HTMLDocument, ByVal URL As String) Event BeforeNewWindow2(ByVal URL As String, NewBrowser As Object, Cancel As Boolean) '------------------------------------------------------------------------------- ' User control-wide mouse events '------------------------------------------------------------------------------- ' Event UserControlMouseUp(ByVal Control As Object, ByVal HWnd As Long, Button As Integer, Shift As Integer, X As Single, Y As Single, Cancel As Boolean) Event UserControlMouseMove(ByVal Control As Object, ByVal HWnd As Long, Button As Integer, Shift As Integer, X As Single, Y As Single, Cancel As Boolean) Event UserControlMouseDown(ByVal Control As Object, ByVal HWnd As Long, Button As Integer, Shift As Integer, X As Single, Y As Single, Cancel As Boolean) '------------------------------------------------------------------------------- ' WebBrowser mouse events '------------------------------------------------------------------------------- ' Event WebBrowserDblClick(Cancel As Boolean) Event WebBrowserMouseUp(Button As Integer, Shift As Integer, X As Single, Y As Single, Cancel As Boolean) Event WebBrowserMouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single, Cancel As Boolean) Event WebBrowserMouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single, Cancel As Boolean) Event WebBrowserMouseDownContextMenu(ByVal IsMouseOnLink As Boolean, ByVal URL As String, ByVal SelText As String, Cancel As Boolean) Event WebBrowserMouseUpContextMenu(ByVal IsMouseOnLink As Boolean, ByVal URL As String, ByVal SelText As String, Cancel As Boolean) '------------------------------------------------------------------------------- ' WebBrowser keyboard events '------------------------------------------------------------------------------- ' Event WebBrowserKeyDown(KeyCode As Integer, Shift As Integer) Event WebBrowserKeyUp(KeyCode As Integer, Shift As Integer) '------------------------------------------------------------------------------- ' Go button keyboard events '------------------------------------------------------------------------------- ' Event GoButtonKeyDown(KeyCode As Integer, Shift As Integer) Event GoButtonKeyUp(KeyCode As Integer, Shift As Integer) '------------------------------------------------------------------------------- ' Address bar keyboard events (combo box) '------------------------------------------------------------------------------- ' Event AddressBarContextMenu(Cancel As Boolean) Event AddressBarKeyDown(KeyCode As Integer, Shift As Integer) Event AddressBarKeyUp(KeyCode As Integer, Shift As Integer) '------------------------------------------------------------------------------- ' Statusbar keyboard events '------------------------------------------------------------------------------- ' Event StatusBarKeyDown(KeyCode As Integer, Shift As Integer) Event StatusBarKeyUp(KeyCode As Integer, Shift As Integer) '------------------------------------------------------------------------------- ' Statusbar mouse events '------------------------------------------------------------------------------- ' Event StatusBarPanelClick(Panel As MSComctlLib.Panel) Event StatusBarPanelDblClick(Panel As MSComctlLib.Panel) Event StatusBarMouseMove(Panel As MSComctlLib.Panel, Button As Integer, Shift As Integer, X As Single, Y As Single) Event StatusBarMouseDown(Panel As MSComctlLib.Panel, Button As Integer, Shift As Integer, X As Single, Y As Single) Event StatusBarMouseUp(Panel As MSComctlLib.Panel, Button As Integer, Shift As Integer, X As Single, Y As Single) Private mstrStatusText As String 'Webrrowser status text Private mlngWBHwnd As Long 'Webbrowser handle Private mHwndComboEdit As Long 'Combo edit box handle Private mobjTopParent As VB.Form 'Reference to Top parent form Private mbRunMode As Boolean 'Run/Develope mode detection variable Private newX As Single 'Variables that contained the converted x, y coordinates Private newY As Single Private mhwndTopParent As Long 'Top parent form handle Private mstrClickedLinkURL As String 'Click-on url Private mstrNavigate2URL As String 'Navigation start url Private mstrNavigatedURL As String 'Navigated url Private mstrTargetFrameName As String 'Naviation target frame Const m_def_PopupWindowAllowed = True Const m_def_OpenHomePageAtStart = True Const m_def_AddressBarVisible = True Const m_def_StatusBarVisible = True Const m_def_MouseEventEnabled = True Const m_def_KeyboardEventEnabled = True Private m_AddressBarVisible As Boolean Private m_PopupWindowAllowed As Boolean Private m_OpenHomePageAtStart As Boolean Private m_StatusBarVisible As Boolean Private m_MouseEventEnabled As Boolean Private m_KeyboardEventEnabled As Boolean '------------------------------------------------------------------------------- ' TopParent '------------------------------------------------------------------------------- ' Get the top parent form of the user control Public Property Get TopParent() As Object On Error Resume Next If mobjTopParent Is Nothing Then Dim objParent As Object Set objParent = UserControl.Parent Do While Not TypeOf objParent Is VB.Form Set objParent = objParent.Parent Loop Set mobjTopParent = objParent Set objParent = Nothing End If Set TopParent = mobjTopParent End Property

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值