comparison src/gui_w32.c @ 27261:a63505f33894 v8.2.4159

patch 8.2.4159: MS-Windows: _WndProc() is very long Commit: https://github.com/vim/vim/commit/92000e2e713a68f80a25472cfa74058366c58c9c Author: K.Takata <kentkt@csc.jp> 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)
author Bram Moolenaar <Bram@vim.org>
date Thu, 20 Jan 2022 16:15:05 +0100
parents 59cdcd1e47b8
children f7d73708b391
comparison
equal deleted inserted replaced
27260:450f249d37b7 27261:a63505f33894
4578 4578
4579 show_sizing_tip(cols, rows); 4579 show_sizing_tip(cols, rows);
4580 return TRUE; 4580 return TRUE;
4581 } 4581 }
4582 4582
4583 #ifdef FEAT_GUI_TABLINE
4584 static void
4585 _OnRButtonUp(HWND hwnd, int x, int y, UINT keyFlags)
4586 {
4587 if (gui_mch_showing_tabline())
4588 {
4589 POINT pt;
4590 RECT rect;
4591
4592 /*
4593 * If the cursor is on the tabline, display the tab menu
4594 */
4595 GetCursorPos(&pt);
4596 GetWindowRect(s_textArea, &rect);
4597 if (pt.y < rect.top)
4598 {
4599 show_tabline_popup_menu();
4600 return;
4601 }
4602 }
4603 FORWARD_WM_RBUTTONUP(hwnd, x, y, keyFlags, DefWindowProcW);
4604 }
4605
4606 static void
4607 _OnLButtonDown(HWND hwnd, BOOL fDoubleClick, int x, int y, UINT keyFlags)
4608 {
4609 /*
4610 * If the user double clicked the tabline, create a new tab
4611 */
4612 if (gui_mch_showing_tabline())
4613 {
4614 POINT pt;
4615 RECT rect;
4616
4617 GetCursorPos(&pt);
4618 GetWindowRect(s_textArea, &rect);
4619 if (pt.y < rect.top)
4620 send_tabline_menu_event(0, TABLINE_MENU_NEW);
4621 }
4622 FORWARD_WM_LBUTTONDOWN(hwnd, fDoubleClick, x, y, keyFlags, DefWindowProcW);
4623 }
4624 #endif
4625
4626 static UINT
4627 _OnNCHitTest(HWND hwnd, int xPos, int yPos)
4628 {
4629 UINT result;
4630 int x, y;
4631
4632 result = FORWARD_WM_NCHITTEST(hwnd, xPos, yPos, DefWindowProcW);
4633 if (result != HTCLIENT)
4634 return result;
4635
4636 #ifdef FEAT_GUI_TABLINE
4637 if (gui_mch_showing_tabline())
4638 {
4639 RECT rct;
4640
4641 // If the cursor is on the GUI tabline, don't process this event
4642 GetWindowRect(s_textArea, &rct);
4643 if (yPos < rct.top)
4644 return result;
4645 }
4646 #endif
4647 (void)gui_mch_get_winpos(&x, &y);
4648 xPos -= x;
4649
4650 if (xPos < 48) // <VN> TODO should use system metric?
4651 return HTBOTTOMLEFT;
4652 else
4653 return HTBOTTOMRIGHT;
4654 }
4655
4656 #if defined(FEAT_TOOLBAR) || defined(FEAT_GUI_TABLINE)
4657 static LRESULT
4658 _OnNotify(HWND hwnd, UINT id, NMHDR *hdr)
4659 {
4660 switch (hdr->code)
4661 {
4662 case TTN_GETDISPINFOW:
4663 case TTN_GETDISPINFO:
4664 {
4665 char_u *str = NULL;
4666 static void *tt_text = NULL;
4667
4668 VIM_CLEAR(tt_text);
4669
4670 # ifdef FEAT_GUI_TABLINE
4671 if (gui_mch_showing_tabline()
4672 && hdr->hwndFrom == TabCtrl_GetToolTips(s_tabhwnd))
4673 {
4674 POINT pt;
4675 /*
4676 * Mouse is over the GUI tabline. Display the
4677 * tooltip for the tab under the cursor
4678 *
4679 * Get the cursor position within the tab control
4680 */
4681 GetCursorPos(&pt);
4682 if (ScreenToClient(s_tabhwnd, &pt) != 0)
4683 {
4684 TCHITTESTINFO htinfo;
4685 int idx;
4686
4687 /*
4688 * Get the tab under the cursor
4689 */
4690 htinfo.pt.x = pt.x;
4691 htinfo.pt.y = pt.y;
4692 idx = TabCtrl_HitTest(s_tabhwnd, &htinfo);
4693 if (idx != -1)
4694 {
4695 tabpage_T *tp;
4696
4697 tp = find_tabpage(idx + 1);
4698 if (tp != NULL)
4699 {
4700 get_tabline_label(tp, TRUE);
4701 str = NameBuff;
4702 }
4703 }
4704 }
4705 }
4706 # endif
4707 # ifdef FEAT_TOOLBAR
4708 # ifdef FEAT_GUI_TABLINE
4709 else
4710 # endif
4711 {
4712 UINT idButton;
4713 vimmenu_T *pMenu;
4714
4715 idButton = (UINT) hdr->idFrom;
4716 pMenu = gui_mswin_find_menu(root_menu, idButton);
4717 if (pMenu)
4718 str = pMenu->strings[MENU_INDEX_TIP];
4719 }
4720 # endif
4721 if (str == NULL)
4722 break;
4723
4724 // Set the maximum width, this also enables using \n for
4725 // line break.
4726 SendMessage(hdr->hwndFrom, TTM_SETMAXTIPWIDTH, 0, 500);
4727
4728 if (hdr->code == TTN_GETDISPINFOW)
4729 {
4730 LPNMTTDISPINFOW lpdi = (LPNMTTDISPINFOW)hdr;
4731
4732 tt_text = enc_to_utf16(str, NULL);
4733 lpdi->lpszText = tt_text;
4734 // can't show tooltip if failed
4735 }
4736 else
4737 {
4738 LPNMTTDISPINFO lpdi = (LPNMTTDISPINFO)hdr;
4739
4740 if (STRLEN(str) < sizeof(lpdi->szText)
4741 || ((tt_text = vim_strsave(str)) == NULL))
4742 vim_strncpy((char_u *)lpdi->szText, str,
4743 sizeof(lpdi->szText) - 1);
4744 else
4745 lpdi->lpszText = tt_text;
4746 }
4747 }
4748 break;
4749
4750 # ifdef FEAT_GUI_TABLINE
4751 case TCN_SELCHANGE:
4752 if (gui_mch_showing_tabline() && (hdr->hwndFrom == s_tabhwnd))
4753 {
4754 send_tabline_event(TabCtrl_GetCurSel(s_tabhwnd) + 1);
4755 return 0L;
4756 }
4757 break;
4758
4759 case NM_RCLICK:
4760 if (gui_mch_showing_tabline() && (hdr->hwndFrom == s_tabhwnd))
4761 {
4762 show_tabline_popup_menu();
4763 return 0L;
4764 }
4765 break;
4766 # endif
4767
4768 default:
4769 break;
4770 }
4771 return DefWindowProcW(hwnd, WM_NOTIFY, (WPARAM)id, (LPARAM)hdr);
4772 }
4773 #endif
4774
4775 #if defined(MENUHINTS) && defined(FEAT_MENU)
4776 static LRESULT
4777 _OnMenuSelect(HWND hwnd, WPARAM wParam, LPARAM lParam)
4778 {
4779 if (((UINT) HIWORD(wParam)
4780 & (0xffff ^ (MF_MOUSESELECT + MF_BITMAP + MF_POPUP)))
4781 == MF_HILITE
4782 && (State & CMDLINE) == 0)
4783 {
4784 UINT idButton;
4785 vimmenu_T *pMenu;
4786 static int did_menu_tip = FALSE;
4787
4788 if (did_menu_tip)
4789 {
4790 msg_clr_cmdline();
4791 setcursor();
4792 out_flush();
4793 did_menu_tip = FALSE;
4794 }
4795
4796 idButton = (UINT)LOWORD(wParam);
4797 pMenu = gui_mswin_find_menu(root_menu, idButton);
4798 if (pMenu != NULL && pMenu->strings[MENU_INDEX_TIP] != 0
4799 && GetMenuState(s_menuBar, pMenu->id, MF_BYCOMMAND) != -1)
4800 {
4801 ++msg_hist_off;
4802 msg((char *)pMenu->strings[MENU_INDEX_TIP]);
4803 --msg_hist_off;
4804 setcursor();
4805 out_flush();
4806 did_menu_tip = TRUE;
4807 }
4808 return 0L;
4809 }
4810 return DefWindowProcW(hwnd, WM_MENUSELECT, wParam, lParam);
4811 }
4812 #endif
4813
4583 static LRESULT 4814 static LRESULT
4584 _OnDpiChanged(HWND hwnd, UINT xdpi, UINT ydpi, RECT *rc) 4815 _OnDpiChanged(HWND hwnd, UINT xdpi, UINT ydpi, RECT *rc)
4585 { 4816 {
4586 s_dpi = ydpi; 4817 s_dpi = ydpi;
4587 s_in_dpichanged = TRUE; 4818 s_in_dpichanged = TRUE;
4646 // HANDLE_MSG(hwnd, WM_WINDOWPOSCHANGING, _OnWindowPosChanging); 4877 // HANDLE_MSG(hwnd, WM_WINDOWPOSCHANGING, _OnWindowPosChanging);
4647 HANDLE_MSG(hwnd, WM_ACTIVATEAPP, _OnActivateApp); 4878 HANDLE_MSG(hwnd, WM_ACTIVATEAPP, _OnActivateApp);
4648 #ifdef FEAT_NETBEANS_INTG 4879 #ifdef FEAT_NETBEANS_INTG
4649 HANDLE_MSG(hwnd, WM_WINDOWPOSCHANGED, _OnWindowPosChanged); 4880 HANDLE_MSG(hwnd, WM_WINDOWPOSCHANGED, _OnWindowPosChanged);
4650 #endif 4881 #endif
4651
4652 #ifdef FEAT_GUI_TABLINE 4882 #ifdef FEAT_GUI_TABLINE
4653 case WM_RBUTTONUP: 4883 HANDLE_MSG(hwnd, WM_RBUTTONUP, _OnRButtonUp);
4654 { 4884 HANDLE_MSG(hwnd, WM_LBUTTONDBLCLK, _OnLButtonDown);
4655 if (gui_mch_showing_tabline()) 4885 #endif
4656 { 4886 HANDLE_MSG(hwnd, WM_NCHITTEST, _OnNCHitTest);
4657 POINT pt;
4658 RECT rect;
4659
4660 /*
4661 * If the cursor is on the tabline, display the tab menu
4662 */
4663 GetCursorPos((LPPOINT)&pt);
4664 GetWindowRect(s_textArea, &rect);
4665 if (pt.y < rect.top)
4666 {
4667 show_tabline_popup_menu();
4668 return 0L;
4669 }
4670 }
4671 return DefWindowProcW(hwnd, uMsg, wParam, lParam);
4672 }
4673 case WM_LBUTTONDBLCLK:
4674 {
4675 /*
4676 * If the user double clicked the tabline, create a new tab
4677 */
4678 if (gui_mch_showing_tabline())
4679 {
4680 POINT pt;
4681 RECT rect;
4682
4683 GetCursorPos((LPPOINT)&pt);
4684 GetWindowRect(s_textArea, &rect);
4685 if (pt.y < rect.top)
4686 send_tabline_menu_event(0, TABLINE_MENU_NEW);
4687 }
4688 return DefWindowProcW(hwnd, uMsg, wParam, lParam);
4689 }
4690 #endif
4691 4887
4692 case WM_QUERYENDSESSION: // System wants to go down. 4888 case WM_QUERYENDSESSION: // System wants to go down.
4693 gui_shell_closed(); // Will exit when no changed buffers. 4889 gui_shell_closed(); // Will exit when no changed buffers.
4694 return FALSE; // Do NOT allow system to go down. 4890 return FALSE; // Do NOT allow system to go down.
4695 4891
4754 case WM_SETTINGCHANGE: 4950 case WM_SETTINGCHANGE:
4755 return _OnSettingChange((UINT)wParam); 4951 return _OnSettingChange((UINT)wParam);
4756 4952
4757 #if defined(FEAT_TOOLBAR) || defined(FEAT_GUI_TABLINE) 4953 #if defined(FEAT_TOOLBAR) || defined(FEAT_GUI_TABLINE)
4758 case WM_NOTIFY: 4954 case WM_NOTIFY:
4759 switch (((LPNMHDR) lParam)->code) 4955 return _OnNotify(hwnd, (UINT)wParam, (NMHDR*)lParam);
4760 { 4956 #endif
4761 case TTN_GETDISPINFOW: 4957
4762 case TTN_GETDISPINFO:
4763 {
4764 LPNMHDR hdr = (LPNMHDR)lParam;
4765 char_u *str = NULL;
4766 static void *tt_text = NULL;
4767
4768 VIM_CLEAR(tt_text);
4769
4770 # ifdef FEAT_GUI_TABLINE
4771 if (gui_mch_showing_tabline()
4772 && hdr->hwndFrom == TabCtrl_GetToolTips(s_tabhwnd))
4773 {
4774 POINT pt;
4775 /*
4776 * Mouse is over the GUI tabline. Display the
4777 * tooltip for the tab under the cursor
4778 *
4779 * Get the cursor position within the tab control
4780 */
4781 GetCursorPos(&pt);
4782 if (ScreenToClient(s_tabhwnd, &pt) != 0)
4783 {
4784 TCHITTESTINFO htinfo;
4785 int idx;
4786
4787 /*
4788 * Get the tab under the cursor
4789 */
4790 htinfo.pt.x = pt.x;
4791 htinfo.pt.y = pt.y;
4792 idx = TabCtrl_HitTest(s_tabhwnd, &htinfo);
4793 if (idx != -1)
4794 {
4795 tabpage_T *tp;
4796
4797 tp = find_tabpage(idx + 1);
4798 if (tp != NULL)
4799 {
4800 get_tabline_label(tp, TRUE);
4801 str = NameBuff;
4802 }
4803 }
4804 }
4805 }
4806 # endif
4807 # ifdef FEAT_TOOLBAR
4808 # ifdef FEAT_GUI_TABLINE
4809 else
4810 # endif
4811 {
4812 UINT idButton;
4813 vimmenu_T *pMenu;
4814
4815 idButton = (UINT) hdr->idFrom;
4816 pMenu = gui_mswin_find_menu(root_menu, idButton);
4817 if (pMenu)
4818 str = pMenu->strings[MENU_INDEX_TIP];
4819 }
4820 # endif
4821 if (str != NULL)
4822 {
4823 if (hdr->code == TTN_GETDISPINFOW)
4824 {
4825 LPNMTTDISPINFOW lpdi = (LPNMTTDISPINFOW)lParam;
4826
4827 // Set the maximum width, this also enables using
4828 // \n for line break.
4829 SendMessage(lpdi->hdr.hwndFrom, TTM_SETMAXTIPWIDTH,
4830 0, 500);
4831
4832 tt_text = enc_to_utf16(str, NULL);
4833 lpdi->lpszText = tt_text;
4834 // can't show tooltip if failed
4835 }
4836 else
4837 {
4838 LPNMTTDISPINFO lpdi = (LPNMTTDISPINFO)lParam;
4839
4840 // Set the maximum width, this also enables using
4841 // \n for line break.
4842 SendMessage(lpdi->hdr.hwndFrom, TTM_SETMAXTIPWIDTH,
4843 0, 500);
4844
4845 if (STRLEN(str) < sizeof(lpdi->szText)
4846 || ((tt_text = vim_strsave(str)) == NULL))
4847 vim_strncpy((char_u *)lpdi->szText, str,
4848 sizeof(lpdi->szText) - 1);
4849 else
4850 lpdi->lpszText = tt_text;
4851 }
4852 }
4853 }
4854 break;
4855 # ifdef FEAT_GUI_TABLINE
4856 case TCN_SELCHANGE:
4857 if (gui_mch_showing_tabline()
4858 && ((LPNMHDR)lParam)->hwndFrom == s_tabhwnd)
4859 {
4860 send_tabline_event(TabCtrl_GetCurSel(s_tabhwnd) + 1);
4861 return 0L;
4862 }
4863 break;
4864
4865 case NM_RCLICK:
4866 if (gui_mch_showing_tabline()
4867 && ((LPNMHDR)lParam)->hwndFrom == s_tabhwnd)
4868 {
4869 show_tabline_popup_menu();
4870 return 0L;
4871 }
4872 break;
4873 # endif
4874 default:
4875 # ifdef FEAT_GUI_TABLINE
4876 if (gui_mch_showing_tabline()
4877 && ((LPNMHDR)lParam)->hwndFrom == s_tabhwnd)
4878 return DefWindowProcW(hwnd, uMsg, wParam, lParam);
4879 # endif
4880 break;
4881 }
4882 break;
4883 #endif
4884 #if defined(MENUHINTS) && defined(FEAT_MENU) 4958 #if defined(MENUHINTS) && defined(FEAT_MENU)
4885 case WM_MENUSELECT: 4959 case WM_MENUSELECT:
4886 if (((UINT) HIWORD(wParam) 4960 return _OnMenuSelect(hwnd, wParam, lParam);
4887 & (0xffff ^ (MF_MOUSESELECT + MF_BITMAP + MF_POPUP))) 4961 #endif
4888 == MF_HILITE
4889 && (State & CMDLINE) == 0)
4890 {
4891 UINT idButton;
4892 vimmenu_T *pMenu;
4893 static int did_menu_tip = FALSE;
4894
4895 if (did_menu_tip)
4896 {
4897 msg_clr_cmdline();
4898 setcursor();
4899 out_flush();
4900 did_menu_tip = FALSE;
4901 }
4902
4903 idButton = (UINT)LOWORD(wParam);
4904 pMenu = gui_mswin_find_menu(root_menu, idButton);
4905 if (pMenu != NULL && pMenu->strings[MENU_INDEX_TIP] != 0
4906 && GetMenuState(s_menuBar, pMenu->id, MF_BYCOMMAND) != -1)
4907 {
4908 ++msg_hist_off;
4909 msg((char *)pMenu->strings[MENU_INDEX_TIP]);
4910 --msg_hist_off;
4911 setcursor();
4912 out_flush();
4913 did_menu_tip = TRUE;
4914 }
4915 return 0L;
4916 }
4917 break;
4918 #endif
4919 case WM_NCHITTEST:
4920 {
4921 LRESULT result;
4922 int x, y;
4923 int xPos = GET_X_LPARAM(lParam);
4924
4925 result = DefWindowProcW(hwnd, uMsg, wParam, lParam);
4926 if (result == HTCLIENT)
4927 {
4928 #ifdef FEAT_GUI_TABLINE
4929 if (gui_mch_showing_tabline())
4930 {
4931 int yPos = GET_Y_LPARAM(lParam);
4932 RECT rct;
4933
4934 // If the cursor is on the GUI tabline, don't process this
4935 // event
4936 GetWindowRect(s_textArea, &rct);
4937 if (yPos < rct.top)
4938 return result;
4939 }
4940 #endif
4941 (void)gui_mch_get_winpos(&x, &y);
4942 xPos -= x;
4943
4944 if (xPos < 48) // <VN> TODO should use system metric?
4945 return HTBOTTOMLEFT;
4946 else
4947 return HTBOTTOMRIGHT;
4948 }
4949 else
4950 return result;
4951 }
4952 // break; notreached
4953 4962
4954 #ifdef FEAT_MBYTE_IME 4963 #ifdef FEAT_MBYTE_IME
4955 case WM_IME_NOTIFY: 4964 case WM_IME_NOTIFY:
4956 if (!_OnImeNotify(hwnd, (DWORD)wParam, (DWORD)lParam)) 4965 if (!_OnImeNotify(hwnd, (DWORD)wParam, (DWORD)lParam))
4957 return DefWindowProcW(hwnd, uMsg, wParam, lParam); 4966 return DefWindowProcW(hwnd, uMsg, wParam, lParam);
4969 default: 4978 default:
4970 #ifdef MSWIN_FIND_REPLACE 4979 #ifdef MSWIN_FIND_REPLACE
4971 if (uMsg == s_findrep_msg && s_findrep_msg != 0) 4980 if (uMsg == s_findrep_msg && s_findrep_msg != 0)
4972 _OnFindRepl(); 4981 _OnFindRepl();
4973 #endif 4982 #endif
4974 return DefWindowProcW(hwnd, uMsg, wParam, lParam); 4983 break;
4975 } 4984 }
4976 4985
4977 return DefWindowProcW(hwnd, uMsg, wParam, lParam); 4986 return DefWindowProcW(hwnd, uMsg, wParam, lParam);
4978 } 4987 }
4979 4988