如何在给出ActiveX控件的HWND的情况下获得COM接口?

时间:2011-04-05 09:28:47

标签: c++ winapi com activex

我正在尝试编写一个用于监视ActiveX控件的小C(C ++也很好)实用程序。鉴于窗口的一些HWND句柄,我想打印

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

    我对(1)的当前解决方案是使用HWND上的AccessibleObjectFromWindow函数来获得IDispatch。它可以工作,但似乎你总是只返回一个可访问的接口(返回的IDispatch只是IAccessible接口的IDispatch部分)。我尝试将我的样本控件的实际CLSID作为第三个参数传递给AccessibleObjectFromWindow,但这也没有帮助。似乎该功能真正符合其名称 - 您始终只能获得辅助功能界面。 : - )

    有人知道这样的“ActiveX间谍”是否可行?如果是这样,怎么样?

2 个答案:

答案 0 :(得分:1)

你没有

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

结合使用

答案 1 :(得分:1)

正如@sehe指出的那样,没有可靠的方法来发现外部控件,更多的是说一些ActiveX控件在没有自己的HWND的情况下可能没有窗口。

但是,如果您可以检测到至少某些控件,则可以查找由热门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和其他接口的接口和属性的doscovery。但是,您需要将其作为托管控件的进程的上下文,这会使枚举变得更加困难:您必须将代码注入到流程中,例如:使用钩子。