WM_DPICHANGED уменьшение размера окна - PullRequest
0 голосов
/ 27 марта 2020

Настройка:

  • Windows 10 Pro v1903
  • 1-й дисплей: стандартное масштабирование DPI 1920x1080
  • 2-й дисплей: 1920x1080, масштабирование 50% DPI.

У меня проблемы с реализацией некоторых изменений DPI для Windows. Предлагаемый прямоугольник (lParam из WM_DPICHANGED) возвращает значения меньшего окна, как только оно попадет на масштабированный экран.

Если я создаю окно 1280x720 на 1-м дисплее, а затем перемещаю его на второй экран, предлагаемый размер становится 1922x1044. Ширина имеет смысл, поскольку масштабированное разрешение должно составлять 1920x1080. Так что я думаю, что это с учетом пикселей для границ. Однако высота, которую он возвращает в предлагаемом прямоугольнике, меньше, чем должна быть в окне, если он был правильно масштабирован. Теперь, когда он сократился до новой высоты, если я go вернусь к исходному экрану, новый предложенный размер станет 1280x694, мы потеряем исходный размер окна.

Я попытался вручную установить положение окна если учитывать саморассчитываемый масштаб, (width * scale, height * scale), но он не работает должным образом, поскольку он не учитывает границы и строки заголовка правильно в SetWindowPos, так как я предполагаю, что вы ожидаете, что вы включите эти вычисленные размеры.

I также попытались уменьшить размер окна до 1280x690 и переместить его на дисплей 2, а затем обратно на дисплей 1, и размер вернется к исходному размеру. Так что это определенно связано с разрешением окна и целевого дисплея. Я пытался протестировать другие приложения с масштабированием DPI с окном 1280x720 (например, Microsoft Office), и они изменяют размеры окна, переходя к дисплею 2 и возвращаясь к дисплею 1, размер которого является правильным 1280x720 по возвращении, он не испытывает сокращение.

Я что-то упустил? Я использую SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2)

Любая помощь будет принята с благодарностью.

1 Ответ

0 голосов
/ 02 апреля 2020

, но он не работает должным образом, поскольку не учитывает границы и строки заголовка правильно

Вы можете попробовать использовать GetWindowRect, чтобы получить ограничивающий прямоугольник окна. А затем масштабировать прямоугольник:

static float dpi;
BOOL InitInstance(...)
{
    dpi = GetDpiForWindow(hWnd);
    SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2);
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{

    switch (message)
    {
    case WM_DPICHANGED:
        {
            WORD newdpi = HIWORD(wParam); //The values of X-axis and the Y-axis are identical for Windows apps
            float scale = newdpi / dpi;
            dpi = newdpi;
            //RECT* rect = (RECT*)lParam;
            RECT old;
            GetWindowRect(hWnd, &old);
            SetWindowPos(hWnd,
                NULL,
                old.left,
                old.top,
                (old.right - old.left) * scale,
                (old.bottom - old.top) * scale,
                SWP_NOZORDER | SWP_NOACTIVATE);
            return 0;
        }
    return 0;
}
...