Web Design that taps into the haromny and vision of your dreams.

Prevent Multiple Instances of Delphi Application Running

By on in Coding

360 words, estimated reading time 2 minutes.

This code will prevent another instance from opening, and pass parameter details (such as file open command) to the existing application.

Sometimes you may only want a single instance of your application to run at any given time. This code will prevent another instance from opening, and pass parameter details (such as file open command) to the existing application.

To go in main (Form1) unit

var WM_FINDINSTANCE: Integer;
 
{The basic code contained in the next three procedures,
 which works with the DPR code to allow file association
 and open double-clicked file in the running instance of app
 was written by Andrius Adamonis}
 
procedure TForm1.WMRestoreApp(var Msg: TMessage);
begin
  if IsIconic(Application.Handle) then
    Application.RESTORE
  else
    Application.BringToFront;
end;
 
procedure TForm1.DefaultHandler(var message);
var
  s: String;
begin
  with TMessage(message) do
    if (Msg = WM_FINDINSTANCE) then
    begin
      Result := MyUniqueConst;
    end
    else
    if Msg = WM_OPENEDITOR then
    begin
      SetLength(S, MAX_PATH);
      GlobalGetAtomName(WPARAM, PChar(S), MAX_PATH);
      ShowMessage(S);
      try
        OpenDocument(S);
 
        except on E: Exception do
            raise Exception.Create('Error opening ' + S + ' - ' + E.message);
      end;
    end
    else
      inherited DefaultHandler(message);
end;
This code goes at the very end of the main unit
 
initialization {Used in the file association and running instance code}
  WM_FINDINSTANCE := RegisterWindowMessage('Your Custom Handle Message Here');
 
  if WM_FINDINSTANCE = 0 then
    raise Exception.Create('Initialization failed');
 
end.

This code goes in the .dpr

program Sample;
 
uses
  Forms,
  SysUtils,
  graphics,
  Windows,
  Unit1 in 'Unit1.pas' {Form1},
 
{$R *.RES}
 
var Previous: HWND;
    ATOM: TAtom;
 
function EnumWindowsCallback(Handle: HWND; Param: LPARAM): Boolean; stdcall;
  function IsMyClass: Boolean;
  var
    ClassName    : array[0..30] of Char;
  begin
    GetClassName(Handle, ClassName, 30);
    [i]//If you change the name of Form1 don't forget to change the string below![/i]
    Result := (StrIComp(ClassName, 'TForm1') = 0) and (SendMessage(Handle, WM_FINDINSTANCE, 0, 0) = MyUniqueConst);
  end;
begin
  Result := not IsMyClass; [i]{ needs True to continue }[/i]
  if not Result [i]{ = MyClass }[/i] then Previous := Handle;
end;
 
begin
  Previous := 0;
  EnumWindows(@EnumWindowsCallback, 0);
 
  if Previous <> 0 then
  begin
    PostMessage(Previous, WM_RESTOREAPP, 0, 0);
    if (ParamCount > 0) then
    begin
      ATOM := GlobalAddAtom(PChar(ParamStr(1)));
      SendMessage(Previous, WM_OPENEDITOR, ATOM, 0);
      GlobalDeleteAtom(ATOM);
    end;
    Exit;
  end;
 
  Application.Initialize;
  Application.Title := 'Sample 1';
  Application.CreateForm(TForm1, Form1);
  Application.Run;
end.

Last updated on: Saturday 24th June 2017

 

Comments

Have a question or suggestion? Please leave a comment to start the discussion.

 

Leave a Reply

Please keep in mind that all comments are moderated according to our privacy policy, and all links are nofollow. Do NOT use keywords in the name field. Let's have a personal and meaningful conversation.

Your email address will not be published.