看到MSDN中可以从HWND取得IHTMLDOCUMENT接口,但不知道可不可以从HWND直接取得IWEBBROWSER2接口?这样控制权就更大了

解决方案 »

  1.   

    应该是可以的,一时记不清方法了,以前反汇编一个程序时见那个程序用这种方式得到了iwebbrowser接口
      

  2.   

    IHTMLDOCUMENT->querinterface(.......
      

  3.   

    C++ Q&A 
    Browser Detection Revisited, Fixing CPopupText, COM and the IService Provider Interface  Q 
    I use the Active Accessibility SDK to obtain an IHTMLDoc-ument2 pointer from a window handle (HWND). Is there any way to obtain an IWebBrowser2 pointer from the IHTMLDocument2 pointer? I抳e tried QueryInterface on both the document pointer as well as the IHTMLWindow2 pointer without results. I also tried the IOmNavigator * from get_navigator on the HTMLWindow2 pointer. Any ideas? A 
    This is a common cause for COM consternation. You have the window, document, or browser and you know you should be able to get the others, but everywhere you turn, QueryInterface delivers a big fat NULL. The answer lies in the mysterious IServiceProvider whose job it is, well, to provide services. IServiceProvider is a great interface: it has only one method, QueryService. If you抮e using ATL smart pointers, it looks like this. First, you have to get the IServiceProvider.CComQIPtr<IServiceProvider> isp = pIHTMLDocument2;This does a QueryInterface on the document for IServiceProvider. Once you have it, you can get the browser like so.CComQIPtr<IWebBrowser2> iwb2;
    isp->QueryService(IID_IWebBrowserApp,
        IID_IWebBrowser2, (void**)&iwb2);      If all this seems confusing, there抯 a good reason for it. A cardinal rule of COM is that QueryInterface must always return an interface to the object queried. But the document doesn抰 implement IWebBrowser2; it only knows how to get the object that does. The document, browser, and window are all separate objects. In general, IServiceProvider is used whenever a bunch of separate but related COM objects together implement some kind of service. QueryInterface asks an object, do you implement this interface? QueryService tells a service provider, "get me whatever object implements this interface, please." With QueryService, the interface pointer returned may or may not be the same object as the one queried. Figure 6 illustrates the system. All the objects implement their various interfaces and store internal pointers to one another; IServiceProvider is your way to get whichever object implements a particular interface. IServiceProvider::QueryService chases the internal pointers to retrieve the object that implements the interface you want.
    Figure 6 Many Objects, One IServiceProvider      IServiceProvider is essential for navigating the DHTML object hierarchy. Say you抮e writing an ActiveX&reg; control and you want to navigate the object model. How do you do it? First, query your IOleClientSite for IServiceProvider like so:CComQIPtr<IServiceProvider> isp = pSite;then, once you have IServiceProvider, you can QueryService it for the application object.CComQIPtr<IWebBrowserApp> iwba;
    isp->QueryService(IID_IWebBrowserApp, 
        IID_IWebBrowserApp, (void **)&iwba); Now you can navigate the object hierarchy (the app object is at the top). If you want the Web browser, it抯 the same as before.CComQIPtr<IWebBrowser2> iwb2;
    isp->QueryService(IID_IWebBrowserApp, 
     IID_IWebBrowser2, (void **)&iwb2));       In all these examples, SID_SWebBrowserApp identifies the service, but you抣l often see code that uses IID_IWebBrowserApp as the service ID. Either will work, since <shlguid.h> #defines SID_SWebBrowserApp to IID_IWebBrowserApp, but for programming pedants SID_SWebBrowserApp is technically more correct, and more clear to anyone reading your code.
          By the way, if you抮e brave enough to implement some far-reaching colossal object system such as the DHTML object model (Lord help you!), then you should implement IServiceProvider too.Got a question? Send questions and comments to [email protected].  --------------------------------------------------------------------------------
    Paul DiLascia is a freelance writer, consultant, and Web/UI designer-at-large. He is the author of Windows++: Writing Reusable Windows Code in C++ (Addison-Wesley, 1992). Paul can be reached at [email protected] or http://www.dilascia.com.