DPI-Skalierung

DPI-Skalierung ist eine Funktion, die entweder vom Betriebssystem oder von der Applikation ausgeführt wird, um die sichtbare Größe des Inhalts proportional zur DPI-Einstellung (Dots Per Inch, dt. Punkte pro Zoll) des Bildschirms zu vergrößern. Grundsätzlich ermöglicht diese Funktion, dass Inhalte auf Systemen mit unterschiedlichen Bildschirmauflösungen in der gleichen physischen Größe dargestellt werden oder zumindest auf sehr hochauflösenden Bildschirmen benutzbar sind. Manchmal erhöht ein Benutzer die DPI-Einstellung, um Inhalte größer zu machen und besser lesen zu können.

A_ScreenDPI gibt die DPI-Einstellung des primären Bildschirms zurück.

Es gibt zwei verschiedene DPI-Skalierungen, die etwas mit AutoHotkey zu tun haben: Gui-DPI-Skalierung und OS-DPI-Skalierung.

Gui-DPI-Skalierung

Standardmäßig führen die Gui-Befehle eine automatische Skalierung durch, so dass GUI-Skripte mit hartkodierten Positionen, Größen und Abständen auf Bildschirmen mit hohem DPI-Wert angemessen skaliert werden. Wenn dies negative Auswirkungen auf das Skript hat oder das Skript die Skalierung selbst vornimmt, kann die automatische Skalierung deaktiviert werden. Weitere Informationen finden Sie unter der Option -DPIScale.

OS-DPI-Skalierung

Bei Applikationen, die nicht DPI-sensitiv sind, führt das Betriebssystem automatisch eine Skalierung für Koordinaten durch, die an bestimmte Systemfunktionen übergeben und von diesen zurückgegeben werden. Diese Art der Skalierung wirkt sich unter AutoHotkey nur auf Systeme mit mehreren Bildschirmen aus, die unterschiedliche DPI-Einstellungen haben.

Pro-Bildschirm-DPI-Sensitivität

In Windows 8.1 und höher können sekundäre Bildschirme unterschiedliche DPI-Einstellungen haben. Von "pro-Bildschirm-DPI-sensitiven" Applikationen wird erwartet, dass sie ihre Fenster entsprechend dem DPI-Wert des Bildschirms skalieren, auf dem sie sich gerade befinden, und sich dynamisch anpassen, wenn das Fenster zwischen den Bildschirmen hin- und hergeschoben wird.

Bei Applikationen, die nicht pro-Bildschirm-DPI-sensitiv sind, führt das System eine Bitmap-Skalierung durch, damit die Fenster ihre Größe ändern können, wenn sie zwischen den Bildschirmen hin- und hergeschoben werden, und verbirgt dies vor der Applikation, indem die Koordinaten und Größen auf die globale DPI-Einstellung skaliert werden, die die Applikation erwartet. Auf einem 11-Zoll-4K-Bildschirm wäre z.B. eine GUI, die für die Darstellung auf 96 dpi (100 %) ausgelegt ist, praktisch unbenutzbar, während eine Skalierung auf 200 % sie benutzbar machen würde.

AutoHotkey ist nicht für die Durchführung einer Pro-Bildschirm-Skalierung ausgelegt und wurde daher nicht als pro-Bildschirm-DPI-sensitiv gekennzeichnet. Dies ist z.B. vorteilhaft, wenn ein GUI-Fenster zwischen einem großen externen Bildschirm mit 100 % DPI und einem kleineren Bildschirm mit 200 % DPI hin- und hergeschoben wird. Die automatische Skalierung hat jedoch auch negative Auswirkungen.

Damit die automatische Skalierung des Systems funktioniert, werden Koordinaten, die von Systemfunktionen wie MoveWindow und GetWindowRect akzeptiert oder zurückgegeben werden, automatisch skaliert. Wenn AutoHotkey diese Funktionen verwendet, um mit externen Fenstern zu arbeiten, führt dies oft zu unerwarteten Ergebnissen, wenn sich die Koordinaten nicht auf dem primären Bildschirm befinden. Erschwerend kommt hinzu, dass einige Funktionen die Koordinaten auf Basis des Bildschirms skalieren, auf dem das zuletzt aktive Fenster des Skripts angezeigt wurde.

Workarounds

In Windows 10 Version 1607 und höher kann die Systemfunktion SetThreadDpiAwarenessContext verwendet werden, um die DPI-Sensitivitätseinstellung des Programms während der Ausführung zu ändern. Wenn Sie z.B. die Pro-Bildschirm-DPI-Sensitivität aktivieren, wird die systemseitige Skalierung deaktiviert, so dass Befehle wie WinMove und WinGetPos Koordinaten (in Pixel) unabhängig von der DPI-Skalierung akzeptieren oder zurückgeben können. Wenn jedoch die Größe einer GUI für einen Bildschirm mit 100 % DPI ausgelegt ist und dann auf einen Bildschirm mit 200 % DPI verschoben wird, passt sie sich nicht automatisch an und kann unbenutzbar werden.

Um die Pro-Bildschirm-DPI-Sensitivität zu aktivieren, rufen Sie die folgende Funktion auf, bevor Sie Funktionen verwenden, die normalerweise von der DPI-Skalierung betroffen sind:

DllCall("SetThreadDpiAwarenessContext", "ptr", -3, "ptr")

In Windows 10 Version 1703 und höher kann -3 mit -4 ersetzt werden, um den Modus "Per Monitor v2" zu aktivieren. Dies ermöglicht die Skalierung von Dialogfenstern, Menüs, Tooltips und einigem mehr. Allerdings wird dadurch auch der Nicht-Clientbereich (Titelleiste) skaliert, was wiederum dazu führen kann, dass der Clientbereich des Fensters zu klein wird, es sei denn, das Skript ist so konzipiert, dass es sich daran anpasst (z.B. durch Reaktion auf die WM_DPICHANGED-Meldung). Dies lässt sich vermeiden, indem der Kontext vor der Erstellung der GUI auf -3 oder vor der Erstellung von Tooltips, Menüs oder Dialogfenstern auf -4 gesetzt wird.

Die DPI-Sensitivität des Threads kann sich temporär ändern, während der Benutzer ein Fenster des Skripts verschiebt oder während das Skript ein Dialogfenster anzeigt. Daher ist es am sichersten, die DPI-Sensitivität unmittelbar vor der Verwendung der Funktionen, die darauf angewiesen sind, einzustellen.

Kompilierte Skripte

Pro-Bildschirm-DPI-Sensitivität kann prozessübergreifend aktiviert werden, indem der Inhalt des <dpiAware>-Eintrags in der Manifest-Ressource des kompilierten Skripts von true (Standardeinstellung in der AutoHotkey-EXE-Datei) auf true/pm geändert wird.