从ActiveX控件中检测IE容器

时间:2009-03-25 03:36:30

标签: com activex

ActiveX控件检测其容器(或容器的容器)是Internet Explorer的好方法是什么?

目前,我这样做是通过调用控件的IOleClientSite :: GetContainer方法并检查容器是否实现IHtmlDocument2接口,但现在,我想检查所有控件的祖先,看看是否有任何实现IHtmlDocument。

问题是控件现在包含在CComCompositeControl中并使用CreateActiveXControls(resourceID)方法创建,该方法将内部控件创建为CAxHostWindow实例的子控件。在这种情况下,CAxHostWindow实例将自己报告为自己的容器,因此我没有找到一种方法来走树(如果此模型中有这样的树)。

2 个答案:

答案 0 :(得分:1)

您可以通过以下陈述获得一些想法,

ActiveX控件通常可以访问以下容器窗口:

•框架窗口:容器主菜单所在的最外层容器窗口。 ActiveX控件通过调用IOleInPlaceFrame :: GetWindow或IOleInPlaceSite :: GetWindowContext来检索此窗口句柄。

•站点窗口:包含ActiveX控件视图的容器窗口。 ActiveX控件通过调用IOleInPlaceSite :: GetWindow来检索此容器窗口。

之后,您可以检查父窗口或同一窗口以查找其文本或其他属性。

在某些情况下,特别是从MFC,ActiveX控件成为反射器窗口的子窗口,其父窗口是从IOleInPlaceSite :: GetWindow返回的窗口。 在这种情况下,很难得到父母..

答案 1 :(得分:1)

所以,我可以想到两种方法。一种方法是获取您的网站的IServiceProvider实现和QueryService()以获得仅IE实现的服务。您可以通过IE头文件查找SID_S *,直到找到符合您需求的文件。

但是这样做的最佳方法(实际上,IE在内部进行的方式)就是检查进程名称。

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;    
}

查看进程名称是否为“iexplore.exe”。