tags:

views:

379

answers:

2

What is a good way for an ActiveX control to detect that its container (or container's container) is Internet Explorer?

Currently, I am doing this by calling the control's IOleClientSite::GetContainer method and checking whether the container implements the IHtmlDocument2 interface, but now, I would like to check all of the control's ancestors to see if any of them implement IHtmlDocument.

The problem is that the control is now contained in a CComCompositeControl and created using the CreateActiveXControls(resourceID) method, which creates the inner control as a child of a CAxHostWindow instance. In this case the CAxHostWindow instance reports itself as its own container, so I have not found a way to walk up the tree (if there is such a tree in this model).

+1  A: 

You may get some idea through following statements,

An ActiveX control typically gains access to the following container windows:

• Frame window: the outer-most container window where the container's main menu resides. An ActiveX control retrieves this window handle by calling either IOleInPlaceFrame::GetWindow or IOleInPlaceSite::GetWindowContext.

• Site window: the container window that contains the ActiveX control's view. An ActiveX control retrieves this container window by calling IOleInPlaceSite::GetWindow.

After that you can check parent window or same window to findout its text or other properties.

In some scenarios especially from MFC, the ActiveX control is made a child of the reflector window whose parent is the window returned from IOleInPlaceSite::GetWindow. In that case, it is very difficult to get the parent..

lakshmanaraj
+1  A: 

So, I can think of two approaches. One would be to get your site's IServiceProvider implementation and QueryService() for some service that only IE implements. You could go groveling through IE header files looking for SID_S* until you find one that suits your needs.

But the best way to do it (indeed, the way IE does it internally in places) is to just check the process name.

bool GetProcessName(LPWSTR pszProcessName, DWORD cchProcessName)
{
    bool success = false;
    // GetCurrentProcess() can't fail.
    DWORD cch = GetProcessImageFileName(GetCurrentProcess(), pszProcessName, cchProcessName);
    if (cch > 0)
    {
        LPWSTR pszFileName = PathFindFileName(pszProcessName);
        if (pszFileName)
        {
            wmemmove(pszProcessName, pszFileName, lstrlen(pszFileName) + 1);
        }
        success = true;
    }
    return success;    
}

And see if the process name is "iexplore.exe".

jeffamaphone
Checking the process name covers most of the surface area I'm concerned about at a fraction of the effort. I was too wrapped up in the details to see it.Thanks, jeffamaphone.
Brandon Payton