comparison src/gui_w32.c @ 27160:4482dd5f8869 v8.2.4109

patch 8.2.4109: MS-Windows: high dpi support is outdated Commit: https://github.com/vim/vim/commit/c81e9bf4f07d350b860b934aa6bf0c2a7c91d07e Author: K.Takata <kentkt@csc.jp> Date: Sun Jan 16 14:15:49 2022 +0000 patch 8.2.4109: MS-Windows: high dpi support is outdated Problem: MS-Windows: high dpi support is outdated. Solution: Improve High DPI support by using PerMonitorV2. (closes https://github.com/vim/vim/issues/9525, closes #3102)
author Bram Moolenaar <Bram@vim.org>
date Sun, 16 Jan 2022 15:30:04 +0100
parents ac75c145f0a9
children 6837d2c14dee
comparison
equal deleted inserted replaced
27159:d0a330b84595 27160:4482dd5f8869
38 static void directx_binddc(void); 38 static void directx_binddc(void);
39 #endif 39 #endif
40 40
41 #ifdef FEAT_MENU 41 #ifdef FEAT_MENU
42 static int gui_mswin_get_menu_height(int fix_window); 42 static int gui_mswin_get_menu_height(int fix_window);
43 #else
44 # define gui_mswin_get_menu_height(fix_window) 0
43 #endif 45 #endif
44 46
45 #if defined(FEAT_RENDER_OPTIONS) || defined(PROTO) 47 #if defined(FEAT_RENDER_OPTIONS) || defined(PROTO)
46 int 48 int
47 gui_mch_set_rendering_options(char_u *s) 49 gui_mch_set_rendering_options(char_u *s)
226 # define WM_XBUTTONDOWN 0x020B 228 # define WM_XBUTTONDOWN 0x020B
227 # define WM_XBUTTONUP 0x020C 229 # define WM_XBUTTONUP 0x020C
228 # define WM_XBUTTONDBLCLK 0x020D 230 # define WM_XBUTTONDBLCLK 0x020D
229 # define MK_XBUTTON1 0x0020 231 # define MK_XBUTTON1 0x0020
230 # define MK_XBUTTON2 0x0040 232 # define MK_XBUTTON2 0x0040
233 #endif
234
235 #ifndef WM_DPICHANGED
236 # define WM_DPICHANGED 0x02E0
231 #endif 237 #endif
232 238
233 #ifdef PROTO 239 #ifdef PROTO
234 /* 240 /*
235 * Define a few things for generating prototypes. This is just to avoid 241 * Define a few things for generating prototypes. This is just to avoid
312 static int s_busy_processing = FALSE; 318 static int s_busy_processing = FALSE;
313 319
314 static int destroying = FALSE; // call DestroyWindow() ourselves 320 static int destroying = FALSE; // call DestroyWindow() ourselves
315 321
316 #ifdef MSWIN_FIND_REPLACE 322 #ifdef MSWIN_FIND_REPLACE
317 static UINT s_findrep_msg = 0; // set in gui_w[16/32].c 323 static UINT s_findrep_msg = 0;
318 static FINDREPLACEW s_findrep_struct; 324 static FINDREPLACEW s_findrep_struct;
319 static HWND s_findrep_hwnd = NULL; 325 static HWND s_findrep_hwnd = NULL;
320 static int s_findrep_is_find; // TRUE for find dialog, FALSE 326 static int s_findrep_is_find; // TRUE for find dialog, FALSE
321 // for find/replace dialog 327 // for find/replace dialog
322 #endif 328 #endif
355 #ifdef GLOBAL_IME 361 #ifdef GLOBAL_IME
356 # define MyTranslateMessage(x) global_ime_TranslateMessage(x) 362 # define MyTranslateMessage(x) global_ime_TranslateMessage(x)
357 #else 363 #else
358 # define MyTranslateMessage(x) TranslateMessage(x) 364 # define MyTranslateMessage(x) TranslateMessage(x)
359 #endif 365 #endif
366
367 #ifndef _DPI_AWARENESS_CONTEXTS_
368 typedef HANDLE DPI_AWARENESS_CONTEXT;
369
370 typedef enum DPI_AWARENESS {
371 DPI_AWARENESS_INVALID = -1,
372 DPI_AWARENESS_UNAWARE = 0,
373 DPI_AWARENESS_SYSTEM_AWARE = 1,
374 DPI_AWARENESS_PER_MONITOR_AWARE = 2
375 } DPI_AWARENESS;
376
377 # define DPI_AWARENESS_CONTEXT_UNAWARE ((DPI_AWARENESS_CONTEXT)-1)
378 # define DPI_AWARENESS_CONTEXT_SYSTEM_AWARE ((DPI_AWARENESS_CONTEXT)-2)
379 # define DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE ((DPI_AWARENESS_CONTEXT)-3)
380 # define DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 ((DPI_AWARENESS_CONTEXT)-4)
381 # define DPI_AWARENESS_CONTEXT_UNAWARE_GDISCALED ((DPI_AWARENESS_CONTEXT)-5)
382 #endif
383
384 #define DEFAULT_DPI 96
385 static int s_dpi = DEFAULT_DPI;
386 static BOOL s_in_dpichanged = FALSE;
387 static DPI_AWARENESS s_process_dpi_aware = DPI_AWARENESS_INVALID;
388
389 static UINT (WINAPI *pGetDpiForSystem)(void) = NULL;
390 static UINT (WINAPI *pGetDpiForWindow)(HWND hwnd) = NULL;
391 static int (WINAPI *pGetSystemMetricsForDpi)(int, UINT) = NULL;
392 //static INT (WINAPI *pGetWindowDpiAwarenessContext)(HWND hwnd) = NULL;
393 static DPI_AWARENESS_CONTEXT (WINAPI *pSetThreadDpiAwarenessContext)(DPI_AWARENESS_CONTEXT dpiContext) = NULL;
394 static DPI_AWARENESS (WINAPI *pGetAwarenessFromDpiAwarenessContext)(DPI_AWARENESS_CONTEXT) = NULL;
395
396 static UINT WINAPI
397 stubGetDpiForSystem(void)
398 {
399 HWND hwnd = GetDesktopWindow();
400 HDC hdc = GetWindowDC(hwnd);
401 UINT dpi = GetDeviceCaps(hdc, LOGPIXELSY);
402 ReleaseDC(hwnd, hdc);
403 return dpi;
404 }
405
406 static int WINAPI
407 stubGetSystemMetricsForDpi(int nIndex, UINT dpi)
408 {
409 return GetSystemMetrics(nIndex);
410 }
411
412 static int
413 adjust_fontsize_by_dpi(int size)
414 {
415 return size * s_dpi / (int)pGetDpiForSystem();
416 }
417
418 static int
419 adjust_by_system_dpi(int size)
420 {
421 return size * (int)pGetDpiForSystem() / DEFAULT_DPI;
422 }
360 423
361 #if defined(FEAT_DIRECTX) 424 #if defined(FEAT_DIRECTX)
362 static int 425 static int
363 directx_enabled(void) 426 directx_enabled(void)
364 { 427 {
1346 SetWindowPos(s_textArea, NULL, x, y, w, h, SWP_NOZORDER | SWP_NOACTIVATE); 1409 SetWindowPos(s_textArea, NULL, x, y, w, h, SWP_NOZORDER | SWP_NOACTIVATE);
1347 1410
1348 #ifdef FEAT_TOOLBAR 1411 #ifdef FEAT_TOOLBAR
1349 if (vim_strchr(p_go, GO_TOOLBAR) != NULL) 1412 if (vim_strchr(p_go, GO_TOOLBAR) != NULL)
1350 SendMessage(s_toolbarhwnd, WM_SIZE, 1413 SendMessage(s_toolbarhwnd, WM_SIZE,
1351 (WPARAM)0, (LPARAM)(w + ((long)(TOOLBAR_BUTTON_HEIGHT+8)<<16))); 1414 (WPARAM)0, MAKELPARAM(w, gui.toolbar_height));
1352 #endif 1415 #endif
1353 #if defined(FEAT_GUI_TABLINE) 1416 #if defined(FEAT_GUI_TABLINE)
1354 if (showing_tabline) 1417 if (showing_tabline)
1355 { 1418 {
1356 int top = 0; 1419 int top = 0;
1357 RECT rect; 1420 RECT rect;
1358 1421
1359 # ifdef FEAT_TOOLBAR 1422 # ifdef FEAT_TOOLBAR
1360 if (vim_strchr(p_go, GO_TOOLBAR) != NULL) 1423 if (vim_strchr(p_go, GO_TOOLBAR) != NULL)
1361 top = TOOLBAR_BUTTON_HEIGHT + TOOLBAR_BORDER_HEIGHT; 1424 top = gui.toolbar_height;
1362 # endif 1425 # endif
1363 GetClientRect(s_hwnd, &rect); 1426 GetClientRect(s_hwnd, &rect);
1364 MoveWindow(s_tabhwnd, 0, top, rect.right, gui.tabline_height, TRUE); 1427 MoveWindow(s_tabhwnd, 0, top, rect.right, gui.tabline_height, TRUE);
1365 } 1428 }
1366 #endif 1429 #endif
1412 int xpad; 1475 int xpad;
1413 1476
1414 GetWindowRect(s_textArea, &rcTxt); 1477 GetWindowRect(s_textArea, &rcTxt);
1415 GetWindowRect(s_hwnd, &rcWnd); 1478 GetWindowRect(s_hwnd, &rcWnd);
1416 xpad = rcWnd.right - rcTxt.right - gui.scrollbar_width 1479 xpad = rcWnd.right - rcTxt.right - gui.scrollbar_width
1417 - GetSystemMetrics(SM_CXFRAME) 1480 - pGetSystemMetricsForDpi(SM_CXFRAME, s_dpi)
1418 - GetSystemMetrics(SM_CXPADDEDBORDER); 1481 - pGetSystemMetricsForDpi(SM_CXPADDEDBORDER, s_dpi);
1419 return (xpad < 0) ? 0 : xpad; 1482 return (xpad < 0) ? 0 : xpad;
1420 } 1483 }
1421 1484
1422 int 1485 int
1423 gui_mch_get_scrollbar_ypadding(void) 1486 gui_mch_get_scrollbar_ypadding(void)
1426 int ypad; 1489 int ypad;
1427 1490
1428 GetWindowRect(s_textArea, &rcTxt); 1491 GetWindowRect(s_textArea, &rcTxt);
1429 GetWindowRect(s_hwnd, &rcWnd); 1492 GetWindowRect(s_hwnd, &rcWnd);
1430 ypad = rcWnd.bottom - rcTxt.bottom - gui.scrollbar_height 1493 ypad = rcWnd.bottom - rcTxt.bottom - gui.scrollbar_height
1431 - GetSystemMetrics(SM_CYFRAME) 1494 - pGetSystemMetricsForDpi(SM_CYFRAME, s_dpi)
1432 - GetSystemMetrics(SM_CXPADDEDBORDER); 1495 - pGetSystemMetricsForDpi(SM_CXPADDEDBORDER, s_dpi);
1433 return (ypad < 0) ? 0 : ypad; 1496 return (ypad < 0) ? 0 : ypad;
1434 } 1497 }
1435 1498
1436 void 1499 void
1437 gui_mch_create_scrollbar( 1500 gui_mch_create_scrollbar(
1465 return &wp->w_scrollbars[SBAR_RIGHT]; 1528 return &wp->w_scrollbars[SBAR_RIGHT];
1466 } 1529 }
1467 return NULL; 1530 return NULL;
1468 } 1531 }
1469 1532
1533 static void
1534 update_scrollbar_size(void)
1535 {
1536 gui.scrollbar_width = pGetSystemMetricsForDpi(SM_CXVSCROLL, s_dpi);
1537 gui.scrollbar_height = pGetSystemMetricsForDpi(SM_CYHSCROLL, s_dpi);
1538 }
1539
1470 /* 1540 /*
1471 * Get the character size of a font. 1541 * Get the character size of a font.
1472 */ 1542 */
1473 static void 1543 static void
1474 GetFontSize(GuiFont font) 1544 GetFontSize(GuiFont font)
1543 { 1613 {
1544 LOGFONTW lf; 1614 LOGFONTW lf;
1545 GuiFont font = NOFONT; 1615 GuiFont font = NOFONT;
1546 1616
1547 if (get_logfont(&lf, name, NULL, giveErrorIfMissing) == OK) 1617 if (get_logfont(&lf, name, NULL, giveErrorIfMissing) == OK)
1618 {
1619 lf.lfHeight = adjust_fontsize_by_dpi(lf.lfHeight);
1548 font = get_font_handle(&lf); 1620 font = get_font_handle(&lf);
1621 }
1549 if (font == NOFONT && giveErrorIfMissing) 1622 if (font == NOFONT && giveErrorIfMissing)
1550 semsg(_(e_unknown_font_str), name); 1623 semsg(_(e_unknown_font_str), name);
1551 return font; 1624 return font;
1552 } 1625 }
1553 1626
2856 HWND hwnd, 2929 HWND hwnd,
2857 UINT state UNUSED, 2930 UINT state UNUSED,
2858 int cx, 2931 int cx,
2859 int cy) 2932 int cy)
2860 { 2933 {
2861 if (!IsMinimized(hwnd)) 2934 if (!IsMinimized(hwnd) && !s_in_dpichanged)
2862 { 2935 {
2863 gui_resize_shell(cx, cy); 2936 gui_resize_shell(cx, cy);
2864 2937
2865 #ifdef FEAT_MENU
2866 // Menu bar may wrap differently now 2938 // Menu bar may wrap differently now
2867 gui_mswin_get_menu_height(TRUE); 2939 gui_mswin_get_menu_height(TRUE);
2868 #endif
2869 } 2940 }
2870 } 2941 }
2871 2942
2872 static void 2943 static void
2873 _OnSetFocus( 2944 _OnSetFocus(
2947 int *rows) 3018 int *rows)
2948 { 3019 {
2949 int base_width, base_height; 3020 int base_width, base_height;
2950 3021
2951 base_width = gui_get_base_width() 3022 base_width = gui_get_base_width()
2952 + (GetSystemMetrics(SM_CXFRAME) + 3023 + (pGetSystemMetricsForDpi(SM_CXFRAME, s_dpi) +
2953 GetSystemMetrics(SM_CXPADDEDBORDER)) * 2; 3024 pGetSystemMetricsForDpi(SM_CXPADDEDBORDER, s_dpi)) * 2;
2954 base_height = gui_get_base_height() 3025 base_height = gui_get_base_height()
2955 + (GetSystemMetrics(SM_CYFRAME) + 3026 + (pGetSystemMetricsForDpi(SM_CYFRAME, s_dpi) +
2956 GetSystemMetrics(SM_CXPADDEDBORDER)) * 2 3027 pGetSystemMetricsForDpi(SM_CXPADDEDBORDER, s_dpi)) * 2
2957 + GetSystemMetrics(SM_CYCAPTION) 3028 + pGetSystemMetricsForDpi(SM_CYCAPTION, s_dpi)
2958 #ifdef FEAT_MENU 3029 + gui_mswin_get_menu_height(FALSE);
2959 + gui_mswin_get_menu_height(FALSE)
2960 #endif
2961 ;
2962 *cols = (w - base_width) / gui.char_width; 3030 *cols = (w - base_width) / gui.char_width;
2963 *rows = (h - base_height) / gui.char_height; 3031 *rows = (h - base_height) / gui.char_height;
2964 *valid_w = base_width + *cols * gui.char_width; 3032 *valid_w = base_width + *cols * gui.char_width;
2965 *valid_h = base_height + *rows * gui.char_height; 3033 *valid_h = base_height + *rows * gui.char_height;
2966 } 3034 }
3243 3311
3244 3312
3245 #ifdef FEAT_MBYTE_IME 3313 #ifdef FEAT_MBYTE_IME
3246 /* 3314 /*
3247 * Set correct LOGFONTW to IME. Use 'guifontwide' if available, otherwise use 3315 * Set correct LOGFONTW to IME. Use 'guifontwide' if available, otherwise use
3248 * 'guifont' 3316 * 'guifont'.
3249 */ 3317 */
3250 static void 3318 static void
3251 update_im_font(void) 3319 update_im_font(void)
3252 { 3320 {
3253 LOGFONTW lf_wide; 3321 LOGFONTW lf_wide, lf;
3254 3322
3255 if (p_guifontwide != NULL && *p_guifontwide != NUL 3323 if (p_guifontwide != NULL && *p_guifontwide != NUL
3256 && gui.wide_font != NOFONT 3324 && gui.wide_font != NOFONT
3257 && GetObjectW((HFONT)gui.wide_font, sizeof(lf_wide), &lf_wide)) 3325 && GetObjectW((HFONT)gui.wide_font, sizeof(lf_wide), &lf_wide))
3258 norm_logfont = lf_wide; 3326 norm_logfont = lf_wide;
3259 else 3327 else
3260 norm_logfont = sub_logfont; 3328 norm_logfont = sub_logfont;
3261 im_set_font(&norm_logfont); 3329
3330 lf = norm_logfont;
3331 if (s_process_dpi_aware == DPI_AWARENESS_UNAWARE)
3332 // Work around when PerMonitorV2 is not enabled in the process level.
3333 lf.lfHeight = lf.lfHeight * DEFAULT_DPI / s_dpi;
3334 im_set_font(&lf);
3262 } 3335 }
3263 #endif 3336 #endif
3264 3337
3265 /* 3338 /*
3266 * Handler of gui.wide_font (p_guifontwide) changed notification. 3339 * Handler of gui.wide_font (p_guifontwide) changed notification.
3308 * Return FAIL if the font could not be loaded, OK otherwise. 3381 * Return FAIL if the font could not be loaded, OK otherwise.
3309 */ 3382 */
3310 int 3383 int
3311 gui_mch_init_font(char_u *font_name, int fontset UNUSED) 3384 gui_mch_init_font(char_u *font_name, int fontset UNUSED)
3312 { 3385 {
3313 LOGFONTW lf; 3386 LOGFONTW lf, lfOrig;
3314 GuiFont font = NOFONT; 3387 GuiFont font = NOFONT;
3315 char_u *p; 3388 char_u *p;
3316 3389
3317 // Load the font 3390 // Load the font
3318 if (get_logfont(&lf, font_name, NULL, TRUE) == OK) 3391 if (get_logfont(&lf, font_name, NULL, TRUE) == OK)
3392 {
3393 lfOrig = lf;
3394 lf.lfHeight = adjust_fontsize_by_dpi(lf.lfHeight);
3319 font = get_font_handle(&lf); 3395 font = get_font_handle(&lf);
3396 }
3320 if (font == NOFONT) 3397 if (font == NOFONT)
3321 return FAIL; 3398 return FAIL;
3322 3399
3323 if (font_name == NULL) 3400 if (font_name == NULL)
3324 font_name = (char_u *)lf.lfFaceName; 3401 font_name = (char_u *)lf.lfFaceName;
3327 #endif 3404 #endif
3328 #ifdef FEAT_MBYTE_IME 3405 #ifdef FEAT_MBYTE_IME
3329 sub_logfont = lf; 3406 sub_logfont = lf;
3330 #endif 3407 #endif
3331 #ifdef FEAT_MBYTE_IME 3408 #ifdef FEAT_MBYTE_IME
3332 update_im_font(); 3409 if (!s_in_dpichanged)
3410 update_im_font();
3333 #endif 3411 #endif
3334 gui_mch_free_font(gui.norm_font); 3412 gui_mch_free_font(gui.norm_font);
3335 gui.norm_font = font; 3413 gui.norm_font = font;
3336 current_font_height = lf.lfHeight; 3414 current_font_height = lfOrig.lfHeight;
3337 GetFontSize(font); 3415 GetFontSize(font);
3338 3416
3339 p = logfont2name(lf); 3417 p = logfont2name(lfOrig);
3340 if (p != NULL) 3418 if (p != NULL)
3341 { 3419 {
3342 hl_set_font_name(p); 3420 hl_set_font_name(p);
3343 3421
3344 // When setting 'guifont' to "*" replace it with the actual font name. 3422 // When setting 'guifont' to "*" replace it with the actual font name.
3345 //
3346 if (STRCMP(font_name, "*") == 0 && STRCMP(p_guifont, "*") == 0) 3423 if (STRCMP(font_name, "*") == 0 && STRCMP(p_guifont, "*") == 0)
3347 { 3424 {
3348 vim_free(p_guifont); 3425 vim_free(p_guifont);
3349 p_guifont = p; 3426 p_guifont = p;
3350 } 3427 }
3426 3503
3427 GetWindowRect(s_hwnd, &rect); 3504 GetWindowRect(s_hwnd, &rect);
3428 if (win_socket_id == 0) 3505 if (win_socket_id == 0)
3429 { 3506 {
3430 gui_resize_shell(rect.right - rect.left 3507 gui_resize_shell(rect.right - rect.left
3431 - (GetSystemMetrics(SM_CXFRAME) + 3508 - (pGetSystemMetricsForDpi(SM_CXFRAME, s_dpi) +
3432 GetSystemMetrics(SM_CXPADDEDBORDER)) * 2, 3509 pGetSystemMetricsForDpi(SM_CXPADDEDBORDER, s_dpi)) * 2,
3433 rect.bottom - rect.top 3510 rect.bottom - rect.top
3434 - (GetSystemMetrics(SM_CYFRAME) + 3511 - (pGetSystemMetricsForDpi(SM_CYFRAME, s_dpi) +
3435 GetSystemMetrics(SM_CXPADDEDBORDER)) * 2 3512 pGetSystemMetricsForDpi(SM_CXPADDEDBORDER, s_dpi)) * 2
3436 - GetSystemMetrics(SM_CYCAPTION) 3513 - pGetSystemMetricsForDpi(SM_CYCAPTION, s_dpi)
3437 #ifdef FEAT_MENU 3514 - gui_mswin_get_menu_height(FALSE));
3438 - gui_mswin_get_menu_height(FALSE)
3439 #endif
3440 );
3441 } 3515 }
3442 else 3516 else
3443 { 3517 {
3444 // Inside another window, don't use the frame and border. 3518 // Inside another window, don't use the frame and border.
3445 gui_resize_shell(rect.right - rect.left, 3519 gui_resize_shell(rect.right - rect.left,
3446 rect.bottom - rect.top 3520 rect.bottom - rect.top - gui_mswin_get_menu_height(FALSE));
3447 #ifdef FEAT_MENU
3448 - gui_mswin_get_menu_height(FALSE)
3449 #endif
3450 );
3451 } 3521 }
3452 } 3522 }
3453 3523
3454 /* 3524 /*
3455 * Set the window title 3525 * Set the window title
4099 #endif // defined(FEAT_BEVAL_GUI) 4169 #endif // defined(FEAT_BEVAL_GUI)
4100 4170
4101 #if defined(FEAT_TOOLBAR) || defined(FEAT_GUI_TABLINE) 4171 #if defined(FEAT_TOOLBAR) || defined(FEAT_GUI_TABLINE)
4102 // Older MSVC compilers don't have LPNMTTDISPINFO[AW] thus we need to define 4172 // Older MSVC compilers don't have LPNMTTDISPINFO[AW] thus we need to define
4103 // it here if LPNMTTDISPINFO isn't defined. 4173 // it here if LPNMTTDISPINFO isn't defined.
4104 // MingW doesn't define LPNMTTDISPINFO but typedefs it. Thus we need to check 4174 // MinGW doesn't define LPNMTTDISPINFO but typedefs it. Thus we need to check
4105 // _MSC_VER. 4175 // _MSC_VER.
4106 # if !defined(LPNMTTDISPINFO) && defined(_MSC_VER) 4176 # if !defined(LPNMTTDISPINFO) && defined(_MSC_VER)
4107 typedef struct tagNMTTDISPINFOA { 4177 typedef struct tagNMTTDISPINFOA {
4108 NMHDR hdr; 4178 NMHDR hdr;
4109 LPSTR lpszText; 4179 LPSTR lpszText;
4176 static int mouse_scroll_lines = 0; 4246 static int mouse_scroll_lines = 0;
4177 4247
4178 static int s_usenewlook; // emulate W95/NT4 non-bold dialogs 4248 static int s_usenewlook; // emulate W95/NT4 non-bold dialogs
4179 #ifdef FEAT_TOOLBAR 4249 #ifdef FEAT_TOOLBAR
4180 static void initialise_toolbar(void); 4250 static void initialise_toolbar(void);
4251 static void update_toolbar_size(void);
4181 static LRESULT CALLBACK toolbar_wndproc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); 4252 static LRESULT CALLBACK toolbar_wndproc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
4182 static int get_toolbar_bitmap(vimmenu_T *menu); 4253 static int get_toolbar_bitmap(vimmenu_T *menu);
4254 #else
4255 # define update_toolbar_size()
4183 #endif 4256 #endif
4184 4257
4185 #ifdef FEAT_GUI_TABLINE 4258 #ifdef FEAT_GUI_TABLINE
4186 static void initialise_tabline(void); 4259 static void initialise_tabline(void);
4187 static LRESULT CALLBACK tabline_wndproc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); 4260 static LRESULT CALLBACK tabline_wndproc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
4417 TEXTMETRIC tm; 4490 TEXTMETRIC tm;
4418 4491
4419 if (gui_w32_get_menu_font(&lfSysmenu) != OK) 4492 if (gui_w32_get_menu_font(&lfSysmenu) != OK)
4420 return; 4493 return;
4421 4494
4495 lfSysmenu.lfHeight = adjust_fontsize_by_dpi(lfSysmenu.lfHeight);
4422 font = CreateFontIndirectW(&lfSysmenu); 4496 font = CreateFontIndirectW(&lfSysmenu);
4423 4497
4424 SendMessage(s_tabhwnd, WM_SETFONT, (WPARAM)font, TRUE); 4498 SendMessage(s_tabhwnd, WM_SETFONT, (WPARAM)font, TRUE);
4425 4499
4426 /* 4500 /*
4439 * The space used by the tab border and the space between the tab label 4513 * The space used by the tab border and the space between the tab label
4440 * and the tab border is included as 7. 4514 * and the tab border is included as 7.
4441 */ 4515 */
4442 gui.tabline_height = tm.tmHeight + tm.tmInternalLeading + 7; 4516 gui.tabline_height = tm.tmHeight + tm.tmInternalLeading + 7;
4443 } 4517 }
4518 #else
4519 # define set_tabline_font()
4444 #endif 4520 #endif
4445 4521
4446 /* 4522 /*
4447 * Invoked when a setting was changed. 4523 * Invoked when a setting was changed.
4448 */ 4524 */
4450 _OnSettingChange(UINT n) 4526 _OnSettingChange(UINT n)
4451 { 4527 {
4452 if (n == SPI_SETWHEELSCROLLLINES) 4528 if (n == SPI_SETWHEELSCROLLLINES)
4453 SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, 4529 SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0,
4454 &mouse_scroll_lines, 0); 4530 &mouse_scroll_lines, 0);
4455 #if defined(FEAT_GUI_TABLINE) && defined(USE_SYSMENU_FONT)
4456 if (n == SPI_SETNONCLIENTMETRICS) 4531 if (n == SPI_SETNONCLIENTMETRICS)
4457 set_tabline_font(); 4532 set_tabline_font();
4458 #endif
4459 return 0; 4533 return 0;
4460 } 4534 }
4461 4535
4462 #ifdef FEAT_NETBEANS_INTG 4536 #ifdef FEAT_NETBEANS_INTG
4463 static void 4537 static void
4554 4628
4555 show_sizing_tip(cols, rows); 4629 show_sizing_tip(cols, rows);
4556 return TRUE; 4630 return TRUE;
4557 } 4631 }
4558 4632
4633 static LRESULT
4634 _OnDpiChanged(HWND hwnd, UINT xdpi, UINT ydpi, RECT *rc)
4635 {
4636 s_dpi = ydpi;
4637 s_in_dpichanged = TRUE;
4638 //TRACE("DPI: %d", ydpi);
4639
4640 update_scrollbar_size();
4641 update_toolbar_size();
4642 set_tabline_font();
4643
4644 gui_init_font(*p_guifont == NUL ? hl_get_font_name() : p_guifont, FALSE);
4645 gui_get_wide_font();
4646 gui_mswin_get_menu_height(FALSE);
4647 #ifdef FEAT_MBYTE_IME
4648 im_set_position(gui.row, gui.col);
4649 #endif
4650 InvalidateRect(hwnd, NULL, TRUE);
4651
4652 s_in_dpichanged = FALSE;
4653 return 0L;
4654 }
4559 4655
4560 4656
4561 static LRESULT CALLBACK 4657 static LRESULT CALLBACK
4562 _WndProc( 4658 _WndProc(
4563 HWND hwnd, 4659 HWND hwnd,
4914 case WM_IME_COMPOSITION: 5010 case WM_IME_COMPOSITION:
4915 if (!_OnImeComposition(hwnd, wParam, lParam)) 5011 if (!_OnImeComposition(hwnd, wParam, lParam))
4916 return MyWindowProc(hwnd, uMsg, wParam, lParam); 5012 return MyWindowProc(hwnd, uMsg, wParam, lParam);
4917 return 1L; 5013 return 1L;
4918 #endif 5014 #endif
5015 case WM_DPICHANGED:
5016 return _OnDpiChanged(hwnd, (UINT)LOWORD(wParam), (UINT)HIWORD(wParam),
5017 (RECT*)lParam);
4919 5018
4920 default: 5019 default:
4921 #ifdef MSWIN_FIND_REPLACE 5020 #ifdef MSWIN_FIND_REPLACE
4922 if (uMsg == s_findrep_msg && s_findrep_msg != 0) 5021 if (uMsg == s_findrep_msg && s_findrep_msg != 0)
4923 _OnFindRepl(); 5022 _OnFindRepl();
5214 } 5313 }
5215 } 5314 }
5216 #endif 5315 #endif
5217 } 5316 }
5218 5317
5318 static void
5319 load_dpi_func(void)
5320 {
5321 HMODULE hUser32;
5322
5323 hUser32 = GetModuleHandle("user32.dll");
5324 if (hUser32 == NULL)
5325 goto fail;
5326
5327 pGetDpiForSystem = (void*)GetProcAddress(hUser32, "GetDpiForSystem");
5328 pGetDpiForWindow = (void*)GetProcAddress(hUser32, "GetDpiForWindow");
5329 pGetSystemMetricsForDpi = (void*)GetProcAddress(hUser32, "GetSystemMetricsForDpi");
5330 //pGetWindowDpiAwarenessContext = (void*)GetProcAddress(hUser32, "GetWindowDpiAwarenessContext");
5331 pSetThreadDpiAwarenessContext = (void*)GetProcAddress(hUser32, "SetThreadDpiAwarenessContext");
5332 pGetAwarenessFromDpiAwarenessContext = (void*)GetProcAddress(hUser32, "GetAwarenessFromDpiAwarenessContext");
5333
5334 if (pSetThreadDpiAwarenessContext != NULL)
5335 {
5336 DPI_AWARENESS_CONTEXT oldctx = pSetThreadDpiAwarenessContext(
5337 DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2);
5338 if (oldctx != NULL)
5339 {
5340 TRACE("DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 enabled");
5341 s_process_dpi_aware = pGetAwarenessFromDpiAwarenessContext(oldctx);
5342 #ifdef DEBUG
5343 if (s_process_dpi_aware == DPI_AWARENESS_UNAWARE)
5344 {
5345 TRACE("WARNING: PerMonitorV2 is not enabled in the process level for some reasons. IME window may not shown correctly.");
5346 }
5347 #endif
5348 return;
5349 }
5350 }
5351
5352 fail:
5353 // Disable PerMonitorV2 APIs.
5354 pGetDpiForSystem = stubGetDpiForSystem;
5355 pGetDpiForWindow = NULL;
5356 pGetSystemMetricsForDpi = stubGetSystemMetricsForDpi;
5357 pSetThreadDpiAwarenessContext = NULL;
5358 pGetAwarenessFromDpiAwarenessContext = NULL;
5359 }
5360
5219 /* 5361 /*
5220 * Initialise the GUI. Create all the windows, set up all the call-backs 5362 * Initialise the GUI. Create all the windows, set up all the call-backs
5221 * etc. 5363 * etc.
5222 */ 5364 */
5223 int 5365 int
5240 */ 5382 */
5241 #ifdef FEAT_TEAROFF 5383 #ifdef FEAT_TEAROFF
5242 s_htearbitmap = LoadBitmap(g_hinst, "IDB_TEAROFF"); 5384 s_htearbitmap = LoadBitmap(g_hinst, "IDB_TEAROFF");
5243 #endif 5385 #endif
5244 5386
5245 gui.scrollbar_width = GetSystemMetrics(SM_CXVSCROLL); 5387 load_dpi_func();
5246 gui.scrollbar_height = GetSystemMetrics(SM_CYHSCROLL); 5388
5389 s_dpi = pGetDpiForSystem();
5390 update_scrollbar_size();
5391
5247 #ifdef FEAT_MENU 5392 #ifdef FEAT_MENU
5248 gui.menu_height = 0; // Windows takes care of this 5393 gui.menu_height = 0; // Windows takes care of this
5249 #endif 5394 #endif
5250 gui.border_width = 0; 5395 gui.border_width = 0;
5396 #ifdef FEAT_TOOLBAR
5397 gui.toolbar_height = TOOLBAR_BUTTON_HEIGHT + TOOLBAR_BORDER_HEIGHT;
5398 #endif
5251 5399
5252 s_brush = CreateSolidBrush(GetSysColor(COLOR_BTNFACE)); 5400 s_brush = CreateSolidBrush(GetSysColor(COLOR_BTNFACE));
5253 5401
5254 // First try using the wide version, so that we can use any title. 5402 // First try using the wide version, so that we can use any title.
5255 // Otherwise only characters in the active codepage will work. 5403 // Otherwise only characters in the active codepage will work.
5334 } 5482 }
5335 5483
5336 if (s_hwnd == NULL) 5484 if (s_hwnd == NULL)
5337 return FAIL; 5485 return FAIL;
5338 5486
5487 if (pGetDpiForWindow != NULL)
5488 {
5489 s_dpi = pGetDpiForWindow(s_hwnd);
5490 update_scrollbar_size();
5491 //TRACE("System DPI: %d, DPI: %d", pGetDpiForSystem(), s_dpi);
5492 }
5493
5339 #ifdef GLOBAL_IME 5494 #ifdef GLOBAL_IME
5340 global_ime_init(atom, s_hwnd); 5495 global_ime_init(atom, s_hwnd);
5341 #endif 5496 #endif
5342 #if defined(FEAT_MBYTE_IME) && defined(DYNAMIC_IME) 5497 #if defined(FEAT_MBYTE_IME) && defined(DYNAMIC_IME)
5343 dyn_imm_load(); 5498 dyn_imm_load();
5389 s_hdc = GetDC(s_textArea); 5544 s_hdc = GetDC(s_textArea);
5390 5545
5391 DragAcceptFiles(s_hwnd, TRUE); 5546 DragAcceptFiles(s_hwnd, TRUE);
5392 5547
5393 // Do we need to bother with this? 5548 // Do we need to bother with this?
5394 // m_fMouseAvail = GetSystemMetrics(SM_MOUSEPRESENT); 5549 // m_fMouseAvail = pGetSystemMetricsForDpi(SM_MOUSEPRESENT, s_dpi);
5395 5550
5396 // Get background/foreground colors from the system 5551 // Get background/foreground colors from the system
5397 gui_mch_def_colors(); 5552 gui_mch_def_colors();
5398 5553
5399 // Get the colors from the "Normal" group (set in syntax.c or in a vimrc 5554 // Get the colors from the "Normal" group (set in syntax.c or in a vimrc
5531 ShowWindow(s_hwnd, SW_SHOWNORMAL); 5686 ShowWindow(s_hwnd, SW_SHOWNORMAL);
5532 5687
5533 GetWindowRect(s_hwnd, &window_rect); 5688 GetWindowRect(s_hwnd, &window_rect);
5534 5689
5535 // compute the size of the outside of the window 5690 // compute the size of the outside of the window
5536 win_width = width + (GetSystemMetrics(SM_CXFRAME) + 5691 win_width = width + (pGetSystemMetricsForDpi(SM_CXFRAME, s_dpi) +
5537 GetSystemMetrics(SM_CXPADDEDBORDER)) * 2; 5692 pGetSystemMetricsForDpi(SM_CXPADDEDBORDER, s_dpi)) * 2;
5538 win_height = height + (GetSystemMetrics(SM_CYFRAME) + 5693 win_height = height + (pGetSystemMetricsForDpi(SM_CYFRAME, s_dpi) +
5539 GetSystemMetrics(SM_CXPADDEDBORDER)) * 2 5694 pGetSystemMetricsForDpi(SM_CXPADDEDBORDER, s_dpi)) * 2
5540 + GetSystemMetrics(SM_CYCAPTION) 5695 + pGetSystemMetricsForDpi(SM_CYCAPTION, s_dpi)
5541 #ifdef FEAT_MENU 5696 + gui_mswin_get_menu_height(FALSE);
5542 + gui_mswin_get_menu_height(FALSE)
5543 #endif
5544 ;
5545 5697
5546 // The following should take care of keeping Vim on the same monitor, no 5698 // The following should take care of keeping Vim on the same monitor, no
5547 // matter if the secondary monitor is left or right of the primary 5699 // matter if the secondary monitor is left or right of the primary
5548 // monitor. 5700 // monitor.
5549 window_rect.right = window_rect.left + win_width; 5701 window_rect.right = window_rect.left + win_width;
5566 win_width, win_height, TRUE); 5718 win_width, win_height, TRUE);
5567 5719
5568 SetActiveWindow(s_hwnd); 5720 SetActiveWindow(s_hwnd);
5569 SetFocus(s_hwnd); 5721 SetFocus(s_hwnd);
5570 5722
5571 #ifdef FEAT_MENU
5572 // Menu may wrap differently now 5723 // Menu may wrap differently now
5573 gui_mswin_get_menu_height(!gui.starting); 5724 gui_mswin_get_menu_height(!gui.starting);
5574 #endif
5575 } 5725 }
5576 5726
5577 5727
5578 void 5728 void
5579 gui_mch_set_scrollbar_thumb( 5729 gui_mch_set_scrollbar_thumb(
5667 switch (dwCommand) 5817 switch (dwCommand)
5668 { 5818 {
5669 case IMN_SETOPENSTATUS: 5819 case IMN_SETOPENSTATUS:
5670 if (pImmGetOpenStatus(hImc)) 5820 if (pImmGetOpenStatus(hImc))
5671 { 5821 {
5672 pImmSetCompositionFontW(hImc, &norm_logfont); 5822 LOGFONTW lf = norm_logfont;
5823 if (s_process_dpi_aware == DPI_AWARENESS_UNAWARE)
5824 // Work around when PerMonitorV2 is not enabled in the process level.
5825 lf.lfHeight = lf.lfHeight * DEFAULT_DPI / s_dpi;
5826 pImmSetCompositionFontW(hImc, &lf);
5673 im_set_position(gui.row, gui.col); 5827 im_set_position(gui.row, gui.col);
5674 5828
5675 // Disable langmap 5829 // Disable langmap
5676 State &= ~LANGMAP; 5830 State &= ~LANGMAP;
5677 if (State & INSERT) 5831 if (State & INSERT)
5835 5989
5836 cfs.dwStyle = CFS_POINT; 5990 cfs.dwStyle = CFS_POINT;
5837 cfs.ptCurrentPos.x = FILL_X(col); 5991 cfs.ptCurrentPos.x = FILL_X(col);
5838 cfs.ptCurrentPos.y = FILL_Y(row); 5992 cfs.ptCurrentPos.y = FILL_Y(row);
5839 MapWindowPoints(s_textArea, s_hwnd, &cfs.ptCurrentPos, 1); 5993 MapWindowPoints(s_textArea, s_hwnd, &cfs.ptCurrentPos, 1);
5994 if (s_process_dpi_aware == DPI_AWARENESS_UNAWARE)
5995 {
5996 // Work around when PerMonitorV2 is not enabled in the process level.
5997 cfs.ptCurrentPos.x = cfs.ptCurrentPos.x * DEFAULT_DPI / s_dpi;
5998 cfs.ptCurrentPos.y = cfs.ptCurrentPos.y * DEFAULT_DPI / s_dpi;
5999 }
5840 pImmSetCompositionWindow(hImc, &cfs); 6000 pImmSetCompositionWindow(hImc, &cfs);
5841 6001
5842 pImmReleaseContext(s_hwnd, hImc); 6002 pImmReleaseContext(s_hwnd, hImc);
5843 } 6003 }
5844 } 6004 }
6436 RECT workarea_rect; 6596 RECT workarea_rect;
6437 6597
6438 get_work_area(&workarea_rect); 6598 get_work_area(&workarea_rect);
6439 6599
6440 *screen_w = workarea_rect.right - workarea_rect.left 6600 *screen_w = workarea_rect.right - workarea_rect.left
6441 - (GetSystemMetrics(SM_CXFRAME) + 6601 - (pGetSystemMetricsForDpi(SM_CXFRAME, s_dpi) +
6442 GetSystemMetrics(SM_CXPADDEDBORDER)) * 2; 6602 pGetSystemMetricsForDpi(SM_CXPADDEDBORDER, s_dpi)) * 2;
6443 6603
6444 // FIXME: dirty trick: Because the gui_get_base_height() doesn't include 6604 // FIXME: dirty trick: Because the gui_get_base_height() doesn't include
6445 // the menubar for MSwin, we subtract it from the screen height, so that 6605 // the menubar for MSwin, we subtract it from the screen height, so that
6446 // the window size can be made to fit on the screen. 6606 // the window size can be made to fit on the screen.
6447 *screen_h = workarea_rect.bottom - workarea_rect.top 6607 *screen_h = workarea_rect.bottom - workarea_rect.top
6448 - (GetSystemMetrics(SM_CYFRAME) + 6608 - (pGetSystemMetricsForDpi(SM_CYFRAME, s_dpi) +
6449 GetSystemMetrics(SM_CXPADDEDBORDER)) * 2 6609 pGetSystemMetricsForDpi(SM_CXPADDEDBORDER, s_dpi)) * 2
6450 - GetSystemMetrics(SM_CYCAPTION) 6610 - pGetSystemMetricsForDpi(SM_CYCAPTION, s_dpi)
6451 #ifdef FEAT_MENU 6611 - gui_mswin_get_menu_height(FALSE);
6452 - gui_mswin_get_menu_height(FALSE)
6453 #endif
6454 ;
6455 } 6612 }
6456 6613
6457 6614
6458 #if defined(FEAT_MENU) || defined(PROTO) 6615 #if defined(FEAT_MENU) || defined(PROTO)
6459 /* 6616 /*
6903 LOGFONTW lfSysmenu; 7060 LOGFONTW lfSysmenu;
6904 int use_lfSysmenu = FALSE; 7061 int use_lfSysmenu = FALSE;
6905 # endif 7062 # endif
6906 garray_T ga; 7063 garray_T ga;
6907 int l; 7064 int l;
7065 int dlg_icon_width;
7066 int dlg_icon_height;
7067 int dpi;
6908 7068
6909 # ifndef NO_CONSOLE 7069 # ifndef NO_CONSOLE
6910 // Don't output anything in silent mode ("ex -s") 7070 // Don't output anything in silent mode ("ex -s")
6911 # ifdef VIMDLL 7071 # ifdef VIMDLL
6912 if (!(gui.in_use || gui.starting)) 7072 if (!(gui.in_use || gui.starting))
6914 if (silent_mode) 7074 if (silent_mode)
6915 return dfltbutton; // return default option 7075 return dfltbutton; // return default option
6916 # endif 7076 # endif
6917 7077
6918 if (s_hwnd == NULL) 7078 if (s_hwnd == NULL)
7079 {
7080 load_dpi_func();
7081 s_dpi = dpi = pGetDpiForSystem();
6919 get_dialog_font_metrics(); 7082 get_dialog_font_metrics();
7083 }
7084 else
7085 dpi = pGetDpiForSystem();
6920 7086
6921 if ((type < 0) || (type > VIM_LAST_TYPE)) 7087 if ((type < 0) || (type > VIM_LAST_TYPE))
6922 type = 0; 7088 type = 0;
6923 7089
6924 // allocate some memory for dialog template 7090 // allocate some memory for dialog template
6972 use_lfSysmenu = TRUE; 7138 use_lfSysmenu = TRUE;
6973 } 7139 }
6974 else 7140 else
6975 # endif 7141 # endif
6976 font = CreateFont(-DLG_FONT_POINT_SIZE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7142 font = CreateFont(-DLG_FONT_POINT_SIZE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6977 VARIABLE_PITCH , DLG_FONT_NAME); 7143 VARIABLE_PITCH, DLG_FONT_NAME);
6978 if (s_usenewlook) 7144 if (s_usenewlook)
6979 { 7145 {
6980 oldFont = SelectFont(hdc, font); 7146 oldFont = SelectFont(hdc, font);
6981 dlgPaddingX = DLG_PADDING_X; 7147 dlgPaddingX = DLG_PADDING_X;
6982 dlgPaddingY = DLG_PADDING_Y; 7148 dlgPaddingY = DLG_PADDING_Y;
6999 RECT workarea_rect; 7165 RECT workarea_rect;
7000 7166
7001 // We don't have a window, use the desktop area. 7167 // We don't have a window, use the desktop area.
7002 get_work_area(&workarea_rect); 7168 get_work_area(&workarea_rect);
7003 maxDialogWidth = workarea_rect.right - workarea_rect.left - 100; 7169 maxDialogWidth = workarea_rect.right - workarea_rect.left - 100;
7004 if (maxDialogWidth > 600) 7170 if (maxDialogWidth > adjust_by_system_dpi(600))
7005 maxDialogWidth = 600; 7171 maxDialogWidth = adjust_by_system_dpi(600);
7006 // Leave some room for the taskbar. 7172 // Leave some room for the taskbar.
7007 maxDialogHeight = workarea_rect.bottom - workarea_rect.top - 150; 7173 maxDialogHeight = workarea_rect.bottom - workarea_rect.top - 150;
7008 } 7174 }
7009 else 7175 else
7010 { 7176 {
7011 // Use our own window for the size, unless it's very small. 7177 // Use our own window for the size, unless it's very small.
7012 GetWindowRect(s_hwnd, &rect); 7178 GetWindowRect(s_hwnd, &rect);
7013 maxDialogWidth = rect.right - rect.left 7179 maxDialogWidth = rect.right - rect.left
7014 - (GetSystemMetrics(SM_CXFRAME) + 7180 - (pGetSystemMetricsForDpi(SM_CXFRAME, dpi) +
7015 GetSystemMetrics(SM_CXPADDEDBORDER)) * 2; 7181 pGetSystemMetricsForDpi(SM_CXPADDEDBORDER, dpi)) * 2;
7016 if (maxDialogWidth < DLG_MIN_MAX_WIDTH) 7182 if (maxDialogWidth < adjust_by_system_dpi(DLG_MIN_MAX_WIDTH))
7017 maxDialogWidth = DLG_MIN_MAX_WIDTH; 7183 maxDialogWidth = adjust_by_system_dpi(DLG_MIN_MAX_WIDTH);
7018 7184
7019 maxDialogHeight = rect.bottom - rect.top 7185 maxDialogHeight = rect.bottom - rect.top
7020 - (GetSystemMetrics(SM_CYFRAME) + 7186 - (pGetSystemMetricsForDpi(SM_CYFRAME, dpi) +
7021 GetSystemMetrics(SM_CXPADDEDBORDER)) * 4 7187 pGetSystemMetricsForDpi(SM_CXPADDEDBORDER, dpi)) * 4
7022 - GetSystemMetrics(SM_CYCAPTION); 7188 - pGetSystemMetricsForDpi(SM_CYCAPTION, dpi);
7023 if (maxDialogHeight < DLG_MIN_MAX_HEIGHT) 7189 if (maxDialogHeight < adjust_by_system_dpi(DLG_MIN_MAX_HEIGHT))
7024 maxDialogHeight = DLG_MIN_MAX_HEIGHT; 7190 maxDialogHeight = adjust_by_system_dpi(DLG_MIN_MAX_HEIGHT);
7025 } 7191 }
7026 7192
7027 // Set dlgwidth to width of message. 7193 // Set dlgwidth to width of message.
7028 // Copy the message into "ga", changing NL to CR-NL and inserting line 7194 // Copy the message into "ga", changing NL to CR-NL and inserting line
7029 // breaks where needed. 7195 // breaks where needed.
7055 textWidth = 0; 7221 textWidth = 0;
7056 7222
7057 if (last_white != NULL) 7223 if (last_white != NULL)
7058 { 7224 {
7059 // break the line just after a space 7225 // break the line just after a space
7060 ga.ga_len -= (int)(pend - (last_white + 1)); 7226 if (pend > last_white)
7227 ga.ga_len -= (int)(pend - (last_white + 1));
7061 pend = last_white + 1; 7228 pend = last_white + 1;
7062 last_white = NULL; 7229 last_white = NULL;
7063 } 7230 }
7064 ga_append(&ga, '\r'); 7231 ga_append(&ga, '\r');
7065 ga_append(&ga, '\n'); 7232 ga_append(&ga, '\n');
7080 if (ga.ga_data != NULL) 7247 if (ga.ga_data != NULL)
7081 message = ga.ga_data; 7248 message = ga.ga_data;
7082 7249
7083 messageWidth += 10; // roundoff space 7250 messageWidth += 10; // roundoff space
7084 7251
7252 dlg_icon_width = adjust_by_system_dpi(DLG_ICON_WIDTH);
7253 dlg_icon_height = adjust_by_system_dpi(DLG_ICON_HEIGHT);
7254
7085 // Add width of icon to dlgwidth, and some space 7255 // Add width of icon to dlgwidth, and some space
7086 dlgwidth = messageWidth + DLG_ICON_WIDTH + 3 * dlgPaddingX 7256 dlgwidth = messageWidth + dlg_icon_width + 3 * dlgPaddingX
7087 + GetSystemMetrics(SM_CXVSCROLL); 7257 + pGetSystemMetricsForDpi(SM_CXVSCROLL, dpi);
7088 7258
7089 if (msgheight < DLG_ICON_HEIGHT) 7259 if (msgheight < dlg_icon_height)
7090 msgheight = DLG_ICON_HEIGHT; 7260 msgheight = dlg_icon_height;
7091 7261
7092 /* 7262 /*
7093 * Check button names. A long one will make the dialog wider. 7263 * Check button names. A long one will make the dialog wider.
7094 * When called early (-register error message) p_go isn't initialized. 7264 * When called early (-register error message) p_go isn't initialized.
7095 */ 7265 */
7173 { 7343 {
7174 msgheight = msgheight - (dlgheight - maxDialogHeight); 7344 msgheight = msgheight - (dlgheight - maxDialogHeight);
7175 dlgheight = maxDialogHeight; 7345 dlgheight = maxDialogHeight;
7176 scroll_flag = WS_VSCROLL; 7346 scroll_flag = WS_VSCROLL;
7177 // Make sure scrollbar doesn't appear in the middle of the dialog 7347 // Make sure scrollbar doesn't appear in the middle of the dialog
7178 messageWidth = dlgwidth - DLG_ICON_WIDTH - 3 * dlgPaddingX; 7348 messageWidth = dlgwidth - dlg_icon_width - 3 * dlgPaddingX;
7179 } 7349 }
7180 7350
7181 add_word(PixelToDialogY(dlgheight)); 7351 add_word(PixelToDialogY(dlgheight));
7182 7352
7183 add_word(0); // Menu 7353 add_word(0); // Menu
7270 7440
7271 // Vim icon 7441 // Vim icon
7272 p = add_dialog_element(p, SS_ICON, 7442 p = add_dialog_element(p, SS_ICON,
7273 PixelToDialogX(dlgPaddingX), 7443 PixelToDialogX(dlgPaddingX),
7274 PixelToDialogY(dlgPaddingY), 7444 PixelToDialogY(dlgPaddingY),
7275 PixelToDialogX(DLG_ICON_WIDTH), 7445 PixelToDialogX(dlg_icon_width),
7276 PixelToDialogY(DLG_ICON_HEIGHT), 7446 PixelToDialogY(dlg_icon_height),
7277 DLG_NONBUTTON_CONTROL + 0, (WORD)0x0082, 7447 DLG_NONBUTTON_CONTROL + 0, (WORD)0x0082,
7278 dlg_icons[type]); 7448 dlg_icons[type]);
7279 7449
7280 // Dialog message 7450 // Dialog message
7281 p = add_dialog_element(p, ES_LEFT|scroll_flag|ES_MULTILINE|ES_READONLY, 7451 p = add_dialog_element(p, ES_LEFT|scroll_flag|ES_MULTILINE|ES_READONLY,
7282 PixelToDialogX(2 * dlgPaddingX + DLG_ICON_WIDTH), 7452 PixelToDialogX(2 * dlgPaddingX + dlg_icon_width),
7283 PixelToDialogY(dlgPaddingY), 7453 PixelToDialogY(dlgPaddingY),
7284 (WORD)(PixelToDialogX(messageWidth) + 1), 7454 (WORD)(PixelToDialogX(messageWidth) + 1),
7285 PixelToDialogY(msgheight), 7455 PixelToDialogY(msgheight),
7286 DLG_NONBUTTON_CONTROL + 1, (WORD)0x0081, (char *)message); 7456 DLG_NONBUTTON_CONTROL + 1, (WORD)0x0081, (char *)message);
7287 7457
7571 if (gui_w32_get_menu_font(&lfSysmenu) == OK) 7741 if (gui_w32_get_menu_font(&lfSysmenu) == OK)
7572 hfontTools = CreateFontIndirectW(&lfSysmenu); 7742 hfontTools = CreateFontIndirectW(&lfSysmenu);
7573 else 7743 else
7574 #endif 7744 #endif
7575 hfontTools = CreateFont(-DLG_FONT_POINT_SIZE, 0, 0, 0, 0, 0, 0, 0, 7745 hfontTools = CreateFont(-DLG_FONT_POINT_SIZE, 0, 0, 0, 0, 0, 0, 0,
7576 0, 0, 0, 0, VARIABLE_PITCH , DLG_FONT_NAME); 7746 0, 0, 0, 0, VARIABLE_PITCH, DLG_FONT_NAME);
7577 7747
7578 if (hfontTools) 7748 if (hfontTools)
7579 { 7749 {
7580 hdc = GetDC(s_hwnd); 7750 hdc = GetDC(s_hwnd);
7581 SelectObject(hdc, hfontTools); 7751 SelectObject(hdc, hfontTools);
7677 use_lfSysmenu = TRUE; 7847 use_lfSysmenu = TRUE;
7678 } 7848 }
7679 else 7849 else
7680 # endif 7850 # endif
7681 font = CreateFont(-DLG_FONT_POINT_SIZE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7851 font = CreateFont(-DLG_FONT_POINT_SIZE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
7682 VARIABLE_PITCH , DLG_FONT_NAME); 7852 VARIABLE_PITCH, DLG_FONT_NAME);
7683 if (s_usenewlook) 7853 if (s_usenewlook)
7684 oldFont = SelectFont(hdc, font); 7854 oldFont = SelectFont(hdc, font);
7685 else 7855 else
7686 oldFont = SelectFont(hdc, GetStockObject(SYSTEM_FONT)); 7856 oldFont = SelectFont(hdc, GetStockObject(SYSTEM_FONT));
7687 7857
7976 SendMessage(s_toolbarhwnd, TB_GETSTYLE, 0, 0) & ~TBSTYLE_TRANSPARENT); 8146 SendMessage(s_toolbarhwnd, TB_GETSTYLE, 0, 0) & ~TBSTYLE_TRANSPARENT);
7977 8147
7978 s_toolbar_wndproc = SubclassWindow(s_toolbarhwnd, toolbar_wndproc); 8148 s_toolbar_wndproc = SubclassWindow(s_toolbarhwnd, toolbar_wndproc);
7979 8149
7980 gui_mch_show_toolbar(vim_strchr(p_go, GO_TOOLBAR) != NULL); 8150 gui_mch_show_toolbar(vim_strchr(p_go, GO_TOOLBAR) != NULL);
8151
8152 update_toolbar_size();
8153 }
8154
8155 static void
8156 update_toolbar_size(void)
8157 {
8158 int w, h;
8159 TBMETRICS tbm = {sizeof(TBMETRICS)};
8160
8161 tbm.dwMask = TBMF_PAD | TBMF_BUTTONSPACING;
8162 SendMessage(s_toolbarhwnd, TB_GETMETRICS, 0, (LPARAM)&tbm);
8163 //TRACE("Pad: %d, %d", tbm.cxPad, tbm.cyPad);
8164 //TRACE("ButtonSpacing: %d, %d", tbm.cxButtonSpacing, tbm.cyButtonSpacing);
8165
8166 w = (TOOLBAR_BUTTON_WIDTH + tbm.cxPad) * s_dpi / DEFAULT_DPI;
8167 h = (TOOLBAR_BUTTON_HEIGHT + tbm.cyPad) * s_dpi / DEFAULT_DPI;
8168 //TRACE("button size: %d, %d", w, h);
8169 SendMessage(s_toolbarhwnd, TB_SETBUTTONSIZE, 0, MAKELPARAM(w, h));
8170 gui.toolbar_height = h + 6;
8171
8172 //DWORD s = SendMessage(s_toolbarhwnd, TB_GETBUTTONSIZE, 0, 0);
8173 //TRACE("actual button size: %d, %d", LOWORD(s), HIWORD(s));
8174
8175 // TODO:
8176 // Currently, this function only updates the size of toolbar buttons.
8177 // It would be nice if the toolbar images are resized based on DPI.
7981 } 8178 }
7982 8179
7983 static LRESULT CALLBACK 8180 static LRESULT CALLBACK
7984 toolbar_wndproc( 8181 toolbar_wndproc(
7985 HWND hwnd, 8182 HWND hwnd,
8069 CW_USEDEFAULT, s_hwnd, NULL, g_hinst, NULL); 8266 CW_USEDEFAULT, s_hwnd, NULL, g_hinst, NULL);
8070 s_tabline_wndproc = SubclassWindow(s_tabhwnd, tabline_wndproc); 8267 s_tabline_wndproc = SubclassWindow(s_tabhwnd, tabline_wndproc);
8071 8268
8072 gui.tabline_height = TABLINE_HEIGHT; 8269 gui.tabline_height = TABLINE_HEIGHT;
8073 8270
8074 # ifdef USE_SYSMENU_FONT
8075 set_tabline_font(); 8271 set_tabline_font();
8076 # endif
8077 } 8272 }
8078 8273
8079 /* 8274 /*
8080 * Get tabpage_T from POINT. 8275 * Get tabpage_T from POINT.
8081 */ 8276 */
8088 8283
8089 if (gui_mch_showing_tabline()) 8284 if (gui_mch_showing_tabline())
8090 { 8285 {
8091 TCHITTESTINFO htinfo; 8286 TCHITTESTINFO htinfo;
8092 htinfo.pt = pt; 8287 htinfo.pt = pt;
8093 // ignore if a window under cusor is not tabcontrol. 8288 // ignore if a window under cursor is not tabcontrol.
8094 if (s_tabhwnd == hWnd) 8289 if (s_tabhwnd == hWnd)
8095 { 8290 {
8096 int idx = TabCtrl_HitTest(s_tabhwnd, &htinfo); 8291 int idx = TabCtrl_HitTest(s_tabhwnd, &htinfo);
8097 if (idx != -1) 8292 if (idx != -1)
8098 ptp = find_tabpage(idx + 1); 8293 ptp = find_tabpage(idx + 1);
8134 if (GetCapture() == hwnd 8329 if (GetCapture() == hwnd
8135 && ((wParam & MK_LBUTTON)) != 0) 8330 && ((wParam & MK_LBUTTON)) != 0)
8136 { 8331 {
8137 pt.x = GET_X_LPARAM(lParam); 8332 pt.x = GET_X_LPARAM(lParam);
8138 pt.y = s_pt.y; 8333 pt.y = s_pt.y;
8139 if (abs(pt.x - s_pt.x) > GetSystemMetrics(SM_CXDRAG)) 8334 if (abs(pt.x - s_pt.x) >
8335 pGetSystemMetricsForDpi(SM_CXDRAG, s_dpi))
8140 { 8336 {
8141 SetCursor(LoadCursor(NULL, IDC_SIZEWE)); 8337 SetCursor(LoadCursor(NULL, IDC_SIZEWE));
8142 8338
8143 tp = GetTabFromPoint(hwnd, pt); 8339 tp = GetTabFromPoint(hwnd, pt);
8144 if (tp != NULL) 8340 if (tp != NULL)