二重起動防止は、単に同じアプリケーションが起動されているかどうかを判定することしかできませんでした。そこで今回は、2回目以降の起動時に、すでに起動されている側のプロセスに向けて、新しいプロセスが起動されたことを通知してみます。最初に起動されていた側では、通知を受け取ったら、2つ目のプロセスが起動したことを表示するようにしてみます。メッセージによる通知2回目以降に起動されたプロセスからすでに起動されているプロセスに対して何か通知を行うには、初回起動のプロセスが所有するウィンドウにアプリケーション固有のメッセージを送ります。0xBFFFまでの範囲についてはアプリケーションが自由にその役割を定義してよいということになっています。これを使用すれば、すでに起動されているプロセスがそのメッセージを取得することで再び起動されたことを知ることができます。ここで1つ問題が出てきます。ウィンドウにメッセージを送るためのPostMessage関数やSendMessage関数は、その引数として対象となるウィンドウのハンドルを必要とします。メッセージを送るためには対象となるウィンドウのハンドルを知らなくてはなりません。そこで今回は、初回起動かどうかを判別するための名前付きカーネルオブジェクトとして、ミューテックスではなくファイルマッピングオブジェクトを採用し、これを使って共有メモリを作成してしまいましょう。最初に起動されたプロセスのウィンドウハンドルを共有メモリに格納してしまえばよいのです。すれば、2回目以降に起動されたプロセスは、その共有メモリからウィンドウハンドルを取得して、そのハンドルの示すウィンドウにメッセージを送ることができます。メッセージの送信・ポストについては、『メッセージの送信とポスト』の項を参照してください。ファイルマッピングオブジェクトについては『プロセス間共有メモリ』の項を参照してください。ところで、メッセージを渡すにはPostMessage関数によるメッセージのポストとSendMessage関数によるメッセージの送信があります。以前にも説明したとおり、SendMessage関数は、相手側でのメッセージ処理が完了するまで呼び出し元のプログラムの実行を停止して待機します。PostMessage関数はメッセージをポストするのみで、相手のメッセージ処理を待たずに直ちに次の処理を行います。どちらを使用するかはプログラムの動きによって異なってきますが、単純に通知するのみならばPostMessage関数で問題ないでしょう。サンプルスクリプト大まかな処理の手順はだいたい以下のようになるかと思います。共有メモリのためのファイルマッピングオブジェクトを作成するファイルマッピングオブジェクトがすでに作成されていたかを調べる作成されていなかった場合(初回起動の場合)ウィンドウをサブクラス化して、メッセージを取得するように設定する共有メモリにメインウィンドウのハンドルを格納するメッセージが送られてくるのを待つ終了時にファイルマッピングオブジェクトをクローズ作成されていた場合(2回目以降の起動の場合)共有メモリからウィンドウハンドルを読み込むメッセージを送るファイルマッピングオブジェクトをクローズ処理を各部分に分けてみていくことにします。APIは以前に説明したものばかりですので、詳しい説明は省きます。起動時(共通)まずは以下の処理をするためのスクリプトです。*FirstRunProc}ファイルマッピングオブジェクトは、同じ名前を指定すればどのプロセスからでもそのオブジェクトを操作できてしまいます。そのため、これらの名前はアプリケーション固有のものにして、他のアプリケーションが使うオブジェクトと重ならないようにしましょう。ファイルマッピングオブジェクト未作成時(初回起動時)ファイルマッピングオブジェクトが作成されていなかった場合(初回起動の場合)の処理です。hMapObjend今回はアプリケーション固有のウィンドウメッセージコードとしてMYWM_RUN_NOTIFYという定数名を定義しています。これは、プログラム起動を通知する際に使用するものです。0xBFFFの範囲にする必要があります。それ以外のものを使うと、動作がおかしくなる可能性があるので注意してください。マッピングオブジェクト作成時(2回目以降起動)マッピングオブジェクトが作成されていた場合(2回目以降の起動の場合)の処理です。hwndTargetend上のスクリプトをいくつか同時に起動させてみましょう。2つ目、3つ目と起動されていくたびに、最初に起動されたプロセスのウィンドウに、起動されたことを示す文字列が表示されていくことと思います。今回はメッセージを送るだけでしたが、メッセージを送る際には2つの4バイトデータをwParamパラメータ、lParamパラメータとして送ることができますし、それ以上のサイズのデータ(例えばファイル名など)も共有メモリを使えば送ることができるでしょう。各自で試してみてください。