定制浏览器
来源:互联网 发布:python从0写人工智能 编辑:程序博客网 时间:2024/04/28 11:55
作者:冯明德
浏览器控件是个典型的Active控件,提供了大量的接口及自动化对象,可以灵活的加以控制,需要的时候,可以通过这些接口控制浏览器的行为,或提供相应的出接口定制浏览器。
一、概述
浏览器对象CLSID:
CLSID_WebBrowser
提供的主要接口
IWebBrowser2 浏览器的接口
当文档建立后,可以得到相应的文档接口,文档中各标记元素的接口。
在DHTML中,大量的对象和事件就是又这些接口提供和管理的。
IHTMLDocument2
IHTMLWindow2
IHTMLEventObj
IHTMLElement
....
浏览器还将调用宿主提供的接口,以发出事件或给用户提供定制机会。
出接口
DIID_DWebBrowserEvents2
DIID_HTMLDocumentEvents
DIID_HTMLWindowEvents
(ICustomDoc)
IDocHostUIHandler
二、事件的相应
除了使用MFC缺省的事件响应机制外,也可以自建事件接受器,来响应事件
也就是,在封装对象中提供DIID_DWebBrowserEvents2 接口,然后将此接口作为接受器连接到浏览器对象。
一种做法是
在派生类中,使用MFC建立接口方案提供一个DIID_DWebBrowserEvents2接口对象嵌套成员。
class CFMDBrowser : public CWebBrowser{...//事件接收器接口//DWebBrowserEvents//这是一个IDispatch分发接口BEGIN_INTERFACE_PART(BrowserEventSink,DWebBrowserEvents)STDMETHOD(GetTypeInfoCount)(UINT *pctinfo);STDMETHOD(GetTypeInfo)(UINT iTInfo,LCID lcid,ITypeInfo **ppTInfo);STDMETHOD(GetIDsOfNames)(REFIID riid,LPOLESTR *rgszNames,UINT cNames,LCID lcid,DISPID *rgDispId);STDMETHOD(Invoke)(DISPID dispIdMember,REFIID riid,LCID lcid,WORD wFlags,DISPPARAMS *pDispParams,VARIANT *pVarResult,EXCEPINFO *pExcepInfo,UINT *puArgErr);END_INTERFACE_PART(BrowserEventSink)DWORD m_dwEventSinkCookie;...}
这是一个接收器接口,无需添入到对象的接口表中。
(无需:BEGIN_INTERFACE_MAP、END_INTERFACE_MAP)
这是一个以分发接口(IDispatch)作为出接口的典型例子。在接口函数的实现中。Invoke负责又分发ID调用不同的虚拟函数。(事件函数作为虚拟函数,供派生类重载)
STDMETHODIMP CFMDBrowser::XBrowserEventSink::Invoke(DISPID dispIdMember,REFIID riid,LCID lcid, WORD wFlags,DISPPARAMS *pDispParams, VARIANT *pVarResult,EXCEPINFO *pExcepInfo, UINT *puArgErr){METHOD_PROLOGUE(CFMDBrowser,BrowserEventSink)//将事件分发到各虚拟函数//分发ID的定义见 exdispid.hswitch(dispIdMember){case DISPID_BEFORENAVIGATE:...HRESULT hr=pThis->OnBeforeNavigate(..) //事件对应的虚拟函数...break; case DISPID_NAVIGATECOMPLETE: ...case ...case ...}
建立与浏览器的连接
得到IConnectionPointContainer接口,查找与DIID_DWebBrowserEvents对应的接收器,建立连接,记录连接的标号(m_dwEventSinkCookie);
BOOL CFMDBrowser::Connect(){IUnknown *p_Unk=GetControlUnknown();if(p_Unk==NULL)return FALSE;BOOL bOK=FALSE;//查找连接点对象IConnectionPointContainer *i_cpc=0;HRESULT hr=p_Unk->QueryInterface(IID_IConnectionPointContainer,(void **)(&i_cpc));if (SUCCEEDED(hr)){IConnectionPoint *i_cp=0;hr=i_cpc->FindConnectionPoint(DIID_DWebBrowserEvents,&i_cp);if (SUCCEEDED(hr)){hr=i_cp->Advise(&m_xBrowserEventSink,&m_dwEventSinkCookie);i_cp->Release();bOK=TRUE;}i_cpc->Release();}return bOK;}
结束时,断开与浏览器的连接
BOOL CFMDBrowser::DisConnect(){IUnknown *p_Unk=GetControlUnknown();if(p_Unk==NULL)return FALSE;BOOL bOK=FALSE;//查找连接点对象IConnectionPointContainer *i_cpc=0;HRESULT hr=p_Unk->QueryInterface(IID_IConnectionPointContainer,(void **)(&i_cpc));if (SUCCEEDED(hr)){IConnectionPoint *i_cp=0;hr=i_cpc->FindConnectionPoint(DIID_DWebBrowserEvents,&i_cp);if (SUCCEEDED(hr)){hr=i_cp->Unadvise(m_dwEventSinkCookie);i_cp->Release();bOK=TRUE;}i_cpc->Release();}return bOK;}
三、定制浏览器UI
浏览器提供了IDocHostUIHandler出接口,向用户查询界面特性
可以提供这个接口,与浏览器连接上,在其实现中,定制界面
1.建立接口
class CFMDBrowser : public CWebBrowser{...//IDocHostUIHandler接口,控制浏览器界面BEGIN_INTERFACE_PART(UIHandlerSink,IDocHostUIHandler)STDMETHOD(ShowContextMenu)(DWORD,POINT*,IUnknown*,IDispatch*);STDMETHOD(GetHostInfo)(DOCHOSTUIINFO*);STDMETHOD(ShowUI)(DWORD,IOleInPlaceActiveObject*,IOleCommandTarget*,IOleInPlaceFrame*,IOleInPlaceUIWindow*);STDMETHOD(HideUI)();STDMETHOD(UpdateUI)();STDMETHOD(EnableModeless)(INT);STDMETHOD(OnDocWindowActivate)(INT);STDMETHOD(OnFrameWindowActivate)(INT);STDMETHOD(ResizeBorder)(LPCRECT,IOleInPlaceUIWindow*,INT);STDMETHOD(TranslateAccelerator)(LPMSG,const GUID*,DWORD);STDMETHOD(GetOptionKeyPath)(LPOLESTR*,DWORD);STDMETHOD(GetDropTarget)(IDropTarget*,IDropTarget**);STDMETHOD(GetExternal)(IDispatch**);STDMETHOD(TranslateUrl)(DWORD,OLECHAR*,OLECHAR**);STDMETHOD(FilterDataObject)(IDataObject*,IDataObject**);END_INTERFACE_PART(UIHandlerSink)...}
无需添加接口映射
2.连接到浏览器
需要在NavigateComplete时间发生后,得到
ICustomDoc接口,由此接口的
SetUIHandler成员设置UI接口。
//设置界面接口IDispatch *i_dispatch=0;if (SUCCEEDED(i_dispatch=pThis->GetDocument())){IHTMLDocument2 *i_htmldoc2=0;if (SUCCEEDED(i_dispatch->QueryInterface(IID_IHTMLDocument2,(void **)(&i_htmldoc2)))){// force connection of IDocHostUIHandlerICustomDoc *i_customdoc=0;if (SUCCEEDED(i_htmldoc2->QueryInterface(IID_ICustomDoc,(void **)(&i_customdoc)))){i_customdoc->SetUIHandler(&(pThis->m_xUIHandlerSink));i_customdoc->Release();}}i_dispatch->Release();}
3.在接口的实现中,控制用户界面
例如更改右键菜单
在STDMETHOD(ShowContextMenu)(DWORD,POINT*,IUnknown*,IDispatch*);
的实现中:
HRESULT CFMDBrowser::ShowContextMenu(DWORD,POINT*,IUnknown*,IDispatch*){..建立自己的菜单 return S_OK; }
http://www.xici.net/b66783/d14811541.htm
http://www.xici.net/b66783/d14811541.htm
- 定制浏览器
- IOS前端浏览器定制
- 浏览器的定制与扩展
- 浏览器的定制与扩展
- 浏览器的定制与扩展
- 浏览器的定制与扩展
- mfc定制浏览器的扩展
- COM技术之浏览器定制
- 浏览器的定制与扩展
- 浏览器的定制与扩展
- 浏览器的定制与扩展
- 浏览器的定制与扩展
- 浏览器的定制与扩展
- 浏览器的定制与扩展
- 浏览器的定制与扩展
- 浏览器的定制与扩展
- 浏览器的定制与扩展
- COM技术之浏览器定制
- TRIM字符串的指定的头尾字符
- 在浏览器控件中启用自动完成功能
- 发票套打程序 源程序发布-V1.0.0.2
- 网页常用Javascript
- IE下自动激活 ActiveX 控件
- 定制浏览器
- web.xml文件详解
- VC中自定义IE浏览器
- Linux's boot process explained
- Oracle异常处理
- 高内聚,低耦合
- Eclipse里面相同变量的高亮显示
- asp.net报告开发的原则
- CommonChannelKeys.cs