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

6
我正在尝试编写一个小型的C(也可以是C++)工具,用于监视ActiveX控件。给定某个窗口的HWND句柄,我想打印:
  1. 此HWND对应的ActiveX控件公开了哪些属性和方法
  2. 可选地,此控件实现了哪些接口
为了测试目的,我将随机的ActiveX控件(如Microsoft滑块控件)嵌入到ActiveX控件测试容器中,以便我知道控件的HWND确实是ActiveX控件的窗口。此外,我知道控件公开了哪些属性/方法,因此可以测试我的工具。
我目前针对(1)的解决方案是使用AccessibleObjectFromWindow函数获取HWND的IDispatch对象。它可以工作,但似乎你总是只能获得可访问性接口(返回的IDispatch只是IAccessible接口的IDispatch部分)。我尝试将样本控件的实际CLSID作为第三个参数传递给AccessibleObjectFromWindow,但也没有帮助。似乎该函数真正地实现了它的名称 - 你总是只能获得可访问性接口。:-)
有人知道是否可能实现这样一个“ActiveX间谍”吗?如果可以,应该如何实现呢?
2个回答

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 和其他接口来继续发现接口和属性。然而,您需要将其置于控件所在进程的上下文中,这使得枚举更加困难:您必须将代码注入进程中,例如使用钩子。

1

你不需要

如果你可以访问ActiveX控件的实现(例如在ATL中),你可以使用查找表来获取拥有HWND的控件;你可以将其与全局实例表结合使用。


哦,我明白了。您的意思是使用 IOleWindow::getWindow 获取ActiveX控件的HWND(用于构建查找表)吗? - Frerich Raabe
2
如果我可以访问HWND 并且可以将所需的控件COM接口(作为RCW)导入,那么是否可以在控件上调用COM接口方法?如果可以,如何操作? - Asad Saeeduddin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接