]> granicus.if.org Git - nethack/commitdiff
Splash dialog and main window handle dpi change notifications.
authorBart House <bart@barthouse.com>
Mon, 3 Dec 2018 02:09:34 +0000 (18:09 -0800)
committerBart House <bart@barthouse.com>
Mon, 3 Dec 2018 02:09:34 +0000 (18:09 -0800)
sys/winnt/win10.c
sys/winnt/win10.h
win/win32/mhfont.c
win/win32/mhfont.h
win/win32/mhmain.c
win/win32/mhmap.c
win/win32/mhsplash.c

index 3ec62a943cdd3287cb283bf73ee9d7581eb5b6ea..48f5bb98a24ec665514dacd12a456eccbdb4dbd6 100644 (file)
@@ -45,17 +45,6 @@ void win10_init()
 
 }
 
-void win10_monitor_size(HWND hWnd, int * width, int * height)
-{
-    HMONITOR monitor = MonitorFromWindow(hWnd, MONITOR_DEFAULTTONEAREST);
-    MONITORINFO info;
-    info.cbSize = sizeof(MONITORINFO);
-    BOOL success = GetMonitorInfo(monitor, &info);
-    nhassert(success);
-    *width = info.rcMonitor.right - info.rcMonitor.left;
-    *height = info.rcMonitor.bottom - info.rcMonitor.top;
-}
-
 int win10_monitor_dpi(HWND hWnd)
 {
     UINT monitorDpi = 96;
@@ -79,5 +68,14 @@ double win10_monitor_scale(HWND hWnd)
 void win10_monitor_info(HWND hWnd, MonitorInfo * monitorInfo)
 {
     monitorInfo->scale = win10_monitor_scale(hWnd);
-    win10_monitor_size(hWnd, &monitorInfo->width, &monitorInfo->height);
+
+    HMONITOR monitor = MonitorFromWindow(hWnd, MONITOR_DEFAULTTONEAREST);
+    MONITORINFO info;
+    info.cbSize = sizeof(MONITORINFO);
+    BOOL success = GetMonitorInfo(monitor, &info);
+    nhassert(success);
+    monitorInfo->width = info.rcMonitor.right - info.rcMonitor.left;
+    monitorInfo->height = info.rcMonitor.bottom - info.rcMonitor.top;
+    monitorInfo->left = info.rcMonitor.left;
+    monitorInfo->top = info.rcMonitor.top;
 }
index 1bf4fce33221888163f4dd9aeda5b805bf199177..458e6991deeebc4ccaf20a2f6d896db566d4c838 100644 (file)
@@ -23,6 +23,8 @@ typedef struct {
     double  scale;  // dpi of monitor / 96
     int     width;  // in pixels
     int     height; // in pixels
+    int     top; // in desktop coordinate pixel space
+    int     left; // in desktop coordinate pixel space
 } MonitorInfo;
 
 extern Win10 gWin10;
index 9f00df770a89bda908184fba0c2dedafb9c667e4..18e09082e8981ad9adefa343216cc708d333c3e6 100644 (file)
 
 static cached_font font_table[MAXFONTS];
 static int font_table_size = 0;
-HFONT version_splash_font;
 
 #define NHFONT_CODE(win, attr) (((attr & 0xFF) << 8) | (win_type & 0xFF))
 
 static void __cdecl font_table_cleanup(void);
 
-void
-mswin_init_splashfonts(HWND hWnd)
+HFONT
+mswin_create_splashfont(HWND hWnd)
 {
     HDC hdc = GetDC(hWnd);
     double scale = win10_monitor_scale(hWnd);
@@ -40,14 +39,10 @@ mswin_init_splashfonts(HWND hWnd)
     lgfnt.lfQuality = DEFAULT_QUALITY;           // output quality
     lgfnt.lfPitchAndFamily = DEFAULT_PITCH;      // pitch and family
     NH_A2W("Times New Roman", lgfnt.lfFaceName, LF_FACESIZE);
-    version_splash_font = CreateFontIndirect(&lgfnt);
+    HFONT font = CreateFontIndirect(&lgfnt);
     ReleaseDC(hWnd, hdc);
-}
 
-void
-mswin_destroy_splashfonts()
-{
-    DeleteObject(version_splash_font);
+    return font;
 }
 
 BOOL 
index 1e472b080ee0efc273384b4bf06e50e08ab7c109..20b5d1400a8e5e20cf3280489644fe9ac325f2b9 100644 (file)
@@ -19,8 +19,7 @@ typedef struct cached_font {
 
 BOOL mswin_font_supports_unicode(HFONT hFont);
 cached_font * mswin_get_font(int win_type, int attr, HDC hdc, BOOL replace);
-void mswin_init_splashfonts(HWND hWnd);
-void mswin_destroy_splashfonts(void);
+HFONT mswin_create_splashfont(HWND hWnd);
 UINT mswin_charset(void);
 
 #endif /* MSWINFont_h */
index 8645a5d197f79aa0a19b6ab53ed1971e640ca6b3..a71534703fe7e945f71c5c0f772cb3046e0926e3 100644 (file)
@@ -501,6 +501,10 @@ MainWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
         exit(1);
         break;
 
+    case WM_DPICHANGED: {
+        mswin_layout_main_window(NULL);
+    } break;
+
     default:
         return DefWindowProc(hWnd, message, wParam, lParam);
     }
index 49c2a4e4e355d889fba8098b1f17592e0bcce702..28989d40bd2bd831e34cf929ead27dbed4a8ae25 100644 (file)
@@ -576,6 +576,13 @@ MapWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
         dirty(data, data->xCur, data->yCur);
         break;
 
+    case WM_DPICHANGED: {
+        RECT rt;
+        GetWindowRect(hWnd, &rt);
+        ScreenToClient(GetNHApp()->hMainWnd, (LPPOINT)&rt);
+        ScreenToClient(GetNHApp()->hMainWnd, ((LPPOINT)&rt) + 1);
+        mswin_update_window_placement(NHW_MAP, &rt);
+    } break;
 
     default:
         return DefWindowProc(hWnd, message, wParam, lParam);
index 734e44bb3bd91ec9806e3107efa1a2eaeff829ec..0271c8081fa23732b800d530f6fe624b6ef7157b 100644 (file)
@@ -25,26 +25,97 @@ INT_PTR CALLBACK NHSplashWndProc(HWND, UINT, WPARAM, LPARAM);
 #define SPLASH_VERSION_X_96DPI 280
 #define SPLASH_VERSION_Y_96DPI 0
 
-extern HFONT version_splash_font;
-
 typedef struct {
+    int boarder_width;
+    int boarder_height;
+    int client_width;
+    int client_height;
+    int ok_control_width;
+    int ok_control_height;
+    int ok_control_offset_x;
+    int ok_control_offset_y;
+    int text_control_width;
+    int text_control_height;
+    int text_control_offset_x;
+    int text_control_offset_y;
+    int window_width;
+    int window_height;
     int width;
     int height;
-    int offsetX;
-    int offsetY;
-    int versionX;
-    int versionY;
+    int offset_x;
+    int offset_y;
+    int version_x;
+    int version_y;
+    HFONT hFont;
 } SplashData;
 
+static void
+mswin_set_splash_data(HWND hWnd, SplashData * sd, double scale)
+{
+    RECT client_rect;
+    RECT window_rect;
+    RECT ok_control_rect;
+    RECT text_control_rect;
+
+    GetClientRect(hWnd, &client_rect);
+    GetWindowRect(hWnd, &window_rect);
+    GetWindowRect(GetDlgItem(hWnd, IDOK), &ok_control_rect);
+    GetWindowRect(GetDlgItem(hWnd, IDC_EXTRAINFO), &text_control_rect);
+
+    sd->boarder_width = (window_rect.right - window_rect.left) -
+                                (client_rect.right - client_rect.left);
+    sd->boarder_height = (window_rect.bottom - window_rect.top) -
+        (client_rect.bottom - client_rect.top);
+
+    sd->ok_control_width = ok_control_rect.right - ok_control_rect.left;
+    sd->ok_control_height = ok_control_rect.bottom - ok_control_rect.top;
+
+    sd->width = (int)(scale * SPLASH_WIDTH_96DPI);
+    sd->height = (int)(scale * SPLASH_HEIGHT_96DPI);
+    sd->offset_x = (int)(scale * SPLASH_OFFSET_X_96DPI);
+    sd->offset_y = (int)(scale * SPLASH_OFFSET_Y_96DPI);
+    sd->version_x = (int)(scale * SPLASH_VERSION_X_96DPI);
+    sd->version_y = (int)(scale * SPLASH_VERSION_Y_96DPI);
+
+    sd->client_width = sd->width + sd->offset_x * 2;
+    sd->client_height = sd->height + sd->ok_control_height +
+        sd->offset_y * 3;
+
+    sd->window_width = sd->client_width + sd->boarder_width;
+    sd->window_height = sd->client_height + sd->boarder_height;
+
+    sd->ok_control_offset_x = (sd->client_width - sd->ok_control_width) / 2;
+    sd->ok_control_offset_y = sd->client_height - sd->ok_control_height - sd->offset_y;
+
+    sd->text_control_width = sd->client_width - sd->offset_x * 2;
+    sd->text_control_height = text_control_rect.bottom - text_control_rect.top;
+
+    sd->text_control_offset_x = sd->offset_x;
+    sd->text_control_offset_y = sd->ok_control_offset_y - sd->offset_y -
+                               sd->text_control_height;
+
+    if (sd->hFont != NULL)
+        DeleteObject(sd->hFont);
+
+    sd->hFont = mswin_create_splashfont(hWnd);
+
+    MoveWindow(hWnd, window_rect.left, window_rect.top,
+        sd->window_width, sd->window_height, TRUE);
+
+    MoveWindow(GetDlgItem(hWnd, IDOK),
+        sd->ok_control_offset_x, sd->ok_control_offset_y,
+        sd->ok_control_width, sd->ok_control_height, TRUE);
+
+    MoveWindow(GetDlgItem(hWnd, IDC_EXTRAINFO),
+        sd->text_control_offset_x, sd->text_control_offset_y,
+        sd->text_control_width, sd->text_control_height, TRUE);
+
+}
+
 void
 mswin_display_splash_window(BOOL show_ver)
 {
     MSG msg;
-    int left, top;
-    RECT splashrt;
-    RECT clientrt;
-    RECT controlrt;
-    int buttop;
     strbuf_t strbuf;
 
     strbuf_init(&strbuf);
@@ -56,57 +127,18 @@ mswin_display_splash_window(BOOL show_ver)
 
     MonitorInfo monitorInfo;
     win10_monitor_info(hWnd, &monitorInfo);
-    
-    SplashData splashData;
 
-    splashData.width = (int) (monitorInfo.scale * SPLASH_WIDTH_96DPI);
-    splashData.height = (int) (monitorInfo.scale * SPLASH_HEIGHT_96DPI);
-    splashData.offsetX = (int) (monitorInfo.scale * SPLASH_OFFSET_X_96DPI);
-    splashData.offsetY = (int) (monitorInfo.scale * SPLASH_OFFSET_Y_96DPI);
-    splashData.versionX = (int) (monitorInfo.scale * SPLASH_VERSION_X_96DPI);
-    splashData.versionY = (int) (monitorInfo.scale * SPLASH_VERSION_Y_96DPI);
+    SplashData splashData;
+    memset(&splashData, 0, sizeof(splashData));
+    mswin_set_splash_data(hWnd, &splashData, monitorInfo.scale);
  
     SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR) &splashData);
     
