分类:
COM
WebBrowser
2008-09-13 07:44
6545人阅读
收藏
举报
一.由来
我还记还得当自认为学习完了C++语法后, 兴致勃勃的打开MFC向导,开始所谓"MFC高级自动化编程"时, 我不由喊道: 这他妈的都是些什么乱七八糟的东西啊.诚然,MFC为了方便愚蠢的程序员,的确是让人瞬间高级编程, 可是愚蠢的我们还是会用CString strTest;写出(PWSTR)strTest.GetBuffer() 这种自作聪明的用法,结果就是整个程序好像发了疯.
终于有一天,我大喊一声: 滚蛋吧,MFC!
太阳当空照,上帝对
我笑: 你Y去写个有WebBrowser控件的窗口吧
二.结构
MFC的HTMLDialog 是一个魔盒, 他容易上手,可是却很难深入,究其缘由, 私以为无外乎MFC包装的太好, 不识庐山真面目,只缘身在此山中. 总是以为作为C类型的程序员,喜欢深入原理是职业特性.
于是首先看到有强人写的纯C实现WebBrowser控件,他在这里: http://www./KB/COM/cwebpage.aspx 这位同志很好的展示了在没有C++的支持下,支持ActiveX是多么痛苦的一件事情...........汗. 在下觉得,撇开C++的类的特性,虚拟特性,重载特性,而去用纯C实现,实在有点过犹不及,当然这种练习修炼内功很好,但是实际应用上显得麻烦.毕竟,ActiveX很好的使用了C++的特性,而不是C的特性.
接着,开始使用纯SDK编写容器. 读者可以搜索csdn中关于SDK实现WebBrowser容器的帖子, 许多人说那是非常繁琐复杂.所谓人云亦云,各位看官不妨跟着我一试,且看到底何如?
WebBrowser容器的实现需要许多接口, 也许正是这吓退了许多人, 实际情况是,许多接口的方法没几个需要实现,大部分只需要直接返回E_NOTIMPL和S_OK, E_FAIL.
让我们命名我们编写的容器叫 WebBrowser (可能名字有点糊涂,但是因为源代码中就是这个名字,所以就不改了,大家只需要注意,这个是一个WebBrowser控件的容器 ), 在实现这个容器后, 我们把他作为一个窗口类的父类,这样 就能实现WebBrowser的页面窗口.
首先一个WB( WebBrowser) 容器需要以下接口:
- public IDispatch
- public IOleClientSite
- public IOleInPlaceSite
- public IOleInPlaceFrame
每个接口需要实现的方法分别是:
-
- virtual STDMETHODIMP QueryInterface(REFIID iid,void**ppvObject);
- virtual STDMETHODIMP_(ULONG) AddRef();
- virtual STDMETHODIMP_(ULONG) Release();
-
- 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);
-
- virtual STDMETHODIMP SaveObject();
- virtual STDMETHODIMP GetMoniker(DWORD dwA,DWORD dwW,IMoniker**pm);
- virtual STDMETHODIMP GetContainer(IOleContainer**pc);
- virtual STDMETHODIMP ShowObject();
- virtual STDMETHODIMP OnShowWindow(BOOL f);
- virtual STDMETHODIMP RequestNewObjectLayout();
-
- virtual STDMETHODIMP GetWindow(HWND *p);
- virtual STDMETHODIMP ContextSensitiveHelp(BOOL);
- virtual STDMETHODIMP CanInPlaceActivate();
- virtual STDMETHODIMP OnInPlaceActivate();
- virtual STDMETHODIMP OnUIActivate();
- virtual STDMETHODIMP GetWindowContext(IOleInPlaceFrame** ppFrame,IOleInPlaceUIWindow **ppDoc,LPRECT r1,LPRECT r2,LPOLEINPLACEFRAMEINFO o);
- virtual STDMETHODIMP Scroll(SIZE s);
- virtual STDMETHODIMP OnUIDeactivate(int);
- virtual STDMETHODIMP OnInPlaceDeactivate();
- virtual STDMETHODIMP DiscardUndoState();
- virtual STDMETHODIMP DeactivateAndUndo();
- virtual STDMETHODIMP OnPosRectChange(LPCRECT);
-
- virtual STDMETHODIMP GetBorder(LPRECT l);
- virtual STDMETHODIMP RequestBorderSpace(LPCBORDERWIDTHS);
- virtual STDMETHODIMP SetBorderSpace(LPCBORDERWIDTHS w);
- virtual STDMETHODIMP SetActiveObject(IOleInPlaceActiveObject*pV,LPCOLESTR s);
- virtual STDMETHODIMP InsertMenus(HMENU h,LPOLEMENUGROUPWIDTHS x);
- virtual STDMETHODIMP SetMenu(HMENU h,HOLEMENU hO,HWND hw);
- virtual STDMETHODIMP RemoveMenus(HMENU h);
- virtual STDMETHODIMP SetStatusText(LPCOLESTR t);
- virtual STDMETHODIMP EnableModeless(BOOL f);
- virtual STDMETHODIMP TranslateAccelerator(LPMSG,WORD);
这里插几句题外话, 我讨厌看文章, 因为萝莉罗嗦也没看到那个爆炸点, 就是你看到他,一下子思路有了头绪, 不再是一头雾水了.可惜,我看到的大部分文章都不是这样, 为了避免这个问题, 我在这里放个屁, 嗯,也算是一个小小的爆破吧.
好,上面已经罗列了需要的接口和接口的方法.
要想实现WB的容器,你必须有这段代码:
- WebBrowser::WebBrowser()
- {
-
- OleInitialize(0);
-
- StgCreateDocfile(0,STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_DIRECT | STGM_CREATE,0,&_pStorage);
-
-
-
-
- _pOleObj->QueryInterface(IID_IOleInPlaceObject,(LPVOID*)&_pInPlaceObj);
- }
上面一段代码已经创建了wb的Ole对象, 接下来,你只需要打开WB,然后打开网页.我们用两个函数实现,他们是OpenWebBrowser() 和 OpenURL( VARIANT* pVarUrl )
OpenWebBrowser:
- BOOL
- WebBrowser::OpenWebBrowser()
- {
- BOOL bRet = FALSE;
-
-
-
-
- if( (RECTWIDTH(_rcWebWnd) && RECTHEIGHT(_rcWebWnd)) == 0 )
- ::GetClientRect( GetHWND() ,&_rcWebWnd);
-
-
-
-
-
- if( _bInPlaced == false )
- {
- _bInPlaced = true;
- _bExternalPlace = 0;
- _GetOleObject()->DoVerb(OLEIVERB_INPLACEACTIVATE,0,this,0, GetHWND(),&_rcWebWnd);
- _bInPlaced = true;
- }
- bRet = TRUE;
- RETURN:
- return bRet;
- }
OpenURL(...)
- BOOL
- WebBrowser::OpenURL(VARIANT* pVarUrl)
- {
- BOOL bRet = FALSE;
-
-
-
-
-
-
-
- GetWebBrowser2()->Navigate2( pVarUrl,0,0,0,0);
- bRet = TRUE;
- RETURN:
- return bRet;
- }
三.细节
前面说过,那几个接口的方法,大部分都是直接返回E_NOTIMPL和S_OK, E_FAIL.,我说大部分,说明必然有些函数需要做一些事情,而且其作用很不小, 请看官别马虎了这段. :)
IDispatch 接口中的 IUnknown 的实现实在是不必多言, 稍微说一下接口枚举:
- STDMETHODIMP WebBrowser::QueryInterface(REFIID iid,void**ppvObject)
- {
- *ppvObject = 0;
- if ( iid == IID_IOleClientSite )
- *ppvObject = (IOleClientSite*)this;
- if ( iid == IID_IUnknown )
- *ppvObject = this;
- if ( iid == IID_IDispatch )
- *ppvObject = (IDispatch*)this;
- if ( _bExternalPlace == false)
- {
- if ( iid == IID_IOleInPlaceSite )
- *ppvObject = (IOleInPlaceSite*)this;
- if ( iid == IID_IOleInPlaceFrame )
- *ppvObject = (IOleInPlaceFrame*)this;
- if ( iid == IID_IOleInPlaceUIWindow )
- *ppvObject = (IOleInPlaceUIWindow*)this;
- }
- if ( iid == DIID_DWebBrowserEvents2 )
- *ppvObject = (DWebBrowserEvents2 *)this;
- if ( iid == IID_IDocHostUIHandler)
- *ppvObject = (IDocHostUIHandler*)this;
- if ( *ppvObject )
- {
- AddRef();
- return S_OK;
- }
- return E_NOINTERFACE;
- }
下面先说GetWindow
- STDMETHODIMP WebBrowser::GetWindow(HWND *p)
- {
- *p = GetHWND();
- return S_OK;
- }
再来说: CanInPlaceActivate(); Ole对象会询问容器,我能不能插进来(脸红中~)? 得到准许后才能温柔的插入,粗暴是不行的哦!
- STDMETHODIMP WebBrowser::CanInPlaceActivate()
- {
- if ( _bInPlaced )
- {
- _bCalledCanInPlace = true;
- return S_OK;
- }
- return S_FALSE;
- }
WebBrowser::GetWindowContext(...) 获取窗口上下文(内容)
- STDMETHODIMP WebBrowser::GetWindowContext(IOleInPlaceFrame** ppFrame,IOleInPlaceUIWindow **ppDoc,LPRECT r1,LPRECT r2,LPOLEINPLACEFRAMEINFO o)
- {
-
-
- *ppFrame = (IOleInPlaceFrame*)this;
- AddRef();
- *ppDoc = NULL;
-
- ::GetClientRect( GetHWND() ,&_rcWebWnd );
- *r1 = _rcWebWnd;
- *r2 = _rcWebWnd;
-
- o->cb = sizeof(OLEINPLACEFRAMEINFO);
- o->fMDIApp = false;
- o->hwndFrame = GetParent( GetHWND() );
- o->haccel = 0;
- o->cAccelEntries = 0;
-
- return S_OK;
- }
好了,下面是最后一个需要加料的函数了: IOleInPlaceFrame 接口的方法: GetBorder
注意这个接口正是上面说过的函数GetWindowContent 传递给OleObj对象的
- STDMETHODIMP WebBrowser::GetBorder(LPRECT l)
- {
- ::GetClientRect( GetHWND() ,&_rcWebWnd );
- *l = _rcWebWnd;
- return S_OK;
- }
到现在为止,对于容器本身的实现已经全部完成了, 但是细心的读者会问到, GetHWND(void)还没有实现那!?
实际上,WebBrowser 作为一个基本类,不应当实现GetHWND(), 相反地, 他应当作为一个纯虚函数,要求其子类实现.
然后,我做了一个实验, 发现作为纯虚函数, 不能在类的构造函数中被调用, 或者间接调用. 而我们在WebBrowser::WebBrowser()中已经间接调用了GetHWND(),所以会有问题, 于是我们耍赖,把GetHWND(){return NULL;}
这样可以解决虚函数的问题.
四. 所有实现
WebBroser.h
- class WebBrowser:
- public IDispatch,
- public IOleClientSite,
- public IOleInPlaceSite,
- public IOleInPlaceFrame,
- public IDocHostUIHandler
- {
- public:
- WebBrowser();
- ~WebBrowser(void);
- public:
-
- virtual STDMETHODIMP QueryInterface(REFIID iid,void**ppvObject);
- virtual STDMETHODIMP_(ULONG) AddRef();
- virtual STDMETHODIMP_(ULONG) Release();
-
- 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);
-
- virtual STDMETHODIMP SaveObject();
- virtual STDMETHODIMP GetMoniker(DWORD dwA,DWORD dwW,IMoniker**pm);
- virtual STDMETHODIMP GetContainer(IOleContainer**pc);
- virtual STDMETHODIMP ShowObject();
- virtual STDMETHODIMP OnShowWindow(BOOL f);
- virtual STDMETHODIMP RequestNewObjectLayout();
-
- virtual STDMETHODIMP GetWindow(HWND *p);
- virtual STDMETHODIMP ContextSensitiveHelp(BOOL);
- virtual STDMETHODIMP CanInPlaceActivate();
- virtual STDMETHODIMP OnInPlaceActivate();
- virtual STDMETHODIMP OnUIActivate();
- virtual STDMETHODIMP GetWindowContext(IOleInPlaceFrame** ppFrame,IOleInPlaceUIWindow **ppDoc,LPRECT r1,LPRECT r2,LPOLEINPLACEFRAMEINFO o);
- virtual STDMETHODIMP Scroll(SIZE s);
- virtual STDMETHODIMP OnUIDeactivate(int);
- virtual STDMETHODIMP OnInPlaceDeactivate();
- virtual STDMETHODIMP DiscardUndoState();
- virtual STDMETHODIMP DeactivateAndUndo();
- virtual STDMETHODIMP OnPosRectChange(LPCRECT);
-
- virtual STDMETHODIMP GetBorder(LPRECT l);
- virtual STDMETHODIMP RequestBorderSpace(LPCBORDERWIDTHS);
- virtual STDMETHODIMP SetBorderSpace(LPCBORDERWIDTHS w);
- virtual STDMETHODIMP SetActiveObject(IOleInPlaceActiveObject*pV,LPCOLESTR s);
- virtual STDMETHODIMP InsertMenus(HMENU h,LPOLEMENUGROUPWIDTHS x);
- virtual STDMETHODIMP SetMenu(HMENU h,HOLEMENU hO,HWND hw);
- virtual STDMETHODIMP RemoveMenus(HMENU h);
- virtual STDMETHODIMP SetStatusText(LPCOLESTR t);
- virtual STDMETHODIMP EnableModeless(BOOL f);
- virtual STDMETHODIMP TranslateAccelerator(LPMSG,WORD);
- protected:
- virtual HWND GetHWND(){return NULL;};
-
- private:
- inline IOleObject* _GetOleObject(){return _pOleObj;};
- inline IOleInPlaceObject* _GetInPlaceObject(){return _pInPlaceObj;};
-
- public:
- IWebBrowser2* GetWebBrowser2();
- IHTMLDocument2* GetHTMLDocument2();
- IHTMLDocument3* GetHTMLDocument3();
- IHTMLWindow2* GetHTMLWindow2();
- IHTMLEventObj* GetHTMLEventObject();
-
- BOOL SetWebRect(LPRECT lprc);
- BOOL OpenWebBrowser();
- BOOL OpenURL(VARIANT* pVarUrl);
-
-
- protected:
- long _refNum;
- private:
- RECT _rcWebWnd;
- bool _bInPlaced;
- bool _bExternalPlace;
- bool _bCalledCanInPlace;
- bool _bWebWndInited;
- private:
-
- IOleObject* _pOleObj;
- IOleInPlaceObject* _pInPlaceObj;
- IStorage* _pStorage;
- IWebBrowser2* _pWB2;
- IHTMLDocument2* _pHtmlDoc2;
- IHTMLDocument3* _pHtmlDoc3;
- IHTMLWindow2* _pHtmlWnd2;
- IHTMLEventObj* _pHtmlEvent;
- };
WebBrowser.cpp
注意: 里面有许多讨厌的东西, 是我加的饲料. 解释一下,我个人很喜欢这种错误处理方式.
读者可以简单的认为: (因为实际上我的实现不是那么简单,因为这个再说就有点复杂,所以简单化)
NULLTEST_SE( fn , wstr ) ; 如果 fn == 0 , 则显示 wstr, 并且跳转到RETURN
HRTEST_SE( fn, wstr); 如果 fn!=S_OK ,则显示wstr,并且跳转到RETURN
另外,考虑到WebBrowser以后总是作为另外一个类的父类,所以他完全不会因为计数器归零而自删除.
- #include "WebBrowser.h"
- WebBrowser::WebBrowser(void):
- _refNum(0),
- _bInPlaced(false),
- _bExternalPlace(false),
- _bCalledCanInPlace(false),
- _bWebWndInited(false),
- _pOleObj(NULL),
- _pInPlaceObj(NULL),
- _pStorage(NULL),
- _pWB2(NULL),
- _pHtmlDoc2(NULL),
- _pHtmlDoc3(NULL),
- _pHtmlWnd2(NULL),
- _pHtmlEvent(NULL)
- {
- ::memset( (PVOID)&_rcWebWnd,0,sizeof(_rcWebWnd));
- HRTEST_SE( OleInitialize(0),L"Ole初始化错误");
- HRTEST_SE( StgCreateDocfile(0,STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_DIRECT | STGM_CREATE,0,&_pStorage),L"StgCreateDocfile错误");
- HRTEST_SE( OleCreate(CLSID_WebBrowser,IID_IOleObject,OLERENDER_DRAW,0,this,_pStorage,(void**)&_pOleObj),L"Ole创建失败");
- HRTEST_SE( _pOleObj->QueryInterface(IID_IOleInPlaceObject,(LPVOID*)&_pInPlaceObj),L"OleInPlaceObject创建失败");
- RETURN:
- return;
- }
- WebBrowser::~WebBrowser(void)
- {
- }
- STDMETHODIMP WebBrowser::QueryInterface(REFIID iid,void**ppvObject)
- {
- *ppvObject = 0;
- if ( iid == IID_IOleClientSite )
- *ppvObject = (IOleClientSite*)this;
- if ( iid == IID_IUnknown )
- *ppvObject = this;
- if ( iid == IID_IDispatch )
- *ppvObject = (IDispatch*)this;
- if ( _bExternalPlace == false)
- {
- if ( iid == IID_IOleInPlaceSite )
- *ppvObject = (IOleInPlaceSite*)this;
- if ( iid == IID_IOleInPlaceFrame )
- *ppvObject = (IOleInPlaceFrame*)this;
- if ( iid == IID_IOleInPlaceUIWindow )
- *ppvObject = (IOleInPlaceUIWindow*)this;
- }
-
- if ( *ppvObject )
- {
- AddRef();
- return S_OK;
- }
- return E_NOINTERFACE;
- }
- STDMETHODIMP_(ULONG) WebBrowser::AddRef()
- {
- return ::InterlockedIncrement( &_refNum );
- }
- STDMETHODIMP_(ULONG) WebBrowser::Release()
- {
- return ::InterlockedDecrement( &_refNum );
- }
- HRESULT _stdcall WebBrowser::GetTypeInfoCount(
- unsigned int * pctinfo)
- {
- return E_NOTIMPL;
- }
- HRESULT _stdcall WebBrowser::GetTypeInfo(
- unsigned int iTInfo,
- LCID lcid,
- ITypeInfo FAR* FAR* ppTInfo)
- {
- return E_NOTIMPL;
- }
- HRESULT _stdcall WebBrowser::GetIDsOfNames(REFIID riid,
- OLECHAR FAR* FAR* rgszNames,
- unsigned int cNames,
- LCID lcid,
- DISPID FAR* rgDispId )
- {
- return E_NOTIMPL;
- }
- HRESULT _stdcall WebBrowser::Invoke(
- DISPID dispIdMember,
- REFIID riid,
- LCID lcid,
- WORD wFlags,
- DISPPARAMS* pDispParams,
- VARIANT* pVarResult,
- EXCEPINFO* pExcepInfo,
- unsigned int* puArgErr)
- {
-
- return E_NOTIMPL;
- }
- STDMETHODIMP WebBrowser::SaveObject()
- {
- return S_OK;
- }
- STDMETHODIMP WebBrowser::GetMoniker(DWORD dwA,DWORD dwW,IMoniker**pm)
- {
- *pm = 0;
- return E_NOTIMPL;
- }
- STDMETHODIMP WebBrowser::GetContainer(IOleContainer**pc)
- {
- *pc = 0;
- return E_FAIL;
- }
- STDMETHODIMP WebBrowser::ShowObject()
- {
- return S_OK;
- }
- STDMETHODIMP WebBrowser::OnShowWindow(BOOL f)
- {
- return S_OK;
- }
- STDMETHODIMP WebBrowser::RequestNewObjectLayout()
- {
- return S_OK;
- }
- STDMETHODIMP WebBrowser::GetWindow(HWND *p)
- {
- *p = GetHWND();
- return S_OK;
- }
- STDMETHODIMP WebBrowser::ContextSensitiveHelp(BOOL)
- {
- return E_NOTIMPL;
- }
- STDMETHODIMP WebBrowser::CanInPlaceActivate()
- {
- if ( _bInPlaced )
- {
- _bCalledCanInPlace = true;
- return S_OK;
- }
- return S_FALSE;
- }
- STDMETHODIMP WebBrowser::OnInPlaceActivate()
- {
- return S_OK;
- }
- STDMETHODIMP WebBrowser::OnUIActivate()
- {
- return S_OK;
- }
- STDMETHODIMP WebBrowser::GetWindowContext(IOleInPlaceFrame** ppFrame,IOleInPlaceUIWindow **ppDoc,LPRECT r1,LPRECT r2,LPOLEINPLACEFRAMEINFO o)
- {
-
- *ppFrame = (IOleInPlaceFrame*)this;
- AddRef();
- *ppDoc = NULL;
- ::GetClientRect( GetHWND() ,&_rcWebWnd );
- *r1 = _rcWebWnd;
- *r2 = _rcWebWnd;
- o->cb = sizeof(OLEINPLACEFRAMEINFO);
- o->fMDIApp = false;
- o->hwndFrame = GetParent( GetHWND() );
- o->haccel = 0;
- o->cAccelEntries = 0;
-
- return S_OK;
- }
- STDMETHODIMP WebBrowser::Scroll(SIZE s)
- {
- return E_NOTIMPL;
- }
- STDMETHODIMP WebBrowser::OnUIDeactivate(int)
- {
- return S_OK;
- }
- STDMETHODIMP WebBrowser::OnInPlaceDeactivate()
- {
- return S_OK;
- }
- STDMETHODIMP WebBrowser::DiscardUndoState()
- {
- return S_OK;
- }
- STDMETHODIMP WebBrowser::DeactivateAndUndo()
- {
- return S_OK;
- }
- STDMETHODIMP WebBrowser::OnPosRectChange(LPCRECT)
- {
- return S_OK;
- }
- STDMETHODIMP WebBrowser::GetBorder(LPRECT l)
- {
- ::GetClientRect( GetHWND() ,&_rcWebWnd );
- *l = _rcWebWnd;
- return S_OK;
- }
- STDMETHODIMP WebBrowser::RequestBorderSpace(LPCBORDERWIDTHS b)
- {
- return S_OK;
- }
- STDMETHODIMP WebBrowser::SetBorderSpace(LPCBORDERWIDTHS b)
- {
- return S_OK;
- }
- STDMETHODIMP WebBrowser::SetActiveObject(IOleInPlaceActiveObject*pV,LPCOLESTR s)
- {
- return S_OK;
- }
- STDMETHODIMP WebBrowser::SetStatusText(LPCOLESTR t)
- {
- return E_NOTIMPL;
- }
- STDMETHODIMP WebBrowser::EnableModeless(BOOL f)
- {
- return E_NOTIMPL;
- }
- STDMETHODIMP WebBrowser::TranslateAccelerator(LPMSG,WORD)
- {
- return E_NOTIMPL;
- }
- HRESULT _stdcall WebBrowser::RemoveMenus(HMENU h)
- {
- return E_NOTIMPL;
- }
- HRESULT _stdcall WebBrowser::InsertMenus(HMENU h,LPOLEMENUGROUPWIDTHS x)
- {
- return E_NOTIMPL;
- }
- HRESULT _stdcall WebBrowser::SetMenu(HMENU h,HOLEMENU hO,HWND hw)
- {
- return E_NOTIMPL;
- }
- IWebBrowser2*
- WebBrowser::GetWebBrowser2()
- {
- if( _pWB2 != NULL )
- return _pWB2;
- NULLTEST_SE( _pOleObj,L"Ole对象为空");
- HRTEST_SE( _pOleObj->QueryInterface(IID_IWebBrowser2,(void**)&_pWB2),L"QueryInterface IID_IWebBrowser2 失败");
- return _pWB2;
- RETURN:
- return NULL;
- }
- IHTMLDocument2*
- WebBrowser::GetHTMLDocument2()
- {
- if( _pHtmlDoc2 != NULL )
- return _pHtmlDoc2;
- IWebBrowser2* pWB2 = NULL;
- NULLTEST(pWB2 = GetWebBrowser2());
- IDispatch* pDp = NULL;
- HRTEST_SE(pWB2->get_Document(&pDp),L"DWebBrowser2::get_Document 错误");
- HRTEST_SE(pDp->QueryInterface(IID_IHTMLDocument2,(void**)&_pHtmlDoc2),L"QueryInterface IID_IHTMLDocument2 失败");
- return _pHtmlDoc2;
- RETURN:
- return NULL;
- }
- IHTMLDocument3*
- WebBrowser::GetHTMLDocument3()
- {
- if( _pHtmlDoc3 != NULL )
- return _pHtmlDoc3;
- IWebBrowser2* pWB2 = NULL;
- NULLTEST(pWB2 = GetWebBrowser2());
- IDispatch* pDp = NULL;
- HRTEST_SE(pWB2->get_Document(&pDp),L"DWebBrowser2::get_Document 错误");
- HRTEST_SE(pDp->QueryInterface(IID_IHTMLDocument3,(void**)&_pHtmlDoc3),L"QueryInterface IID_IHTMLDocument3 失败");
- return _pHtmlDoc3;
- RETURN:
- return NULL;
- }
- IHTMLWindow2*
- WebBrowser::GetHTMLWindow2()
- {
- if( _pHtmlWnd2 != NULL)
- return _pHtmlWnd2;
- IHTMLDocument2* pHD2 = GetHTMLDocument2();
- NULLTEST( pHD2 );
- HRTEST_SE( pHD2->get_parentWindow(&_pHtmlWnd2),L"IHTMLWindow2::get_parentWindow 错误" );
- return _pHtmlWnd2;
- RETURN:
- return NULL;
- }
- IHTMLEventObj*
- WebBrowser::GetHTMLEventObject()
- {
- if( _pHtmlEvent != NULL )
- return _pHtmlEvent;
- IHTMLWindow2* pHW2;
- NULLTEST( pHW2 = GetHTMLWindow2() );
- HRTEST_SE( pHW2->get_event(&_pHtmlEvent),L"IHTMLWindow2::get_event 错误");
- return _pHtmlEvent;
- RETURN:
- return NULL;
- }
- BOOL
- WebBrowser::SetWebRect(LPRECT lprc)
- {
- BOOL bRet = FALSE;
- if( false == _bInPlaced )
- {
- _rcWebWnd = *lprc;
- }
- else
- {
- SIZEL size;
- size.cx = RECTWIDTH(*lprc);
- size.cy = RECTHEIGHT(*lprc);
- IOleObject* pOleObj;
- NULLTEST( pOleObj= _GetOleObject());
- HRTEST_E( pOleObj->SetExtent( 1,&size ),L"SetExtent 错误");
- IOleInPlaceObject* pInPlace;
- NULLTEST( pInPlace = _GetInPlaceObject());
- HRTEST_E( pInPlace->SetObjectRects(lprc,lprc),L"SetObjectRects 错误");
- _rcWebWnd = *lprc;
- }
- bRet = TRUE;
- RETURN:
- return bRet;
- }
- BOOL
- WebBrowser::OpenWebBrowser()
- {
- BOOL bRet = FALSE;
- NULLTEST_E( _GetOleObject(),L"ActiveX对象为空" );
-
- if( (RECTWIDTH(_rcWebWnd) && RECTHEIGHT(_rcWebWnd)) == 0 )
- ::GetClientRect( GetHWND() ,&_rcWebWnd);
-
- if( _bInPlaced == false )
- {
- _bInPlaced = true;
- _bExternalPlace = 0;
-
- HRTEST_E( _GetOleObject()->DoVerb(OLEIVERB_INPLACEACTIVATE,0,this,0, GetHWND() ,&_rcWebWnd),L"关于INPLACE的DoVerb错误");
- _bInPlaced = true;
-
-
-
- IConnectionPointContainer* pCPC = NULL;
- IConnectionPoint* pCP = NULL;
- HRTEST_E( GetWebBrowser2()->QueryInterface(IID_IConnectionPointContainer,(void**)&pCPC),L"枚举IConnectionPointContainer接口失败");
- HRTEST_E( pCPC->FindConnectionPoint( DIID_DWebBrowserEvents2,&pCP),L"FindConnectionPoint失败");
- DWORD dwCookie = 0;
- HRTEST_E( pCP->Advise( (IUnknown*)(void*)this,&dwCookie),L"IConnectionPoint::Advise失败");
- }
- bRet = TRUE;
- RETURN:
- return bRet;
- }
- BOOL
- WebBrowser::OpenURL(VARIANT* pVarUrl)
- {
- BOOL bRet = FALSE;
- HRTEST_E( GetWebBrowser2()->Navigate2( pVarUrl,0,0,0,0),L"GetWebBrowser2 失败");
- bRet = TRUE;
- RETURN:
- return bRet;
- }
五.例子
- class WebBrowserWindow :
- public WebBrowser
- {
- public:
- WebBrowserWindow(void);
- ~WebBrowserWindow(void);
- public:
- virtual HWND GetHWND(){ return YourWindow};
- private:
- LRESULT OnCreate( WPARAM wParam,LPARAM lParam);
-
- };
六.下期预告,如果有的话
如果有人感兴趣的话, 以后会说道如何扩展WebBrowser, 让他包罗万象, 你会发现很简单.
如果有问题,欢迎提问. 谢谢.
|