const
ProgUID = '
geheim :-p';
BSF_ALLOWSFW = $00000080;
// fehlt in Unit Windows neben z.B. BSF_QUERY
var
s:
string;
HMutex: THandle = 0;
PBroadcastRecipients: PDWORD;
WM_CCCSingleInstanceBroadcast: UINT = 0;
function TIrgendeineKlasse.SingleInstanceBroadcastReceiver(
var m: TMessage): Boolean;
// muss zwecks Akzeptanz durch Application.HookMainWindow als Methode einer Klasse implementiert sein
begin
Result := False;
if m.Msg = WM_CCCSingleInstanceBroadcast
then
Application.BringToFront;
end;
initialization
WM_CCCSingleInstanceBroadcast := RegisterWindowMessage(ProgUID);
// eindeutige Message-ID holen
HMutex := CreateMutex(
nil, True, ProgUID);
if (HMutex = 0)
or (GetLastError = ERROR_ALREADY_EXISTS)
or
(GetLastError = ERROR_ACCESS_DENIED)
then
begin
// dieser Code läuft nur in der 2. Instanz des Programms
New(PBroadcastRecipients);
try
PBroadcastRecipients^ := BSM_APPLICATIONS;
BroadcastSystemMessage(BSF_ALLOWSFW
or BSF_IGNORECURRENTTASK
or
BSF_POSTMESSAGE, PBroadcastRecipients, WM_CCCSingleInstanceBroadcast, 0, 0);
// an alle: hier ist noch einer
SwitchToThread;
// Rest der Zeitscheibe verwerfen, damit die Instanz sich nach vorn bringen kann (falls das durch Race-Condition nicht klappt: Pech gehabt)
finally
Dispose(PBroadcastRecipients);
end;
MessageBox(0, '
Das Programm läuft bereits', '
',
MB_SYSTEMMODAL
or MB_SETFOREGROUND
or MB_TOPMOST);
// über die erste Instanz legen
Halt;
end;
Application.HookMainWindow(TIrgendeineKlasse.SingleInstanceBroadcastReceiver);
// Klassenmethode sollte gehen - dieser Teil ist bei mir ganz anders umgesetzt
finalization
if HMutex > 0
then
CloseHandle(HMutex);
end.