// The project references this unit to prevent multiple instances from appearing at the same time
unit MultInst;

interface

uses
 Windows, Messages, SysUtils, Classes, Forms;

implementation

const 
 STR_UNIQUE ='{2BE6D96E-827F-4BF9-B33E-8740412CDE96}';
 MI_ACTIVEAPP = 1;   {Activate application}
 MI_GETHANDLE = 2;   {Get handle}

var
 iMessageID: Integer;
 OldWProc: TFNWndProc;
 MutHandle: THandle;
 BSMRecipients: DWORD;

function NewWndProc (Handle: HWND; Msg: Integer; wParam, lParam: Longint):
 Longint; stdcall ;
begin 
 Result: =0;
 if Msg = iMessageIDthen
 begin
   case wParamof 
     MI_ACTIVEAPP: {Active Application}
       if lParam <>0 then
       begin
          {Activate the previous instance of the received message}
         {Why activate in another program?}
         {Because SetForegroundWindow cannot bring the form to the front in the same process}
         if IsIconic (lParam)then
           OpenIcon (lParam)
         else
           SetForegroundWindow (lParam);
         Application.Terminate; {Terminate this instance}
       end ;
     MI_GETHANDLE: {Get Program Handle}
       begin
         PostMessage (HWND (lParam), iMessageID, MI_ACTIVEAPP,
           Application.Handle);
       end ;
   end ;
 end
 else
   Result: = CallWindowProc (OldWProc, Handle, Msg, wParam, lParam);
end ;

procedure InitInstance;
begin
  {replaces application message handling}
 OldWProc: = TFNWndProc (SetWindowLong (Application.Handle, GWL_WNDPROC,
   Longint (@NewWndProc)));

 {Open mutex object}
 MutHandle: = OpenMutex (MUTEX_ALL_ACCESS, False, STR_UNIQUE);
 if MutHandle =0 then
 begin
    {create mutex object}
   MutHandle: = CreateMutex (nil , False, STR_UNIQUE);
 end
 else begin
   Application.ShowMainForm: = False;
   {Already have a program instance, broadcast message to obtain the instance handle}
   BSMRecipients: = BSM_APPLICATIONS;
   BroadCastSystemMessage (BSF_IGNORECURRENTTASK or BSF_POSTMESSAGE,
       @BSMRecipients, iMessageID, MI_GETHANDLE, Application.Handle);
 end ;
end ;

initialization
  {registration message}
 iMessageID: = RegisterWindowMessage (STR_UNIQUE);
 InitInstance;

finalization
  {restore message processing}
 if OldWProc <> Nilthen
   SetWindowLong (Application.Handle, GWL_WNDPROC, LongInt (OldWProc));

 {Close mutex object}
 if MutHandle <>0 then CloseHandle (MutHandle);

end .