From 95f9485ff859e348add33d008aada45d35778725 Mon Sep 17 00:00:00 2001 From: driver1998 Date: Wed, 2 Sep 2020 11:19:09 +0800 Subject: [PATCH] Main UI: HiDPI support --- src/win/86Box.manifest | 38 +++++++----- src/win/win_ui.c | 138 +++++++++++++++++++---------------------- 2 files changed, 86 insertions(+), 90 deletions(-) diff --git a/src/win/86Box.manifest b/src/win/86Box.manifest index ebccd7674..cf0e13b91 100644 --- a/src/win/86Box.manifest +++ b/src/win/86Box.manifest @@ -1,21 +1,27 @@  - - + + - + - + + + + true + permonitorv2 + + diff --git a/src/win/win_ui.c b/src/win/win_ui.c index ef7d6cd89..c72c83b0c 100644 --- a/src/win/win_ui.c +++ b/src/win/win_ui.c @@ -70,6 +70,8 @@ static wchar_t wTitle[512]; static HHOOK hKeyboardHook; static int hook_enabled = 0, manager_wm = 0; static int save_window_pos = 0, pause_state = 0; +static int dpi = 96; +static int padded_frame = 0; static int vis = -1; @@ -111,6 +113,24 @@ int win_get_system_metrics(int index, int dpi) { return GetSystemMetrics(index); } +void +ResizeWindowByClientArea(HWND hwnd, int width, int height) +{ + if (vid_resize || padded_frame) { + int padding = win_get_system_metrics(SM_CXPADDEDBORDER, dpi); + width += (win_get_system_metrics(SM_CXFRAME, dpi) + padding) * 2; + height += (win_get_system_metrics(SM_CYFRAME, dpi) + padding) * 2; + } else { + width += win_get_system_metrics(SM_CXFIXEDFRAME, dpi) * 2; + height += win_get_system_metrics(SM_CYFIXEDFRAME, dpi) * 2; + } + + height += win_get_system_metrics(SM_CYCAPTION, dpi); + height += win_get_system_metrics(SM_CYBORDER, dpi) + win_get_system_metrics(SM_CYMENUSIZE, dpi); + + SetWindowPos(hwnd, NULL, 0, 0, width, height, SWP_NOMOVE); +} + /* Set host cursor visible or not. */ void show_cursor(int val) @@ -328,8 +348,8 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { HMENU hmenu; - int i, sb_borders[3]; - RECT rect; + int i; + RECT rect, *rect_p; int temp_x, temp_y; @@ -430,42 +450,20 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) if (vid_resize) SetWindowLongPtr(hwnd, GWL_STYLE, (WS_OVERLAPPEDWINDOW) | WS_VISIBLE); - else - SetWindowLongPtr(hwnd, GWL_STYLE, (WS_OVERLAPPEDWINDOW & ~WS_SIZEBOX & ~WS_THICKFRAME & ~WS_MAXIMIZEBOX) | WS_VISIBLE); + else + SetWindowLongPtr(hwnd, GWL_STYLE, (WS_OVERLAPPEDWINDOW & ~WS_SIZEBOX & ~WS_MAXIMIZEBOX) | WS_VISIBLE); - SendMessage(hwndSBAR, SB_GETBORDERS, 0, (LPARAM) sb_borders); - - GetWindowRect(hwnd, &rect); - - /* Main Window. */ - if (GetSystemMetrics(SM_CXPADDEDBORDER) == 0) { - /* For platforms that subsystem version < 6.0 (default on mingw/msys2) */ - /* In this case, border sizes are different between resizable and non-resizable window */ - MoveWindow(hwnd, rect.left, rect.top, - unscaled_size_x + (GetSystemMetrics(vid_resize ? SM_CXSIZEFRAME : SM_CXFIXEDFRAME) * 2), - unscaled_size_y + (GetSystemMetrics(vid_resize ? SM_CYSIZEFRAME : SM_CYFIXEDFRAME) * 2) + (GetSystemMetrics(SM_CYBORDER) + GetSystemMetrics(SM_CYMENUSIZE)) + GetSystemMetrics(SM_CYCAPTION) + sbar_height, - TRUE); - } else { - /* For platforms that subsystem version >= 6.0 (default on llvm-mingw, mainly for Windows/ARM) */ - /* In this case, border sizes are the same between resizable and non-resizable window */ - MoveWindow(hwnd, rect.left, rect.top, - unscaled_size_x + ((GetSystemMetrics(SM_CXFRAME) + GetSystemMetrics(SM_CXPADDEDBORDER)) * 2), - unscaled_size_y + ((GetSystemMetrics(SM_CYFRAME) + GetSystemMetrics(SM_CXPADDEDBORDER)) * 2) + (GetSystemMetrics(SM_CYBORDER) + GetSystemMetrics(SM_CYMENUSIZE)) + GetSystemMetrics(SM_CYCAPTION) + sbar_height, - TRUE); - } + /* Main Window. */ + ResizeWindowByClientArea(hwnd, unscaled_size_x, unscaled_size_y + sbar_height); /* Render window. */ MoveWindow(hwndRender, 0, 0, unscaled_size_x, unscaled_size_y, TRUE); GetWindowRect(hwndRender, &rect); /* Status bar. */ - MoveWindow(hwndSBAR, - 0, rect.bottom + GetSystemMetrics(SM_CYEDGE), - unscaled_size_x, 17, TRUE); + MoveWindow(hwndSBAR, 0, rect.bottom, unscaled_size_x, 17, TRUE); if (mouse_capture) { - GetWindowRect(hwndRender, &rect); - ClipCursor(&rect); } @@ -478,6 +476,9 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) EnableMenuItem(hmenu, IDM_VID_SCALE_2X, vid_resize ? MF_GRAYED : MF_ENABLED); EnableMenuItem(hmenu, IDM_VID_SCALE_3X, vid_resize ? MF_GRAYED : MF_ENABLED); EnableMenuItem(hmenu, IDM_VID_SCALE_4X, vid_resize ? MF_GRAYED : MF_ENABLED); + + scrnsz_x = unscaled_size_x; + scrnsz_y = unscaled_size_y; doresize = 1; config_save(); break; @@ -662,12 +663,22 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) case WM_ENTERMENULOOP: break; + case WM_DPICHANGED: + dpi = HIWORD(wParam); + GetWindowRect(hwndSBAR, &rect); + sbar_height = rect.bottom - rect.top; + rect_p = (RECT*)lParam; + if (vid_resize) { + MoveWindow(hwnd, rect_p->left, rect_p->top, rect_p->right - rect_p->left, rect_p->bottom - rect_p->top, TRUE); + } else if (!user_resize) { + doresize = 1; + } + break; + case WM_SIZE: if (user_resize && !vid_resize) break; - SendMessage(hwndSBAR, SB_GETBORDERS, 0, (LPARAM) sb_borders); - temp_x = (lParam & 0xFFFF); temp_y = (lParam >> 16); @@ -684,26 +695,22 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) if (temp_y < 1) temp_y = 1; - if ((temp_x != scrnsz_x) || (temp_y != scrnsz_y)) + if (vid_resize && ((temp_x != scrnsz_x) || (temp_y != scrnsz_y))) { + scrnsz_x = temp_x; + scrnsz_y = temp_y; doresize = 1; + } - scrnsz_x = temp_x; - scrnsz_y = temp_y; - - MoveWindow(hwndRender, 0, 0, scrnsz_x, scrnsz_y, TRUE); + MoveWindow(hwndRender, 0, 0, temp_x, temp_y, TRUE); GetWindowRect(hwndRender, &rect); /* Status bar. */ - MoveWindow(hwndSBAR, - 0, rect.bottom + GetSystemMetrics(SM_CYEDGE), - scrnsz_x, 17, TRUE); + MoveWindow(hwndSBAR, 0, rect.bottom, temp_x, 17, TRUE); - plat_vidsize(scrnsz_x, scrnsz_y); + plat_vidsize(temp_x, temp_y); if (mouse_capture) { - GetWindowRect(hwndRender, &rect); - ClipCursor(&rect); } @@ -1014,6 +1021,19 @@ ui_init(int nCmdShow) ui_window_title(title); + /* Get the current DPI */ + dpi = win_get_dpi(hwndMain); + + /* Check if we have a padded window frame */ + padded_frame = (GetSystemMetrics(SM_CXPADDEDBORDER) != 0); + + /* Create the status bar window. */ + StatusBarCreate(hwndMain, IDC_STATUS, hinstance); + + /* Get the actual height of the status bar */ + GetWindowRect(hwndSBAR, &sbar_rect); + sbar_height = sbar_rect.bottom - sbar_rect.top; + /* Set up main window for resizing if configured. */ if (vid_resize) SetWindowLongPtr(hwnd, GWL_STYLE, @@ -1060,15 +1080,6 @@ ui_init(int nCmdShow) /* Initialize the mouse module. */ win_mouse_init(); - /* Create the status bar window. */ - StatusBarCreate(hwndMain, IDC_STATUS, hinstance); - - /* Get the actual height of the statusbar, - * since that is not something we can change. - */ - GetWindowRect(hwndSBAR, &sbar_rect); - sbar_height = sbar_rect.bottom - sbar_rect.top; - /* * Before we can create the Render window, we first have * to prepare some other things that it depends on. @@ -1262,42 +1273,21 @@ plat_pause(int p) void plat_resize(int x, int y) { - int sb_borders[3]; RECT r; /* First, see if we should resize the UI window. */ if (!vid_resize) { video_wait_for_blit(); - SendMessage(hwndSBAR, SB_GETBORDERS, 0, (LPARAM) sb_borders); - GetWindowRect(hwndMain, &r); - - if (GetSystemMetrics(SM_CXPADDEDBORDER) == 0) { - /* For platforms that subsystem version < 6.0 (gcc on mingw/msys2) */ - /* In this case, border sizes are different between resizable and non-resizable window */ - MoveWindow(hwndMain, r.left, r.top, - x + (GetSystemMetrics(vid_resize ? SM_CXSIZEFRAME : SM_CXFIXEDFRAME) * 2), - y + (GetSystemMetrics(vid_resize ? SM_CYSIZEFRAME : SM_CYFIXEDFRAME) * 2) + (GetSystemMetrics(SM_CYBORDER) + GetSystemMetrics(SM_CYMENUSIZE)) + GetSystemMetrics(SM_CYCAPTION) + sbar_height, - TRUE); - } else { - /* For platforms that subsystem version >= 6.0 (clang/llvm on llvm-mingw, mainly for Windows/ARM) */ - /* In this case, border sizes are the same between resizable and non-resizable window */ - MoveWindow(hwndMain, r.left, r.top, - x + ((GetSystemMetrics(SM_CXFRAME) + GetSystemMetrics(SM_CXPADDEDBORDER)) * 2), - y + ((GetSystemMetrics(SM_CYFRAME) + GetSystemMetrics(SM_CXPADDEDBORDER)) * 2) + (GetSystemMetrics(SM_CYBORDER) + GetSystemMetrics(SM_CYMENUSIZE)) + GetSystemMetrics(SM_CYCAPTION) + sbar_height, - TRUE); - } + ResizeWindowByClientArea(hwndMain, x, y + sbar_height); MoveWindow(hwndRender, 0, 0, x, y, TRUE); GetWindowRect(hwndRender, &r); - MoveWindow(hwndSBAR, - 0, r.bottom + GetSystemMetrics(SM_CYEDGE), - x, 17, TRUE); + MoveWindow(hwndSBAR, 0, y, x, 17, TRUE); if (mouse_capture) { - GetWindowRect(hwndRender, &r); ClipCursor(&r); } }