{The code for OneInstance.dpr} program OneInstance; uses Windows, Forms, Unit1 in 'Unit1.pas' {Form1}; {$R *.RES} begin {Attempt to create a named mutex} CreateMutex(nil, false, 'MyApp'); {if it failed then there is another instance} if GetLastError = ERROR_ALREADY_EXISTS then begin {Send all windows our custom message - only our other} {instance will recognise it, and restore itself} SendMessage(HWND_BROADCAST, RegisterWindowMessage('MyApp'), 0, 0); {Lets quit} Halt(0); end; Application.Initialize; {Tell Delphi to un-hide it's hidden application window} {This allows our instance to have a icon on the task bar} Application.ShowMainForm := true; ShowWindow(Application.Handle, SW_RESTORE); Application.CreateForm(TForm1, Form1); Application.Run; end. {The code for unit1.pas} unit Unit1; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs; type TForm1 = class(TForm) procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation {$R *.DFM} var OldWindowProc : Pointer; {Variable for the old windows proc} MyMsg : DWord; {custom systemwide message} function NewWindowProc(WindowHandle : hWnd; TheMessage : LongInt; ParamW : LongInt; ParamL : LongInt) : LongInt stdcall; begin if TheMessage = MyMsg then begin {Tell the application to restore, let it restore the form} SendMessage(Application.handle, WM_SYSCOMMAND, SC_RESTORE, 0); SetForegroundWindow(Application.Handle); {We handled the message - we are done} Result := 0; exit; end; {Call the original winproc} Result := CallWindowProc(OldWindowProc, WindowHandle, TheMessage, ParamW, ParamL); end; procedure TForm1.FormCreate(Sender: TObject); begin {Register a custom windows message} MyMsg := RegisterWindowMessage('MyApp'); {Set form1's windows proc to ours and remember the old window proc} OldWindowProc := Pointer(SetWindowLong(Form1.Handle, GWL_WNDPROC, LongInt(@NewWindowProc))); end; procedure TForm1.FormDestroy(Sender: TObject); begin {Set form1's window proc back to it's original procedure} SetWindowLong(Form1.Handle, GWL_WNDPROC, LongInt(OldWindowProc)); end; begin {Tell Delphi to hide it's hidden application window for now to avoid} {a "flash" on the taskbar if we halt due to another instance} ShowWindow(Application.Handle, SW_HIDE); end. |