-    mswin_init_splashfonts(hWnd);
     GetNHApp()->hPopupWnd = hWnd;
-    /* Get control size */
-    GetWindowRect(GetDlgItem(hWnd, IDOK), &controlrt);
-    controlrt.right -= controlrt.left;
-    controlrt.bottom -= controlrt.top;
-    /* Get current client area */
-    GetClientRect(hWnd, &clientrt);
-    /* Get window size */
-    GetWindowRect(hWnd, &splashrt);
-    splashrt.right -= splashrt.left;
-    splashrt.bottom -= splashrt.top;
-    /* Get difference between requested client area and current value */
-    splashrt.right += splashData.width + splashData.offsetX * 2
-                   - clientrt.right;
-    splashrt.bottom += splashData.height + controlrt.bottom 
-                    + splashData.offsetY * 3
-                    - clientrt.bottom;
-    /* Place the window centered */
-    /* On the screen, not on the parent window */
-    left = (monitorInfo.width - splashrt.right) / 2;
-    top = (monitorInfo.height - splashrt.bottom) / 2;
-    MoveWindow(hWnd, left, top, splashrt.right, splashrt.bottom, TRUE);
-    /* Place the OK control */
-    GetClientRect(hWnd, &clientrt);
-    MoveWindow(GetDlgItem(hWnd, IDOK),
-               (clientrt.right - clientrt.left - controlrt.right) / 2,
-               clientrt.bottom - controlrt.bottom - splashData.offsetY,
-               controlrt.right, controlrt.bottom, TRUE);
-    buttop = clientrt.bottom - controlrt.bottom - splashData.offsetY;
-    /* Place the text control */
-    GetWindowRect(GetDlgItem(hWnd, IDC_EXTRAINFO), &controlrt);
-    controlrt.right -= controlrt.left;
-    controlrt.bottom -= controlrt.top;
-    GetClientRect(hWnd, &clientrt);
-    MoveWindow(GetDlgItem(hWnd, IDC_EXTRAINFO),
-        clientrt.left + splashData.offsetX,
-        buttop - controlrt.bottom - splashData.offsetY,
-        clientrt.right - 2 * splashData.offsetX, controlrt.bottom, TRUE);
+
+    int left = monitorInfo.left + (monitorInfo.width - splashData.window_width) / 2;
+    int top = monitorInfo.top + (monitorInfo.height - splashData.window_height) / 2;
+    MoveWindow(hWnd, left, top, splashData.window_width, splashData.window_height, TRUE);
 
     /* Fill the text control */
     strbuf_reserve(&strbuf, BUFSIZ);
