Get Window Handle (HWND) of a window created by a library call

aeon picture aeon · Jan 19, 2013 · Viewed 12.6k times · Source

EDIT: I forgot to mention, I do not have source code for the DLL that creates window, so I can't actually change the function to return HWND.

I am creating a Win32 application, and am using a DLL that creates a window for me through one of its exported function "void X();" I call X() in my WinMain().

It does create a window for me. I want to get the HWND of the window that was created by this exported library function, as X() returns void, so I can use it for other API calls. Can someone tell the easiest to get the HWND?

I have searched and questions answered here, but I cant somehow figure out the exact, appropriate solution. I tried EnumWIndows() and then getting the Process ID, and then comparing with the current thread process ID. But I guess there should be a far better much more efficient and a easy way to get HWND. After all, I am in the WinMain of the process that created this window in the first place.

If I need to explain anything, that I have missed out writing here, please let me know.

I am sure that this is very basic and am missing something blatantly here. Sorry. Thanks & Regards!

Answer

rodrigo picture rodrigo · Jan 19, 2013

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.