Reputation: 85
I have an application which checks during the OnCreate of the main form if another instance of the application is already running by creating a mutex. If it is then the second instance passes a message to the first, then closes itself down. It works fine, except for a small niggle of the second application flashing it's main form briefly on the screen before it closes.
I have an ugly hack of starting the application with the main form WindowState set to wsMinimize, and then use a timer with a 1ms delay to maximise the form. But this seems like a terrible hack.
Any better ideas?
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;
Upvotes: 1
Views: 479
Reputation: 17203
Don't perform your checks inside the form class, since the form is created it will show.
IMHO the better place to perform a check like yours is the .dpr file itself.
For example:
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.
Upvotes: 4