(转)续 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
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值