![]() |
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. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 19:31 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