{*******************************************************}
unit multinst;
interface
uses Forms, Windows, Dialogs, SysUtils;
const
MI_NO_ERROR = 0;
MI_FAIL_SUBCLASS = 1;
MI_FAIL_CREATE_MUTEX = 2;
function GetMIError: Integer;
function InitInstance : Boolean;
implementation
uses RegWork, FileWork;
var
UniqueAppStr : PChar;
MessageId: Integer;
WProc: TFNWndProc = Nil;
MutHandle: THandle = 0;
MIError: Integer = 0;
function GetMIError: Integer;
begin
Result := MIError;
end;
function NewWndProc(Handle: HWND; Msg: Integer; wParam, lParam: Longint): Longint; StdCall;
begin
Result := 1;
if Msg = MessageID then begin
if IsIconic(Application.Handle) then OpenIcon(Application.Handle)
else SetForegroundWindow(Application.Handle);
FileWork.LoadFileName(RegWork.RWGetParamStr1);
end
else Result := CallWindowProc(WProc, Handle, Msg, wParam, lParam);
end;
procedure SubClassApplication;
begin
WProc := TFNWndProc(SetWindowLong(Application.Handle, GWL_WNDPROC, Longint(@NewWndProc)));
if WProc = Nil then MIError := MIError or MI_FAIL_SUBCLASS;
end;
procedure DoFirstInstance;
begin
SubClassApplication;
MutHandle := CreateMutex(Nil, False, UniqueAppStr);
if MutHandle = 0 then MIError := MIError or MI_FAIL_CREATE_MUTEX;
end;
procedure BroadcastFocusMessage;
begin
Application.ShowMainForm := False;
PostMessage(HWND_BROADCAST, MessageId, 0, 0);
end;
function InitInstance : Boolean;
begin
MutHandle := OpenMutex(MUTEX_ALL_ACCESS, False, UniqueAppStr);
if MutHandle = 0 then begin
ShowWindow(Application.Handle, SW_ShowNormal);
Application.ShowMainForm:=True;
DoFirstInstance;
result := True;
end
else begin
RegWork.RWSetParamStr1;
BroadcastFocusMessage;
result := False;
end;
end;
initialization
begin
UniqueAppStr := PChar(Application.ExeName);
MessageID := RegisterWindowMessage(UniqueAppStr);
ShowWindow(Application.Handle, SW_Hide);
Application.ShowMainForm:=FALSE;
end;
finalization
begin
if WProc <> Nil then SetWindowLong(Application.Handle, GWL_WNDPROC, LongInt(WProc));
end;
end.
ΠΠ°ΠΊ Π½Π΅ Π΄ΠΎΠΏΡΡΡΠΈΡΡ Π·Π°ΠΏΡΡΠΊ Π²ΡΠΎΡΠΎΠΉ ΠΊΠΎΠΏΠΈΠΈ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ IX
YoungHacker ΡΠ΅ΠΊΠΎΠΌΠ΅Π½Π΄ΡΠ΅Ρ ΡΠ»Π΅Π΄ΡΡΡΠΈΠΉ ΠΊΠΎΠ΄:
ΠΡΠ» Π²Π·ΡΡ ΠΈΠ· ΠΊΡΠ»ΠΈΠ±Ρ ΠΈ Π΄ΠΎΡΠ°Π±ΠΎΡΠ°Π½, ΠΏΠΎΡΠΊΠΎΠ»ΡΠΊΡ Π²ΠΎΠ·Π½ΠΈΠΊΠ°Π»ΠΈ ΡΠΈΡΡΠ°ΡΠΈΠΈ ΠΊΠΎΠ³Π΄Π° ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠ°, ΠΏΠΎ HotKey Π½Π°Π·Π½Π°ΡΠ΅Π½Π½ΡΠΌ Π½Π° ΡΡΠ»ΡΠΊ, Π·Π°ΠΏΡΡΠΊΠ°Π»Π°ΡΡ Π΄Π²Π°ΠΆΠ΄Ρ ΠΈ Π±ΠΎΠ»Π΅Π΅ ΡΠ°Π·. Π‘Π²ΡΠ·Π°Π½ΠΎ Ρ ΡΠ΅ΠΌ ΡΡΠΎ ΠΏΠΎΠΈΡΠΊ ΠΌΡΡΠ΅ΠΊΡΠ° ΠΈ Π΅Π³ΠΎ ΡΠΎΠ·Π΄Π°Π½ΠΈΠ΅ ΡΠ°Π·Π½Π΅ΡΠ΅Π½Ρ Π²ΠΎ Π²ΡΠ΅ΠΌΠ΅Π½ΠΈ ΠΈ ΠΏΠΎΠΊΠ° Π² ΠΎΠ΄Π½ΠΎΠΌ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΈ ΠΌΡΡΠ΅ΠΊΡ Π½Π΅ Π½Π°ΡΠ΅Π»ΡΡ Π½ΠΎ Π΅ΡΠ΅ Π½Π΅ ΡΠΎΠ·Π΄Π°Π»ΡΡ Π²ΡΠΎΡΠΎΠ΅ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΡΠΎΠΆΠ΅ Π½Π΅ Π½Π°Ρ ΠΎΠ΄ΠΈΡ ΠΌΡΡΠ΅ΠΊΡΠ° ΠΈ ΠΈΠ½ΠΈΡΠΈΠΈΡΡΠ΅Ρ Π΅Π³ΠΎ ΡΠΎΠ·Π΄Π°Π½ΠΈΠ΅
ΠΠΎΠΈΡΠΊ ΠΎΠΊΠΎΠ½ ΠΈ ΡΠΎΠ·Π΄Π°Π½ΠΈΠ΅ ΠΈΡ Π½Π°ΡΡΠ²Π°ΡΡΡΡ Π½Π° ΡΠ΅-ΠΆΠ΅ ΠΏΡΠΎΠ±Π»Π΅ΠΌΡ. ΠΠ· RxLib Π€ΡΠ½ΠΊΡΠΈΡ ΡΠΎΠΆΠ΅ Π½Π΅ ΠΎΠ±Ρ ΠΎΠ΄ΠΈΡ ΡΡΠΎΠΉ ΡΠΈΡΡΠ°ΡΠΈΠΈ.
ΠΠΎΠΉ Π²Π°ΡΠΈΠ°Π½Ρ Π½Π΅ΠΌΠ½ΠΎΠ³ΠΎ Π΄ΠΎΡΠ°Π±Π°ΡΡΠ²Π°Π΅Ρ ΡΠΆΠ΅ Π·Π½Π°ΡΠΈΡΠ΅Π»ΡΠ½ΠΎ ΠΏΠ΅ΡΠ΅ΡΠ°Π±ΠΎΡΠ°Π½Π½ΠΎΠ΅ ΡΠΎ ΡΡΠΎ ΠΏΡΠ΅Π΄ΠΎΡΡΠ°Π²ΠΈΠ»ΠΈ ΡΠ°Π·ΡΠ°Π±ΠΎΡΡΠΈΠΊΠΈ Delphi 2 ΠΠ°ΡΠ΅ΠΊΠ° (Pacheco) ΠΈ Π’Π°ΠΉΡ Π°ΠΉΡΠ° (Teixeira). ΠΈ Π½Π°Ρ ΠΎΠ΄ΠΈΡΡΡ Π² ΡΠ°ΠΉΠ»Π΅ TPrevInstUnit. Π ΡΠ°ΠΉΠ»Π΅ ΠΏΡΠΎΠ΅ΠΊΡΠ° ΠΏΠΈΡΠ΅ΡΡΡ ΡΠ»Π΅Π΄ΡΡΡΠΈΠΉ Π²ΡΠ·ΠΎΠ²:
begin
//β ΠΠ°ΠΉΡΠΈ ΠΏΡΠ΅Π΄ΡΠ΄ΡΡΡΡ Π²Π΅ΡΡΠΈΡ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ
if (initinstance) then begin
β¦
Application.Initialize;
β¦
Application.CreateForm(β¦);
β¦
Application.Run;
end;
end.
Π€Π°ΠΉΠ» TPrevInstUnitunit TPrevInstUnit;
interface
uses Forms, Windows, Dialogs, SysUtils;
function InitInstance : Boolean;
implementation
const
UniqueAppStr : PChar = #0; // Π Π°Π·Π»ΠΈΡΠ½ΠΎΠ΅ Π΄Π»Ρ ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ
// ΠΠΎ ΠΎΠ΄ΠΈΠ½Π°ΠΊΠΎΠ²ΠΎΠ΅ Π΄Π»Ρ ΠΊΠ°ΠΆΠ΄ΠΎΠΉ ΠΊΠΎΠΏΠΈΠΈ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ
var
MessageId : Integer;
OldWProc : TFNWndProc = Nil;
MutHandle : THandle = 0;
SecondExecution : Boolean = False;
function NewWndProc(Handle: HWND; Msg: Integer; wParam, lParam: Longint): Longint; StdCall;
begin
//- ΠΡΠ»ΠΈ ΡΡΠΎ - ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠ΅ ΠΎ ΡΠ΅Π³ΠΈΡΡΡΠ°ΡΠΈΠΈ... }
if (Msg = MessageID) then begin
//- Π΅ΡΠ»ΠΈ ΠΎΡΠ½ΠΎΠ²Π½Π°Ρ ΡΠΎΡΠΌΠ° ΠΌΠΈΠ½ΠΈΠΌΠΈΠ·ΠΈΡΠΎΠ²Π°Π½Π°
if IsIconic(Application.Handle) then begin
//- Π²ΠΎΡΡΡΠ°Π½Π°Π²Π»ΠΈΠ²Π°Π΅ΠΌ
Π΅Π΅Application.Restore;
end
else begin
//- Π²ΡΡΠ°ΡΠΊΠΈΠ²Π°Π΅ΠΌ Π½Π° ΠΏΠ΅ΡΠ΅Π΄
ShowWindow(Application.Handle, SW_SHOW);
SetForegroundWindow(Application.Handle);
Application.BringToFront;
end;
Result := 0;
end
else
{ Π ΠΏΡΠΎΡΠΈΠ²Π½ΠΎΠΌ ΡΠ»ΡΡΠ°Π΅ ΠΏΠΎΡΡΠ»Π°Π΅ΠΌ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠ΅ ΠΏΡΠ΅Π΄ΡΠ΄ΡΡΠ΅ΠΌΡ ΠΎΠΊΠ½Ρ }
Result := CallWindowProc(OldWProc, Handle, Msg, wParam, lParam);
end;
function InitInstance : Boolean;
var
BSMRecipients: DWORD;
begin
Result := False;
//- ΠΏΡΠΎΠ±ΡΠ΅ΠΌ ΠΎΡΠΊΡΡΡΡ MUTEX ΡΠΎΠ·Π΄Π°Π½Π½ΡΠΉ ΠΏΡΠ΅Π΄ΡΠ΄ΡΡΠ΅ΠΉ ΠΊΠΎΠΏΠΈΠ΅ΠΉ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ
MutHandle := CreateMutex(Nil, True, UniqueAppStr);
//- ΠΡΡΠ΅ΠΊΡ ΡΠΆΠ΅ Π±ΡΠ» ΡΠΎΠ·Π΄Π°Π½ ?
SecondExecution := (GetLastError = ERROR_ALREADY_EXISTS);
if (MutHandle = 0) then begin
ShowMessage('ΠΡΠΈΠ±ΠΊΠ° ΡΠΎΠ·Π΄Π°Π½ΠΈΡ Mutex.');
Exit;
end;
if Not (SecondExecution) then begin
//- Π½Π°Π·Π½Π°ΡΠ°Π΅ΠΌ Π½ΠΎΠ²ΡΠΉ ΠΎΠ±ΡΠ°Π±ΠΎΡΡΠΈΠΊ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠΉ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ, Π° ΡΡΠ°ΡΡΠΉ ΡΠΎΡ ΡΠ°Π½ΡΠ΅ΠΌ
OldWProc := TFNWndProc(SetWindowLong(Application.Handle, GWL_WNDPROC, Longint(@NewWndProc)));
//- Π΅ΡΠ»ΠΈ ΠΎΠ±ΡΠ°Π±ΠΎΡΡΠΈΠΊ Π½Π΅ Π½Π°ΠΉΠ΄Π΅Π½ ΡΡΡΠ°Π½Π°Π²Π»ΠΈΠ²Π°Π΅ΠΌ ΠΎΡΠΈΠ±ΠΊΡ
if (OldWProc = Nil) then begin
ShowMessage('ΠΡΠΈΠ±ΠΊΠ° ΠΏΠΎΠΈΡΠΊΠ° ΡΡΠ°Π½Π΄Π°ΡΡΠ½ΠΎΠ³ΠΎ ΠΎΠ±ΡΠ°Π±ΠΎΡΡΠΈΠΊΠ° ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠΉ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ.');
Exit;
end;
//- Π£ΡΡΠ°Π½ΠΎΠ²ΠΈΡΡ "Π½ΠΎΡΠΌΠ°Π»ΡΠ½ΡΠΉ" ΡΡΠ°ΡΡΡ ΠΎΡΠ½ΠΎΠ²Π½ΠΎΠ³ΠΎ ΠΎΠΊΠ½Π° ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ
ShowWindow(Application.Handle, SW_ShowNormal);
//- ΠΏΠΎΠΊΠ°ΠΆΠ΅ΠΌ ΠΎΡΠ½ΠΎΠ²Π½ΡΡ ΡΠΎΡΠΌΡ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ
Application.ShowMainForm := True;
//- Π²ΡΠ΅ Π½ΠΎΡΠΌΠ°Π»ΡΠ½ΠΎ ΠΌΠ°ΠΌΠ° ΡΡΡΠ½ ΡΠΈΠ½ ΡΠΈΠ½ ΡΠΈΠ½ ΡΠΈΡΠΈ ΡΡΠ½ ΡΡΠ½
Result := True;
end
else begin
//- ΡΡΡΠ°Π½ΠΎΠ²ΠΈΡΡ ΡΡΠ°ΡΡΡ ΠΎΠΊΠ½Π° ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ "Π½Π΅Π²ΠΈΠ΄ΠΈΠΌΡΠΉ"
ShowWindow(Application.Handle, SW_Hide);
//- ΠΠ΅ ΠΏΠΎΠΊΠ°ΠΆΠ΅ΠΌ ΠΎΡΠ½ΠΎΠ²Π½ΡΡ ΡΠΎΡΠΌΡ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ
Application.ShowMainForm := False;
//- ΠΠΎΡΡΠ»Π°Π΅ΠΌ Π΄ΡΡΠ³ΠΎΠΌΡ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠ΅ ΠΈ ΠΈΠ½ΡΠΎΡΠΌΠΈΡΡΠ΅ΠΌ ΠΎ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎΡΡΠΈ
// ΠΏΠ΅ΡΠ΅Π²Π΅ΡΡΠΈ ΡΠΎΠΊΡΡ Π½Π° ΡΠ΅Π±Ρ
BSMRecipients := BSM_APPLICATIONS;
BroadCastSystemMessage(BSF_IGNORECURRENTTASK or BSF_POSTMESSAGE, @BSMRecipients, MessageID, 0, 0);
end;
end;
initialization
begin
//- Π‘ΠΎΠ·Π΄Π°ΡΡ ΡΠ½ΠΊΠ°Π»ΡΠ½ΡΡ ΡΡΡΠΎΠΊΡ Π΄Π»Ρ ΠΎΠΏΠΎΠ·Π½Π°Π½ΠΈΡ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ
UniqueAppStr := PChar('YoungHackerNetworkDataBaseProgramm');
//- ΠΠ°ΡΠ΅Π³ΠΈΡΡΡΠΈΡΠΎΠ²Π°ΡΡ Π² ΡΠΈΡΡΠ΅ΠΌΠ΅ ΡΠ½ΠΈΠΊΠ°Π»ΡΠ½ΠΎΠ΅ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠ΅
MessageID := RegisterWindowMessage(UniqueAppStr);
end;
finalization
begin
if (OldWProc <> Nil) then
{ ΠΡΠΈΠ²ΠΎΠ΄ΠΈΠΌ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π² ΠΈΡΡ ΠΎΠ΄Π½ΠΎΠ΅ ΡΠΎΡΡΠΎΡΠ½ΠΈΠ΅ }
SetWindowLong(Application.Handle, GWL_WNDPROC, LongInt(OldWProc));
end;
end.
ΠΠ°ΠΊ Π½Π΅ Π΄ΠΎΠΏΡΡΡΠΈΡΡ Π·Π°ΠΏΡΡΠΊ Π²ΡΠΎΡΠΎΠΉ ΠΊΠΎΠΏΠΈΠΈ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ X
Nomadic ΡΠ΅ΠΊΠΎΠΌΠ΅Π½Π΄ΡΠ΅Ρ ΡΠ»Π΅Π΄ΡΡΡΠΈΠΉ ΠΊΠΎΠ΄:
FindWindow ΡΠ²Π»ΡΠ΅ΡΡΡ Π½Π΅ΠΏΠΎΠ»Π½ΡΠΌ ΡΠ΅ΡΠ΅Π½ΠΈΠ΅ΠΌ (Π΅ΡΠ»ΠΈ ΠΌΠ΅Π½ΡΠ΅ΡΡΡ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ ΠΎΠΊΠ½Π° ΠΈΠ»ΠΈ Π΅ΡΠ»ΠΈ Π΅ΡΡΡ Π΄ΡΡΠ³Π°Ρ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠ° Ρ ΡΠ°ΠΊΠΈΠΌ ΠΆΠ΅ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΎΠΌ ΠΈΠ»ΠΈ ΡΠΈΠΏΠΎΠΌ ΠΎΠΊΠ½Π°).
ΠΡΠΎΡΠΈΡΠ½ΠΎ: ΠΡΠΎ ΡΠ°Π±ΠΎΡΠ°Π΅Ρ ΠΌΠ΅Π΄Π»Π΅Π½Π½ΠΎ.
ΠΡΠ°Π²ΠΈΠ»ΡΠ½ΠΎ β ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΠΎΠ±ΡΠ΅ΠΊΡΡ ΡΠΈΠ½Ρ ΡΠΎΠ½ΠΈΠ·Π°ΡΠΈΠΈ Win32 API.
ΠΠ΅Π½ΠΈΠ²ΠΎ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΡΠ΅ΠΌΠ°ΡΠΎΡΡ, ΠΏΠΎΠΊΠ°ΠΆΡ Π½Π° ΠΈΠΌΠ΅Π½ΠΎΠ²Π°Π½Π½ΡΡ ΠΌΡΡΠ΅ΠΊΡΠ°Ρ (ΡΠ΅ΠΌΠ°ΡΠΎΡΡ Ρ Π΄Π²ΡΠΌΡ ΡΠΎΡΡΠΎΡΠ½ΠΈΡΠΌΠΈ).
Unit OneInstance32;
interface
implementation
uses
Forms;
var
g_hAppMutex: THandle;
function OneInstance: boolean;
var
g_hAppCritSecMutex: THandle;
dw: Longint;