WM_DPICHANGED メッセージ

ウィンドウの有効 dpi (1 インチあたりのドット数) が変更されたときに送信されます。 DPI は、ウィンドウのスケール係数です。 DPI が変更される可能性がある複数のイベントがあります。 次の一覧は、DPI 変更の考えられる原因を示しています。

  • ウィンドウが、異なる DPI を使用している新しいモニターに移動した。
  • ウィンドウをホストしているモニターの DPI が変更された。

ウィンドウの現在の DPI は常に、WM_DPICHANGED によって送信された最後の DPI と等しくなります。 これは、DPI の変更に対応するスレッドに対してウィンドウを拡大縮小するスケール係数です。

#define WM_DPICHANGED       0x02E0

パラメーター

wParam

wParamHIWORD には、ウィンドウの新しい dpi の Y 軸の値が含まれています。 wParamLOWORD には、ウィンドウの新しい DPI の X 軸の値が含まれています。 たとえば、96、120、144、192 です。 Windows アプリの場合、X 軸と Y 軸の値は同じです。

lParam

新しい DPI に合わせて拡大縮小された現在のウィンドウの推奨されるサイズと位置を提供する RECT 構造体へのポインター。 このメッセージを処理するときに、lParam によって提供される推奨事項に基づいて、アプリがウィンドウの位置とサイズを変更する必要があります。

戻り値

アプリケーションでこのメッセージを処理する場合は、0 を返す必要があります。

解説

このメッセージは、PROCESS_PER_MONITOR_DPI_AWARE アプリケーションまたは DPI_AWARENESS_PER_MONITOR_AWARE スレッドとのみ関連性があります。 最上位のウィンドウまたはプロセスが DPI 非対応またはシステム DPI 対応として実行されている場合は、特定の DPI の変更でこれを受け取る可能性がありますが、そのような状況では無視しても問題ありません。 さまざまな種類の対応の詳細については、「PROCESS_DPI_AWARENESS」と「DPI_AWARENESS」を参照してください。 以前のバージョンの Windows では、アプリケーションのレベルで DPI 対応を関連付ける必要がありました。 それらのアプリでは PROCESS_DPI_AWARENESS を使用します。 現在、DPI 対応は、アプリケーション全体ではなく、スレッドと個々のウィンドウに関連付けられます。 これらのアプリは DPI_AWARENESS を使用します。

X 軸または Y 軸の値は同じなので、それらを使用する必要があるのは、アプリケーションを拡大縮小するときだけです。

このメッセージを正しく処理するには、lParam によって提供される推奨事項に基づいて、SetWindowPos を使用してウィンドウのサイズと位置を変更する必要があります。 これを行わないと、新しいモニター上のその他すべてを基準にしてウィンドウが拡大または縮小されます。 たとえば、ユーザーが複数のモニターを使用していて、96 DPI のモニターから 192 DPI のモニターにウィンドウをドラッグすると、192 DPI のモニター上の他の項目に対してウィンドウは半分のサイズで表示されます。

DPI の基本値は USER_DEFAULT_SCREEN_DPI として定義され、96 に設定されています。 モニターのスケール係数を決定するには、DPI 値を USER_DEFAULT_SCREEN_DPI で除算します。 次の表は、DPI 値のサンプルと、関連するスケール係数を示しています。

DPI 値 スケーリング率
96 100%
120 125%
144 150%
192 200%

次の例では、DPI 変更ハンドラーのサンプルを示します。

    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;
    }

次のコードは、値を 100% (96 DPI) から、g_dpi で定義された任意の DPI に線形にスケーリングします。

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

値をスケーリングする別の方法は、DPI 値をスケール係数に変換して使用する方法です。

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

要件

要件 Value
サポートされている最小のクライアント
Windows 8.1 [デスクトップ アプリのみ]
サポートされている最小のサーバー
Windows Server 2012 R2 [デスクトップ アプリのみ]
ヘッダー
WinUser.h

関連項目

DPI_AWARENESS

PROCESS_DPI_AWARENESS