1

アプリケーションの別のインスタンスがミューテックスを作成して既に実行されているかどうか、メイン フォームの OnCreate 中にチェックするアプリケーションがあります。そうである場合、2 番目のインスタンスは最初のインスタンスにメッセージを渡し、それ自体を閉じます。それは正常に動作しますが、2 つ目のアプリケーションが閉じる前にメイン フォームが画面上で一瞬点滅するというわずかな変化を除いては問題ありません。

メイン フォーム WindowState を wsMinimize に設定してアプリケーションを起動し、1 ミリ秒の遅延でタイマーを使用してフォームを最大化するという醜いハックがあります。しかし、これはひどいハックのようです。

より良いアイデアはありますか?

procedure TMyAwesomeForm.FormCreate(Sender: TObject);
var
  h: HWND;
begin
  // Try to create mutex
  if CreateMutex(nil, True, '6EACD0BF-F3E0-44D9-91E7-47467B5A2B6A') = 0 then
    RaiseLastOSError;

  // If application already running
  if GetLastError = ERROR_ALREADY_EXISTS then 
  begin 
    // Prevent this instance from being the receipient of it's own message by changing form name
    MyAwesomeForm.Name := 'KillMe';

    // If this instance was started with parameters:   
    if ParamCount > 0 then 
    begin
      h := FindWindow(nil, 'MyAwesomeForm');

      //Pass the parameter to original application
      SendMessage(h, WM_MY_MESSAGE, strtoint(ParamStr(1)),0); 
    end;

    // Shut this instance down - there can be only one
    Application.Terminate; 
  end;

  // Create Jump Lists     
  JumpList := TJumpList.Create;  
  JumpList.ApplicationId := 'TaskbarDemo.Unique.Id';
  JumpList.DeleteList;
  CreateJList();
end;
4

1 に答える 1

4

フォームが作成されると表示されるため、フォーム クラス内でチェックを実行しないでください。

あなたのようなチェックを実行するのに適した場所は、.dprファイル自体です。

例えば:

program Project3;

uses
  Forms,
  Windows, //<--- new citizens here
  SysUtils,
  Messages,
  Unit1 in 'Unit1.pas' {Form1};

{$R *.res}

function IsAlreadyRunning: Boolean;
var
  h: HWND;
begin
  //no comments, sorry, but I don't use comments to explain what the 
  //code explains by itself.
  Result := False;

  if CreateMutex(nil, True, '6EACD0BF-F3E0-44D9-91E7-47467B5A2B6A') = 0 then
    RaiseLastOSError;

  if GetLastError = ERROR_ALREADY_EXISTS then
  begin
    if ParamCount > 0 then
    begin
      h := FindWindow(nil, 'MyAwesomeForm');
      if h <> 0 then
        PostMessage(h, WM_MY_MESSAGE, strtoint(ParamStr(1)),0);
      Result := True;
    end;
  end;
end;

begin
  if not IsAlreadyRunning then
  begin
    Application.Initialize;
    Application.MainFormOnTaskbar := True;
    Application.CreateForm(TForm1, Form1);
    Application.Run;
  end;
end.
于 2013-03-02T01:17:39.123 に答える