Ich baue eine Win7 / 8/10 x64 Direct3D11-Desktop-Anwendung, die es dem Benutzer ermöglicht, zwischen Fenster- und Vollbildmodus umzuschalten (richtiger Vollbildmodus, nicht nur ein maximiertes Fenster *). Bei einem Dual-Monitor-Setup treten einige Probleme auf.
Der Schalter selbst wird manuell mit IDXGISwapChain::SetFullscreenState
ausgeführt und funktioniert wie vorgesehen: Der Monitor, der den Löwenanteil des Fensterbereichs beherbergt (nennen wir ihn Monitor A), geht in den dedizierten Vollbildmodus über, während er den anderen (Monitor B) als verlässt Es war, so dass der Benutzer normal mit Windows auf B sowie die Vollbild-Anwendung auf A interagieren kann.
Wenn jedoch ein Fenster auf B gezogen oder in der Größe verändert wird, so dass es zu A übergeht, wird der Vollbildstatus der Anwendung gestört: Manchmal kehrt er einfach in den Fenstermodus zurück (manchmal bleibt die interne Verfolgungsvariable der Anwendung nicht synchron) Es bleibt in einem Quasi-Vollbild-Modus, in dem es scheinbar keine weiteren Modus-Schalter mehr gibt und so weiter. Das Gleiche passiert, wenn ein Fenster, das sowohl A als auch B überlappte, bevor die Anwendung in den Vollbildmodus überging, den Fokus erhält.
Gibt es eine Möglichkeit, dies zu verhindern?
Ich möchte, dass das Betriebssystem den dedizierten Vollbildmodus meiner Anwendung berücksichtigt und es in einem robusten Zustand hält, auch wenn andere Fenster auf diesen Monitor gezogen werden. Ich möchte, dass das Verhalten ähnlich zu einem "immer auf der Spitze, maximierten randlosen Fenster" an seiner Stelle ist, dh andere Fenster "verschwinden einfach dahinter" und beeinflussen den Zustand meines Vollbildfensters überhaupt nicht.
Ich habe einige Problemumgehungen versucht, wie zum Beispiel auf WM_KILLFOCUS
zu reagieren und meine Anwendung vorübergehend in ein "maximixed randless window" zu schalten, bis sie WM_SETFOCUS
wieder empfängt, aber die WM_KILLFOCUS
Nachricht hat eine Verzögerung während der es Zeit gibt ein Benutzer, der ein anderes Fenster in den Bereich zieht, der sich dann noch im Vollbildmodus befindet, wodurch er mich auf Platz eins zurücksetzt.
* Der Grund, warum ich diese Funktion möchte, anstatt einfach ein maximiertes randloses Fenster zu verwenden (was auch ein unterstützter Modus ist, btw), hat damit viel weniger Maus-Bewegung-Rendering Latenz, vsync Kontrolle (ON / OFF) usw., die - kurz gesagt - für die Art dieser Anwendung (die kein Spiel ist) wichtig sind.
Obwohl nicht ideal ( ideal wäre, dass es eine Möglichkeit gäbe, dass das Betriebssystem selbst das richtig handhabt), habe ich eine vernünftige Problemumgehung gefunden, mit der ich im Moment leben kann. Es ist eine Variation des in der Frage erwähnten Konzepts ("..wie auf WM_KILLFOCUS
zu reagieren und meine Anwendung vorübergehend in ein maximiertes randloses Fenster zu verwandeln"), aber ohne das lähmende Verzögerungsproblem:
Wenn die Anwendung in den dedizierten Vollbildmodus wechselt, erfasst sie auch die Maus mit einem Aufruf von SetCapture
. Dies hat keine Auswirkungen auf die Fähigkeit des Benutzers, mit anderen Fenstern auf Monitor B zu interagieren, aber wird sicherstellen, dass eine solche de / aktivierende Interaktion - wie ein Mausklick in einer anderen Anwendung - WM_LBUTTONDOWN
sendet Meine Anwendung vor verliert den Fokus. Wichtig ist, dass dies sofort geschieht, im Gegensatz zur Nachricht WM_KILLFOCUS
, die eine signifikante Latenz aufweist.
Wenn eine solche WM_LBUTTONDOWN
-Nachricht empfangen wird (während im Vollbildmodus), überprüft die Anwendung, ob der Klick außerhalb des Bildschirmbereichs erfolgt ist. Wenn dies der Fall ist, bedeutet das, dass es den Fokus verliert und sich somit all den Komplikationen aussetzt, die in der ursprünglichen Frage aufgeworfen wurden. Daher wird der dedizierte Vollbildmodus vorübergehend beendet und durch ein (visuell identisches) grenzenloses maximiertes Fenster ersetzt. Wenn die Anwendung den Fokus zurückgewinnt, geht sie zurück in dedizierten Vollbildmodus.
Das funktioniert gut, da Sie nicht wirklich auf die Reaktionsfähigkeit der Anwendung achten, wenn Sie ohnehin nicht darauf zugreifen. Die größte Unannehmlichkeit hier ist das Flimmern des Modusschalters, das bei diesen Fokusübertragungen auftritt, aber angesichts der Alternativen finde ich es einen akzeptablen Preis für das, was ich erreichen möchte (aber auf alle Fälle - ich wäre sehr < > Interesse an einer besseren Lösung
Bearbeiten 1: Es ist erwähnenswert, dass WM_KILLFOCUS
auch behandelt wird, da es andere Möglichkeiten gibt, dass eine Anwendung den Fokus verliert als durch Mausklicks.
Edit 2: Ich habe kürzlich festgestellt, dass die Behandlung der WM_BUTTONDOWN
Nachricht überflüssig ist. SetCapture
alone stellt sicher, dass die Nachricht WM_KILLFOCUS
schnell genug empfangen wird.
Tags und Links c++ winapi multiple-monitors fullscreen direct3d11