konisi さんが書きました:> hiraさんのコードで多重起動は解決しました。ありがとうございました。
> ところで、どうやって元から起動していた実行ファイルの窓をアクティブにするかが分かりません。
>
> システム系無知ですみません^^;
確かに、いきなりEnumWindows関数は難しいですね。
しかし、英語名からある程度意味は推測できると思います。
このEnumWindows関数は現在デスクトップ上で実行中のあらゆるプログラムのウィンドウハンドルを列挙、つまり簡単にいうとウィンドウを1つずつ順番にお目当てのウィンドウハンドルが得られるまで調べていくものです。
コード: 全て選択
Declare Function EnumWindows Lib "user32" (lpEnumFunc As VoidPtr,lParam As LPARAM) As Long
Function EnumWindowsProc(hWnd As HWND,lParam As LPARAM) As Long
Dim dwProcessId As DWord
GetWindowThreadProcessId(hWnd,VarPtr(dwProcessId))
If dwProcessId=lParam And IsWindowVisible(hWnd)<>0 Then ShowWindow(hWnd,SW_RESTORE)
EnumWindowsProc=1
End Function
そしてお目当てのウィンドウが見つかったらShowWindow関数を呼び出して
アクティブにしています。
この場合、ウィンドウを所有しているスレッドが属するプロセスIDが等しいかどうかで判断しているようですね。
よって、hira様のプログラムは非常に安全性が高い方法だと言えます。
ウィンドウ名やウィンドウクラスで調べる方法もありますが、
その場合、同じ名前のウィンドウが存在すると致命的なバグが発生します。
konisi さんが書きました:> そもそも私はミューテックスがどのようなものか知らずにレス返してましたが、BackSearchABで調べたらGetLastError関数で確実に183(ERROR_ALREADY_EXISTS)が返るようにするものかなと解釈したところです。間違ってたら指摘してやってください。
イメージとしてはそれで合っています。
~余談~
私の場合、共有メモリで実現します。
最初に起動したアプリケーションでは共有メモリを新規作成し、
共有メモリに自分のウィンドウハンドルを書き込んでおきます。
次に実行されるプログラムでは共有メモリの新規作成に失敗するので、
そのタイミングで共有メモリからウィンドウハンドルを取り出して、
アクティブ化した後、自分自身を終了させるという方法です。