web-dev-qa-db-ja.com

GetModuleHandle(NULL)とhInstance

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に関する独自の質問としては述べられていません。

24
Proxy

EXEでは、違いはありません。 hInstance from WinMain()GetModuleHandle(NULL)はどちらも同じHINSTANCE(.exeファイルのモジュール)を参照します。ただし、DLLの内部にウィンドウを作成している場合は、DLLのhInstanceを使用する必要がありますが、GetModuleHandle(NULL)は引き続き返すため、違いはありますDLLをロードしたEXEのHINSTANCE.

31
Remy Lebeau
HMODULE WINAPI GetModuleHandle( _In_opt_  LPCTSTR lpModuleName );

渡されたモジュール名のモジュールハンドルを渡します。NULLを渡した場合、現在実行中のEXEのモジュールハンドルを取得します。モジュール名を具体的に指定すると、プロセスのアドレス空間にマップされているそのdllのモジュールハンドルを取得します。使用方法は、dllによってエクスポートされた関数を呼び出そうとしているとき、またはそのdllのダイアログテンプレートを使用しようとしているときです。

2
Tony Thomas

WinMain HINSTANCEを直接使用するよりもGetModuleHandle(NULL)を使用することで得られる潜在的な利点の1つは、アーキテクチャから得られます。 linux/windows/whateverで実行されるプラットフォームに依存しないシステムを提供する場合は、プラットフォームに依存する変換を行うレイヤーを使用できます。その場合は、メインアプリケーションコードにHINSTANCEなどのプラットフォーム依存オブジェクトが表示されないようにする必要があります。したがって、そのプラットフォーム依存を回避するために、プラットフォーム依存クラスのコンストラクターにGetModuleHandle(NULL)を入れました。これは、WinMain HINSTANCEを直接使用するのと同じ効果がありますが、メインコードベース自体から特定の機能を抽象化します。

1

これらの答えに私の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;
}
0
c00000fd