续 WebBrowser 的扩展
上次写了WebBrowser这个容器( 详细参看: http://blog.csdn.net/norsd/archive/2008/09/13/2921389.aspx )今天来说说如何在 WebBrowser的基础上扩展更多的功能. WebBrowserEx : public WebBrowser ,public IDocHostUIHandler1.实现IDocH
·
上次写了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 部分
- //IDocHostUIHandler
- virtual HRESULT STDMETHODCALLTYPE ShowContextMenu(
- DWORD dwID,
- POINT *ppt,
- IUnknown *pcmdtReserved,
- IDispatch *pdispReserved);
- virtual HRESULT STDMETHODCALLTYPE GetHostInfo(
- DOCHOSTUIINFO *pInfo);
- virtual HRESULT STDMETHODCALLTYPE ShowUI(
- DWORD dwID,
- IOleInPlaceActiveObject *pActiveObject,
- IOleCommandTarget *pCommandTarget,
- IOleInPlaceFrame *pFrame,
- IOleInPlaceUIWindow *pDoc);
- virtual HRESULT STDMETHODCALLTYPE HideUI( void);
- virtual HRESULT STDMETHODCALLTYPE UpdateUI( void);
- //IOleInPlaceFrame已经包含了这个方法 , IOleInPlaceFrame接口在WebBrowser中实现,所以不必要再次实现
- //virtual HRESULT STDMETHODCALLTYPE EnableModeless(
- // BOOL fEnable);
- virtual HRESULT STDMETHODCALLTYPE OnDocWindowActivate(
- BOOL fActivate);
- virtual HRESULT STDMETHODCALLTYPE OnFrameWindowActivate(
- BOOL fActivate);
- virtual HRESULT STDMETHODCALLTYPE ResizeBorder(
- LPCRECT prcBorder,
- IOleInPlaceUIWindow *pUIWindow,
- BOOL fRameWindow);
- virtual HRESULT STDMETHODCALLTYPE TranslateAccelerator(
- LPMSG lpMsg,
- const GUID *pguidCmdGroup,
- DWORD nCmdID);
- virtual HRESULT STDMETHODCALLTYPE GetOptionKeyPath(
- LPOLESTR *pchKey,
- DWORD dw);
- virtual HRESULT STDMETHODCALLTYPE GetDropTarget(
- IDropTarget *pDropTarget,
- IDropTarget **ppDropTarget);
- virtual HRESULT STDMETHODCALLTYPE GetExternal(
- IDispatch **ppDispatch);
- virtual HRESULT STDMETHODCALLTYPE TranslateUrl(
- DWORD dwTranslate,
- OLECHAR *pchURLIn,
- OLECHAR **ppchURLOut);
- virtual HRESULT STDMETHODCALLTYPE FilterDataObject(
- IDataObject *pDO,
- IDataObject **ppDORet);
- /*
- =====================
- | IDocHostUIHandler |
- =====================
- */
- HRESULT WebBrowser:: ShowContextMenu(
- DWORD dwID,
- POINT *ppt,
- IUnknown *pcmdtReserved,
- IDispatch *pdispReserved){return E_NOTIMPL;}
- HRESULT WebBrowser:: GetHostInfo(
- DOCHOSTUIINFO *pInfo){return E_NOTIMPL;}
- HRESULT WebBrowser:: ShowUI(
- DWORD dwID,
- IOleInPlaceActiveObject *pActiveObject,
- IOleCommandTarget *pCommandTarget,
- IOleInPlaceFrame *pFrame,
- IOleInPlaceUIWindow *pDoc){return E_NOTIMPL;}
- HRESULT WebBrowser:: HideUI( void){return E_NOTIMPL;}
- HRESULT WebBrowser:: UpdateUI( void){return E_NOTIMPL;}
- //HRESULT WebBrowser:: EnableModeless(
- // BOOL fEnable){return E_NOTIMPL;}
- HRESULT WebBrowser:: OnDocWindowActivate(
- BOOL fActivate){return E_NOTIMPL;}
- HRESULT WebBrowser:: OnFrameWindowActivate(
- BOOL fActivate){return E_NOTIMPL;}
- HRESULT WebBrowser:: ResizeBorder(
- LPCRECT prcBorder,
- IOleInPlaceUIWindow *pUIWindow,
- BOOL fRameWindow){return E_NOTIMPL;}
- HRESULT WebBrowser:: TranslateAccelerator(
- LPMSG lpMsg,
- const GUID *pguidCmdGroup,
- DWORD nCmdID){return E_NOTIMPL;}
- HRESULT WebBrowser:: GetOptionKeyPath(
- LPOLESTR *pchKey,
- DWORD dw){return E_NOTIMPL;}
- HRESULT WebBrowser:: GetDropTarget(
- IDropTarget *pDropTarget,
- IDropTarget **ppDropTarget)
- {
- return E_NOTIMPL;//使用默认拖拽
- //return S_OK;//自定义拖拽
- }
- HRESULT WebBrowser:: GetExternal( IDispatch **ppDispatch)
- {
- return E_NOTIMPL;
- }
- HRESULT WebBrowser:: TranslateUrl(
- DWORD dwTranslate,
- OLECHAR *pchURLIn,
- OLECHAR **ppchURLOut){return E_NOTIMPL;}
- HRESULT WebBrowser:: FilterDataObject(
- IDataObject *pDO,
- IDataObject **ppDORet){return E_NOTIMPL;}
很多人在那篇提问如何在SDK的模式下支持
IDocHostUIHandler, 我的这篇文章就是一个答案了, 你会慢慢爱上SDK的.
2.拖拽的处理
那篇文章:
http://www.vckbase.com/document/viewdoc/?id=1486 中由于是MFC的实现, 对于SDK实现来说缺少了一点东西,
3.处理HTML的众多Event
在MFC的 HTMLDialog 中, 可以实现诸如 MouseMove 之类的消息, 让我们用SDK实现之.
下面实现了一个简单的事件onmousemove
WebBrowserEx.h 部分:
- virtual STDMETHODIMP_(void) DocumentComplete( IDispatch *pDisp,VARIANT *URL);//其实是: virtual void __stdcall DocumentComplete(...)
- void
- WebBrowserEx::DocumentComplete( IDispatch *pDisp,VARIANT *URL)
- {
- // 装载Event 响应函数
- IHTMLDocument3* pHtmlDoc3 = GetHTMLDocument3();
- BSTR bsMouseMoveEvent = ::SysAllocString(L"onmousemove");
- pHtmlDoc3->attachEvent(
- bsMouseMoveEvent,
- CHtmlEvents::CreateEventObject( (EVENT_FUNCTION) WebBrowserEx::OnHtmlMouseMove, 0, this ));
- ::SysFreeString(bsMouseMoveEvent);
- // 注意在卸载的时候要调用detachEvent
- WebBrowser::DocumentComplete( pDisp, URL );// 掉哦那个基类
- return;
- }
其实现类似于MSDN中的相关类.
HtmlEvents.h
- //EVENT_FUNCTION 函数指针定义 被应用于:CreateEventObject;
- typedef HRESULT (*EVENT_FUNCTION)(LPVOID);
- class CHtmlEvents:
- public IDispatch
- {
- public:
- CHtmlEvents();
- virtual ~CHtmlEvents(void);
- // IUnknown methods
- virtual STDMETHODIMP QueryInterface(REFIID iid,void**ppvObject);
- virtual STDMETHODIMP_(ULONG) AddRef();
- virtual STDMETHODIMP_(ULONG) Release();
- // IDispatch Methods
- HRESULT _stdcall GetTypeInfoCount(unsigned int * pctinfo);
- HRESULT _stdcall GetTypeInfo(unsigned int iTInfo,LCID lcid,ITypeInfo FAR* FAR* ppTInfo);
- HRESULT _stdcall GetIDsOfNames(REFIID riid,OLECHAR FAR* FAR* rgszNames,unsigned int cNames,LCID lcid,DISPID FAR* rgDispId);
- HRESULT _stdcall Invoke(DISPID dispIdMember,REFIID riid,LCID lcid,WORD wFlags,DISPPARAMS FAR* pDispParams,VARIANT FAR* pVarResult,EXCEPINFO FAR* pExcepInfo,unsigned int FAR* puArgErr);
- //Other Method
- static LPDISPATCH CreateEventObject(EVENT_FUNCTION pFunc, DISPID id, LPVOID lpUserData);
- private:
- long _lRef;
- EVENT_FUNCTION _fnEvent;
- DISPID _id;
- LPVOID _pUserData;
- };
- #include "HtmlEvents.h"
- // CHtmlEvents class
- CHtmlEvents::CHtmlEvents()
- {
- }
- CHtmlEvents::~CHtmlEvents()
- {
- }
- /*
- ==================
- |IUnknown methods|
- ==================
- */
- STDMETHODIMP CHtmlEvents::QueryInterface(REFIID iid,void**ppvObject)
- {
- if( iid == IID_IUnknown || iid == IID_IDispatch )
- {
- *ppvObject = this;
- AddRef();
- return S_OK;
- }
- return E_NOTIMPL;
- }
- STDMETHODIMP_(ULONG) CHtmlEvents::AddRef()
- {
- return InterlockedIncrement(&_lRef);
- }
- STDMETHODIMP_(ULONG) CHtmlEvents::Release()
- {
- return ::InterlockedDecrement(&_lRef);
- }
- /*
- =====================
- | IDispatch Methods |
- =====================
- */
- HRESULT _stdcall CHtmlEvents::GetTypeInfoCount(
- unsigned int * pctinfo)
- {
- return E_NOTIMPL;
- }
- HRESULT _stdcall CHtmlEvents::GetTypeInfo(
- unsigned int iTInfo,
- LCID lcid,
- ITypeInfo FAR* FAR* ppTInfo)
- {
- return E_NOTIMPL;
- }
- HRESULT _stdcall CHtmlEvents::GetIDsOfNames(REFIID riid,
- OLECHAR FAR* FAR* rgszNames,
- unsigned int cNames,
- LCID lcid,
- DISPID FAR* rgDispId
- )
- {
- return E_NOTIMPL;
- }
- HRESULT _stdcall CHtmlEvents::Invoke(
- DISPID dispIdMember,
- REFIID riid,
- LCID lcid,
- WORD wFlags,
- DISPPARAMS* pDispParams,
- VARIANT* pVarResult,
- EXCEPINFO* pExcepInfo,
- unsigned int* puArgErr)
- {
- if( DISPID_VALUE == dispIdMember )
- {
- (_fnEvent)( _pUserData );
- return S_OK;
- }
- return E_NOTIMPL;
- }
- //返回一个CHtmlEvents的实例
- //pFunc 表示当相关消息发生时, CHtmlEvents的实例调用pFunc这个函数, 同时参数是lpUserData,MSDN上有相关实现.
- //他的注销可以通过Detach 后 delete
- //或者 Release() 自动销毁,这里我们用了 Detach后delete
- LPDISPATCH CHtmlEvents::CreateEventObject(EVENT_FUNCTION pFunc, DISPID id, LPVOID lpUserData)
- {
- CHtmlEvents* npHE = new CHtmlEvents;
- npHE->_fnEvent = pFunc;
- npHE->_id = id;
- npHE->_pUserData = lpUserData;
- return reinterpret_cast<LPDISPATCH>(npHE);
- };
更多推荐
已为社区贡献4条内容
所有评论(0)