Registriert seit: 26. Mär 2010
254 Beiträge
Delphi XE Enterprise
|
AW: 1. Instanz nach vorn bringen, wenn 2. geöffnet wird - fensterunabhängig!
6. Mär 2013, 16:11
Letzter Stand (2. Instanz bringt die erste nach vorn):
Delphi-Quellcode:
const
ProgUID = 'geheim :-p';
WM_AnswerToSecondInstance = WM_USER + 1;
var
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
var
LHandle: HWnd;
TopWindow: HWnd;
begin
Result := False;
if m.Msg = WM_CCCSingleInstanceBroadcast then
begin
// Logic copied from Application.BringToFront
if Application.MainFormOnTaskBar and (Application.MainForm <> nil) then
LHandle := Application.MainForm.Handle
else
LHandle := Application.Handle;
if LHandle <> 0 then
begin
TopWindow := GetLastActivePopup(LHandle);
if (TopWindow <> 0) and (TopWindow <> Application.Handle) and
IsWindowVisible(TopWindow) and IsWindowEnabled(TopWindow) then
PostMessage(m.WParam, m.LParam, TopWindow, 0);
end;
end;
end;
function TIrgendeineKlasse.SecondInstanceReceiver(var m: TMessage): Boolean; // muss zwecks Akzeptanz durch Application.HookMainWindow als Methode einer Klasse implementiert sein
begin
Result := False;
case m.Msg of
WM_AnswerToSecondInstance:
SetForegroundWindow(m.WParam);
end;
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
Application.HookMainWindow(TIrgendeineKlasse.SecondInstanceReceiver); // Klassenmethode sollte gehen - dieser Teil ist bei mir ganz anders umgesetzt
New(PBroadcastRecipients);
try
PBroadcastRecipients^ := BSM_APPLICATIONS;
BroadcastSystemMessage(BSF_IGNORECURRENTTASK, PBroadcastRecipients,
WM_CCCSingleInstanceBroadcast, MessageDistributor.Handle,
WM_AnswerToSecondInstance); // an alle: hier ist noch einer
finally
Dispose(PBroadcastRecipients);
end;
SwitchToThread; // Rest der Zeitscheibe verwerfen, damit die 1. Instanz antworten kann (falls das durch Race-Condition nicht klappt: Pech gehabt)
Application.ProcessMessages; // Antwort verarbeiten
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.
Mann, ist das viel Code geworden, aber letztlich steckt ja gar nicht so viel dahinter...
"Seit er seinen neuen Computer hat, löst er alle seine Probleme, die er vorher nicht hatte."
|
|
Zitat
|