![]() |
Fenster wiederherstellen mit SetForeGround
Ich habe eine Anwendung geschrieben die beim 2. Aufruf des Programms eine Message an alle Fenster schickt,
bekommt die 1. Instanz der Anwendung diese Botschaft so soll das Fenster wiederhergestellt bzw. angezeigt werden in der exakten größe was aber zur Zeit noch nicht klappt. Wie die Message verschickt wird steht in einem anderen Beitrag von mir ( ![]() Ich habe schon einige Dinge probiert und hier der letzte Versuch, das Program scheint zwar den Focus zubekommen jedoch wird das Fenster nicht korrekt wiederhergestellt. :gruebel:
Delphi-Quellcode:
procedure TfrmMain.OnAppMsg(var Msg: TMsg; var Handled: Boolean);
begin Handled := False; if Msg.message = dwMessage then begin if Msg.wParam = glPrgMode then begin ShowWindow(Application.MainFormHandle, SW_NORMAL); SetForegroundWindow(Application.MainFormHandle); end; Handled := True; end; end; |
Re: Fenster wiederherstellen mit SetForeGround
Unter XP lässt sich ein Fenster nicht mehr so einfach in den Vordergrund bringen. Und das hat auch seinen sinn, da immer mehr Entwickler ihr Programmfenster in den Vordergrund gebracht haben, wenn irgendein Ereignis eingetreten ist und das Fenster, in dem der Benutzer gerade gearbeitet hat, seinen Eingabefokus verloren hat und auf einmal im Hintergrund war. Mich nervt so etwas tierisch. Ein einfaches Blinken in der Taskleiste reicht vollkommen, um auf etwas aufmerksam zumachen. Der Benutzer kann dann selber entscheiden, ob er weiterarbeite oder scih um das andere Fenster kümmern will.
Wenn du es aber trotzdem unbedingt so machen muss, dann guck mal hier: ![]() |
Re: Fenster wiederherstellen mit SetForeGround
Du hast da schon vollkommen recht, ich mags auch nicht wenn irgendwelche Programme meinen plötzlich irgendetwas zu machen
was sie nicht sollen, aber in Kombination mit dem Verhindern eines Mehrfach aufrufes find ich es schon sinnvoll, da der Anwender ja genau das will also er will das Programm starten und weil es schon längst offen ist soll es halt in den Vordergrund geholt werden, ich werd mir daher den Beitrag auf den du verwiesen hast durchlesen. |
Re: Fenster wiederherstellen mit SetForeGround
Moin, Moin,
wenn es nur darum geht, einen Mehrfachstart zu vermeiden und das ggf. bereits gestartete Programm zu aktivieren, dann gibt es doch eine andere/bessere Lösung: Normalerweise regelt man das über einen Mutex... |
Re: Fenster wiederherstellen mit SetForeGround
Das hat er, denke ich mal, schon alles.
|
Re: Fenster wiederherstellen mit SetForeGround
Zitat:
das Verhindern per Mutex mache ich schon lange es ging hier nur darum das die 1. Instanz der Anwendung wiederhergestellt wird beim erneuten aufrufen der Anwendung. ![]() |
Re: Fenster wiederherstellen mit SetForeGround
Hmmm, seltsam.
Dann sollte es eigentlich funktionieren. Verwende ähnlichen (!) Code, allerdings in einer Unit ausgelagert - und das funktioniert bisher einwandfrei. Versuch's doch mal folgender Unit anstelle deines codes in der .dpr
Delphi-Quellcode:
unit rzM_OneInstanceOnly;
// Unit lediglich in das Projekt aufnehmen, danach werden mehrere Instanzen // des Programmes unterbunden; bei erneutem Aufruf wird automatisch die // erste Instanz aktiviert. interface { ----------------------------------------------------------------- } implementation { ------------------------------------------------------------ } uses Forms,SysUtils,Windows; var Mutex : THandle; MName : String; h : HWnd; initialization { ------------------------------------------------------------ } MName:=ExtractFileName(ChangeFileExt(Application.ExeName,'_MTX')); Mutex:=CreateMutex(nil,true,pchar(MName)); // Mutex anlegen if GetLastError=ERROR_ALREADY_EXISTS then begin // Fehler, Pgm schon aktiv! h:=0; // vorhandene Instanz suchen repeat h:=Windows.FindWindowEx(0,h,PChar('TApplication'),PChar(Application.Title)) until h<>Application.Handle; if h<>0 then begin // aktivieren Windows.ShowWindow(h,SW_Restore); Windows.SetForegroundWindow(h); end; Application.Terminate; // und diesen zweiten Aufruf beenden! end; finalization { -------------------------------------------------------------- } ReleaseMutex(Mutex); // Mutex der ersten Instanz wieder freigeben! end. |
Re: Fenster wiederherstellen mit SetForeGround
Ja der Trick könnte evtl sein aus der Zweitapplikation heraus (die ja den Fokus hat) die erste nach vorne zu holen.
Was du ja aktuell machst, ist der ersten eine Nachricht zu schicken, sie möge sich in den Vordergrund drängeln. Vielleicht sollte man das Pferd andersherum aufzäumen. |
Re: Fenster wiederherstellen mit SetForeGround
Ich habe das ganze jetzt am laufen, mit der Funktion "ForceForeGroundWindow" die im Beitrag den Luckie gepostet hat steht,
so wie taaktaak das gemacht hat, habe ich das früher auch so gemacht was auch alles funktioniert. Jedoch mit der aktuellen variante das eine Windows Botschaft verschickt wird, war das Resultat das zwar das Fenster nach vorne geholt wurde jedoch nicht mehr maximiert war, was es zuvor noch war. So müßte der Anwender jedesmal das Fenster erst wieder maximieren, mit der Funktion ForceForeGroundWindow klappt alles wunderbar. Ich kann jetzt meine Anwendung einmal im Modus "A" und einmal im Modus "B" starten, versuche ich den jeweiligen Modus noch mal zustarten so wird das entsprechend richtige Fenster wiederhergestellt. Vielen dank für die Hilfe und die Tipps. :dp: |
Re: Fenster wiederherstellen mit SetForeGround
Will ja nüscht sagen, aber ich hab dich im Vorthread schon auf forceForegroundWindow und die Suche verwiesen.
Also wäre der richtige Weg, der auch funktioniert, mit den Nachrichten das Handle herauszufinden und dann von der startenden Applikation die andere in den Vordergrund zu holen. ForceForegroundWindow ist halt der unsaubere aber funktionierende Weg. |
Re: Fenster wiederherstellen mit SetForeGround
Zitat:
nichts ob wohl es Beiträge zu diesem Suchbegriff gibt. Zitat:
Vordergrund, wie du das meinst müßte erstmal der Empfänger eine Botschaft zurück schicken damit ich das Handle erhalte um dann das Fenster in den Vordergrund zuholen oder wie ? Zitat:
oder von einem anderen Fenster in den Vordergrund geholt wird. Vorausgesetzt das Fenster stellt sich nicht alle nasenlang in den Vordergrund das wäre ja wirklich nervig. |
Re: Fenster wiederherstellen mit SetForeGround
Ok ich gebe zu ich habe das mit der DP-Suche jetzt nicht vorher überprüft :P
Genau so, du kannst doch der aufgerufenen Applikation eine Nachricht zurückliefern, so würde ich das mal versuchen. Ich würde es daher unsauber nennen, da Microsoft schon dafür gesorgt hat, dass Applikationen, die nicht den Userinput-Fokus haben, sich nicht selber in den Vordergrund holen dürfen - was ich im übrigens absolut begrüsse. Ich mag selber solche Applikationen nicht, die von sich selbst überzeugt sind, dass sie unglaublich wichtig sein müssen. Wer weiss was im nächsten OS kommt, vielleicht funktioniert forceForegroundWindow dort auch nicht mehr (hat das jemand mal in Vista getestet? :) |
Re: Fenster wiederherstellen mit SetForeGround
Ich werde das dann mal ausprobieren das die Anwendung eine Nachricht zurück schickt und darauf hin die 2. Instanz die
erste in den Vordergrund holt. Einen Vista Rechner habe ich zu Testzwecken hier stehen, ich glaube das ForceForeGroundWindow sollte da auch drauf laufen bin mir nicht sicher ob ich das Gestern getestet habe als ich kurz die Anwendung unter Vista installiert habe, der Test bezog sich generell auf die Lauffähigkeit unter Vista. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:51 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz