アプリケーション起動時に、既に起動済みなら、
Unit1のとある論理型に代入し、
MainFormのonCreate時のスプラッシュ表示処理を、
省きたいのです。
私的に考えたのは、
とあるファイルに起動されてる数を記録し、
起動されたら増やし、終了したら減らす、
というものですが、
異常終了したら、処理が行われないので、
良い方法はないかと?
自分のアプリがいくつ起動されているか、動的に取得できればいいのですね?
SetProp() GetProp() というAPIで Application ウィンドウにしるしをつけておいて
その数を数えます。Unit1 を以下のようにして試したところ、うまくいくようです。
function EnumWndProc(hWindow:HWND;lData:LPARAM):BOOL;stdcall;
var
pNum:PInteger;
begin
result := true;
pNum := PInteger(lData);
if GetProp(hWindow,'HogeHoge') = 123456 then
pNum^ := pNum^+1;
end;
function EnumMyApp:integer;
begin
result := 0;
EnumWindows(@EnumWndProc,LPARAM(@result));
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
Label1.Caption := IntToStr(EnumMyApp);
end;
initialization
SetProp(Application.Handle,'HogeHoge',123456);
finalization
RemoveProp(Application.Handle,'HogeHoge');
end.
initialization
SetProp(Application.Handle,'HogeHoge',123456);
finalization
RemoveProp(Application.Handle,'HogeHoge');
はユニットの最後で良いのでしょうか?
るるとん@Kのご質問の真意は
起動されている数を記録したいのか
それとも
多重起動していたらスプラッシュの表示を省きたいのか
どちらでしょうか?
後者なら、ミューテックスを利用して多重起動かどうかを判断し、
その結果でスプラッシュを表示するかどうか選択すればよいと思います。
ミューテックスについてはOpenMutexやCreateMutexで検索すれば
たくさん情報が出てきます。
ミューテックなら、初めのウインドウを閉じたら、なくなるのじゃ無いですか?
るるとん@K
123456っていうのは何でしょう?
SetPropのヘルプがでません
1のときだけ表示するようにするんですね
出来ました
> 1のときだけ表示するようにするんですね
あっ、そういう場合は「二重起動の禁止」というふうに言います。
ミューテックスを使うのが一般的です。
例えばこことか。
http://homepage2.nifty.com/Mr_XRAY/Halbow/Notes/N011.html
> ミューテックなら、初めのウインドウを閉じたら、なくなるのじゃ無いですか?
そうです。ですから、次に起動されたとき、自分が最初の一つであることが分かるわけです。
それでいいんじゃないですか?
あっ、そうか、二重起動の禁止じゃなくて、すでに起動されてたら、スプラッシュ
を表示しない、とかのようにしたいわけですね。それなら、ミューテックスより、
わたしの最初のコードの方が使いやすいですね。
> ミューテックなら、初めのウインドウを閉じたら、なくなるのじゃ無いですか?
私がした質問への回答はどうなりましたか? (^^;;
多重起動していたらスプラッシュの表示を省くのが最終の目的です
>多重起動していたらスプラッシュの表示を省くのが最終の目的です
わかりました。
>jokさん
>あっ、そうか、二重起動の禁止じゃなくて、すでに起動されてたら、スプラッシュ
>を表示しない、とかのようにしたいわけですね。それなら、ミューテックスより、
>わたしの最初のコードの方が使いやすいですね。
すでに起動しているかどうかという情報をOpenMutexで取得して、
"禁止"しなければよいのではないでしょうか?
> すでに起動しているかどうかという情報をOpenMutexで取得して、
> "禁止"しなければよいのではないでしょうか?
そうですね。二重起動の禁止では、常に一つのアプリしか起動していないので
勘違いしていました。OpenMutex ではなく CreateMutex の方が一度ですみ
ますね。EnumWindows() はコストがかかるので、ミューテックスの方が
いいですね、たしかに。参考サイトのコードをつかって
const
UN:string = 'HogeHoge';
function IsPrevAppExist(UniqueName:string):Boolean;
begin
result := false;
CreateMutex(nil,true,PChar(UniqueName));
if GetLastError = ERROR_ALREADY_EXISTS then
result := true;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
if not IsPrevAppExist(UN) then
ShowMessage('This is Splash Message!');
end;
のようにしてうまくいきました。
ウインドウAを開く、
(ミューテックが生成される)
(スプラッシュ表示)
ウインドウBを開く
ウインドウAを閉じる
(ミューテック解放)
(この状態で、Bは開かれている)
ウインドウCを開く
(スプラッシュ表示)
には、なるのでは?
わたしのコードを試しましたか?
ミューテックスはウィンドウとは関係なく、プロセスが終了すると参照カウント
が減るようになっています。それをつくったすべてのプロセスが終了すると
参照カウントがゼロになるので、ミューテックスが消滅します。上のコードでは
メインウィンドウの OnCreate イベントハンドラでつくっていますので、アプリが
終了するまで、参照カウントが減りません。
ウインドウAを開く、
(ミューテックが生成される) → 参照カウント 1
(スプラッシュ表示)
ウインドウBを開く → 参照カウント 2
ウインドウAを閉じる → 参照カウント 1
(ミューテック解放) はしない
(この状態で、Bは開かれている)
ウインドウCを開く → 参照カウント 2
(スプラッシュ表示) は表示されない
には、なるのでは?
有難う御座います
うまく行きました
ちょっと話はずれますが、SDI式のエディタをつくってるんでしたね?
このスレの質問から類推すると、ドキュメントを読み込むたびに、違うプロセス
を立ち上げているんですよね? 有名な秀丸エディタもSDI式ですが、プロセスは
一つらしいです。Delphi で同じようにするためにはちょっと工夫が必要です。
中村さんの
http://www.asahi-net.or.jp/~HA3T-NKMR/tips025.htm
が大変参考になると思います。
参考になります。読ませていただきますn(__)n
> jokさん
> OpenMutex ではなく CreateMutex の方が一度ですみますね。
参考になりました。ありがとうございました。
ツイート | ![]() |