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) managementWM_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.
Roman R.
source share