Reputation: 835
I want to monitor any window is created globally. The closest API I found is SetWinEventHook
on EVENT_OBJECT_CREATE
, however, it not only hooks window creation but also controls. I wonder if there is any way that does not cost too much, and can hook not only CBT windows.
I tried to use IsWindow()
to detect if the callback hwnd is a window hwnd, but it seems always return true regardless if the hwnd is a window or control.
I would prefer using managed api rather than adding other dlls, although if it is absolute necessary it is still an open option.
Lastly, how can I hook the windows maximise, minimise and restore events? Tried EVENT_OBJECT_STATECHANGE
but it seems not the correct one. Tried EVENT_SYSTEM_MOVESIZESTART
and EVENT_SYSTEM_MOVESIZEEND
but also not capturing the max/min/restore events.
Partial code can be seen as follows:
private List<IntPtr> _hooks;
private User32ex.WinEventDelegate _delegate;
private void StartService() {
_delegate = WinEventProc;
_hooks.Add(User32ex.SetWinEventHook(User32.WindowsEventHookType.EVENT_OBJECT_CREATE, User32.WindowsEventHookType.EVENT_OBJECT_DESTROY, IntPtr.Zero, _delegate, 0, 0, User32.WindowsEventHookFlags.WINEVENT_OUTOFCONTEXT));
// Other hooks
}
private void WinEventProc(IntPtr hWinEventHook, User32.WindowsEventHookType eventType, IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime) {
if (hwnd == IntPtr.Zero || !User32.IsWindow(hwnd)) return;
switch (eventType) {
case User32.WindowsEventHookType.EVENT_OBJECT_CREATE:
Debug.Print($"Create: {hwnd}");
// Do something - here captures all objects not only windows but also controls etc
break;
case User32.WindowsEventHookType.EVENT_OBJECT_STATECHANGE:
Debug.Print($"State change: {hwnd}");
// Do something
break;
// Other cases
}
}
Many thanks in advance!
Upvotes: 2
Views: 1432
Reputation: 1317
Welcome to the beautiful world of Windows API! The reason your hook hooks not only "windows", but also "controls" is that in Windows both "windows" and "controls" are just windows. There might be different kinds of windows they might look different and behave differently; controls are just windows with specific looks and specific behaviours.
Since all of them just windows, you can't just hook to "windows" not hooking to "controls" at the same time. However, when you already hooked to one, you may identify if the window you've hooked to is the kind of window you would like to hook. As suggested in the comments, you may use window styles:
// this is a pretty crude and basic way to sort out "controls"
BOOL isControl_KindOf = GetWindowLong(hwnd, GWL_STYLE) & WS_CHILD;
Upvotes: 2