Самый простой, но немного некорректный способ - найти заголовок окна по
FindWindow() и выполнять какие-либо действия в зависимости от того, есть ли
такое окно или нет. Второй выриант - через определение мутексов. Если определить
мутекс не удастся - всем окнам передается системное сообщение.
Нижеприведенный пример проверяет наличие окна, если таковое имеется - делает
его видимым (если оно минимизировано). Впрочем - дольше объяснять, смотрите
сами.
|
|
{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. | |