Windows APIを使用してプログラミングするとき、私は常にHINSTANCE
からのWinMain
をすぐにグローバル変数にしました。 [OK]ボタンを作成する場合は、次のようにします(グローバル_HINSTANCE g_hInstance
_を指定):
_return CreateWindow("BUTTON", "OK", WS_TABSTOP|WS_VISIBLE|WS_CHILD|BS_DEFPUSHBUTTON, 10, 10, 100, 30, exampleParentWindow, EXAMPLECHILDID, g_hInstance, NULL);
_
しかし最近、GetModuleHandle(NULL)
*の呼び出しを使用して、パラメーターとして渡したり、グローバル名前空間を詰まらせたりすることなく、インスタンスハンドルが決定されるのを見てきました。したがって、上記の例は次のようになります。
_return CreateWindow("BUTTON", "OK", WS_TABSTOP|WS_VISIBLE|WS_CHILD|BS_DEFPUSHBUTTON, 10, 10, 100, 30, exampleParentWindow, EXAMPLECHILDID, GetModuleHandle(NULL), NULL);
_
*コンパイラがサポートしている場合は、GetModuleHandle(nullptr)
と書くことができ、ステートメントは同じ結果になります。
インスタンスハンドルを明示的に指定するよりもGetModuleHandle(NULL)
を呼び出す利点(ある場合)は何ですか?
細かい説明:これには答えがあることはわかっていますが、StackOverflowに関する独自の質問としては述べられていません。
EXEでは、違いはありません。 hInstance
from WinMain()
とGetModuleHandle(NULL)
はどちらも同じHINSTANCE
(.exeファイルのモジュール)を参照します。ただし、DLLの内部にウィンドウを作成している場合は、DLLのhInstance
を使用する必要がありますが、GetModuleHandle(NULL)
は引き続き返すため、違いはありますDLLをロードしたEXEのHINSTANCE
.
HMODULE WINAPI GetModuleHandle( _In_opt_ LPCTSTR lpModuleName );
渡されたモジュール名のモジュールハンドルを渡します。NULLを渡した場合、現在実行中のEXEのモジュールハンドルを取得します。モジュール名を具体的に指定すると、プロセスのアドレス空間にマップされているそのdllのモジュールハンドルを取得します。使用方法は、dllによってエクスポートされた関数を呼び出そうとしているとき、またはそのdllのダイアログテンプレートを使用しようとしているときです。
WinMain HINSTANCEを直接使用するよりもGetModuleHandle(NULL)を使用することで得られる潜在的な利点の1つは、アーキテクチャから得られます。 linux/windows/whateverで実行されるプラットフォームに依存しないシステムを提供する場合は、プラットフォームに依存する変換を行うレイヤーを使用できます。その場合は、メインアプリケーションコードにHINSTANCEなどのプラットフォーム依存オブジェクトが表示されないようにする必要があります。したがって、そのプラットフォーム依存を回避するために、プラットフォーム依存クラスのコンストラクターにGetModuleHandle(NULL)を入れました。これは、WinMain HINSTANCEを直接使用するのと同じ効果がありますが、メインコードベース自体から特定の機能を抽象化します。
これらの答えに私の2セントを追加します。 DLL内からモジュールハンドルを取得する必要がある場合(およびしたくない、またはDllMain
呼び出しからグローバル変数に保存できない場合)代わりにこの関数を使用して取得できます。
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;
}