开发者

How do I get a COM interface given a HWND of an ActiveX control?

I'm trying to write a little C (C++ is fine, too) utility for spying ActiveX controls. Given some HWND handle of a window I'd like to print

  1. which properties and which methods are exposed by the ActiveX control for this HWND
  2. optionally, what interfaces does the control implement

For testing purposes, I'm embedding random ActiveX controls (like, the Microsoft Slider control) into the ActiveX Control Test Container so that I know that the HWND of the control is indeed the window of an ActiveX control. Furthermore, I know what properties/methods the control exposes, so I can开发者_C百科 test my tool.

My current solution for (1) is to use the AccessibleObjectFromWindow function on the HWND to get an IDispatch. It works, but it seems you really always only get an accessible interface back (the IDispatch which is returned is just the IDispatch part of the IAccessible interface). I tried passing the actual CLSID of my sample control as the third argument to AccessibleObjectFromWindow but that didn't help either. Seems that function really lives up to it's name - you always only get the accessibility interface. :-)

Does anybody know whether such an "ActiveX spy" is possible at all? If so, how?


You don't

If you have access to the implementation of the activex control (e.g. in ATL) you can use a lookup table to get back at the control owning the HWND; you could use this in conjunction with the global instance table


As @sehe pointed out, there is no reliable way to discover controls externally, and more to say some ActiveX controls are/might be windowless without their own HWNDs.

However, if you are OK to detect at least some controls out there, you can look for those hosted by popular ATL CAxHostWindow class. This host will respond to specific window messages letting you obtain both host and control interfaces:

  • WM_ATLGETHOST gets you IUnknown of the control host (site)
  • WM_ATLGETCONTROL gets you IUnknown of the control itself

Both message identifiers can be obtained using RegisterWindowMessage API:

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

Having control's IUnknown on hands you can move on with doscovery of interfaces and properties requesting IDispatch, IProvideClassInfo and other interfaces. However, you need to make it the context of the process hosting the control, which makes enumeration harder: you have to inject your code into the process, e.g. using a hook.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