获取由库调用创建的窗口的窗口句柄(HWND)

时间:2013-01-19 07:36:06

标签: c++ visual-studio winapi hwnd

编辑:我忘了提一下,我没有创建窗口的DLL的源代码,所以我实际上无法更改函数来返回HWND。

我正在创建一个Win32应用程序,并且正在使用一个DLL,它通过其导出的函数“void X();”为我创建了一个窗口。我在WinMain()中调用X()。

它确实为我创建了一个窗口。我想得到由这个导出的库函数创建的窗口的HWND,因为X()返回void,所以我可以将它用于其他API调用。 有人能说最容易得到HWND吗?

我已经在这里搜索并回答了问题,但我无法以某种方式找出确切的,合适的解决方案。我尝试了EnumWIndows()然后获取进程ID,然后与当前线程进程ID进行比较。但我想应该有一个更好的效率和一个简单的方法来获得HWND。 毕竟,我是在创建这个窗口的过程的WinMain中。

如果我需要解释一下,我错过了写在这里,请告诉我。

我确信这是非常基本的,并且在这里公然遗漏了一些东西。抱歉。 谢谢&此致!

2 个答案:

答案 0 :(得分:2)

最简单的方法是使用函数SetWindowsHookEx(WH_CBT, fun, NULL, GetCurrentThreadId())。然后,当发生许多事件时,将调用fun函数(由您定义的回调)。你想要的是HCBT_CREATEWND

有些想法(完全未经测试):

HWND hDllHandle = NULL;
LRESULT CALLBACK X_CBTProc(int nCode, WPARAM wParam, LPARAM lParam)
{
    if (nCode == HCBT_CREATEWND)
        hDllHandle = (HWND)wParam;
    return CallNextHookEx(NULL, nCode, wParam, lParam); //The first parameter is useless
}

HWND CallXAndGetHWND()
{
    HHOOK hDllHook = SetWindowsHookEx(WH_CBT, X_CBTProc, NULL, GetCurrentThreadId());
    X();
    UnhookWindowsHookEx(hDllHook);
    //hDllHandle is a global variable, so will be now you window!
    return hDllHandle;
}

请注意,此函数不支持线程,但很可能您只需在代码开头调用一次,因此无关紧要。

小心!许多函数,甚至是Win32 API函数,都会创建隐藏的窗口。此代码将挂钩所有这些代码并返回要创建的最后一个代码。如果需要,更改它以返回任何其他内容,甚至是它们的列表应该是微不足道的。

答案 1 :(得分:2)

使用Spy ++或Winspector等工具查看应用创建的所有HWND,特别是其类名和窗口标题。然后,您可以将这些值复制到代码中,并在DLL创建窗口后对FindWindow()进行一次调用,例如:

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    // ...
    X();
    HWND hWnd = FindWindow("ClassNameHere", "TitleHere");
    // ...
    return 0;
}