Масштабирование не-клиентской области для поддержки высокого разрешения для каждого монитора в приложении, поддерживающем Windows 8.1 - PullRequest
0 голосов
/ 09 января 2019

Я занимаюсь разработкой приложения, которое работает на Windows 10 и 8.1 и столкнулось с проблемой масштабирования не клиентской области (строка меню, строка заголовка) при перемещении между мониторами с различным DPI. Клиентская область обрабатывается, но не-клиентская область выходит за рамки. Для DPI Awareness установлено значение PerMonitorAware (v1, поскольку v2 недоступна в Windows 8.1).

Функция EnableNonClientDpiScaling делает именно то, что мне нужно (это принятый ответ на все подобные вопросы) - увы, это только часть API от Windows 10 на.

Есть ли способ вручную обработать это без вышеупомянутой функции - чтобы сохранить поддержку Windows 8.1? Или поддержка Windows 8.1 означает, что невозможно изменить размер области, не являющейся клиентом, при перемещении между экранами с различным DPI?

Ответы [ 2 ]

0 голосов
/ 09 января 2019

Благодаря Андерсу, GetProcAddress было именно тем, что я искал. Хотя это не решает проблему изменения размера области, не связанной с клиентом, в Win 8.1 (кажется, что на самом деле нет ничего, кроме рисования всего себя), это позволяет установить самую последнюю DPI_AWARENESS_CONTEXT для Win 10:

// the following sets PROCESS_PER_MONITOR_AWARE_V2 on Win10 and
// reverts to PROCESS_PER_MONITOR_AWARE on Win 8.1

typedef BOOL(__stdcall *SetProcessDpiAwarenessContext)(DPI_AWARENESS_CONTEXT);
SetProcessDpiAwarenessContext dpi_call = nullptr;
dpi_call = reinterpret_cast<SetProcessDpiAwarenessContext>(GetProcAddress(
    GetModuleHandle(TEXT("User32.dll")),
    "SetProcessDpiAwarenessContext"));
if (dpi_call != nullptr) {
    if (!(*dpi_call)((DPI_AWARENESS_CONTEXT) - 4))
        throw std::runtime_error("Unable to set DPI aware app.");
} else {
    if (SetProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE) != S_OK)
        throw std::runtime_error("Unable to set DPI aware app.");
}
0 голосов
/ 09 января 2019

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

Позвоните EnableNonClientDpiScaling в тех версиях, где оно доступно (GetProcAddress или эквивалент на любом языке, который вы используете).

То, как работает новый элемент манифеста осведомленности в Windows 10, означает, что вы можете использовать Per-Monitor v2 там, где он поддерживается (1703 и более поздние версии), а также PMv1, System или Unaware в более старых сборках. PMv2 обеспечивает автоматическое масштабирование диалогов DialogBox.

...