UnitMultinst;InterfaceConstMi_querywindowhandle=1; Mi_respondwindowhandle=2; Mi_error_none=0; Mi_error_failsubclass=1; Mi_error_creatingmutex=2;//Call this function to determine if error occurred in startup.//Value would be one or more of the mi_error_* ERROR flags.functionGetmierror:integer;ImplementationusesForms, Windows, sysutils;ConstUniqueappstr='DDG. i_am_the_eggman!';varMessageid:integer; Wproc:tfnwndproc; Muthandle:thandle; Mierror:integer;functionGetmierror:integer;beginResult:=Mierror;End;functionNewwndproc (Handle:hwnd; Msg:integer; WParam, Lparam:longint): Longint; stdcall;beginResult:=0; //If This is the registered message ... ifMSG = MessageID Then begin CaseWParam ofMi_querywindowhandle://A new instance is asking for main window handle in order //to focus the main window, so normalize apps and send back //message with main window handle. begin ifIsiconic (Application.handle) Then beginApplication.MainForm.WindowState:=Wsnormal; Application.restore; End; PostMessage (HWND (LParam), MessageID, Mi_respondwindowhandle, Application.MainForm.Handle); End; Mi_respondwindowhandle://The running instance have returned its main window handle, //So we need to focus it and go away. beginSetForegroundWindow (HWND (LParam)); Application.terminate; End; End; End //Otherwise, pass message on to old window proc ElseResult:=CallWindowProc (Wproc, Handle, MSG, WParam, LParam);End;proceduresubclassapplication;begin //We Subclass application window procedure so //Application.onmessage remains available for user.Wproc: =Tfnwndproc (SetWindowLong (Application.handle, GWL_WNDPROC, Longint (@NewWndProc))); //Set appropriate error flag if error condition occurred ifWproc =Nil ThenMierror:= MierrororMi_error_failsubclass;End;proceduredofirstinstance;//This was called only for the first instance of the applicationbegin //Create The mutex with the (hopefully) unique stringMuthandle: = CreateMutex (Nil, False, UNIQUEAPPSTR); ifMuthandle =0 ThenMierror:= MierrororMi_error_creatingmutex;End;procedureBroadcastfocusmessage;//This was called when there was already an instance running.varBsmrecipients:dword;begin //Prevent main form from flashingApplication.showmainform: =False; //Post Message to try-establish a dialogue with previous instanceBsmrecipients: =bsm_applications; Broadcastsystemmessage (Bsf_ignorecurrenttaskorbsf_postmessage, @BSMRecipients, MessageID, Mi_querywindowhandle, application.handle);End;procedureInitInstance;beginsubclassapplication; //Hook application message loopMuthandle: =OpenMutex (mutex_all_access, False, UNIQUEAPPSTR); ifMuthandle =0 Then //Mutex object has not yet been created, meaning that no previous //instance has been created.dofirstinstanceElseBroadcastfocusmessage;End;initializationMessageID:=RegisterWindowMessage (UNIQUEAPPSTR); InitInstance;Finalization //Restore Old application window procedure ifWproc <> Nil ThenSetWindowLong (Application.handle, GWL_WNDPROC, Longint (Wproc)); ifMuthandle <>0 ThenCloseHandle (Muthandle);//Free MutexEnd.
Activating the previous program (registering a global message, using a mutex probe, notifying the first program if the broadcast message is already occupied)