⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gui_w32.c

📁 VIM文本编辑器
💻 C
📖 第 1 页 / 共 5 页
字号:
	    break;

	default:
	    /* TRACE("Unknown scrollbar event %d\n", code); */
	    return 0;
    }

    si.cbSize = sizeof(si);
    si.fMask = SIF_POS;
    if (scroll_shift > 0)
	si.nPos = val >> scroll_shift;
    else
	si.nPos = val;
    SetScrollInfo(hwndCtl, SB_CTL, &si, TRUE);

    /*
     * When moving a vertical scrollbar, move the other vertical scrollbar too.
     */
    if (sb->wp != NULL)
    {
	if (sb == &sb->wp->w_scrollbars[SBAR_LEFT])
	    SetScrollInfo(sb->wp->w_scrollbars[SBAR_RIGHT].id,
							   SB_CTL, &si, TRUE);
	else
	    SetScrollInfo(sb->wp->w_scrollbars[SBAR_LEFT].id,
							   SB_CTL, &si, TRUE);
    }

    /*
     * Scrollbars seem to grab focus and vim doesn't read the input queue until
     * you stop dragging the scrollbar.  We get here each time the scrollbar is
     * dragged another pixel, but as far as the rest of vim goes, it thinks
     * we're just hanging in the call to DispatchMessage() in
     * process_message().  The DispatchMessage() call that hangs was passed a
     * mouse button click event in the scrollbar window. -- webb.
     *
     * Solution: Do the scrolling right here.  But only when allowed.
     * Ignore the scrollbars while executing an external command or when there
     * are still characters to be processed.
     */
    if (dont_scroll || !termcap_active || !vim_is_input_buf_empty())
	return 0;

    if (dragging)
    {
	if (sb->wp == NULL)
	    gui.dragged_sb = SBAR_BOTTOM;
	else if (sb == &sb->wp->w_scrollbars[SBAR_LEFT])
	    gui.dragged_sb = SBAR_LEFT;
	else
	    gui.dragged_sb = SBAR_RIGHT;
	gui.dragged_wp = sb->wp;
    }
    else
	gui.dragged_sb = SBAR_NONE;

    /* Vertical sbar info is kept in the first sbar (the left one) */
    if (sb->wp != NULL)
	sb = &sb->wp->w_scrollbars[0];

    /*
     * Check validity of value
     */
    if (val < 0)
	val = 0;
    if (val > sb->max - sb->size + 1)
	val = sb->max - sb->size + 1;

    sb->value = val;

#ifdef RIGHTLEFT
    if (sb->wp == NULL && curwin->w_p_rl)
    {
	val = sb->max + 1 - sb->size - val;
	if (val < 0)
	    val = 0;
    }
#endif

    scrollbar_value = val;

    if (sb->wp != NULL)		/* vertical scrollbar */
    {
	current_scrollbar = 0;
	for (wp = firstwin; wp != sb->wp && wp != NULL; wp = wp->w_next)
	    current_scrollbar++;
	if (wp == NULL)
	    return 0;

	if (State & NORMAL)
	{
	    gui_do_scroll();
	    setcursor();
	}
	else if (State & INSERT)
	{
	    ins_scroll();
	    setcursor();
	}
	else if (State & CMDLINE)
	{
	    if (!msg_scrolled)
	    {
		gui_do_scroll();
		redrawcmdline();
	    }
	}
    }
    else
    {
	colnr_t	    old_leftcol = curwin->w_leftcol;

	if (State & NORMAL)
	    gui_do_horiz_scroll();
	else if (State & INSERT)
	    ins_horscroll();
	else if (State & CMDLINE)
	{
	    if (!msg_scrolled)
	    {
		gui_do_horiz_scroll();
		redrawcmdline();
	    }
	}
	if (old_leftcol != curwin->w_leftcol)
	{
	    updateWindow(curwin);   /* update window, status line and cmdline */
	    setcursor();
	}
    }
    out_flush();

    return 0;
}

/*
 * Setup for the Intellimouse
 */
    static void
