To start with, Colin Fraser asked:

> Does anyone have handy any code that will stop an application 
> running more
> than once instance...

Luke Pascoe replied:

You can cheat and use CreateMutex:
procedure AppStartup;
var
  Mutex: THandle;
begin
  Mutex := CreateMutex(NIL, False, 'MyAppNameString');
  if WaitForSingleObject(Mutex, 100) = WAIT_TIMEOUT then
  begin
    ShowMessage('App is already running on this computer.');
    Application.Terminate
  end;
end;

Tim Perry's solution was:

program Project1;

uses
  Forms,
  Windows,
  Dialogs,
  Unit1 in 'Unit1.pas' {Form1};

{$R *.RES}

const
  MutexName = 'Project1Mutex';

var
  Project1MutexH: THandle;

procedure RestorePrevInstance;
var
  PrevInst: HWND;
begin
  PrevInst := FindWindow('TForm1', nil);
  if PrevInst <> 0 then
  begin
    if IsIconic(PrevInst) then
      ShowWindow(PrevInst, SW_RESTORE)
    else if IsIconic(GetWindow(PrevInst, GW_OWNER)) then
      ShowWindow(GetWindow(PrevInst, GW_OWNER), SW_RESTORE)
    else
      SetForegroundWindow(PrevInst);
  end;
  Application.Terminate;
end;

begin
  Project1MutexH := CreateMutex(nil, True, MutexName);
  if Project1MutexH = 0 then
  begin
    ShowMessage('Initialization Error');
    Halt;
  end;
  if GetLastError = ERROR_ALREADY_EXISTS then
  begin
    Application.ShowMainForm := False;
    RestorePrevInstance;
  end;

  Application.Initialize;
  Application.CreateForm(TForm1, Form1);
  Application.Run;

  CloseHandle(Project1MutexH);
end.

When I tried Luke's code, it didn't seem to work. I don't know why but
Project1MutexH kept coming back with 48 and GetLastError kept returning 0
(ie not ERROR_ALREADY_EXISTS). So I put Tim's and Luke's solution together
(might try Pat Sheehan's if I have time) and got the following that seems to
work fine. If anyone can see a problem, I'd appreciate a call.

program Project1;

uses
  Forms,
  Windows,
  Dialogs,
  Unit1 in 'Unit1.pas' {Form1};

{$R *.RES}

const
  MutexName = 'Project1Mutex';

var
  Project1MutexH: THandle;

procedure RestorePrevInstance;
var
  PrevInst: HWND;
begin
  PrevInst := FindWindow('TForm1', nil);
  if PrevInst <> 0 then
  begin
    if IsIconic(PrevInst) then
      ShowWindow(PrevInst, SW_RESTORE)
    else if IsIconic(GetWindow(PrevInst, GW_OWNER)) then
      ShowWindow(GetWindow(PrevInst, GW_OWNER), SW_RESTORE)
    else
      SetForegroundWindow(PrevInst);
  end;
  //Don't need this line now: Application.Terminate;
end;

begin
  Project1MutexH := CreateMutex(nil, False, MutexName);
  if WaitForSingleObject(Mutex, 100) = WAIT_TIMEOUT then begin
    ShowMessage('App is already running on this computer.');
    RestorePrevInstance;
  end else begin
    Application.Initialize;
    Application.CreateForm(TForm1, Form1);
    Application.Run;
  end;
end.

---------------------------------------------------------------------------
    New Zealand Delphi Users group - Delphi List - [EMAIL PROTECTED]
                  Website: http://www.delphi.org.nz
To UnSub, send email to: [EMAIL PROTECTED] 
with body of "unsubscribe delphi"

Reply via email to