How to get a COM interface considering the HWND of an ActiveX control?

I am trying to write a small C utility (C ++ is also good) for spying ActiveX controls. Given some HWND window handle, I would like to print

  • which properties and methods are set by the ActiveX control for this HWND
  • optionally which interfaces the control implements

For testing purposes, I inject random ActiveX controls (such as a Microsoft Slider control) into the ActiveX Control test container so that the HWND of the control is indeed an ActiveX control window. In addition, I know what properties / methods control provides, so I can test my tool.

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

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

+6
c ++ winapi com activex
source share
2 answers

You do not

If you have access to an activex control implementation (for example, in ATL), you can use the lookup table to return to the control that owns the HWND; you can use this in conjunction with the global instance table

+1
source share

As pointed out in this question, there is no reliable way to detect external controls, and in addition, some ActiveX controls can be windowless without their own HWND s.

However, if you are fine to detect at least some controls, you can search for those that are hosted in the popular ATL CAxHostWindow class. This host will respond to specific window messages, allowing you to receive both the host and control interfaces:

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

Both message identifiers can be obtained using the RegisterWindowMessage API:

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

Having IUnknown control in your hands, you can continue to work with opening interfaces and properties with the request of IDispatch , IProvideClassInfo and other interfaces. However, you need to make this the context of the process in which the control is located, which simplifies the enumeration: you need to insert your code into this process, for example. using the hook.

+1
source share

All Articles