@@ -164,7 +196,7 @@ mswin_display_splash_window(BOOL show_ver)
     }
 
     GetNHApp()->hPopupWnd = NULL;
-    mswin_destroy_splashfonts();
+    DeleteObject(splashData.hFont);
 }
 
 INT_PTR CALLBACK
@@ -200,7 +232,7 @@ NHSplashWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
         SetBkMode(hdc, OPAQUE);
         OldBitmap = SelectObject(hdcBitmap, GetNHApp()->bmpSplash);
         (*GetNHApp()->lpfnTransparentBlt)(hdc,
-            splashData->offsetX, splashData->offsetY,
+            splashData->offset_x, splashData->offset_y,
             splashData->width, splashData->height, hdcBitmap,
             0, 0, SPLASH_WIDTH_96DPI, SPLASH_HEIGHT_96DPI,
             TILE_BK_COLOR);
@@ -212,11 +244,11 @@ NHSplashWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
         /* Print version number */
 
         SetTextColor(hdc, RGB(0, 0, 0));
-        rt.right = rt.left = splashData->offsetX + splashData->versionX;
-        rt.bottom = rt.top = splashData->offsetY + splashData->versionY;
+        rt.right = rt.left = splashData->offset_x + splashData->version_x;
+        rt.bottom = rt.top = splashData->offset_y + splashData->version_y;
         Sprintf(VersionString, "%d.%d.%d", VERSION_MAJOR, VERSION_MINOR,
                 PATCHLEVEL);
-        OldFont = SelectObject(hdc, version_splash_font);
+        OldFont = SelectObject(hdc, splashData->hFont);
         DrawText(hdc, VersionString, strlen(VersionString), &rt,
                  DT_LEFT | DT_NOPREFIX | DT_CALCRECT);
         DrawText(hdc, VersionString, strlen(VersionString), &rt,
@@ -235,6 +267,18 @@ NHSplashWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
             return TRUE;
         }
         break;
+
+    case WM_DPICHANGED: {
+        SplashData *splashData = (SplashData *)GetWindowLongPtr(hWnd, GWLP_USERDATA);
+
+        MonitorInfo monitorInfo;
+        win10_monitor_info(hWnd, &monitorInfo);
+
+        mswin_set_splash_data(hWnd, splashData, monitorInfo.scale);
+
+        InvalidateRect(hWnd, NULL, TRUE);
+    } break;
+
     }
     return FALSE;
 }