问题:
在使用Active Accessibility SDK的过程中,我从某个窗口的句柄来获得IHTMLDocument2指针。有没有什么方法可以从IHTMLDocument2指针来获得IWebBrowser2指针?我用QueryInterface在两个接口(IHTMLDocument2 和 IWebBrowser2)上试过,但没有成功。我也用网景(Netscape)的 HTMLWindow2 指针试过从get_navigator获取IOmNavigator *。也以失败告终。请高手指点。
解答:
这个问题通常是COM编程中存在的共性问题。你有了窗口,文档,或者浏览器,你明明知道可以通过这些已知数据来得到其它的信息,但往往在实际环境中一运行,QueryInterface总是给你送回一个肥大的NULL。这个问题的答案实际上隐藏在神秘的IServiceProvider接口中,顾名思义,IServiceProvider的作用就是提供服务。IServiceProvider是个非常棒的接口:它只有一个方法——QueryService。如果你会用ATL智能指针,就像下面这样。首先必须获得IServiceProvider接口,
CComQIPtr isp = pIHTMLDocument2;
这行代码实际上就是对文档执行了一次 QueryInterface,以询问IServiceProvider接口。一旦具备了isp,你便可以象下面这样获得浏览器。
CComQIPtr iwb2;
isp->QueryService(IID_IWebBrowserApp,IID_IWebBrowser2, (void**)&iwb2);
如果你还是不明白上面所讲东西,没有关系,很正常。COM编程的一个根本规则是:QueryInterface必须总是要返回所查询对象的接口。但是文档不实现 IWebBrowser2
图一 多个对象,一个IServiceProvider
从本质上讲,IServiceProvider用于导航DHTML对象层次。假设你正在写一个ActiveX控件来导航这个对象模型。你如何做呢?首先要像下面这样查询IOleClientSite来取得IServiceProvider:
CComQIPtr isp = pSite;
然后,一旦你具备了IServiceProvider,则可以用QueryService来从中查询应用对象。
CComQIPtr iwba;
isp->QueryService(IID_IWebBrowserApp, IID_IWebBrowserApp, (void **)&iwba);
接下来你就可以导航这个对象层次了(应用对象在最顶层)。如果你想要得到Web浏览器,那么与前面类似。
CComQIPtr iwb2;
isp->QueryService(IID_IWebBrowserApp, IID_IWebBrowser2, (void **)&iwb2));
在所有这些例子中,SID_SWebBrowserApp都是服务标示,但你也能常常见到将IID_IWebBrowserApp作为服务ID的代码。两种用法都可以行得通,因为文件中有个宏定义:
郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。
新闻热点
疑难解答