2

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

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

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

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

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

我确信这是非常基本的,并且在这里公然遗漏了一些东西。对不起。感谢和问候!

4

2 回答 2

2

The easiest way to do that is to use the function SetWindowsHookEx(WH_CBT, fun, NULL, GetCurrentThreadId()). Then the fun function, a callback defined by you, will be called when a number of events happen. The one you want is the HCBT_CREATEWND.

Somethink like that (totally untested):

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

Note that this function is not thread-aware, but most likely you will call it just once at the beginning of your code, so it shouldn't matter.

And beware! Many functions, even Win32 API functions, create hidden windows. This code will hook all of them and return the last one to be created. Changing it to return any other, or even a list of them, if needed, should be trivial.

于 2013-01-19T08:42:46.927 回答
2

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

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    // ...
    X();
    HWND hWnd = FindWindow("ClassNameHere", "TitleHere");
    // ...
    return 0;
}
于 2013-01-19T16:50:32.573 回答