9

初心者なのでとても初歩的な質問かもしれません。DirectX 11 を開始しています。最初のアプリケーションの作成中に wWinMain が使用され、WinMain と wWinMain の違いを探しているときに、このパラメーター prevInstance に出会いました。

MSDN によれば、prevInstance は常に null であり、常に null であるため、なぜ存在するのでしょうか (作成者が無用なパラメーターを与えていないと考えるのは論理的であるため)。そして(本から引用)、

アプリケーションの以前のインスタンスが既に実行されているかどうかを判断する方法が必要な場合、ドキュメントでは CreateMutex を使用して一意の名前のミューテックスを作成することを推奨しています。ミューテックスは作成されますが、CreateMutex 関数は ERROR_ALREADY_EXISTS を返します。

ミューテックスとは何か、およびその使用方法 (適切なリンクで十分です)。また、アプリケーションの別のインスタンスが存在するかどうかを確認するには、メソッドが必要なようです。prevInstance には、それへのポインタまたは参照が必要ですが、null であるため、明らかにそうではありません。その理由と、prevInstance の役割は何ですか?

4

2 に答える 2

17

Raymond Chen のブログは、今日の私たちにとって "変わった" Windows API の側面について議論することにほぼ完全に専念しています。幸いなことに、彼はこの質問に正確に答えるブログ投稿を持っています。

16 ビット Windows には、GetInstanceData という関数がありました。この関数は、HINSTANCE、ポインター、および長さを取り、そのインスタンスから現在のインスタンスにメモリをコピーしました。(これは、ReadProcessMemory に相当する 16 ビットの一種ですが、2 番目と 3 番目のパラメーターが同じでなければならないという制限があります。)

...

これが、WinMain への hPrevInstance パラメータの理由です。hPrevInstance が NULL でない場合、それは既に実行されているプログラムのコピーのインスタンス ハンドルです。GetInstanceData を使用してそこからデータをコピーすると、すぐに立ち上がることができます。たとえば、メイン ウィンドウ ハンドルを前のインスタンスからコピーして、それと通信できるようにすることができます。

hPrevInstance が NULL であるかどうかによって、プログラムの最初のコピーであるかどうかがわかります。16 ビット Windows では、プログラムの最初のインスタンスのみがそのクラスを登録しました。2 番目以降のインスタンスは、最初のインスタンスによって登録されたクラスを引き続き使用します。(実際、試みたとしても、クラスが既に存在するため、登録は失敗します。) したがって、hPrevInstance が NULL でない場合、すべての 16 ビット Windows プログラムはクラスの登録をスキップしました。

Win32 を設計した人々は、WinMain を移植するときに、ちょっとした問題に直面しました。hPrevInstance に何を渡すか? 結局のところ、モジュール/インスタンス全体は Win32 には存在しませんでした。別のアドレス空間は、2 番目のインスタンスで再初期化をスキップしたプログラムが機能しなくなることを意味していました。そのため、Win32 は常に NULL を渡し、すべてのプログラムが最初のものであると信じ込ませます。

もちろん、hPrevInstance互換性の理由を除いて、現在の Windows API とは無関係であるため、MSDN ではミューテックスを使用してアプリケーションの以前のインスタンスを検出することをお勧めしています。

ミューテックスは「相互排除」の略です。については、MSDN のドキュメントを参照できますCreateMutex()。アプリケーションの以前のインスタンスを検出するためにミューテックスを使用する例はたくさんあります。基本的な考え方は、思いついた一意の名前でミューテックスを作成し、その名前付きミューテックスを作成しようとすることです。CreateMutex()で失敗した場合ERROR_ALREADY_EXISTSは、アプリケーションのインスタンスが既に起動されていることがわかります。

于 2011-09-17T23:13:38.603 に答える
1

prev インスタンス パラメータは、16 ビット Windows との互換性のために用意されています。WinMain の MSDN リファレンスに記載されていたと思いますが、少なくとも以前はそうでした。

于 2011-09-17T23:14:07.520 に答える