init_mouse_wheel(void)
{

#ifndef SPI_GETWHEELSCROLLLINES
# define SPI_GETWHEELSCROLLLINES    104
#endif

#define VMOUSEZ_CLASSNAME  "MouseZ"		/* hidden wheel window class */
#define VMOUSEZ_TITLE      "Magellan MSWHEEL"	/* hidden wheel window title */
#define VMSH_MOUSEWHEEL    "MSWHEEL_ROLLMSG"
#define VMSH_SCROLL_LINES  "MSH_SCROLL_LINES_MSG"

    HWND hdl_mswheel;
    UINT msh_msgscrolllines;

    msh_msgmousewheel = 0;
    mouse_scroll_lines = 3;	/* reasonable default */

    if (os_version.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS
	    || (os_version.dwPlatformId == VER_PLATFORM_WIN32_NT
		&& os_version.dwMajorVersion < 4))
    {	/*
	 * If Win95 or NT 3.51,
	 * try to find the hidden point32 window.
	 */
	hdl_mswheel = FindWindow(VMOUSEZ_CLASSNAME, VMOUSEZ_TITLE);
	if (hdl_mswheel)
	{
	    msh_msgscrolllines = RegisterWindowMessage(VMSH_SCROLL_LINES);
	    if (msh_msgscrolllines)
	    {
		mouse_scroll_lines = SendMessage(hdl_mswheel,
			msh_msgscrolllines, 0, 0);
		msh_msgmousewheel  = RegisterWindowMessage(VMSH_MOUSEWHEEL);
	    }
	}
    }
    else if (os_version.dwPlatformId == VER_PLATFORM_WIN32_NT
	    && os_version.dwMajorVersion >= 4)
    {
	/* if NT 4.0 (or Win98) get scroll lines directly from system */
	SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0,
		&mouse_scroll_lines, 0);
    }
}


/* Intellimouse wheel handler */
    static void
_OnMouseWheel(
    HWND hwnd,
    short zDelta)
{
/* Treat a mouse wheel event as if it were a scroll request */
    int i;
    int size;
    HWND hwndCtl;

    if (curwin->w_scrollbars[SBAR_RIGHT].id != 0)
    {
	hwndCtl = curwin->w_scrollbars[SBAR_RIGHT].id;
	size = curwin->w_scrollbars[SBAR_RIGHT].size;
    }
    else if (curwin->w_scrollbars[SBAR_LEFT].id != 0)
    {
	hwndCtl = curwin->w_scrollbars[SBAR_LEFT].id;
	size = curwin->w_scrollbars[SBAR_LEFT].size;
    }
    else
	return;

    size = curwin->w_height;
    if (mouse_scroll_lines == 0)
	init_mouse_wheel();

    if (mouse_scroll_lines > 0
	    && mouse_scroll_lines < (size > 2 ? size - 2 : 1))
    {
	for (i = mouse_scroll_lines; i > 0; --i)
	    _OnScroll(hwnd, hwndCtl, zDelta >= 0 ? SB_LINEUP : SB_LINEDOWN, 0);
    }
    else
	_OnScroll(hwnd, hwndCtl, zDelta >= 0 ? SB_PAGEUP : SB_PAGEDOWN, 0);
}

/*
 * Get current x mouse coordinate in text window.
 * Return -1 when unknown.
 */
    int
gui_mch_get_mouse_x(void)
{
    RECT rct;
    POINT mp;

    if (GetWindowRect(s_textArea, &rct))
    {
	if (GetCursorPos((LPPOINT)&mp))
	    return (int)(mp.x - rct.left);
    }
    return -1;
}

/*
 * Get current y mouse coordinate in text window.
 * Return -1 when unknown.
 */
    int
gui_mch_get_mouse_y(void)
{
    RECT rct;
    POINT mp;

    if (GetWindowRect(s_textArea, &rct))
    {
	if (GetCursorPos((LPPOINT)&mp))
	    return (int)(mp.y - rct.top);
    }
    return -1;
}

/*
 * Move mouse pointer to character at (x, y).
 */
    void
gui_mch_setmouse(int x, int y)
{
    RECT rct;

    if (GetWindowRect(s_textArea, &rct))
	(void)SetCursorPos(x + gui.border_offset + rct.left,
			   y + gui.border_offset + rct.top);
}

    static void
