Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How come FindWindow finds a window that EnumChildWindows doesn't?

I'm looking for a window that its class name is "CLIPBRDWNDCLASS" (it can be found in office apps and other applications).

If I use FindWindow or FindWindowEx I find the first HWND that has this class, but I want all the windows with that class, so I decided to use recursive EnumChildWindows to enumerate all windows and find the window I want:

//-------------------------------------------------------------------------------
BOOL CALLBACK enum_wnd_proc(HWND h, LPARAM lp)
{
    char cls[1024] = {0};
    ::GetClassNameA(h, cls, 1024);

    if(std::string(cls) == "CLIPBRDWNDCLASS")
    {
        // match!
    }

    ::EnumChildWindows(h, enum_wnd_proc, NULL);

    return TRUE;
}
//-------------------------------------------------------------------------------
int _tmain(int argc, _TCHAR* argv[])
{
    ::EnumWindows(enum_wnd_proc, NULL); 
    return 0;
}
//-------------------------------------------------------------------------------

The this is that this window does not return by the EnumWindows, only by FindWindow.

Does anyone can tell why it doesn't work ???

like image 341
TCS Avatar asked Dec 12 '22 04:12

TCS


2 Answers

The reason EnumWindows doesn't work is that the window you are looking for is a message only window.

FindWindowEx can find them in two cases:

  1. If both hwndParent and hwndChildAfter are NULL.
  2. If you specify 'HWND_MESSAGE' as your parent window.

This code will find all the relevant windows for you (a modified version of a solution from here):

HWND hWindow = FindWindowExA(HWND_MESSAGE, NULL, "CLIPBRDWNDCLASS", NULL);
while (hWindow )
{
    // Do something here with window...

    // Find next window
    hWindow = FindWindowExA(HWND_MESSAGE, hWindow , "CLIPBRDWNDCLASS", NULL);
}

Also note that unlike what's written in the above link, GetParent() for message only windows does not return HWND_MESSAGE (at least not for my tests).

like image 62
Asaf Avatar answered Dec 15 '22 00:12

Asaf


My old easy way to ENUMERATE all message-only windows:

EnumChildWindows(GetAncestor(FindWindowEx(HWND_MESSAGE,0,0,0),GA_PARENT),addr EnumChildProc,0)

// GetAncestor(FindWindowEx(HWND_MESSAGE,0,0,0),GA_PARENT) = "GetMessageWindow" (class "Message")

// GetAncestor(FindWindowEx(HWND_DESKTOP,0,0,0),GA_PARENT) = GetDesktopWindow (class "#32769")

like image 36
kero Avatar answered Dec 14 '22 22:12

kero