WM_DPICHANGED訊息
當視窗的有效點數 (dpi) 變更時傳送。 DPI 是視窗的縮放比例。 有多個事件可能會導致 DPI 變更。 下列清單指出 DPI 變更的可能原因。
- 視窗會移至具有不同 DPI 的新監視器。
- 裝載視窗之監視器的 DPI 會變更。
視窗目前的 DPI 一律等於WM_DPICHANGED傳送的最後一個 DPI。 這是視窗應該針對知道 DPI 變更的線程調整為的縮放比例。
#define WM_DPICHANGED 0x02E0
參數
-
wParam
-
wParam 的 HIWORD 包含視窗新 dpi 的 Y 軸值。 wParam 的 LOWORD 包含視窗新 DPI 的 X 軸值。 例如,96、120、144 或 192。 X 軸和 Y 軸的值與 Windows 應用程式的值相同。
-
lParam
-
RECT 結構的指標,提供針對新 DPI 調整之目前窗口的建議大小和位置。 預期應用程式會在處理此訊息時,根據 lParam 所提供的建議,重新調整視窗位置及重設大小。
傳回值
如果應用程式處理此訊息,它應該會傳回零。
備註
此訊息僅與 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 的基底值定義為設定為 96 的 USER_DEFAULT_SCREEN_DPI。 若要判斷監視器的縮放比例,請採用 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;
需求
需求 | 值 |
---|---|
最低支援的用戶端 |
Windows 8.1 [僅限傳統型應用程式] |
最低支援的伺服器 |
Windows Server 2012 R2 [僅限傳統型應用程式] |
頁首 |
|