сообщение WM_DPICHANGED

Отправлено, когда эффективные точки на дюйм (dpi) для окна изменились. DPI — это коэффициент масштабирования окна. Существует несколько событий, которые могут привести к изменению DPI. В следующем списке указаны возможные причины изменения в DPI.

  • Окно перемещается в новый монитор с другим DPI.
  • DPI монитора, в котором размещается окно, изменяется.

Текущий DPI для окна всегда равен последнему DPI, отправленном WM_DPICHANGED. Это коэффициент масштабирования, в который должно быть масштабирование окна для потоков, которые знают об изменениях DPI.

#define WM_DPICHANGED       0x02E0

Параметры

wParam

HIWORD wParam содержит значение оси Y нового dpi окна. LoWORD wParam содержит значение оси X нового DPI окна. Например, 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 определяется как 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) до произвольного DPI, определенного g_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;

Requirements

Требование Значение
Минимальная версия клиента
Windows 8.1 [только классические приложения]
Минимальная версия сервера
Windows Server 2012 R2 [только классические приложения]
Верхний колонтитул
WinUser.h

См. также

DPI_AWARENESS

PROCESS_DPI_AWARENESS