Entwickler-Ecke
Grafische Benutzeroberflächen (VCL & FireMonkey) - Problem mit zweiter Programminstanz
dickeWade - Mo 28.02.11 12:16
Titel: Problem mit zweiter Programminstanz
Hallöchen und einen schönen Tag :)
Mich beschäftigt folgendes kleines Problem. Ich will von meinem Programm nur eine Instanz laufen haben. Wird es ein zweites Mal gestartet, suche ich das Hauptfenster, aktiviere ich es, bringe es in den Vordergrund und beende die zweite Instanz wieder.
Delphi-Quelltext
1: 2: 3: 4: 5: 6:
| FensterHandle := FindWindow('TFestplattenRecorderForm', nil); if FensterHandle <> 0 then begin ShowWindow(FensterHandle, SW_RESTORE); SetForegroundWindow(FensterHandle); end; |
Das funktioniert an sich auch ganz fein, bis auf eine Schwierigkeit. Ist das Fenster der ersten Instanz gerade minimiert, wird es zwar "wieder hervorgeholt" und alles ist schön. Fortan kann ich es aber nicht mehr minimieren. Mit dem nCmdShow - Parameter SW_SHOWNORMAL hab ich das gleiche Ergebnis. Dito wenn ich statt ShowWindow den Befehl:
Delphi-Quelltext
1:
| SendMessage(FensterHandle, WM_SYSCOMMAND, SC_RESTORE, 0); |
benutze.
Vielen Dank im Vorraus :)
Gruß Tommi
guinnes - Mo 28.02.11 12:33
Es gibt dafür die Komponente OneInstance von Andreas Hausladen
Xion - Mo 28.02.11 13:15
Probiers mal so:
Delphi-Quelltext
1:
| SendMessage(FensterHandle,WM_SHOWFORM,0,0); |
dickeWade - Mo 28.02.11 13:16
Vielen Dank für die schnelle Antwort.
Werde ich doch flink mal ausprobieren :D
Gruß Tommi
Sinspin - Mo 28.02.11 16:09
Ich arbeite immer mit einem Mutex. Der Name dessen ist eine GUID und somit weltweit eindeutig. So kann nie aus versehen ein anderes Programm genauso heißen.
Eine GUID kannst Du in Delphi via Strg+Umschalt + G erzeugen.
In der DPR dazu das folgende schreiben:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18:
| var Mutex: THandle;
begin Mutex := CreateMutex(nil, True, '{30E93268-B040-433A-9E22-96F391F4D4D4}'); if (Mutex <> 0) and (GetLastError = 0) then begin Application.Initialize; Application.CreateForm(TForm1, Form1); Application.Run; if Mutex <> 0 then CloseHandle(Mutex); end else begin MessageDlg('Programm darf nur einmal gestartet werden!', mtError, [mbOK], 0); end; end. |
dickeWade - Mi 02.03.11 18:40
Dankeschön :D
Ich sehe schon, es gibt verschiedene Methoden die erste Instanz zu finden. Werde ich alle mal ausprobieren und schauen was mir am besten gefällt. Das Senden einer Message an die erste Instanz funktioniert bei mir auch gut, nur das mit dem schicken der Kommandezeile werde ich mal mit Atomen probieren. Mit GlobalAlloc kam ich nicht weiter. Kam nix an.
Allerdings funktioniert das Wiederherstellen des Fensters der ersten Instanz immer noch nicht wenn es in der Taskleiste verkleinert schlummert. Es kommt zwar zum Vorschein und alles ist Prima, aber fortan lässt es sich eben nicht mehr verkleinern. "WM_SHOWFORM" hab ich probiert, die Konstante wurde aber nicht gefunden :?
Mir fällt da gerade ein Möglichkleit ein:
Delphi-Quelltext
1:
| SendMessage(FensterHandle,WM_DuSollstDichVergroessernFallsDuMinimiertBist,0,0); |
Also dass die erste Instanz das Wiederherstellen und Anzeigen des Fensters übernimmt. Probier ich heute Abend mal aus...
Gruß Tommi
dickeWade - Sa 05.03.11 17:32
So hab die Lösung gefunden und die funktioniert auch bestens :)
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
| const WM_ZweiteInstanz = WM_USER + 11;
......
procedure TFestplattenRecorderForm.MessageVonZweiterInstanz(var Msg: TMessage); begin Application.Restore; Application.BringToFront; end; |
Dankeschön nochmals :)
Hab ich schon erwähnt, dass das hier ein tolles Forum ist? Ich lese ja schon ein paar Wochen hier und hab schon einige gute Tips gefunden.
Gruß Tommi
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!