【问题标题】:How come FindWindow finds a window that EnumChildWindows doesn't?FindWindow 怎么会找到 EnumChildWindows 找不到的窗口?
【发布时间】:2012-03-01 14:49:28
【问题描述】:

我正在寻找一个类名为“CLIPBRDWNDCLASS”的窗口(可以在办公应用程序和其他应用程序中找到)。

如果我使用 FindWindow 或 FindWindowEx,我会找到第一个具有此类的 HWND,但我想要 all 具有该类的窗口,因此我决定使用递归 EnumChildWindows 枚举所有窗口并找到我想要的窗口:

//-------------------------------------------------------------------------------
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;
}
//-------------------------------------------------------------------------------

这是这个窗口不由EnumWindows返回,只由FindWindow返回。

有没有人能说出为什么它不起作用???

【问题讨论】:

  • 首先,EnumChildWindows()is already recursive,您不需要在回调函数中再次调用它。其次,尝试打印你遇到的所有窗口的类名,看看它是否给你一个提示。
  • @Asaf - 感谢 EnumChildWindows() 是递归的,我不知道。我认为它只有直接的孩子。我试过打印所有的名字,但它没有让我到任何地方......看起来这个窗口只是忽略了 EnumChildWindows(),但可以使用 FindWindowEx() 找到。
  • 是的,他们的名字很糟糕。您是否尝试在与 Windows 本身相同的进程中使用它?
  • @Asaf - 不...我认为这不重要...

标签: c++ windows winapi


【解决方案1】:

EnumWindows 不起作用的原因是您要查找的窗口是message only window

FindWindowEx可以在两种情况下找到它们:

  1. 如果hwndParenthwndChildAfter 都为NULL。
  2. 如果您将“HWND_MESSAGE”指定为父窗口。

此代码将为您找到所有相关窗口(来自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);
}

另请注意,与上面链接中的内容不同,GetParent() 仅用于消息窗口确实返回 HWND_MESSAGE(至少对于我的测试而言不是)。

【讨论】:

    【解决方案2】:

    枚举所有仅消息窗口的旧方法:

    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")

    【讨论】:

      猜你喜欢
      • 2012-06-07
      • 2013-05-08
      • 1970-01-01
      • 1970-01-01
      • 2014-03-24
      • 2016-12-22
      • 1970-01-01
      • 2017-06-28
      • 2021-08-24
      相关资源
      最近更新 更多