?
Solved

How can we get IWebBrowser2 interface pointer of a ShowModalDialog?

Posted on 2006-05-23
8
Medium Priority
?
3,010 Views
1 Endorsement
Last Modified: 2013-11-18

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
Comment
Question by:reddyrajareddy
  • 3
  • 2
6 Comments
 
LVL 86

Expert Comment

by:jkr
ID: 16742888
>>When I query for IWebBrowser2 interface pointer I am getting error.

Which error?
0
 

Author Comment

by:reddyrajareddy
ID: 16747587

E_NOINTERFACE
"The service exists, but the interface requested does not exist on that service."
0
 
LVL 8

Expert Comment

by:mrblue
ID: 16774965
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
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 

Author Comment

by:reddyrajareddy
ID: 16778935

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
 
LVL 8

Accepted Solution

by:
mrblue earned 1500 total points
ID: 16779634
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
 

Author Comment

by:reddyrajareddy
ID: 17047583

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

Featured Post

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

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.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

IntroductionThis article is the second in a three part article series on the Visual Studio 2008 Debugger.  It provides tips in setting and using breakpoints. If not familiar with this debugger, you can find a basic introduction in the EE article loc…
Article by: evilrix
Looking for a way to avoid searching through large data sets for data that doesn't exist? A Bloom Filter might be what you need. This data structure is a probabilistic filter that allows you to avoid unnecessary searches when you know the data defin…
The goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.
Suggested Courses

807 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question