Detect application windows

702 views Asked by At

I use CBT Windows Hook to detect window creation/deletion/min-max/move-size events.

I works well, but I need to filter whose events coming from normal widgets. Practically I need to being notified by CBT hook only for those windows that the user consider windows.

The problem that I'm facing make me mad, since I continuosly get spurious events even if I filter window as follow:

BOOL FilterWindowHandle(HWND hwnd)
{
    // Filtered window having WS_CHILDWINDOW style
    if ((GetWindowLongPtr(hwnd, GWL_STYLE) & WS_CHILDWINDOW) != 0)
        return (TRUE);
    // Filtered window not having WS_CAPTION style
    if ((GetWindowLongPtr(hwnd, GWL_STYLE) & WS_CAPTION) == 0)
        return (TRUE);
    // Not filtered
    return (FALSE);
}

Those spurious events comes from shadow effects, menus and everything displayed on screen.

Is there a robust method to filter real windows from its children?

I avoid the test of WS_BORDER or similar, since some applications could create their main window without border... or am I wrong?

2

There are 2 answers

0
Leo Davidson On BEST ANSWER

A good fit for "things the user considers windows" is the set of windows displayed in the Alt-Tab list (or on the Taskbar).

This OldNewThing article explains the rules (although the rules are not fixed or guaranteed to remain the same):

The general rule is:

For each visible window, walk up its owner chain until you find the root owner. Then walk back down the visible last active popup chain until you find a visible window. If you're back to where you're started, then put the window in the Alt+Tab list.

This can be overridden with explicit window styles:

A window with the WS_EX_TOOLWINDOW extended style is treated as if it weren't visible, even if it is. A window with the WS_EX_APPWINDOW extended style is treated as if it has no owner, even if it does.

See the full OldNewThing post which those two quotes come from for more detail.

0
Ran On

A useful criteria that I've used in the past is to test whether the window is a top-level window, i.e. its parent is NULL.