SetForegroundWindow()

Thomasio

Erfahrenes Mitglied
Seit XP mag Windows die Funktionen SetWindowPos() und SetForegroundWindow() nicht mehr besonders, da blinkt es nur noch in der Taskleiste, aber in den Vordergrund kommt da nichts mehr
Für Delphi habe ich ein paar workarounds ala ForceForegroundWindow() gefunden, aber meine "Übersetzung" nach API plain funktioniert trotzdem nicht
Vermutlich bin ich nur zu doof dazu, aber ich verstehe nicht ganz, warum das bei mir mal funktioniert und mal nicht

Zu Testzwecken habe ich es mal so weit gebracht:

Wenn ich in meine Anwendung einen Timer rein mache, der alle paar Sekunden anschlägt und das Fenster in den Vordergrund holt und diese Anwendung selber starte, dann kann ich 100 andere Fenster drüber legen, jedes Mal wenn der Timer zuschlägt kommt meine Anwendung schön brav nach vorne

Wenn ich in meiner Anwendung via ShellExecute eine zweite Anwendung starte, dann kann ich in der Zweiten machen was immer ich will, wenn die erste Anwendung bei Start der Zweiten nicht im Vordergrund ist, dann bleibt die Zweite im Hintergrund und blinkt nur in der Taskleiste, selbst wenn ich sie zwischendurch nach vorne hole, lege ich ein anderes Fenster drüber bleibt sie wieder hinten

Kann mir jemand eine API plain Funktion geben, die ein Fenster zuverlässig in den Vordergrund holt?
 
Ich kann mir gut vorstellen, dass da die Benutzer-Einstellung "Disable Focus stealing from Apps" mit rein spielt.

Du kannst aber auch mal mit BringWindowToTop() spielen.

Generell halte ich Programme, die mir ins Gesicht springen bzw. den Fokus klauen für ziemlich nervig. Das sind dann immer Kandidaten zur sofortigen Deinstallation :)
 
BringWindowToTop habe ich auch schon probiert, Ergebnis ist gleich

Ich kenne das Problem selber, ich mag Anwendungen die den Focus klauen auch nicht, ich brauche die Funkktion zu genau einem einzigen, bestimmten Zweck
Wenn eine Anwendung bereits in Hintergrund oder minimiert offen ist, die via mutex mehrfaches Ausführen nicht erlaubt, und der User versucht die Anwendung ein zweites Mal zu starten, dann soll die zweite Instanz der Anwendung, bevor der mutex sie wieder schliesst die erste Instanz nach vorne holen, um dem User zu zeigen, dass sie bereits da ist

Eine Anwendung die bei Start ForegroundWindow wird, z.B. weil die aufrufende Anwendung zu dieser Zeit ForegroundWindow ist, klaut den Focus nach Belieben, zu jeder späteren Zeit, auch wenn ich das gar nicht will, aber wenn die erste Instanz der Anwendung im Hintergrund gestartet wurde, dann funktioniert gar nichts

Ich kann da einbauen was ich will, das Ergebnis ist immer ein ungewollter, nerviger Focus-Klau oder gar nichts, nur der gewünschte Effekt lässt sich nicht erstellen, weil die zweite Instanz zur Zeit der mutex Abfrage noch gar kein Fenster hat, darum nicht im Vordergrund ist und somit dank WinXP keine der beiden Instanzen eine Berechtigung hat das ForegroundWindow zu setzen

Kurz gesagt, Windows unterbindet die einzige nützliche Funktion von SetForegroundWindow, während alle nervigen und ungewollten Effekte davon erhalten bleiben
 
Hmm, dann sehe ich zwei Möglichkeiten:

1) Du erzeugst ein Mini-Fenster, damit du etwas mit Fokus hast und kannst dann den Fokus aufs andere Fenster schieben.

oder

2) Du sendest irgendwie eine Nachricht an die offenen Instanz, und die klebt sich selbst in den Vordergrund.
 
Und genau das ist es was nicht funktioniert, bzw. was ich nicht auf die Reihe bekomme
Da kann ich erzeugen oder senden was immer ich will, die erste Instanz kommt NUR dann nach vorne, wenn diese bei ihrem Start selbst Vordergrund war

Ich kann es selber kaum erklären, aber ich versuchs mal:

Wenn meine Anwendung sich beim ersten Start nach vorne drängeln will, dann geht das nur dann, wenn sie aus einer Vordergrund Anwendung heraus geöffnet wurde, z.B. per Doppelklick auf die .exe im Windows Explorer
In dem Fall kann ich die Anwendung auf einem Dutzend Wegen, zu jeder beliebigen späteren Zeit wieder nach vorne holen inkl Focus Klau und weiteren unbeabsichtigten Effekten

Wenn meine Anwendung beim ersten Start nicht aus einer Vordergrund Anwendung heraus gestartet wurde, also z.B. via ShellExecute aus einer anderen Anwendung die zu diesem Zeitpunkt nicht im Vordergrund ist, dann kann meine Anwendung sich von Anfang an nicht nach vorne drängeln, weder bei Start noch zu irgendeinem späteren Zeitpunkt, völlig egal von wo der Befehl kommt sie in den Vordergrund zu holen, selbst dann wenn ich testhalber eine völlig unabhängige dritte Anwendung schreibe, die nichts weiter macht als ein Fenster öffnen, sich in den Vordergrund drängeln und dann SetForegoundWindow() mit dem Handle meiner Anwendung aufrufen, bleibt meine Anwendung ganz stur hinten und es blinkt nur in der Taskleiste
Dementsprechend funktioniert das auch dann nicht, wenn die zweite Instanz der Anwendung die erste Instanz nach vorne holen will, ganz egal, ob die zweite Instanz kurzzeitig ein Vordergrundfenster erstellt oder nicht

Ich kenne aber 2 Beispiele, dafür, dass es irgendwie machbar ist
Der Windows Task-Manager und das Hauptfenster von ICQ, bleiben unter allen Umständen im Vordergrund, völlig egal was man versucht, die überlagern selbst die Taskleiste
Es geht also auch unter XP irgendwie, und ich stelle mir vor, wenn man dieses absolute Vordergrundverhalten auf bestimmte Systemereignisse begrenzt, müsste das für meine Zwecke nutzbar sein, die Frage ist nur, wie?
 
Was diese On-Top-Fenster machen: Den Stil WS_EX_TOPMOST einzusetzen.

Das könnte evtl. helfen, den Stil einmal mit SetWindowLong( hWnd, GWL_EXSTYLE, GetWindowLong( hWnd, GWL_EXSTYLE ) | WS_EX_TOPMOST ) anbringen und dann nochmal die anderen Funktionen testen.
 
Zurück