GetModuleHandle(NULL) vs hInstance
Asked Answered
G

4

30

When programming using the Windows API, I've always made the HINSTANCE from WinMain a global variable immediately. If I want to make an OK button, I'd do it like so (given global HINSTANCE g_hInstance):

return CreateWindow("BUTTON", "OK", WS_TABSTOP|WS_VISIBLE|WS_CHILD|BS_DEFPUSHBUTTON, 10, 10, 100, 30, exampleParentWindow, EXAMPLECHILDID, g_hInstance, NULL);

but lately I've been seeing the instance handle determined without having to be passed as a parameter or clogging up the global namespace, using a call to GetModuleHandle(NULL)*. So, the example above would look like this:

return CreateWindow("BUTTON", "OK", WS_TABSTOP|WS_VISIBLE|WS_CHILD|BS_DEFPUSHBUTTON, 10, 10, 100, 30, exampleParentWindow, EXAMPLECHILDID, GetModuleHandle(NULL), NULL);

*If your compiler supports it, you can write GetModuleHandle(nullptr) and the statement will have the same result.

What's the advantage (if any) of calling GetModuleHandle(NULL) over explicitly specifying the instance handle?

Fine Print: I know this has an answer, but it has not been phrased as its own question on StackOverflow.

Gaullism answered 12/2, 2014 at 3:31 Comment(0)
R
45

In an EXE, it does not make any difference. hInstance from WinMain() and GetModuleHandle(NULL) both refer to the same HINSTANCE (the module of the .exe file). But it does make a difference if you are creating windows inside of a DLL instead, since you have to use the DLL's hInstance but GetModuleHandle(NULL) will still return the HINSTANCE of the EXE that loaded the DLL.

Redstart answered 12/2, 2014 at 3:45 Comment(1)
+1 And if anyone needs an example where this is important, consider which module resource table CreateDialog looks in when resolving the dialog template id being requested. Menu's, icons, etc. Gotta find them somewhere.Ammoniacal
G
4
HMODULE WINAPI GetModuleHandle( _In_opt_  LPCTSTR lpModuleName );

Give the module handle of the module name passed.If you are passing NULL, the you get the module handle of the EXE which is currently running. If you specifically name the module name, you get the module handle of that dll which is mapped to the process address space. The use is that when you are trying to call a function exported by the dll, or trying to use a dialog template in side that dll.At that time if you use the HMODULE returned form GetMoudleHandle(NULL) your code wont work.

Gonococcus answered 12/2, 2014 at 3:49 Comment(0)
O
4

Just to add my two-cents to these answers. In case you need to get the module handle from within a DLL (and don't want to, or can't save it in a global variable from the DllMain call) you can use this function to get it instead:

HMODULE getThisModuleHandle()
{
    //Returns module handle where this function is running in: EXE or DLL
    HMODULE hModule = NULL;
    ::GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | 
        GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, 
        (LPCTSTR)getThisModuleHandle, &hModule);

    return hModule;
}
Oldtimer answered 28/6, 2019 at 10:3 Comment(0)
T
3

One potential gain you get from using GetModuleHandle(NULL) over directly using the WinMain HINSTANCE comes more from architecture. If you want to provide a platform-independent system that runs on linux/windows/whatever you can have a layer that does platform-dependent translations. If that's the case you don't want platform dependent objects such as HINSTANCE showing up in the main application code. So, to circumvent that platform-dependence I put GetModuleHandle(NULL) in the constructor of the platform-dependent class which has the same effect that direct use of the WinMain HINSTANCE does but that abstracts that specific functionality out of the main codebase itself.

Trajan answered 5/6, 2019 at 20:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.