gui_w32_get_valid_dimensions(
    int w,
    int h,
    int *valid_w,
    int *valid_h)
{
    int	    base_width, base_height;

    base_width = gui_get_base_width()
	+ GetSystemMetrics(SM_CXSIZEFRAME) * 2;
    base_height = gui_get_base_height()
	+ GetSystemMetrics(SM_CYSIZEFRAME) * 2
	+ GetSystemMetrics(SM_CYCAPTION)
	+ gui_w32_get_menu_height(FALSE);
    *valid_w = base_width +
		    ((w - base_width) / gui.char_width) * gui.char_width;
    *valid_h = base_height +
		    ((h - base_height) / gui.char_height) * gui.char_height;
}

/*
 * Even though we have _DuringSizing() which makes the rubber band a valid
 * size, we need this for when the user maximises the window.
 * TODO: Doesn't seem to adjust the width though for some reason.
 */
    static BOOL
_OnWindowPosChanging(
    HWND hwnd,
    LPWINDOWPOS lpwpos)
{
    if (!(lpwpos->flags & SWP_NOSIZE))
    {
	gui_w32_get_valid_dimensions(lpwpos->cx, lpwpos->cy,
				     &lpwpos->cx, &lpwpos->cy);
    }
    return 0;
}

    static int
_DuringSizing(
    HWND hwnd,
    UINT fwSide,
    LPRECT lprc)
{
    int	    w, h;
    int	    valid_w, valid_h;
    int	    w_offset, h_offset;

    w = lprc->right - lprc->left;
    h = lprc->bottom - lprc->top;
    gui_w32_get_valid_dimensions(w, h, &valid_w, &valid_h);
    w_offset = w - valid_w;
    h_offset = h - valid_h;

    if (fwSide == WMSZ_LEFT || fwSide == WMSZ_TOPLEFT
			    || fwSide == WMSZ_BOTTOMLEFT)
	lprc->left += w_offset;
    else if (fwSide == WMSZ_RIGHT || fwSide == WMSZ_TOPRIGHT
			    || fwSide == WMSZ_BOTTOMRIGHT)
	lprc->right -= w_offset;

    if (fwSide == WMSZ_TOP || fwSide == WMSZ_TOPLEFT
			    || fwSide == WMSZ_TOPRIGHT)
	lprc->top += h_offset;
    else if (fwSide == WMSZ_BOTTOM || fwSide == WMSZ_BOTTOMLEFT
			    || fwSide == WMSZ_BOTTOMRIGHT)
	lprc->bottom -= h_offset;
    return TRUE;
}

/*
 * Erase parts of the window that are not redrawn.
 * Draw the rectangle just under the left and/or right scrollbars.
 */
    static void
_OnEraseBG(HWND hwnd)
{
    HDC		hdc =  GetDC(hwnd);
    RECT	rect, drect;
    WIN		*wp;

    GetClientRect(hwnd, &rect);

    /* Draw blank rectangles for hidden scrollbars */
    for (wp = firstwin; wp; wp = wp->w_next)
    {
	if (wp->w_height == 0)
	{
	    drect.top = rect.bottom - gui.char_height * (Rows - wp->w_winpos);
	    if (gui.which_scrollbars[SBAR_BOTTOM])
		drect.top -= gui.scrollbar_height;
	    drect.bottom = drect.top + gui.char_height;
	    if (gui.which_scrollbars[SBAR_LEFT])
	    {
		drect.left = 0;
		drect.right = gui.scrollbar_width;
		FillRect(hdc, &drect, GetSysColorBrush(COLOR_BTNFACE));
	    }
	    if (gui.which_scrollbars[SBAR_RIGHT])
	    {
		drect.left = rect.right - gui.scrollbar_width;
		drect.right = rect.right;
		FillRect(hdc, &drect, GetSysColorBrush(COLOR_BTNFACE));
	    }
	}
    }

    /* draw the rectangle below vertical scrollbars */
    /* top of the rectangle is just below the last window */
    drect.top = rect.bottom - gui.char_height
			   * (Rows - (lastwin->w_winpos + lastwin->w_height));
    drect.top += lastwin->w_status_height * gui.char_height;

    if (gui.which_scrollbars[SBAR_BOTTOM])
	drect.top -= gui.scrollbar_height;
    drect.bottom = rect.bottom;

    if (gui.which_scrollbars[SBAR_LEFT])
    {
	drect.left = 0;
	drect.right = gui.scrollbar_width;
	FillRect(hdc, &drect, GetSysColorBrush(COLOR_BTNFACE));
    }
    if (gui.which_scrollbars[SBAR_RIGHT])
    {
	drect.left = rect.right - gui.scrollbar_width;
	drect.right = rect.right;
	FillRect(hdc, &drect, GetSysColorBrush(COLOR_BTNFACE));
    }
    ReleaseDC(hwnd, hdc);
}

    static BOOL
