`
xumingrencai
  • 浏览: 1181317 次
文章分类
社区版块
存档分类
最新评论

(转)续 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. virtualHRESULTSTDMETHODCALLTYPEShowContextMenu(
  3. DWORDdwID,
  4. POINT*ppt,
  5. IUnknown*pcmdtReserved,
  6. IDispatch*pdispReserved);
  7. virtualHRESULTSTDMETHODCALLTYPEGetHostInfo(
  8. DOCHOSTUIINFO*pInfo);
  9. virtualHRESULTSTDMETHODCALLTYPEShowUI(
  10. DWORDdwID,
  11. IOleInPlaceActiveObject*pActiveObject,
  12. IOleCommandTarget*pCommandTarget,
  13. IOleInPlaceFrame*pFrame,
  14. IOleInPlaceUIWindow*pDoc);
  15. virtualHRESULTSTDMETHODCALLTYPEHideUI(void);
  16. virtualHRESULTSTDMETHODCALLTYPEUpdateUI(void);
  17. //IOleInPlaceFrame已经包含了这个方法 , IOleInPlaceFrame接口在WebBrowser中实现,所以不必要再次实现
  18. //virtualHRESULTSTDMETHODCALLTYPEEnableModeless(
  19. //BOOLfEnable);
  20. virtualHRESULTSTDMETHODCALLTYPEOnDocWindowActivate(
  21. BOOLfActivate);
  22. virtualHRESULTSTDMETHODCALLTYPEOnFrameWindowActivate(
  23. BOOLfActivate);
  24. virtualHRESULTSTDMETHODCALLTYPEResizeBorder(
  25. LPCRECTprcBorder,
  26. IOleInPlaceUIWindow*pUIWindow,
  27. BOOLfRameWindow);
  28. virtualHRESULTSTDMETHODCALLTYPETranslateAccelerator(
  29. LPMSGlpMsg,
  30. constGUID*pguidCmdGroup,
  31. DWORDnCmdID);
  32. virtualHRESULTSTDMETHODCALLTYPEGetOptionKeyPath(
  33. LPOLESTR*pchKey,
  34. DWORDdw);
  35. virtualHRESULTSTDMETHODCALLTYPEGetDropTarget(
  36. IDropTarget*pDropTarget,
  37. IDropTarget**ppDropTarget);
  38. virtualHRESULTSTDMETHODCALLTYPEGetExternal(
  39. IDispatch**ppDispatch);
  40. virtualHRESULTSTDMETHODCALLTYPETranslateUrl(
  41. DWORDdwTranslate,
  42. OLECHAR*pchURLIn,
  43. OLECHAR**ppchURLOut);
  44. virtualHRESULTSTDMETHODCALLTYPEFilterDataObject(
  45. IDataObject*pDO,
  46. IDataObject**ppDORet);
WebBrowserEx.cpp 部分
  1. /*
  2. =====================
  3. |IDocHostUIHandler|
  4. =====================
  5. */
  6. HRESULTWebBrowser::ShowContextMenu(
  7. DWORDdwID,
  8. POINT*ppt,
  9. IUnknown*pcmdtReserved,
  10. IDispatch*pdispReserved){returnE_NOTIMPL;}
  11. HRESULTWebBrowser::GetHostInfo(
  12. DOCHOSTUIINFO*pInfo){returnE_NOTIMPL;}
  13. HRESULTWebBrowser::ShowUI(
  14. DWORDdwID,
  15. IOleInPlaceActiveObject*pActiveObject,
  16. IOleCommandTarget*pCommandTarget,
  17. IOleInPlaceFrame*pFrame,
  18. IOleInPlaceUIWindow*pDoc){returnE_NOTIMPL;}
  19. HRESULTWebBrowser::HideUI(void){returnE_NOTIMPL;}
  20. HRESULTWebBrowser::UpdateUI(void){returnE_NOTIMPL;}
  21. //HRESULTWebBrowser::EnableModeless(
  22. //BOOLfEnable){returnE_NOTIMPL;}
  23. HRESULTWebBrowser::OnDocWindowActivate(
  24. BOOLfActivate){returnE_NOTIMPL;}
  25. HRESULTWebBrowser::OnFrameWindowActivate(
  26. BOOLfActivate){returnE_NOTIMPL;}
  27. HRESULTWebBrowser::ResizeBorder(
  28. LPCRECTprcBorder,
  29. IOleInPlaceUIWindow*pUIWindow,
  30. BOOLfRameWindow){returnE_NOTIMPL;}
  31. HRESULTWebBrowser::TranslateAccelerator(
  32. LPMSGlpMsg,
  33. constGUID*pguidCmdGroup,
  34. DWORDnCmdID){returnE_NOTIMPL;}
  35. HRESULTWebBrowser::GetOptionKeyPath(
  36. LPOLESTR*pchKey,
  37. DWORDdw){returnE_NOTIMPL;}
  38. HRESULTWebBrowser::GetDropTarget(
  39. IDropTarget*pDropTarget,
  40. IDropTarget**ppDropTarget)
  41. {
  42. returnE_NOTIMPL;//使用默认拖拽
  43. //returnS_OK;//自定义拖拽
  44. }
  45. HRESULTWebBrowser::GetExternal(IDispatch**ppDispatch)
  46. {
  47. returnE_NOTIMPL;
  48. }
  49. HRESULTWebBrowser::TranslateUrl(
  50. DWORDdwTranslate,
  51. OLECHAR*pchURLIn,
  52. OLECHAR**ppchURLOut){returnE_NOTIMPL;}
  53. HRESULTWebBrowser::FilterDataObject(
  54. IDataObject*pDO,
  55. IDataObject**ppDORet){returnE_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. virtualSTDMETHODIMP_(void)DocumentComplete(IDispatch*pDisp,VARIANT*URL);//其实是:virtualvoid__stdcallDocumentComplete(...)
WebBrowserEx.cpp部分
  1. void
  2. WebBrowserEx::DocumentComplete(IDispatch*pDisp,VARIANT*URL)
  3. {
  4. // 装载Event响应函数
  5. IHTMLDocument3*pHtmlDoc3=GetHTMLDocument3();
  6. BSTRbsMouseMoveEvent=::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. typedefHRESULT(*EVENT_FUNCTION)(LPVOID);
  3. classCHtmlEvents:
  4. publicIDispatch
  5. {
  6. public:
  7. CHtmlEvents();
  8. virtual~CHtmlEvents(void);
  9. //IUnknownmethods
  10. virtualSTDMETHODIMPQueryInterface(REFIIDiid,void**ppvObject);
  11. virtualSTDMETHODIMP_(ULONG)AddRef();
  12. virtualSTDMETHODIMP_(ULONG)Release();
  13. //IDispatchMethods
  14. HRESULT_stdcallGetTypeInfoCount(unsignedint*pctinfo);
  15. HRESULT_stdcallGetTypeInfo(unsignedintiTInfo,LCIDlcid,ITypeInfoFAR*FAR*ppTInfo);
  16. HRESULT_stdcallGetIDsOfNames(REFIIDriid,OLECHARFAR*FAR*rgszNames,unsignedintcNames,LCIDlcid,DISPIDFAR*rgDispId);
  17. HRESULT_stdcallInvoke(DISPIDdispIdMember,REFIIDriid,LCIDlcid,WORDwFlags,DISPPARAMSFAR*pDispParams,VARIANTFAR*pVarResult,EXCEPINFOFAR*pExcepInfo,unsignedintFAR*puArgErr);
  18. //OtherMethod
  19. staticLPDISPATCHCreateEventObject(EVENT_FUNCTIONpFunc,DISPIDid,LPVOIDlpUserData);
  20. private:
  21. long_lRef;
  22. EVENT_FUNCTION_fnEvent;
  23. DISPID_id;
  24. LPVOID_pUserData;
  25. };
HtmlEvents.cpp
  1. #include"HtmlEvents.h"
  2. //CHtmlEventsclass
  3. CHtmlEvents::CHtmlEvents()
  4. {
  5. }
  6. CHtmlEvents::~CHtmlEvents()
  7. {
  8. }
  9. /*
  10. ==================
  11. |IUnknownmethods|
  12. ==================
  13. */
  14. STDMETHODIMPCHtmlEvents::QueryInterface(REFIIDiid,void**ppvObject)
  15. {
  16. if(iid==IID_IUnknown||iid==IID_IDispatch)
  17. {
  18. *ppvObject=this;
  19. AddRef();
  20. returnS_OK;
  21. }
  22. returnE_NOTIMPL;
  23. }
  24. STDMETHODIMP_(ULONG)CHtmlEvents::AddRef()
  25. {
  26. returnInterlockedIncrement(&_lRef);
  27. }
  28. STDMETHODIMP_(ULONG)CHtmlEvents::Release()
  29. {
  30. return::InterlockedDecrement(&_lRef);
  31. }
  32. /*
  33. =====================
  34. |IDispatchMethods|
  35. =====================
  36. */
  37. HRESULT_stdcallCHtmlEvents::GetTypeInfoCount(
  38. unsignedint*pctinfo)
  39. {
  40. returnE_NOTIMPL;
  41. }
  42. HRESULT_stdcallCHtmlEvents::GetTypeInfo(
  43. unsignedintiTInfo,
  44. LCIDlcid,
  45. ITypeInfoFAR*FAR*ppTInfo)
  46. {
  47. returnE_NOTIMPL;
  48. }
  49. HRESULT_stdcallCHtmlEvents::GetIDsOfNames(REFIIDriid,
  50. OLECHARFAR*FAR*rgszNames,
  51. unsignedintcNames,
  52. LCIDlcid,
  53. DISPIDFAR*rgDispId
  54. )
  55. {
  56. returnE_NOTIMPL;
  57. }
  58. HRESULT_stdcallCHtmlEvents::Invoke(
  59. DISPIDdispIdMember,
  60. REFIIDriid,
  61. LCIDlcid,
  62. WORDwFlags,
  63. DISPPARAMS*pDispParams,
  64. VARIANT*pVarResult,
  65. EXCEPINFO*pExcepInfo,
  66. unsignedint*puArgErr)
  67. {
  68. if(DISPID_VALUE==dispIdMember)
  69. {
  70. (_fnEvent)(_pUserData);
  71. returnS_OK;
  72. }
  73. returnE_NOTIMPL;
  74. }
  75. //返回一个CHtmlEvents的实例
  76. //pFunc表示当相关消息发生时,CHtmlEvents的实例调用pFunc这个函数,同时参数是lpUserData,MSDN上有相关实现.
  77. //他的注销可以通过Detach后delete
  78. //或者Release()自动销毁,这里我们用了Detach后delete
  79. LPDISPATCHCHtmlEvents::CreateEventObject(EVENT_FUNCTIONpFunc,DISPIDid,LPVOIDlpUserData)
  80. {
  81. CHtmlEvents*npHE=newCHtmlEvents;
  82. npHE->_fnEvent=pFunc;
  83. npHE->_id=id;
  84. npHE->_pUserData=lpUserData;
  85. returnreinterpret_cast<LPDISPATCH>(npHE);
  86. };
还有一些诸如window.external 接口的实现因为已经有人说的很详细了,所以不再谈论了.

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

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics