【问题标题】:How do I get a COM interface given a HWND of an ActiveX control?给定 ActiveX 控件的 HWND,如何获得 COM 接口?
【发布时间】:2011-07-29 19:42:06
【问题描述】:

我正在尝试编写一个小 C(C++ 也可以)实用程序来监视 ActiveX 控件。给定我想打印的窗口的一些 HWND 句柄

  1. ActiveX 控件为此 HWND 公开了哪些属性和方法
  2. 可选,控件实现了哪些接口

出于测试目的,我将随机 ActiveX 控件(如 Microsoft Slider 控件)嵌入到ActiveX Control Test Container 中,以便我知道控件的 HWND 确实是 ActiveX 控件的窗口。此外,我知道控件公开了哪些属性/方法,因此我可以测试我的工具。

我目前针对 (1) 的解决方案是使用 HWND 上的 AccessibleObjectFromWindow 函数来获取 IDispatch。它有效,但似乎你真的总是只能得到一个可访问的接口(返回的 IDispatch 只是 IAccessible 接口的 IDispatch 部分)。我尝试将示例控件的实际 CLSID 作为第三个参数传递给AccessibleObjectFromWindow,但这也无济于事。似乎该功能确实名副其实——您总是只能获得可访问性界面。 :-)

有谁知道这样的“ActiveX 间谍”是否存在?如果有,怎么做?

【问题讨论】:

    标签: c++ winapi com activex


    【解决方案1】:

    你没有

    如果您有权访问 activex 控件的实现(例如在 ATL 中),您可以使用查找表来返回拥有 HWND 的控件;您可以将其与 global instance table

    结合使用

    【讨论】:

    • 嗯,我明白了。您的意思是使用 IOleWindow::getWindow 来获取 ActiveX 控件的 HWND(用于构建查找表)?
    • 如果我可以访问 HWND 并且 可以导入控件的所需 COM 接口(作为 RCW),是否可以在控件上调用 COM 接口方法?如果有,怎么做?
    【解决方案2】:

    正如@sehe 指出的那样,没有可靠的方法来从外部发现控件,更重要的是,如果没有自己的HWNDs,某些 ActiveX 控件是/可能是无窗口的。

    但是,如果您可以检测到至少一些控件,则可以查找由流行的 ATL CAxHostWindow 类托管的控件。该主机将响应特定的窗口消息,让您获得主机和控制接口:

    • WM_ATLGETHOST 获取您的控制主机(站点)的IUnknown
    • WM_ATLGETCONTROL 为您提供控件本身的 IUnknown

    两个消息标识符都可以使用RegisterWindowMessage API 获取:

    const UINT WM_ATLGETHOST = RegisterWindowMessage(_T("WM_ATLGETHOST"));
    const UINT WM_ATLGETCONTROL = RegisterWindowMessage(_T("WM_ATLGETCONTROL"));
    

    拥有控制权的IUnknown,您可以继续查找请求IDispatchIProvideClassInfo 和其他接口的接口和属性。但是,您需要使其成为托管控件的进程的上下文,这使得枚举变得更加困难:您必须将代码注入到进程中,例如使用钩子。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-04-05
      • 2011-04-02
      • 2016-11-12
      • 2011-01-21
      • 2010-11-24
      • 1970-01-01
      • 2010-12-18
      相关资源
      最近更新 更多