_OnCreate (HWND hwnd, LPCREATESTRUCT lpcs)
{
#ifdef MULTI_BYTE
    /* get system fixed font size*/
    static const char ach[] = {'W', 'f', 'g', 'M'};

    HDC	    hdc = GetWindowDC(hwnd);
    HFONT   hfntOld = SelectFont(hdc, GetStockObject(SYSTEM_FIXED_FONT));
    SIZE    siz;

    GetTextExtentPoint(hdc, ach, sizeof(ach), &siz);

    sysfixed_width = siz.cx / sizeof(ach);
    /*
     * Make characters one pixel higher, so that italic and bold fonts don't
     * draw off the bottom of their character space.  Also means that we can
     * underline an underscore for normal text.
     */
    sysfixed_height = siz.cy + 1;

    /* TRACE("GetFontSize: h %d, w %d\n", gui.char_height, gui.char_width); */

    SelectFont(hdc, hfntOld);

    ReleaseDC(hwnd, hdc);

#endif
    return 0;
}

#ifdef WIN32_FIND_REPLACE
/*
 * Handle a Find/Replace window message.
 */
    static void
_OnFindRepl(void)
{
    char_u cmd[600]; //XXX kludge

    /* Add a char before the command if needed */
    if (State & INSERT)
	cmd[0] = Ctrl('O');
    else if ((State | NORMAL) == 0 && State != CONFIRM)
	cmd[0] = ESC;
    else
	cmd[0] = NUL;
    cmd[1] = NUL;

    if (s_findrep_struct.Flags & FR_DIALOGTERM)
    {
	if (State == CONFIRM)
	{
	    add_to_input_buf("q", 1);
	}
	return;
    }

    if (s_findrep_struct.Flags & FR_FINDNEXT)
    {
	if (State == CONFIRM)
	{
	    STRCAT(cmd, "n");
	}
	else
	{
	    if (s_findrep_struct.Flags & FR_DOWN)
		STRCAT(cmd, "/");
	    else
		STRCAT(cmd, "?");

	    if (s_findrep_struct.Flags & FR_WHOLEWORD)
		STRCAT(cmd, "\\<");
	    STRCAT(cmd, s_findrep_struct.lpstrFindWhat);
	    if (s_findrep_struct.Flags & FR_WHOLEWORD)
		STRCAT(cmd, "\\>");

	    STRCAT(cmd, "\r");
	}
	/*
	 * Give main window the focus back: this is so
	 * the cursor isn't hollow.
	 */
	(void)SetFocus(s_hwnd);
    }
    else if (s_findrep_struct.Flags & FR_REPLACE)
    {
	if (State == CONFIRM)
	{
	    STRCAT(cmd, "y");
	}
	else
	{
	    STRCAT(cmd, ":%sno/");
	    STRCAT(cmd, s_findrep_struct.lpstrFindWhat);
	    STRCAT(cmd, "/");
	    STRCAT(cmd, s_findrep_struct.lpstrReplaceWith);
	    STRCAT(cmd, "/gc\r");
	}
	/*
	 * Give main window the focus back: this is to allow
	 * handling of the confirmation y/n/a/q stuff.
	 */
	(void)SetFocus(s_hwnd);
    }
    else if (s_findrep_struct.Flags & FR_REPLACEALL)
    {
	if (State == CONFIRM)
	{
	    STRCAT(cmd, "a");
	}
	else
	{
	    STRCAT(cmd, ":%sno/");
	    STRCAT(cmd, s_findrep_struct.lpstrFindWhat);
	    STRCAT(cmd, "/");
	    STRCAT(cmd, s_findrep_struct.lpstrReplaceWith);
	    STRCAT(cmd, "/g\r");
	}
    }
    if (*cmd)
	add_to_input_buf(cmd, STRLEN(cmd));
}
#endif

    static void
HandleMouseHide(UINT uMsg, LPARAM lParam)
{
    static LPARAM last_lParam = 0L;

    /* We sometimes get a mousemove when the mouse didn't move... */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -