Mercurial > vim
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) |