• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 3174
  • Last Modified:

How can we get IWebBrowser2 interface pointer of a ShowModalDialog?


Internet Explorer is loading my activeX and calling SetSite() for popups opened by ShowModalDialog. When I query for IWebBrowser2 interface pointer I am getting error.

I tried to get IHTMLDocuent interface pointer by using Microsoft Active Accessibilty Technique.
(http://support.microsoft.com/default.aspx?kbid=249232). Problem is, IE is creating Internet Explorer_Server window after returning form SetSite method().

So please let me know how can I get IWebBrowser2 (or IHTMLDocument2) interface pointer. This is the sample code what I wrote to get interface pointer.


 CComQIPtr<IOleClientSite, &IID_IOleClientSite> m_spClientSite;
 CComPtr<IWebBrowser2> m_spWebBrowser2;
 CComPtr<IServiceProvider> m_spSP;


STDMETHODIMP CMyTestObj::SetSite(IUnknown *pUnkSite)
{
 HRESULT hr;
 if(pUnkSite)
 {
  m_spClientSite=pUnkSite;
  m_spClientSite->QueryInterface(IID_IServiceProvider,(void **)&m_spSP);
  m_spSP->QueryService(IID_IWebBrowserApp, IID_IWebBrowser2,(void **)&m_spWebBrowser2);
   
  // Retrieve and store the IWebBrowser2 pointer
  if (m_spWebBrowser2 == NULL)
  {
   .....
   .....
  }
 }

 ........
 ........
}


1
reddyrajareddy
Asked:
reddyrajareddy
  • 3
  • 2
1 Solution
 
jkrCommented:
>>When I query for IWebBrowser2 interface pointer I am getting error.

Which error?
0
 
reddyrajareddyAuthor Commented:

E_NOINTERFACE
"The service exists, but the interface requested does not exist on that service."
0
 
Dariusz DziaraProgrammerCommented:
This is code I have used literally & it worked (IWebBrowser2 interface pointer was not NULL) when ActiveX control is created on html page in IE.

// EELightControl.h : Declaration of the CEELightControl

#ifndef __EELIGHTCONTROL_H_
#define __EELIGHTCONTROL_H_

#include "resource.h"       // main symbols
#include <atlctl.h>


/////////////////////////////////////////////////////////////////////////////
// CEELightControl
class ATL_NO_VTABLE CEELightControl :
      public CComObjectRootEx<CComSingleThreadModel>,
      public IDispatchImpl<IEELightControl, &IID_IEELightControl, &LIBID_TEST_EE_IECONTROLLib>,
      public CComControl<CEELightControl>,
      public IPersistStreamInitImpl<CEELightControl>,
      public IOleControlImpl<CEELightControl>,
      public IOleObjectImpl<CEELightControl>,
      public IOleInPlaceActiveObjectImpl<CEELightControl>,
      public IViewObjectExImpl<CEELightControl>,
      public IOleInPlaceObjectWindowlessImpl<CEELightControl>,
      public CComCoClass<CEELightControl, &CLSID_EELightControl>
{
public:
      CEELightControl()
      {
      }

DECLARE_REGISTRY_RESOURCEID(IDR_EELIGHTCONTROL)

DECLARE_PROTECT_FINAL_CONSTRUCT()

BEGIN_COM_MAP(CEELightControl)
      COM_INTERFACE_ENTRY(IEELightControl)
      COM_INTERFACE_ENTRY(IDispatch)
      COM_INTERFACE_ENTRY(IViewObjectEx)
      COM_INTERFACE_ENTRY(IViewObject2)
      COM_INTERFACE_ENTRY(IViewObject)
      COM_INTERFACE_ENTRY(IOleInPlaceObjectWindowless)
      COM_INTERFACE_ENTRY(IOleInPlaceObject)
      COM_INTERFACE_ENTRY2(IOleWindow, IOleInPlaceObjectWindowless)
      COM_INTERFACE_ENTRY(IOleInPlaceActiveObject)
      COM_INTERFACE_ENTRY(IOleControl)
      COM_INTERFACE_ENTRY(IOleObject)
      COM_INTERFACE_ENTRY(IPersistStreamInit)
      COM_INTERFACE_ENTRY2(IPersist, IPersistStreamInit)
END_COM_MAP()

BEGIN_PROP_MAP(CEELightControl)
      PROP_DATA_ENTRY("_cx", m_sizeExtent.cx, VT_UI4)
      PROP_DATA_ENTRY("_cy", m_sizeExtent.cy, VT_UI4)
      // Example entries
      // PROP_ENTRY("Property Description", dispid, clsid)
      // PROP_PAGE(CLSID_StockColorPage)
END_PROP_MAP()

BEGIN_MSG_MAP(CEELightControl)
      CHAIN_MSG_MAP(CComControl<CEELightControl>)
      DEFAULT_REFLECTION_HANDLER()
END_MSG_MAP()
// Handler prototypes:
//  LRESULT MessageHandler(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
//  LRESULT CommandHandler(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);
//  LRESULT NotifyHandler(int idCtrl, LPNMHDR pnmh, BOOL& bHandled);



// IViewObjectEx
      DECLARE_VIEW_STATUS(VIEWSTATUS_SOLIDBKGND | VIEWSTATUS_OPAQUE)

// IEELightControl
public:

      HRESULT OnDraw(ATL_DRAWINFO& di)
      {
//...
      }

      STDMETHOD(SetClientSite)(IOleClientSite *pClientSite)
      {
            if(pClientSite != NULL) {
                  HRESULT hRes;

                  hRes = pClientSite->QueryInterface(IID_IServiceProvider, (void **)&m_pIServiceProvider);

                  if(SUCCEEDED(hRes)) {
                        hRes = m_pIServiceProvider->QueryService(IID_IWebBrowserApp, IID_IWebBrowser2, (void **)&m_pIWebBrowser);
                  };
            };

            return IOleObject_SetClientSite(pClientSite);
      }
private:
      CComPtr<IServiceProvider> m_pIServiceProvider;
      CComPtr<IWebBrowser2> m_pIWebBrowser;
};

#endif //__EELIGHTCONTROL_H_
0
Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
reddyrajareddyAuthor Commented:

I tested above code. Let me explain the result.

I kept the object tag in a .html page with appropriate clsid. When I open the page in main browser, I could get IWebBrowser2 interface pointer.

If I open the page with ShowModalDialog( ), QueryService is returning E_NOINTERFACE.

Are you sure that you are getting IWebBrowser2 interface pointer in ShowModalDialog case?
0
 
Dariusz DziaraProgrammerCommented:
No, it does not work for popup window. I suspect that this is different container and it does not support SID_IWebBrowserApp service.

However I have found in MSDN this suggesting different service for older IE:

==================================================
Using C++
For ActiveX controls, Microsoft Support Online's answer to the question "How do I access Internet Explorer's object model from a contained control?"  tells how to get a pointer to the dispatch interface for the window object, IOmWindow, from your IOleClientSite interface. Here's some code that will work for both Internet Explorer 3.x and 4.x (I've modified their example  slightly):

#include <mshtml.h>
...
IOleClientSite* pClientSite;
...
// pClientSite should already point to the control's client site.

IServiceProvider* pISP;
IDispatch* pIHTMLDocument;

pClientSite->QueryInterface(IID_IServiceProvider, (void **)&pISP);
pISP->QueryService(SID_SContainerDispatch, IID_IDispatch, (void**)& pIHTMLDocument);

// From pIHTMLDocument we can get the window object
// (IOmWindow was superceded by IHTMLWindow2 in Internet Explorer4.x)
IDispatch* pIOmWindow;
pIHTMLDocument->get_Script(&pIOmWindow);

// Now we can get the navigator object.
IDispatch* pIOmNavigator;
pIOmWindow->get_navigator(&pIOmNavigator);

BSTR appName, appVersion;
pIOmNavigator->get_appName(&appName);
pIOmNavigator->get_appVersion(&appVersion);

On the other hand, if all you want to know is whether you are being hosted by Internet Explorer 3.x or Internet Explorer 4.x, here is an even easier way:

IOleClientSite* pClientSite;
// pClientSite should already point to the control's client site

IServiceProvider* pISP;
IWebBrowser2* pIWebBrowser2;
HRESULT hr;

pClientSite->QueryInterface(IID_IServiceProvider, (void **)&pISP);
hr = pISP->QueryService(IID_IWebBrowserApp, IID_IWebBrowser2,
                  (LPVOID*)& pIWebBrowser2);
if (hr == S_OK)
{
   // We're running on Internet Explorer4.x or greater
   //(IWebBrowser2 is only on Internet Explorer 4).
}
else
{
   // Are we at least being hosted by Internet Explorer3.x?
   IDispatch* pIDispatch;
   hr = pISP->QueryService(IID_IWebBrowserApp, IID_IDispatch,
                       (void **)& pIDispatch);
   if (hr == S_OK)
{
   // Yup, it's Internet Explorer3.x alright.
}
else
{
   // Dang, must be a non-Internet Explorer container (VB, Netscape, who knows...)
}
}
==================================================

I have tested the following code and and least it returns non-NULL pointers although I am not sure to what object.

      STDMETHOD(SetClientSite)(IOleClientSite *pClientSite)
      {
            if(pClientSite != NULL) {
                  HRESULT hRes;

                  hRes = pClientSite->QueryInterface(IID_IServiceProvider, (void **)&m_pIServiceProvider);

                  if(SUCCEEDED(hRes)) {
                        CComPtr<IDispatch> pIHTMLDocument;
                        CComPtr<IDispatch> pIHTMLWindow2;

                        hRes = m_pIServiceProvider->QueryService(SID_SContainerDispatch, IID_IDispatch, (void **)&pIHTMLDocument);

                        if(SUCCEEDED(hRes)) {
                              OLECHAR *rgszNames[] = {OLESTR("Script")};
                              DISPID rgDispId;
                              DISPPARAMS dispparamsNoArgs = {NULL, NULL, 0, 0};
                              CComVariant vVarResult;

                              hRes = pIHTMLDocument->GetIDsOfNames(IID_NULL, rgszNames, sizeof(rgszNames)/sizeof(rgszNames), LOCALE_SYSTEM_DEFAULT, &rgDispId);

                              if(SUCCEEDED(hRes)) {
                                    hRes = pIHTMLDocument->Invoke(rgDispId, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &dispparamsNoArgs, &vVarResult, NULL, NULL);

                                    if(SUCCEEDED(hRes)) {
                                          pIHTMLWindow2 = vVarResult.pdispVal;

                                          hRes = pIHTMLWindow2.QueryInterface(&m_pIHTMLWindow2vtbl);  // of type CComPtr<IHTMLWindow2>
                                    };
                              };
                                                                                    
                        };
                  };
            };

            return IOleObject_SetClientSite(pClientSite);
      }

0
 
reddyrajareddyAuthor Commented:

Hi mrblue,

Thanks for your reply.

I cound't test the code in your last post. I think you are getting an interface pointer that provides access to the scripting object. I will try to access the document object model by using scripting object.

But I solved the problem by using an other way.

I kept an Iframe in the HTML loaded by ShowModalDialog. The src of Iframe is another html page which has only <object> tab. Now I am able to retrive IWebBrowser2 interface pointer.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Get expert help—faster!

Need expert help—fast? Use the Help Bell for personalized assistance getting answers to your important questions.

  • 3
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now