Mal wieder: Doppeltes starten einer Anwendung unterbinden
Mahlzeit,
ich versuche ein Programm per ShellExecute in ein anderes Programm einzubinden. Dabei darf diese Anwendung immer nur 1x gestartet werden. Wenn man versucht die Anwendung ein 2. mal zu starten soll die 1. Instanz in den Vordergrund geholt werden. Ich habe also im Quelltext der aufzurufenden Anwendung folgenden Code hinterlegt. Der Aufruf und das Unterbinden von Mehrfachstarts funktionieren, aber die Anwendung wird nur beim 1. Versuch in den Vordergrund geholt... Ich vermute das "BringWindowToTop" der falsche Befehl ist, aber "ShowWindow" bringt auch nicht den Erwünschten Erfolg (Es wird nur ein kleines Blaues Fenster über der Taskleiste angezeigt). Was anderes habe ich in den anderen Threads nicht gefunden... Sieht Jemand was ich falsch mache?
Delphi-Quellcode:
{$R *.res}
const MutexName = 'ErweiterteListen'; var hMutex: THandle; NextHandle: Hwnd; foundedHandle : Hwnd; NextTitle: array[0..260] of char; foundHandle : Boolean; begin Application.Initialize; Application.MainFormOnTaskbar := True; Application.CreateForm(TListStatSchnittForm, ListStatSchnittForm); foundHandle := false; hMutex := CreateMutex(NIL, True, MutexName); if (hMutex = 0) OR (GetLastError = ERROR_ALREADY_EXISTS) then begin //Ab hier wird die schon gestartete Anwendung gesucht CloseHandle(hMutex); begin NextHandle := GetWindow(Application.Handle, GW_HWNDFIRST); while (NextHandle > 0) and (foundHandle = false) do begin GetWindowText(NextHandle, NextTitle, 255); if (Pos(ListStatSchnittForm.Caption, StrPas(NextTitle)) <> 0) and (NextHandle <> application.Handle) and (NextHandle <> ListStatSchnittForm.Handle) then begin foundedHandle := NextHandle; foundHandle := true; end else NextHandle := GetWindow(NextHandle, GW_HWNDNEXT); end; end; if foundHandle then begin BringWindowToTop(foundedHandle); //ShowWindow(foundedHandle, SW_SHOW); halt; end end; Application.Run; end. |
Re: Mal wieder: Doppeltes starten einer Anwendung unterbinde
Kennt Ihr das: In DEM MOMENT in dem ich hier den Thread abgesendet habe finde ich die Lösung :roll:
Danke fürs Kopfzerbrechen, ich musste nur "FindWindow('TListStatSchnittForm', nil);" nutzen ^^
Delphi-Quellcode:
{$R *.res}
const MutexName = 'ErweiterteListen'; var hMutex: THandle; NextHandle: Hwnd; foundedHandle : Hwnd; NextTitle: array[0..260] of char; foundHandle : Boolean; begin Application.Initialize; Application.MainFormOnTaskbar := True; Application.CreateForm(TListStatSchnittForm, ListStatSchnittForm); foundHandle := false; hMutex := CreateMutex(NIL, True, MutexName); if (hMutex = 0) OR (GetLastError = ERROR_ALREADY_EXISTS) then begin CloseHandle(hMutex); begin NextHandle := FindWindow('TListStatSchnittForm', nil); while (NextHandle > 0) and (foundHandle = false) do begin GetWindowText(NextHandle, NextTitle, 255); if (Pos(ListStatSchnittForm.Caption, StrPas(NextTitle)) <> 0) and (NextHandle <> application.Handle) and (NextHandle <> ListStatSchnittForm.Handle) then begin foundedHandle := NextHandle; foundHandle := true; end else NextHandle := GetWindow(NextHandle, GW_HWNDNEXT); end; end; if foundHandle then begin BringWindowToTop(foundedHandle); //ShowWindow(foundedHandle, SW_SHOW); halt; end end; Application.Run; end. |
Re: Mal wieder: Doppeltes starten einer Anwendung unterbinde
Zitat:
Ich persönlich finde es auch etwas kompliziert: Den Code zum Finden des Fenster-Handle gibt einem WinSpy wesentlich kürzer aus. Da Du Deinen Titel und die Klasse kennst, ist das Fenster auch eindeutig identifizierbar. So kannst Du das herausfiltern des Fensternamens sparen, wenn Du bei FindWindow statt nil als zweiten Parameter, den Titel angibst. Ich mag mich irren, aber Handle ist Handle und dann sollte BringWindowToTop() auch gehen. Und schließlich würde ich Deinen Code vor Application.Initialize platzieren. Das spart Zeit, Speicher etc. weil gleich als erstes geprüft wird, ob bereits ein Instanz läuft. Ich "löse" mein Problem etwas unorthodox - allerdings Dank Deines Schemas - dann so (dpr-Datei):
Delphi-Quellcode:
In der Unit fürs MainForm reagiere ich dann so:
Const
MutexName ='Eindeutiger Name für ein Chat-Programm'; Var hMutex : THandle; Wnd : Hwnd; Begin hMutex:=CreateMutex(nil, True, MutexName); If GetLastError = ERROR_ALREADY_EXISTS Then Begin CloseHandle(hMutex); Wnd:=FindWindow('TChat', 'Nachrichten'); If Wnd <> 0 Then Begin SendMessage(Wnd, WM_2ndInstance, 0, 0); Halt; End; End; Application.Initialize; Application.ShowMainForm:=False; Application.CreateForm(TChat, Chat); Application.Run; End.
Delphi-Quellcode:
Keine Ahnung, ob man das so macht. Aber es funktioniert.
Const
WM_2ndInstance = $0406; Type TChat = Class(TForm) ... Private Procedure WM2ndInstance(Var Msg: TMessage); Message WM_2ndInstance; ... End; ... Procedure TChat.WM2ndInstance(Var Msg: TMessage); Begin Show; End; Gruß, Alex |
Alle Zeitangaben in WEZ +1. Es ist jetzt 17:38 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz