From a3a139e3efe294c40371a70d46bedfe0836f0cbf Mon Sep 17 00:00:00 2001 From: driver1998 Date: Wed, 2 Sep 2020 11:03:14 +0800 Subject: [PATCH] Add PMv2 related APIs --- src/include/86box/win.h | 15 ++++++++++++++ src/win/win_ui.c | 44 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+) diff --git a/src/include/86box/win.h b/src/include/86box/win.h index 5537f4f30..9d3e8724b 100644 --- a/src/include/86box/win.h +++ b/src/include/86box/win.h @@ -33,6 +33,19 @@ # include "resource.h" # undef BITMAP +/* DPI Awareness Context, copied from MinGW-w64 windef.h */ +#ifndef _DPI_AWARENESS_CONTEXTS_ +DECLARE_HANDLE(DPI_AWARENESS_CONTEXT); +#define DPI_AWARENESS_CONTEXT_UNAWARE ((DPI_AWARENESS_CONTEXT)-1) +#define DPI_AWARENESS_CONTEXT_SYSTEM_AWARE ((DPI_AWARENESS_CONTEXT)-2) +#define DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE ((DPI_AWARENESS_CONTEXT)-3) +#define DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 ((DPI_AWARENESS_CONTEXT)-4) +#define DPI_AWARENESS_CONTEXT_UNAWARE_GDISCALED ((DPI_AWARENESS_CONTEXT)-5) +#endif + +#ifndef WM_DPICHANGED_AFTERPARENT +#define WM_DPICHANGED_AFTERPARENT 0x02E3 +#endif /* Class names and such. */ #define CLASS_NAME L"86BoxMainWnd" @@ -119,6 +132,8 @@ extern void win_joystick_handle(PRAWINPUT raw); extern void win_notify_dlg_open(void); extern void win_notify_dlg_closed(void); +extern int win_get_dpi(HWND hwnd); +extern int win_get_system_metrics(int i, int dpi); extern LPARAM win_get_string(int id); diff --git a/src/win/win_ui.c b/src/win/win_ui.c index edcf91385..ef7d6cd89 100644 --- a/src/win/win_ui.c +++ b/src/win/win_ui.c @@ -37,6 +37,7 @@ #include <86box/vid_ega.h> // for update_overscan #include <86box/plat.h> #include <86box/plat_midi.h> +#include <86box/plat_dynld.h> #include <86box/ui.h> #include <86box/win.h> #include <86box/version.h> @@ -73,6 +74,43 @@ static int save_window_pos = 0, pause_state = 0; static int vis = -1; +/* Per Monitor DPI Aware v2 APIs, Windows 10 v1703+ */ +void* user32_handle = NULL; +static UINT (WINAPI *pGetDpiForWindow)(HWND); +static UINT (WINAPI *pGetSystemMetricsForDpi)(int i, UINT dpi); +static DPI_AWARENESS_CONTEXT (WINAPI *pGetWindowDpiAwarenessContext)(HWND); +static BOOL (WINAPI *pAreDpiAwarenessContextsEqual)(DPI_AWARENESS_CONTEXT A, DPI_AWARENESS_CONTEXT B); +static dllimp_t user32_imports[] = { +{ "GetDpiForWindow", &pGetDpiForWindow }, +{ "GetSystemMetricsForDpi", &pGetSystemMetricsForDpi }, +{ "GetWindowDpiAwarenessContext", &pGetWindowDpiAwarenessContext }, +{ "AreDpiAwarenessContextsEqual", &pAreDpiAwarenessContextsEqual }, +{ NULL, NULL } +}; + +int +win_get_dpi(HWND hwnd) { + if (user32_handle != NULL) { + return pGetDpiForWindow(hwnd); + } else { + HDC dc = GetDC(hwnd); + UINT dpi = GetDeviceCaps(dc, LOGPIXELSX); + ReleaseDC(hwnd, dc); + return dpi; + } +} + +int win_get_system_metrics(int index, int dpi) { + if (user32_handle != NULL) { + /* Only call GetSystemMetricsForDpi when we are using PMv2 */ + DPI_AWARENESS_CONTEXT c = pGetWindowDpiAwarenessContext(hwndMain); + if (pAreDpiAwarenessContextsEqual(c, DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2)) + return pGetSystemMetricsForDpi(index, dpi); + } + + return GetSystemMetrics(index); +} + /* Set host cursor visible or not. */ void show_cursor(int val) @@ -894,6 +932,9 @@ ui_init(int nCmdShow) TASKDIALOGCONFIG tdconfig = {0}; TASKDIALOG_BUTTON tdbuttons[] = {{IDCANCEL, MAKEINTRESOURCE(IDS_2119)}}; + /* Load DPI related Windows 10 APIs */ + user32_handle = dynld_module("user32.dll", user32_imports); + /* Set up TaskDialog configuration. */ tdconfig.cbSize = sizeof(tdconfig); tdconfig.dwFlags = TDF_ENABLE_HYPERLINKS; @@ -1137,6 +1178,9 @@ ui_init(int nCmdShow) discord_close(); #endif + if (user32_handle != NULL) + dynld_close(user32_handle); + return(messages.wParam); }