winapiwin32guihinstance

Determine the current HINSTANCE?


The HINSTANCE of a win32 application is passed to WinMain, but is there any other way of determining the current HINSTANCE (in case you couldn't tell, I'm very new to win32 programming!)? I need to create a window inside of a library and (since the library is cross platform), I'd prefer not to have to pass it in.


Solution

  • As a library author, you commonly don't know the module into which your code gets compiled and linked. Consequently, discovering the module's handle is challenging because you wouldn't know what name to pass into GetModuleHandleW().

    The solution is to delegate producing an answer to the linker. Common linkers for Windows (link.exe, lld, ld) all agree on injecting a synthetic symbol __ImageBase with an RVA of 0 which allows library authors to figure out the current module's handle at runtime from a location known at link time1:

    HMODULE GetCurrentModuleHandle() {
        EXTERN_C IMAGE_DOS_HEADER __ImageBase;
        return ((HMODULE)&__ImageBase);
    }
    

    If you are concerned that your code is being linked by a linker that doesn't support the __ImageBase symbol you can call GetModuleHandleExW() with the GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS flag instead:

    HMODULE GetCurrentModuleHandle() {
        HMODULE ImageBase;
        if (GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
                               (LPCWSTR)&GetCurrentModuleHandle,
                               &ImageBase)) {
            return ImageBase;
        }
        return 0;
    }
    

    1 Raymond Chen's article Accessing the current module’s HINSTANCE from a static library has more details.