📄 gui_w32.c
字号:
if (uMsg == WM_MOUSEMOVE)
{
if (lParam == last_lParam)
return;
last_lParam = lParam;
}
/* Handle specially, to centralise coding. We need to be sure we catch all
* possible events which should cause us to restore the cursor (as it is a
* shared resource, we take full responsibility for it).
*/
switch (uMsg)
{
// Omit these, because a shift or control key should not hide the pointer
// case WM_KEYDOWN:
// case WM_SYSKEYDOWN:
case WM_KEYUP:
case WM_SYSKEYUP:
case WM_CHAR:
case WM_SYSCHAR:
/*
* blank out the pointer if necessary
*/
if (p_mh)
gui_mch_mousehide(TRUE);
break;
case WM_MOUSEMOVE:
case WM_LBUTTONDOWN:
case WM_LBUTTONUP:
case WM_MBUTTONDOWN:
case WM_MBUTTONUP:
case WM_RBUTTONDOWN:
case WM_RBUTTONUP:
case WM_NCMOUSEMOVE:
case WM_NCLBUTTONDOWN:
case WM_NCLBUTTONUP:
case WM_NCMBUTTONDOWN:
case WM_NCMBUTTONUP:
case WM_NCRBUTTONDOWN:
case WM_NCRBUTTONUP:
case WM_KILLFOCUS:
/*
* if the pointer is currently hidden, then we should show it.
*/
gui_mch_mousehide(FALSE);
break;
}
}
static LRESULT CALLBACK
_WndProc(
HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam)
{
/*
TRACE("WndProc: hwnd = %08x, msg = %x, wParam = %x, lParam = %x\n",
hwnd, uMsg, wParam, lParam);
*/
HandleMouseHide(uMsg, lParam);
s_uMsg = uMsg;
s_wParam = wParam;
s_lParam = lParam;
switch (uMsg)
{
HANDLE_MSG(hwnd, WM_DEADCHAR, _OnDeadChar);
HANDLE_MSG(hwnd, WM_SYSDEADCHAR, _OnDeadChar);
/* HANDLE_MSG(hwnd, WM_ACTIVATE, _OnActivate); */
HANDLE_MSG(hwnd, WM_CHAR, _OnChar);
HANDLE_MSG(hwnd, WM_CLOSE, _OnClose);
/* HANDLE_MSG(hwnd, WM_COMMAND, _OnCommand); */
HANDLE_MSG(hwnd, WM_DESTROY, _OnDestroy);
HANDLE_MSG(hwnd, WM_DROPFILES, _OnDropFiles);
HANDLE_MSG(hwnd, WM_HSCROLL, _OnScroll);
HANDLE_MSG(hwnd, WM_KILLFOCUS, _OnKillFocus);
HANDLE_MSG(hwnd, WM_COMMAND, _OnMenu);
/* HANDLE_MSG(hwnd, WM_MOVE, _OnMove); */
/* HANDLE_MSG(hwnd, WM_NCACTIVATE, _OnNCActivate); */
HANDLE_MSG(hwnd, WM_SETFOCUS, _OnSetFocus);
HANDLE_MSG(hwnd, WM_SIZE, _OnSize);
/* HANDLE_MSG(hwnd, WM_SYSCOMMAND, _OnSysCommand); */
/* HANDLE_MSG(hwnd, WM_SYSKEYDOWN, _OnAltKey); */
/* HANDLE_MSG(hwnd, WM_SYSKEYUP, _OnAltKey); */
HANDLE_MSG(hwnd, WM_VSCROLL, _OnScroll);
HANDLE_MSG(hwnd, WM_WINDOWPOSCHANGING, _OnWindowPosChanging);
HANDLE_MSG(hwnd, WM_ACTIVATEAPP, _OnActivateApp);
/* HANDLE_MSG(hwnd, WM_SYSCHAR, _OnSysChar); */
case WM_SYSCHAR:
/*
* if 'winaltkeys' is "no", or it's "menu" and it's not a menu
* shortcut key, handle like a typed ALT key, otherwise call Windows
* ALT key handling.
*/
if (p_wak[0] == 'n'
|| (p_wak[0] == 'm' && !gui_is_menu_shortcut((int)wParam)))
return HANDLE_WM_SYSCHAR((hwnd), (wParam), (lParam), (_OnSysChar));
else
return DefWindowProc(hwnd, uMsg, wParam, lParam);
case WM_ERASEBKGND:
_OnEraseBG(hwnd);
break;
case WM_CREATE: /* HANDLE_MSG doesn't seem to handle this one */
return _OnCreate (hwnd, (LPCREATESTRUCT)lParam);
case WM_SIZING: /* HANDLE_MSG doesn't seem to handle this one */
return _DuringSizing(hwnd, wParam, (LPRECT)lParam);
case WM_MOUSEWHEEL:
_OnMouseWheel(hwnd, HIWORD(wParam));
break;
#ifdef USE_GUI_WIN32_TOOLBAR
case WM_NOTIFY:
switch (((LPNMHDR) lParam)->code)
{
case TTN_NEEDTEXT:
{
LPTOOLTIPTEXT lpttt;
UINT idButton;
int idx;
GuiMenu *pMenu;
lpttt = (LPTOOLTIPTEXT)lParam;
idButton = lpttt->hdr.idFrom;
pMenu = gui_w32_find_menu(gui.root_menu, idButton);
if (pMenu)
{
idx = MENU_INDEX_TIP;
if (pMenu->strings[idx])
{
lpttt->hinst = NULL; /* string, not resource*/
lpttt->lpszText = pMenu->strings[idx];
}
}
}
break;
default:
break;
}
break;
#endif
#ifdef MENUHINTS
case WM_MENUSELECT:
if ((((UINT) HIWORD(wParam) &
(0xffff ^ (MF_MOUSESELECT + MF_BITMAP))) == MF_HILITE) &
((State & CMDLINE) == 0))
{
UINT idButton;
int idx;
GuiMenu *pMenu;
idButton = (UINT)LOWORD(wParam);
pMenu = gui_w32_find_menu(gui.root_menu, idButton);
if (pMenu)
{
idx = MENU_INDEX_TIP;
if (pMenu->strings[idx])
msg(pMenu->strings[idx]);
else
msg("");
setcursor();
out_flush();
}
}
break;
#endif
default:
if (uMsg == msh_msgmousewheel && msh_msgmousewheel != 0)
{ /* handle MSH_MOUSEWHEEL messages for Intellimouse */
_OnMouseWheel(hwnd, HIWORD(wParam));
break;
}
#ifdef WIN32_FIND_REPLACE
else if (uMsg == s_findrep_msg && s_findrep_msg != 0)
{
_OnFindRepl();
}
#endif
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
return 1;
}
static LRESULT CALLBACK
_TextAreaWndProc(
HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam)
{
/*
TRACE("TextAreaWndProc: hwnd = %08x, msg = %x, wParam = %x, lParam = %x\n",
hwnd, uMsg, wParam, lParam);
*/
HandleMouseHide(uMsg, lParam);
s_uMsg = uMsg;
s_wParam = wParam;
s_lParam = lParam;
switch (uMsg)
{
HANDLE_MSG(hwnd, WM_LBUTTONDBLCLK,_OnMouseButtonDown);
HANDLE_MSG(hwnd, WM_LBUTTONDOWN,_OnMouseButtonDown);
HANDLE_MSG(hwnd, WM_LBUTTONUP, _OnMouseMoveOrRelease);
HANDLE_MSG(hwnd, WM_MBUTTONDBLCLK,_OnMouseButtonDown);
HANDLE_MSG(hwnd, WM_MBUTTONDOWN,_OnMouseButtonDown);
HANDLE_MSG(hwnd, WM_MBUTTONUP, _OnMouseMoveOrRelease);
HANDLE_MSG(hwnd, WM_MOUSEMOVE, _OnMouseMoveOrRelease);
HANDLE_MSG(hwnd, WM_PAINT, _OnPaint);
HANDLE_MSG(hwnd, WM_RBUTTONDBLCLK,_OnMouseButtonDown);
HANDLE_MSG(hwnd, WM_RBUTTONDOWN,_OnMouseButtonDown);
HANDLE_MSG(hwnd, WM_RBUTTONUP, _OnMouseMoveOrRelease);
default:
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
}
/*
* End of call-back routines
*/
/*
* Parse the GUI related command-line arguments. Any arguments used are
* deleted from argv, and *argc is decremented accordingly. This is called
* when vim is started, whether or not the GUI has been started.
*/
void
gui_mch_prepare(int *argc, char **argv)
{
/* We don't have any command line arguments for the Windows GUI yet */
/* get the OS version info */
os_version.dwOSVersionInfoSize = sizeof(os_version);
GetVersionEx(&os_version); /* this call works on Win32s, Win95 and WinNT */
}
/*
* Initialise the GUI. Create all the windows, set up all the call-backs
* etc.
*/
int
gui_mch_init(void)
{
const char szVimWndClass[] = VIM_CLASS;
const char szTextAreaClass[] = "VimTextArea";
WNDCLASS wndclass;
/* Display any pending error messages */
mch_display_error();
/*
* Load the tearoff bitmap
*/
s_htearbitmap = LoadBitmap(s_hinst, "IDB_TEAROFF");
gui.scrollbar_width = GetSystemMetrics(SM_CXVSCROLL);
gui.scrollbar_height = GetSystemMetrics(SM_CYHSCROLL);
gui.menu_height = 0; /* Windows takes care of this */
gui.border_width = 0;
wndclass.style = CS_HREDRAW | CS_VREDRAW;
wndclass.lpfnWndProc = _WndProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = s_hinst;
wndclass.hIcon = LoadIcon(wndclass.hInstance, "IDR_VIM");
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndclass.hbrBackground = GetStockBrush(LTGRAY_BRUSH);
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = szVimWndClass;
if (RegisterClass(&wndclass) == 0)
return FAIL;
s_hwnd = CreateWindow(
szVimWndClass, "Vim W32 GUI",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
100, /* Any value will do */
100, /* Any value will do */
NULL, NULL,
s_hinst, NULL);
if (s_hwnd == NULL)
return FAIL;
/* Create the text area window */
wndclass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
wndclass.lpfnWndProc = _TextAreaWndProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = s_hinst;
wndclass.hIcon = NULL;
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndclass.hbrBackground = NULL;
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = szTextAreaClass;
if (RegisterClass(&wndclass) == 0)
return FAIL;
s_textArea = CreateWindow(
szTextAreaClass, "Vim text area",
WS_CHILD | WS_VISIBLE, 0, 0,
100, /* Any value will do for now */
100, /* Any value will do for now */
s_hwnd, NULL,
s_hinst, NULL);
if (s_textArea == NULL)
return FAIL;
s_menuBar = CreateMenu();
s_hdc = GetDC(s_textArea);
DragAcceptFiles(s_hwnd, TRUE);
/* Do we need to bother with this? */
/* m_fMouseAvail = GetSystemMetrics(SM_MOUSEPRESENT); */
/* Get background/foreground colors from system */
gui.norm_pixel = GetSysColor(COLOR_WINDOWTEXT);
gui.back_pixel = GetSysColor(COLOR_WINDOW);
gui.def_norm_pixel = gui.norm_pixel;
gui.def_back_pixel = gui.back_pixel;
/* Get the colors from the "Normal" group (set in syntax.c or in a vimrc
* file) */
set_normal_colors();
/*
* Check that none of the colors are the same as the background color.
* Then store the current values as the defaults.
*/
gui_check_colors();
gui.def_norm_pixel = gui.norm_pixel;
gui.def_back_pixel = gui.back_pixel;
/* Get the colors for the highlight groups (gui_check_colors() might have
* changed them) */
highlight_gui_started();
/*
* Start out by adding the configured border width into the border offset
*/
gui.border_offset = gui.border_width;
/*
* Set up for Intellimouse processing
*/
init_mouse_wheel();
/*
* compute a couple of metrics used for the dialogs
*/
get_dialog_font_metrics();
#ifdef USE_GUI_WIN32_TOOLBAR
/*
* Create the toolbar
*/
initialise_toolbar();
#endif
#ifdef WIN32_FIND_REPLACE
/*
* Initialise the dialog box stuff
*/
s_findrep_msg = RegisterWindowMessage(FINDMSGSTRING);
/* Initialise the struct */
s_findrep_struct.lStructSize = sizeof(s_findrep_struct);
s_findrep_struct.lpstrFindWhat = alloc(256);
s_findrep_struct.lpstrFindWhat[0] = NUL;
s_findrep_struct.lpstrReplaceWith = alloc(256);
s_findrep_struct.lpstrReplaceWith[0] = NUL;
s_findrep_struct.wFindWhatLen = 256;
s_findrep_struct.wReplaceWithLen = 256;
#endif
return OK;
}
/*
* Called when the foreground or background color has been changed.
*/
void
gui_mch_new_colors(void)
{
/* nothing to do? */
}
/*
* Open the GUI window which was created by a call to gui_mch_init().
*/
int
gui_mch_open(void)
{
/* Actually open the window */
ShowWindow(s_hwnd, SW_SHOWNORMAL);
return OK;
}
void
gui_mch_exit(int rc)
{
ReleaseDC(s_textArea, s_hdc);
/*
* Unload the tearoff bitmap
*/
(void)DeleteObject((HGDIOBJ) s_htearbitmap);
/* Destroy our window (if we have one). */
if (s_hwnd != NULL)
{
destroying = TRUE; /* ignore WM_DESTROY message now */
DestroyWindow(s_hwnd);
}
}
/*
* Set the size of the window to the given width and height in pixels.
*/
void
gui_mch_set_winsize(int width, int height, int min_width, int min_height,
int base_width, int base_height)
{
RECT workarea_rect;
int win_width, win_height;
int win_xpos, win_ypos;
WINDOWPLACEMENT wndpl;
/* try to keep window completely on screen */
/* get size of the screen work area (excludes taskbar, appbars) */
SystemParametersInfo(SPI_GETWORKAREA, 0, &workarea_rect, 0);
/* get current posision of our window */
wndpl.length = sizeof(WINDOWPLACEMENT);
GetWindowPlacement(s_hwnd, &wndpl);
if (wndpl.showCmd == SW_SHOWNORMAL)
{
win_xpos = wndpl.rcNormalPosition.left;
win_ypos = wndpl.rcNormalPosition.top;
}
else
{
win_xpos = workarea_rect.left;
win_ypos = workarea_rect.top;
}
/* compute the size of the outside of the window */
win_width = width + GetSystemMetrics(SM_CXSIZEFRAME) * 2;
win_height = height + GetSystemMetrics(SM_CYSIZEFRAME) * 2
+ GetSystemMetrics(SM_CYCAPTION)
+ gui_w32_get_menu_height(FALSE);
/* if the window is going off the screen, move it on to the screen */
if (win_xpos + win_width > workarea_rect.right)
win_xpos = workarea_rect.right - win_width;
if (win_xpos < workarea_rect.left)
win_xpos = workarea_rect.left;
if (win_ypos + win_height > workarea_rect.bottom)
win_ypos = workarea_rect.bottom - win_height;
if (win_ypos < workarea_rect.top)
win_ypos = workarea_rect.top;
/* set window position */
SetWindowPos(s_hwnd, NULL, win_xpos, win_ypos, win_width, win_height,
SWP_NOZORDER | SWP_NOACTIVATE);
/* Menu may wrap differently now */
gui_w32_get_menu_height(!gui.starting);
}
void
gui_mch_get_screen_dimensions(int *screen_w, int *screen_h)
{
RECT workarea_rect;
/* get size of the screen work area (excludes taskbar, appbars) */
SystemParametersInfo(SPI_GETWORKAREA, 0, &workarea_rect, 0);
*screen_w = workarea_rect.right - workarea_rect.left
- GetSystemMetrics(SM_CXSIZEFRAME) * 2;
*screen_h = workarea_rect.bottom - workarea_rect.top
- GetSystemMetrics(SM_CYSIZEFRAME) * 2
- GetSystemMetrics(SM_CYCAPTION)
- gui_w32_get_menu_height(FALSE);
}
void
gui_mch_set_text_area_pos(int x, int y, int w, int h)
{
SetWindowPos(s_textArea, NULL, x, y, w, h, SWP_NOZORDER | SWP_NOACTIVATE);
#ifdef USE_GUI_WIN32_TOOLBAR
if (vim_strchr(p_guioptions, GO_TOOLBAR) != NULL)
SendMessage(s_toolbarhwnd, WM_SIZE,
(WPARAM)0, (LPARAM)(w + (long)(TOOLBAR_BUTTON_HEIGHT+8)<<16));
#endif
}
/*
* Scrollbar stuff:
*/
void
gui_mch_enable_scrollbar(
GuiScrollbar *sb,
int flag)
{
ShowScrollBar(sb->id, SB_CTL, flag);
}
void
gui_mch_set_scrollbar_thumb(
GuiScrollbar *sb,
int val,
int size,
int max)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -