プロが教えるわが家の防犯対策術!

 現在、2重起動防止のため下記のようなコードにしています。 Delphiではデバッグ実行時のフォームも2重起動の対象となるため、開発環境があるときは、2重起動のチェックをしないようにしてあります。

 これでうまく行くのですが、何だか野暮ったい気がします。 こう少しスマートな解決策はないでしょうか?

program Sample;

uses
 Forms,
 Windows, Dialogs,
 uFrmSample in 'uFrmSample.pas' {frmSample};

{$R *.res}

var
 MainWnd: THandle;
begin
 {Delphi開発環境の存在をチェックする}
 MainWnd := FindWindow(nil, 'delphi 6');
 if MainWnd = 0 then begin
  {間発環境が実行中でなければ2重起動をチェックする}
  MainWnd := FindWindow('TFrmSample', nil);
  if MainWnd <> 0 then begin
   ShowMessage('既に起動しています');
   SetForegroundWindow(MainWnd);
   Exit;
  end;
 end;
 Application.Initialize;
 Application.CreateForm(TfrmSample, frmSample);
 Application.Run;
end.

以上、よろしくおねがいします。

A 回答 (3件)

実現したいことは(FindWindowではIDE使用時に誤動作してしまうので)FindWindow以外での二重起動の防止ではありませんか。



もしそうでしたらMutexを使ってみてはどうでしょう。「delphi 二重起動防止」などで検索するとたくさん現れます。
    • good
    • 0
この回答へのお礼

的確な回答ありがとうございます。

 ミューテックスを使った方法は知っていましたが、何だか難しそうなので敬遠していました。 でも、今回の質問を機に"くろねこ研究所"を参考にして、下記のコードで動作確認をしてみました。

program Sample;

uses
 Forms,
 Windows,
 Dialogs,
 uFrmSample in 'uFrmSample.pas' {frmSample};

{$R *.res}

var
 hMutex: THandle;
 MainWnd: THandle;
begin
 //Mutexを作成する
 hMutex := CreateMutex(nil, true, 'Sample');
 //Mutexが既に存在しているか判断する
 if  (hMutex <> 0) and
    (GetLastError() = ERROR_ALREADY_EXISTS) then begin
  //存在していた場合、そのインスタンスを再前面にする
  MainWnd := FindWindow('TFrmSample', nil);
  ShowMessage('既に起動しています');
  SetForegroundWindow(MainWnd);
  Exit; //起動中止
 end;
 Application.Initialize;
 Application.CreateForm(TfrmSample, frmSample);
 Application.Run;
 //ミューテックスの開放
 if (hMutex <> 0) then ReleaseMutex(hMutex);
 if (hMutex <> 0) then CloseHandle(hMutex);
end.

 結果、非常にうまくいっています。 デバッグ実行でもEXEからの実行でも期待どおりの動作をしました。 これからは、ミューテックスを使った方法に切り替えることにします。

(以前からの方法でも同じですが、ユニークな名前を作成するとき注意が必要ですね。)

お礼日時:2008/11/11 09:33

コンパイルスイッチを参照するようにしてみてはいかがでしょう



{$IFOPT D+}
// デバッグ情報の生成オプションがついている場合
{$ENDIF}

といった具合です
    • good
    • 0
この回答へのお礼

ご親切な回答ありがとうございます。

 動作を確認しました。 しかしこの方法では、リリースするときデバッグオプションを外し忘れると、先の状況と同じになります。

(別にサイズやリバースエンジニアリングに気を使っていないので、通常はデバッグオプションをチェックしたままリリースしています。)

お礼日時:2008/11/11 08:58

プロジェクトのオプション > ディレクトリ/条件タブの『条件定義(C)』にDEBUGなどを定義しておきます



デバッグ時に実行させたいコードを
{$IFDEF DEBUG}
// ここにデバッグ時のコードを記述
{$ENDIF}
といった具合にしましょう

Delphiのヘルプで『条件コンパイル』などを検索してみてください
    • good
    • 0
この回答へのお礼

すばやい回答ありがとうございます。

 私の質問のポイントが曖昧だったようです。ソースコードや環境設定を変えずにデバッグ実行なのかEXEからの実行なのかを識別する方法はないでしょうか?

 ご指摘の方法だと、直接{$DEFINE DEBUG}と書いてから条件分けするのと同じで、リリースコンパイルするときにDEBUGを削除し忘れる可能性があります。(とういか忘れた経験があります。)

お礼日時:2008/11/10 16:25

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!