|
15番会議室「FAQ編纂委員会」に寄せられた「よくある質問の答え」
[Q]
Delphi1.0の時はhPrevInstをチェックする事で二重起動を防止すること
が出来たのですが、2.0では上手く行きません。Delphi2.0で二重起動し
ないようにする方法を教えてください。
[A]
まずDelphi2.0(Win32)ではhPrevInstは常に0になります。よって、この
値を見て判断する方法は使えません。ではどうするのかと言うと方法は
幾つかあります。
1. FindWindowによる方法
2. ToolHelp32を使う方法
3. Mutexを使う方法
1ではスタートアップグループに二重登録した時には二重起動してしま
う様です。2はWin95ではOKだがNTでは使えないそうです。3は今の所、
特に問題点の指摘はされていませんので、ここでは3の方法について説
明します。
ユニークな名前を持つミューテックスやセマフォなどのオブジェクト
を作成する事を前提として、それがオープンできるかどうかを調べる
というものです。
例えばプロジェクトソースで以下の様な処理を行います。なおこの例
ではミューテックスの名前を'hPrevInst'としていますが全然ユニーク
ではないので、この部分は適当な名前に変えて下さい。
関連する内容として、クラス名もユニークな名前を付けるように心が
けましょう。DelphiではMainFormのNameプロパティの頭にTを付けたも
の(MainFormのクラス名)がそれに当ります。
{ プロジェクトソースを編集します }
program Project1;
uses
{ usesにWindows等必要なユニットを追加して下さい }
Windows, Forms,
Unit1 in 'Unit1.pas' {MyMainForm};
{$R *.RES}
var
hMutex: THandle;
Wnd, AppWnd: HWnd;
begin
{ ミューテックスをオープンしてみる }
hMutex := OpenMutex(MUTEX_ALL_ACCESS, False, 'hPrevInst');
{ CreateMutexの所と同じ名前にします }
if hMutex <> 0 then
begin
{ オープン出来るなら既に実行されている }
{ 必要ならここに二重起動時の処理を入れる }
{ 以下はアプリケーションのアクティブ化の例 }
Wnd := FindWindow('TMyMainForm', nil);
{ クラス名で既にオープンされているフォームを探します }
if Wnd <> 0 then
begin
SetForegroundWindow(Wnd); { 前面に移動してアクティブ化 }
{ TApplicationのウィンドウハンドルを取得 }
AppWnd := GetWindowLong(Wnd, GWL_HWNDPARENT);
if AppWnd <> 0 then Wnd := AppWnd;
if IsIconic(Wnd) then { アイコン状態なら元に戻す }
SendMessage(AppWnd, WM_SYSCOMMAND, SC_RESTORE, -1);
end;
{ ミューテックスを閉じる }
CloseHandle(hMutex);
end
else
begin
{ ミューテックスを作成 }
hMutex := CreateMutex(nil, False, 'hPrevInst');
{ 'hPrevInst'の代わりになるべくユニークな名前を付けましょう }
{ 以下は通常通りの処理を行う }
Application.Initialize;
Application.CreateForm(TMyMainForm, MyMainForm);
Application.Run;
{ ミューテックスを開放 }
ReleaseMutex(hMutex);
end;
end.
注)ミューテックス(mutex: mutual exclusion)
'相互排他'の先頭の文字を組み合わせた造語。お互いに非同期で
実行しているスレッドやプロセス間で通信する1つの方法。
ここにあるドキュメントは NIFTY SERVEの Delphi Users' Forum FDELPHIに寄せられる質問の中から、よくある質問への回答を FDELPHIのメンバーがまとめたものです。 したがって、これらの回答はボーランド株式会社がサポートする公式のものではなく、掲示されている内容についての問い合わせは受けられない場合があります。
Copyright 1996-1998 Delphi Users' ForumFAQ編纂委員会
|