WM_DPICHANGED-Meldung

Wird gesendet, wenn sich die effektiven Punkte pro Zoll (dpi) für ein Fenster geändert haben. Der DPI-Wert ist der Skalierungsfaktor für ein Fenster. Es gibt mehrere Ereignisse, die dazu führen können, dass sich der DPI-Wert ändert. Die folgende Liste gibt die möglichen Ursachen für die Änderung der DPI-Werte an.

  • Das Fenster wird auf einen neuen Monitor verschoben, der einen anderen DPI-Wert aufweist.
  • Der DPI-Wert des Monitors, auf dem das Fenster gehostet wird.

Der aktuelle DPI-Wert für ein Fenster entspricht immer dem letzten DPI-Wert, der von WM_DPICHANGED gesendet wird. Dies ist der Skalierungsfaktor, auf den das Fenster für Threads skaliert werden soll, die DPI-Änderungen kennen.

#define WM_DPICHANGED       0x02E0

Parameter

wParam

Das HIWORD des wParam enthält den Y-Achsenwert des neuen DPI-Werts des Fensters. Das LOWORD des wParam enthält den X-Achsenwert des neuen DPI-Werts des Fensters. Beispiel: 96, 120, 144 oder 192. Die Werte der X-Achse und der Y-Achse sind für Windows-Apps identisch.

lParam

Ein Zeiger auf eine RECT-Struktur, die eine vorgeschlagene Größe und Position des aktuellen Fensters für den neuen DPI-Wert bereitstellt. Die Erwartung besteht darin, dass Apps Fenster basierend auf den von lParam beim Behandeln dieser Meldung bereitgestellten Vorschlägen neu positionieren und ihre Größe ändern.

Rückgabewert

Wenn eine Anwendung diese Meldung verarbeitet, sollte sie 0 (null) zurückgeben.

Hinweise

Diese Meldung ist nur für PROCESS_PER_MONITOR_DPI_AWARE-Anwendungen oder DPI_AWARENESS_PER_MONITOR_AWARE-Threads relevant. Sie kann bei bestimmten DPI-Änderungen empfangen werden, wenn Ihr oberstes Fenster oder Ihr Prozess als DPI-Unaware oder System-DPI-Aware ausgeführt wird, aber in diesen Situationen kann sie sicher ignoriert werden. Weitere Informationen zu den verschiedenen Bewusstseinstypen finden Sie unter PROCESS_DPI_AWARENESS und DPI_AWARENESS. Ältere Versionen von Windows mussten die DPI-Erkennung auf der Ebene einer Anwendung binden. Diese Apps verwenden PROCESS_DPI_AWARENESS. Derzeit ist die DPI-Erkennung an Threads und einzelne Fenster und nicht an die gesamte Anwendung gebunden. Diese Apps verwenden DPI_AWARENESS.

Sie müssen nur den Wert der X- oder Y-Achse verwenden, wenn Sie Ihre Anwendung skalieren, da sie identisch sind.

Um diese Meldung ordnungsgemäß zu behandeln, müssen Sie die Größe des Fensters basierend auf den von lParam bereitgestellten Vorschlägen ändern und das Fenster mithilfe von SetWindowPos ändern. Wenn Sie dies nicht tun, wird Ihr Fenster im Hinblick auf alles andere auf dem neuen Monitor vergrößert oder verkleinern. Wenn ein Benutzer z. B. mehrere Monitore verwendet und das Fenster von einem 96 DPI-Monitor auf einen 192 DPI-Monitor zieht, scheint das Fenster in Bezug auf andere Elemente auf dem 192 DPI-Monitor halb so groß zu sein.

Der Basiswert von DPI wird als USER_DEFAULT_SCREEN_DPI definiert, der auf 96 festgelegt ist. Um den Skalierungsfaktor für einen Monitor zu ermitteln, nehmen Sie den DPI-Wert und dividieren ihn durch USER_DEFAULT_SCREEN_DPI. Die folgende Tabelle enthält einige beispielhafte DPI-Werte und zugehörige Skalierungsfaktoren.

DPI-Wert Skalierungsprozentsatz
96 100 %
120 125%
144 150%
192 200 %

Das folgende Beispiel enthält einen beispielhaften DPI-Änderungshandler.

    case WM_DPICHANGED:
    {
        g_dpi = HIWORD(wParam);
        UpdateDpiDependentFontsAndResources();

        RECT* const prcNewWindow = (RECT*)lParam;
        SetWindowPos(hWnd,
            NULL,
            prcNewWindow ->left,
            prcNewWindow ->top,
            prcNewWindow->right - prcNewWindow->left,
            prcNewWindow->bottom - prcNewWindow->top,
            SWP_NOZORDER | SWP_NOACTIVATE);
        break;
    }

Der folgende Code skaliert linear einen Wert von 100 % (96 DPI) auf einen beliebigen DPI-Wert, der durch g_dpi definiert wird.

    INT iBorderWidth100 = 5;
    iBorderWidth = MulDiv(iBorderWidth100, g_dpi, USER_DEFAULT_SCREEN_DPI);

Eine alternative Möglichkeit zum Skalieren eines Werts besteht darin, den DPI-Wert in einen Skalierungsfaktor zu konvertieren und diesen zu verwenden.

    INT iBorderWidth100 = 5;
    FLOAT fscale = (float) g_dpi / USER_DEFAULT_SCREEN_DPI;
    iBorderWidth = iBorderWidth100 * fscale;

Anforderungen

Anforderung Wert
Unterstützte Mindestversion (Client)
Windows 8.1 [nur Desktop-Apps]
Unterstützte Mindestversion (Server)
Windows Server 2012 R2 [nur Desktop-Apps]
Header
WinUser.h

Siehe auch

DPI_AWARENESS

PROCESS_DPI_AWARENESS