# HG changeset patch # User Bram Moolenaar # Date 1642691705 -3600 # Node ID a63505f338942577bbeb4e1a2c22d771e543e5bd # Parent 450f249d37b76b69ca6f0174a336c835b4fb1ab1 patch 8.2.4159: MS-Windows: _WndProc() is very long Commit: https://github.com/vim/vim/commit/92000e2e713a68f80a25472cfa74058366c58c9c Author: K.Takata Date: Thu Jan 20 15:10:57 2022 +0000 patch 8.2.4159: MS-Windows: _WndProc() is very long Problem: MS-Windows: _WndProc() is very long. Solution: Move code to separate functions. (Ken Takata, closes https://github.com/vim/vim/issues/9573) diff --git a/src/gui_w32.c b/src/gui_w32.c --- a/src/gui_w32.c +++ b/src/gui_w32.c @@ -4580,6 +4580,237 @@ destroy_sizing_tip(void) return TRUE; } +#ifdef FEAT_GUI_TABLINE + static void +_OnRButtonUp(HWND hwnd, int x, int y, UINT keyFlags) +{ + if (gui_mch_showing_tabline()) + { + POINT pt; + RECT rect; + + /* + * If the cursor is on the tabline, display the tab menu + */ + GetCursorPos(&pt); + GetWindowRect(s_textArea, &rect); + if (pt.y < rect.top) + { + show_tabline_popup_menu(); + return; + } + } + FORWARD_WM_RBUTTONUP(hwnd, x, y, keyFlags, DefWindowProcW); +} + + static void +_OnLButtonDown(HWND hwnd, BOOL fDoubleClick, int x, int y, UINT keyFlags) +{ + /* + * If the user double clicked the tabline, create a new tab + */ + if (gui_mch_showing_tabline()) + { + POINT pt; + RECT rect; + + GetCursorPos(&pt); + GetWindowRect(s_textArea, &rect); + if (pt.y < rect.top) + send_tabline_menu_event(0, TABLINE_MENU_NEW); + } + FORWARD_WM_LBUTTONDOWN(hwnd, fDoubleClick, x, y, keyFlags, DefWindowProcW); +} +#endif + + static UINT +_OnNCHitTest(HWND hwnd, int xPos, int yPos) +{ + UINT result; + int x, y; + + result = FORWARD_WM_NCHITTEST(hwnd, xPos, yPos, DefWindowProcW); + if (result != HTCLIENT) + return result; + +#ifdef FEAT_GUI_TABLINE + if (gui_mch_showing_tabline()) + { + RECT rct; + + // If the cursor is on the GUI tabline, don't process this event + GetWindowRect(s_textArea, &rct); + if (yPos < rct.top) + return result; + } +#endif + (void)gui_mch_get_winpos(&x, &y); + xPos -= x; + + if (xPos < 48) // TODO should use system metric? + return HTBOTTOMLEFT; + else + return HTBOTTOMRIGHT; +} + +#if defined(FEAT_TOOLBAR) || defined(FEAT_GUI_TABLINE) + static LRESULT +_OnNotify(HWND hwnd, UINT id, NMHDR *hdr) +{ + switch (hdr->code) + { + case TTN_GETDISPINFOW: + case TTN_GETDISPINFO: + { + char_u *str = NULL; + static void *tt_text = NULL; + + VIM_CLEAR(tt_text); + +# ifdef FEAT_GUI_TABLINE + if (gui_mch_showing_tabline() + && hdr->hwndFrom == TabCtrl_GetToolTips(s_tabhwnd)) + { + POINT pt; + /* + * Mouse is over the GUI tabline. Display the + * tooltip for the tab under the cursor + * + * Get the cursor position within the tab control + */ + GetCursorPos(&pt); + if (ScreenToClient(s_tabhwnd, &pt) != 0) + { + TCHITTESTINFO htinfo; + int idx; + + /* + * Get the tab under the cursor + */ + htinfo.pt.x = pt.x; + htinfo.pt.y = pt.y; + idx = TabCtrl_HitTest(s_tabhwnd, &htinfo); + if (idx != -1) + { + tabpage_T *tp; + + tp = find_tabpage(idx + 1); + if (tp != NULL) + { + get_tabline_label(tp, TRUE); + str = NameBuff; + } + } + } + } +# endif +# ifdef FEAT_TOOLBAR +# ifdef FEAT_GUI_TABLINE + else +# endif + { + UINT idButton; + vimmenu_T *pMenu; + + idButton = (UINT) hdr->idFrom; + pMenu = gui_mswin_find_menu(root_menu, idButton); + if (pMenu) + str = pMenu->strings[MENU_INDEX_TIP]; + } +# endif + if (str == NULL) + break; + + // Set the maximum width, this also enables using \n for + // line break. + SendMessage(hdr->hwndFrom, TTM_SETMAXTIPWIDTH, 0, 500); + + if (hdr->code == TTN_GETDISPINFOW) + { + LPNMTTDISPINFOW lpdi = (LPNMTTDISPINFOW)hdr; + + tt_text = enc_to_utf16(str, NULL); + lpdi->lpszText = tt_text; + // can't show tooltip if failed + } + else + { + LPNMTTDISPINFO lpdi = (LPNMTTDISPINFO)hdr; + + if (STRLEN(str) < sizeof(lpdi->szText) + || ((tt_text = vim_strsave(str)) == NULL)) + vim_strncpy((char_u *)lpdi->szText, str, + sizeof(lpdi->szText) - 1); + else + lpdi->lpszText = tt_text; + } + } + break; + +# ifdef FEAT_GUI_TABLINE + case TCN_SELCHANGE: + if (gui_mch_showing_tabline() && (hdr->hwndFrom == s_tabhwnd)) + { + send_tabline_event(TabCtrl_GetCurSel(s_tabhwnd) + 1); + return 0L; + } + break; + + case NM_RCLICK: + if (gui_mch_showing_tabline() && (hdr->hwndFrom == s_tabhwnd)) + { + show_tabline_popup_menu(); + return 0L; + } + break; +# endif + + default: + break; + } + return DefWindowProcW(hwnd, WM_NOTIFY, (WPARAM)id, (LPARAM)hdr); +} +#endif + +#if defined(MENUHINTS) && defined(FEAT_MENU) + static LRESULT +_OnMenuSelect(HWND hwnd, WPARAM wParam, LPARAM lParam) +{ + if (((UINT) HIWORD(wParam) + & (0xffff ^ (MF_MOUSESELECT + MF_BITMAP + MF_POPUP))) + == MF_HILITE + && (State & CMDLINE) == 0) + { + UINT idButton; + vimmenu_T *pMenu; + static int did_menu_tip = FALSE; + + if (did_menu_tip) + { + msg_clr_cmdline(); + setcursor(); + out_flush(); + did_menu_tip = FALSE; + } + + idButton = (UINT)LOWORD(wParam); + pMenu = gui_mswin_find_menu(root_menu, idButton); + if (pMenu != NULL && pMenu->strings[MENU_INDEX_TIP] != 0 + && GetMenuState(s_menuBar, pMenu->id, MF_BYCOMMAND) != -1) + { + ++msg_hist_off; + msg((char *)pMenu->strings[MENU_INDEX_TIP]); + --msg_hist_off; + setcursor(); + out_flush(); + did_menu_tip = TRUE; + } + return 0L; + } + return DefWindowProcW(hwnd, WM_MENUSELECT, wParam, lParam); +} +#endif + static LRESULT _OnDpiChanged(HWND hwnd, UINT xdpi, UINT ydpi, RECT *rc) { @@ -4648,46 +4879,11 @@ destroy_sizing_tip(void) #ifdef FEAT_NETBEANS_INTG HANDLE_MSG(hwnd, WM_WINDOWPOSCHANGED, _OnWindowPosChanged); #endif - #ifdef FEAT_GUI_TABLINE - case WM_RBUTTONUP: - { - if (gui_mch_showing_tabline()) - { - POINT pt; - RECT rect; - - /* - * If the cursor is on the tabline, display the tab menu - */ - GetCursorPos((LPPOINT)&pt); - GetWindowRect(s_textArea, &rect); - if (pt.y < rect.top) - { - show_tabline_popup_menu(); - return 0L; - } - } - return DefWindowProcW(hwnd, uMsg, wParam, lParam); - } - case WM_LBUTTONDBLCLK: - { - /* - * If the user double clicked the tabline, create a new tab - */ - if (gui_mch_showing_tabline()) - { - POINT pt; - RECT rect; - - GetCursorPos((LPPOINT)&pt); - GetWindowRect(s_textArea, &rect); - if (pt.y < rect.top) - send_tabline_menu_event(0, TABLINE_MENU_NEW); - } - return DefWindowProcW(hwnd, uMsg, wParam, lParam); - } -#endif + HANDLE_MSG(hwnd, WM_RBUTTONUP, _OnRButtonUp); + HANDLE_MSG(hwnd, WM_LBUTTONDBLCLK, _OnLButtonDown); +#endif + HANDLE_MSG(hwnd, WM_NCHITTEST, _OnNCHitTest); case WM_QUERYENDSESSION: // System wants to go down. gui_shell_closed(); // Will exit when no changed buffers. @@ -4756,200 +4952,13 @@ destroy_sizing_tip(void) #if defined(FEAT_TOOLBAR) || defined(FEAT_GUI_TABLINE) case WM_NOTIFY: - switch (((LPNMHDR) lParam)->code) - { - case TTN_GETDISPINFOW: - case TTN_GETDISPINFO: - { - LPNMHDR hdr = (LPNMHDR)lParam; - char_u *str = NULL; - static void *tt_text = NULL; - - VIM_CLEAR(tt_text); - -# ifdef FEAT_GUI_TABLINE - if (gui_mch_showing_tabline() - && hdr->hwndFrom == TabCtrl_GetToolTips(s_tabhwnd)) - { - POINT pt; - /* - * Mouse is over the GUI tabline. Display the - * tooltip for the tab under the cursor - * - * Get the cursor position within the tab control - */ - GetCursorPos(&pt); - if (ScreenToClient(s_tabhwnd, &pt) != 0) - { - TCHITTESTINFO htinfo; - int idx; - - /* - * Get the tab under the cursor - */ - htinfo.pt.x = pt.x; - htinfo.pt.y = pt.y; - idx = TabCtrl_HitTest(s_tabhwnd, &htinfo); - if (idx != -1) - { - tabpage_T *tp; - - tp = find_tabpage(idx + 1); - if (tp != NULL) - { - get_tabline_label(tp, TRUE); - str = NameBuff; - } - } - } - } -# endif -# ifdef FEAT_TOOLBAR -# ifdef FEAT_GUI_TABLINE - else -# endif - { - UINT idButton; - vimmenu_T *pMenu; - - idButton = (UINT) hdr->idFrom; - pMenu = gui_mswin_find_menu(root_menu, idButton); - if (pMenu) - str = pMenu->strings[MENU_INDEX_TIP]; - } -# endif - if (str != NULL) - { - if (hdr->code == TTN_GETDISPINFOW) - { - LPNMTTDISPINFOW lpdi = (LPNMTTDISPINFOW)lParam; - - // Set the maximum width, this also enables using - // \n for line break. - SendMessage(lpdi->hdr.hwndFrom, TTM_SETMAXTIPWIDTH, - 0, 500); - - tt_text = enc_to_utf16(str, NULL); - lpdi->lpszText = tt_text; - // can't show tooltip if failed - } - else - { - LPNMTTDISPINFO lpdi = (LPNMTTDISPINFO)lParam; - - // Set the maximum width, this also enables using - // \n for line break. - SendMessage(lpdi->hdr.hwndFrom, TTM_SETMAXTIPWIDTH, - 0, 500); - - if (STRLEN(str) < sizeof(lpdi->szText) - || ((tt_text = vim_strsave(str)) == NULL)) - vim_strncpy((char_u *)lpdi->szText, str, - sizeof(lpdi->szText) - 1); - else - lpdi->lpszText = tt_text; - } - } - } - break; -# ifdef FEAT_GUI_TABLINE - case TCN_SELCHANGE: - if (gui_mch_showing_tabline() - && ((LPNMHDR)lParam)->hwndFrom == s_tabhwnd) - { - send_tabline_event(TabCtrl_GetCurSel(s_tabhwnd) + 1); - return 0L; - } - break; - - case NM_RCLICK: - if (gui_mch_showing_tabline() - && ((LPNMHDR)lParam)->hwndFrom == s_tabhwnd) - { - show_tabline_popup_menu(); - return 0L; - } - break; -# endif - default: -# ifdef FEAT_GUI_TABLINE - if (gui_mch_showing_tabline() - && ((LPNMHDR)lParam)->hwndFrom == s_tabhwnd) - return DefWindowProcW(hwnd, uMsg, wParam, lParam); -# endif - break; - } - break; -#endif + return _OnNotify(hwnd, (UINT)wParam, (NMHDR*)lParam); +#endif + #if defined(MENUHINTS) && defined(FEAT_MENU) case WM_MENUSELECT: - if (((UINT) HIWORD(wParam) - & (0xffff ^ (MF_MOUSESELECT + MF_BITMAP + MF_POPUP))) - == MF_HILITE - && (State & CMDLINE) == 0) - { - UINT idButton; - vimmenu_T *pMenu; - static int did_menu_tip = FALSE; - - if (did_menu_tip) - { - msg_clr_cmdline(); - setcursor(); - out_flush(); - did_menu_tip = FALSE; - } - - idButton = (UINT)LOWORD(wParam); - pMenu = gui_mswin_find_menu(root_menu, idButton); - if (pMenu != NULL && pMenu->strings[MENU_INDEX_TIP] != 0 - && GetMenuState(s_menuBar, pMenu->id, MF_BYCOMMAND) != -1) - { - ++msg_hist_off; - msg((char *)pMenu->strings[MENU_INDEX_TIP]); - --msg_hist_off; - setcursor(); - out_flush(); - did_menu_tip = TRUE; - } - return 0L; - } - break; -#endif - case WM_NCHITTEST: - { - LRESULT result; - int x, y; - int xPos = GET_X_LPARAM(lParam); - - result = DefWindowProcW(hwnd, uMsg, wParam, lParam); - if (result == HTCLIENT) - { -#ifdef FEAT_GUI_TABLINE - if (gui_mch_showing_tabline()) - { - int yPos = GET_Y_LPARAM(lParam); - RECT rct; - - // If the cursor is on the GUI tabline, don't process this - // event - GetWindowRect(s_textArea, &rct); - if (yPos < rct.top) - return result; - } -#endif - (void)gui_mch_get_winpos(&x, &y); - xPos -= x; - - if (xPos < 48) // TODO should use system metric? - return HTBOTTOMLEFT; - else - return HTBOTTOMRIGHT; - } - else - return result; - } - // break; notreached + return _OnMenuSelect(hwnd, wParam, lParam); +#endif #ifdef FEAT_MBYTE_IME case WM_IME_NOTIFY: @@ -4971,7 +4980,7 @@ destroy_sizing_tip(void) if (uMsg == s_findrep_msg && s_findrep_msg != 0) _OnFindRepl(); #endif - return DefWindowProcW(hwnd, uMsg, wParam, lParam); + break; } return DefWindowProcW(hwnd, uMsg, wParam, lParam); diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -751,6 +751,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 4159, +/**/ 4158, /**/ 4157,