6

因为我找不到这个问题的答案,所以我对 MSDN 进行了更深入的研究,发现了 isChild()。它可能会给我另一个问题的答案。

现在,为了使用 isChild() 我需要传递要检查的父应用程序的 HWND,在本例中是我自己的应用程序。如何获得我自己的应用程序的 HWND?

我不知道标题,因为它不断变化,所以我不能使用 FindWindow()。

谢谢

编辑:

由于不清楚,我将添加更多信息:我不是在创建窗口。我无权创建窗口。我的代码是一段代码,它与其他程序员正在编写的任何应用程序一起编译,我无法访问窗口的创建方式、标题或任何其他信息。那么,如何将 HWND 获取到我正在运行的应用程序的“WINDOW”?

4

8 回答 8

9

您的应用程序没有 HWND。窗户可以。一个应用程序可能没有窗口,也可能有很多窗口,因此没有“获取应用程序的 HWND”的通用功能。

显而易见的解决方案就是在拿到手柄时抓住它。创建窗口时,将返回一个 HWND。存储那个。

于 2009-07-14T14:03:36.667 回答
6

使用 GetTopWindow() 和 GetNextWindow() 遍历窗口 z 顺序。

但是,不要认为有必要,但您可以使用 GetCurrentProcessId() 和 GetWindowThreadProcessId(),可能类似以下内容会对您有所帮助:

HWND FindMyTopMostWindow()
{
    DWORD dwProcID = GetCurrentProcessId();
    HWND hWnd = GetTopWindow(GetDesktopWindow());
    while(hWnd)
    {
        DWORD dwWndProcID = 0;
        GetWindowThreadProcessId(hWnd, &dwWndProcID);
        if(dwWndProcID == dwProcID)
            return hWnd;            
        hWnd = GetNextWindow(hWnd, GW_HWNDNEXT);
    }
    return NULL;
 }
于 2009-07-14T14:06:04.290 回答
1

你不能只抓住从 CreateWindow 返回的句柄吗?如果不是,为什么不呢?

于 2009-07-14T13:57:50.947 回答
1

正如其他人已经指出的那样

  • 通常,一个应用程序可以有零个或多个顶级窗口。
  • 如果您自己创建窗口,您可以在某处记住 HWND。

但也许您的代码在 DLL 中,因此您实际上并没有自己创建顶级窗口。那么该怎么办?

我建议如下:

  • 用于EnumWindows枚举所有顶级窗口。
  • 用于GetWindowLongPtr获取每个顶级窗口的 HINSTANCE。将此与应用程序的 HINSTANCE 进行比较,您可以使用GetModuleHandle(NULL). 如果它们相同,则您已找到主窗口。

编辑:这是一些代码。原来你也必须使用IsWindowVisible,因为似乎有很多不可见的“帮助”窗口。

HWND hwndMain;

BOOL CALLBACK EnumWindowProc(HWND hwnd, LPARAM lParam)
{
    HINSTANCE hinst=(HINSTANCE)GetModuleHandle(NULL);

    if((HINSTANCE)GetWindowLongPtr(hwnd, GWL_HINSTANCE)==hinst &&
        IsWindowVisible(hwnd))
    {
        hwndMain=hwnd;
        return FALSE;
    }
    else
        return TRUE;
}

然后在你想找到窗口的地方:

hwndMain=NULL;
EnumWindows(EnumWindowProc, 0);

在此之后,hwndMain应该包含窗口的句柄,或者NULL如果不存在。

使用EnumWindows有点麻烦,但建议GetWindow不要在循环中调用,因为正如 MSDN 指出的那样:“调用 GetWindow 来执行此任务的应用程序可能会陷入无限循环或引用已被破坏的窗口的句柄。”

于 2009-07-14T14:20:22.163 回答
1

大概您的代码被主应用程序代码调用,否则它有什么用?在这种情况下,我不明白为什么您的代码的 API 不能包含某种方式来通知您应用程序主窗口的句柄。

于 2009-07-14T15:04:07.333 回答
1

您可以在呼吁 user32.dll http://msdn.microsoft.com/en-us/library/ms821625.aspx的线程中注入 DLL

于 2009-07-31T16:21:06.813 回答
0

这对我来说很旧,但是 IIRC 你应该在窗口 proc 中接收 HWND 作为参数。您可以在开始时将它保存在某个全局变量中。

于 2009-07-14T13:59:17.933 回答
0

你的windows类名呢?窗口创建总是不同吗?如果没有,你仍然可以使用 FindWindow()。

于 2009-07-14T14:04:46.367 回答