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

📄 os_win32.c

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

#ifdef USE_GUI_WIN32

#include <shellapi.h>	/* required for FindExecutable() */

/*
 * GUI version of mch_windinit().
 */
    void
mch_windinit()
{
    extern int _fmode;

    PlatformId();

    /* Specify window size.  Is there a place to get the default from? */
    Rows = 25;
    Columns = 80;

    _fmode = O_BINARY;		/* we do our own CR-LF translation */

    /* Look for 'vimrun' */
    if (!gui_is_win32s())
    {
	char_u vimrun_location[2 * _MAX_PATH + 2];
	char_u widename[40];

	/* First try in same directory as gvim.exe */
	STRCPY(vimrun_location, exe_name);
	STRCPY(gettail(vimrun_location), "vimrun.exe");
	if (mch_getperm(vimrun_location) >= 0)
	{
	    STRCPY(gettail(vimrun_location), "vimrun ");
	    vimrun_path = (char *)vim_strsave(vimrun_location);
	    s_dont_use_vimrun = FALSE;
	}
	else
	{
	    /* There appears to be a bug in FindExecutableA() on Windows NT.
	     * Use FindExecutableW() instead... */
	    if (g_PlatformId == VER_PLATFORM_WIN32_NT)
	    {
		MultiByteToWideChar(CP_ACP, 0, (LPCTSTR)"vimrun.exe", -1,
							(LPWSTR)widename, 20);
		if (FindExecutableW((LPCWSTR)widename, (LPCWSTR)"",
			    (LPWSTR)vimrun_location) > (HINSTANCE)32)
		    s_dont_use_vimrun = FALSE;
	    }
	    else
	    {
		if (FindExecutableA((LPCTSTR)"vimrun.exe", (LPCTSTR)"",
			    (LPTSTR)vimrun_location) > (HINSTANCE)32)
		    s_dont_use_vimrun = FALSE;
	    }
	}

	if (s_dont_use_vimrun)
	    MessageBox(NULL,
			"VIMRUN.EXE not found in your $PATH.\n"
			"External commands will not pause after completion.\n"
			"See  :help win32-vimrun  for more information.",
			"Vim Warning",
			MB_ICONWARNING);
    }

#ifdef USE_CLIPBOARD
    clip_init(TRUE);

    /*
     * Vim's own clipboard format recognises whether the text is char, line, or
     * rectangular block.  Only useful for copying between two Vims.
     */
    clipboard.format = RegisterClipboardFormat("VimClipboard");
#endif
}

/*
 * GUI version of mch_windexit().
 * Shut down and exit with status `r'
 * Careful: mch_windexit() may be called before mch_windinit()!
 */
    void
mch_windexit(
    int r)
{
    mch_display_error();

    ml_close_all(TRUE);		/* remove all memfiles */

# ifdef HAVE_OLE
    UninitOLE();
# endif

    if (gui.in_use)
	gui_exit(r);
    exit(r);
}

#else /* USE_GUI_WIN32 */

static char g_szOrigTitle[256];
static int  g_fWindInitCalled = FALSE;
static CONSOLE_CURSOR_INFO g_cci;
static DWORD g_cmodein = 0;
static DWORD g_cmodeout = 0;

/*
 * Because of a bug in the Windows 95 Console, we need to set the screen size
 * back when switching screens.
 */
static int g_nOldRows = 0;
static int g_nOldColumns = 0;

/*
 * non-GUI version of mch_windinit().
 */
    void
mch_windinit()
{
    CONSOLE_SCREEN_BUFFER_INFO csbi;
    extern int _fmode;

    PlatformId();

    _fmode = O_BINARY;		/* we do our own CR-LF translation */
    out_flush();

    /* Obtain handles for the standard Console I/O devices */
    if (read_cmd_fd == 0)
	g_hConIn =  GetStdHandle(STD_INPUT_HANDLE);
    else
	create_conin();
    g_hSavOut = GetStdHandle(STD_OUTPUT_HANDLE);
    g_hCurOut = g_hSavOut;

    /* Get current text attributes */
    GetConsoleScreenBufferInfo(g_hSavOut, &csbi);
    g_attrCurrent = g_attrDefault = csbi.wAttributes;
    GetConsoleCursorInfo(g_hSavOut, &g_cci);

    /* set termcap codes to current text attributes */
    update_tcap(csbi.wAttributes);

    GetConsoleMode(g_hConIn,  &g_cmodein);
    GetConsoleMode(g_hSavOut, &g_cmodeout);

    GetConsoleTitle(g_szOrigTitle, sizeof(g_szOrigTitle));
    ui_get_winsize();

    g_nOldRows = Rows;
    g_nOldColumns = Columns;

#ifdef MCH_WRITE_DUMP
    fdDump = fopen("dump", "wt");

    if (fdDump)
    {
	time_t t;

	time(&t);
	fputs(ctime(&t), fdDump);
	fflush(fdDump);
    }
#endif

    g_fWindInitCalled = TRUE;

#ifdef USE_MOUSE
    g_fMouseAvail = GetSystemMetrics(SM_MOUSEPRESENT);
#endif

#ifdef USE_CLIPBOARD
    clip_init(TRUE);

    /*
     * Vim's own clipboard format recognises whether the text is char, line, or
     * rectangular block.  Only useful for copying between two Vims.
     */
    clipboard.format = RegisterClipboardFormat("VimClipboard");
#endif

    /* This will be NULL on anything but NT 4.0 */
    s_pfnGetConsoleKeyboardLayoutName =
	(PFNGCKLN) GetProcAddress(GetModuleHandle("kernel32.dll"),
				  "GetConsoleKeyboardLayoutNameA");
    /*
     * We don't really want to jump to our own screen yet; do that after
     * starttermcap().	This flashes the window, sorry about that, but
     * otherwise "vim -r" doesn't work.
     */
    g_hCurOut = g_hSavOut;
    SetConsoleActiveScreenBuffer(g_hCurOut);
}


/*
 * non-GUI version of mch_windexit().
 * Shut down and exit with status `r'
 * Careful: mch_windexit() may be called before mch_windinit()!
 */
    void
mch_windexit(
    int r)
{
    stoptermcap();
    out_char('\r');
    out_char('\n');
    out_flush();

    if (g_fWindInitCalled)
	settmode(TMODE_COOK);

    if (g_hConOut != INVALID_HANDLE_VALUE)
    {
	(void)CloseHandle(g_hConOut);

	if (g_hSavOut != INVALID_HANDLE_VALUE)
	{
	    SetConsoleTextAttribute(g_hSavOut, g_attrDefault);
	    SetConsoleCursorInfo(g_hSavOut, &g_cci);
	}
    }

    ml_close_all(TRUE);		/* remove all memfiles */

    if (g_fWindInitCalled)
    {
	mch_restore_title(3);

#ifdef MCH_WRITE_DUMP
	if (fdDump)
	{
	    time_t t;

	    time(&t);
	    fputs(ctime(&t), fdDump);
	    fclose(fdDump);
	}
	fdDump = NULL;
#endif
    }

    exit(r);
}
#endif /* USE_GUI_WIN32 */


/*
 * Do we have an interactive window?
 */
    int
mch_check_win(
    int argc,
    char **argv)
{
    char	temp[256];
    int		i;

    /* store the name of the executable, may be used for $VIM */
    GetModuleFileName(NULL, temp, 255);
    if (*temp != NUL)
	exe_name = FullName_save((char_u *)temp, FALSE);

    /* Init the tables for toupper() and tolower() */
    for (i = 0; i < 256; ++i)
	toupper_tab[i] = tolower_tab[i] = i;
    CharUpperBuff(toupper_tab, 256);
    CharLowerBuff(tolower_tab, 256);

#ifdef USE_GUI_WIN32
    return OK;	    /* GUI always has a tty */
#else
    if (isatty(1))
	return OK;
    return FAIL;
#endif
}


/*
 * Return TRUE if the input comes from a terminal, FALSE otherwise.
 */
    int
mch_input_isatty()
{
#ifdef USE_GUI_WIN32
    return OK;	    /* GUI always has a tty */
#else
    if (isatty(read_cmd_fd))
	return TRUE;
    return FALSE;
#endif
}


/*
 * Turn a file name into its canonical form.  Replace slashes with backslashes.
 * This used to replace backslashes with slashes, but that caused problems
 * when using the file name as a command.  We can't have a mix of slashes and
 * backslashes, because comparing file names will not work correctly.  The
 * commands that use file names should be prepared to handle the backslashes.
 */
    static void
canonicalize_filename(
    char *pszName)
{
    if (pszName == NULL)
	return;

    for ( ; *pszName;  pszName++)
    {
	if (*pszName == '/')
	    *pszName = '\\';
    }
}


/*
 * fname_case(): Set the case of the file name, if it already exists.
 */
    void
fname_case(
    char_u *name)
{
    char szTrueName[_MAX_PATH + 2];
    char *psz, *pszPrev;
    const int len = (name != NULL)  ?  STRLEN(name)  :	0;

    if (len == 0)
	return;

    STRNCPY(szTrueName, name, _MAX_PATH);
    szTrueName[_MAX_PATH] = '\0';   /* ensure it's sealed off! */
    STRCAT(szTrueName, "\\");	/* sentinel */

    for (psz = szTrueName;  *psz != NUL;  psz++)
	if (*psz == '/')
	    *psz = '\\';

    psz = pszPrev = szTrueName;

    /* Skip leading \\ in UNC name or drive letter */
    if (len > 2 && ((psz[0] == '\\' && psz[1] == '\\')
				       || (isalpha(psz[0]) && psz[1] == ':')))
    {
	psz = pszPrev = szTrueName + 2;
    }

    while (*psz != NUL)
    {
	WIN32_FIND_DATA	fb;
	HANDLE		hFind;

	while (*psz != '\\')
	    psz++;
	*psz = NUL;

	if ((hFind = FindFirstFile(szTrueName, &fb)) != INVALID_HANDLE_VALUE)
	{
	    /* avoid ".." and ".", etc */
	    if (_stricoll(pszPrev, fb.cFileName) == 0)
		STRCPY(pszPrev, fb.cFileName);
	    FindClose(hFind);
	}

	*psz++ = '\\';
	pszPrev = psz;
    }

    *--psz = NUL;   /* remove sentinel */

    STRCPY(name, szTrueName);
}


/*
 * mch_settitle(): set titlebar of our window
 * Can the icon also be set?
 */
    void
mch_settitle(
    char_u *title,
    char_u *icon)
{
#ifdef USE_GUI_WIN32
    gui_mch_settitle(title, icon);
#else
    if (title != NULL)
	SetConsoleTitle(title);
#endif
}


/*
 * Restore the window/icon title.
 * which is one of:
 *  1: Just restore title
 *  2: Just restore icon (which we don't have)
 *  3: Restore title and icon (which we don't have)
 */
    void
mch_restore_title(
    int which)
{
#ifndef USE_GUI_WIN32
    mch_settitle((which & 1) ? g_szOrigTitle : NULL, NULL);
#endif
}


/*
 * Return TRUE if we can restore the title (we can)
 */
    int
mch_can_restore_title()
{
    return TRUE;
}


/*
 * Return TRUE if we can restore the icon (we can't)
 */
    int
mch_can_restore_icon()
{
    return FALSE;
}


/*
 * Insert user name in s[len].
 */
    int
mch_get_user_name(
    char_u *s,
    int len)
{
    char szUserName[MAX_COMPUTERNAME_LENGTH + 1];
    DWORD cch = sizeof szUserName;

    if (GetUserName(szUserName, &cch))
    {
	STRNCPY(s, szUserName, len);
	return OK;
    }
    s[0] = NUL;
    return FAIL;
}


/*
 * Insert host name in s[len].
 */
    void
mch_get_host_name(
    char_u	*s,
    int		len)
{
    char szHostName[MAX_COMPUTERNAME_LENGTH + 1];
    DWORD cch = sizeof szHostName;

    if (GetComputerName(szHostName, &cch))
    {
	STRCPY(s, "PC ");
	STRNCPY(s + 3, szHostName, len - 3);
    }
    else
	STRNCPY(s, "PC (Win32 Vim)", len);
}


/*
 * return process ID
 */
    long
mch_get_pid()
{
    return (long)GetCurrentProcessId();
}


/*
 * Get name of current directory into buffer 'buf' of length 'len' bytes.
 * Return OK for success, FAIL for failure.
 */
    int
mch_dirname(
    char_u	*buf,
    int		len)
{
    /*
     * Originally this was:
     *    return (getcwd(buf, len) != NULL ? OK : FAIL);
     * But the Win32s known bug list says that getcwd() doesn't work
     * so use the Win32 system call instead. <Negri>
     */
    return (GetCurrentDirectory(len,buf) != 0 ? OK : FAIL);
}


/*
 * Get absolute file name into buffer 'buf' of length 'len' bytes,
 * turning all '/'s into '\\'s and getting the correct case of each
 * component of the file name.	Return OK or FAIL.
 */
    int
mch_FullName(
    char_u *fname,
    char_u *buf,
    int len,
    int force)
{
    int nResult = FAIL;

    if (fname == NULL)		/* always fail */
	return FAIL;

    if (_fullpath(buf, fname, len - 1) == NULL)
	STRNCPY(buf, fname, len);   /* failed, use the relative path name */
    else
    {
	if (mch_isdir(fname))
	    STRCAT(buf, "\\");
	nResult = OK;
    }

    fname_case(buf);

    return nResult;
}


/*
 * return TRUE if `fname' is an absolute path name
 */
    int
mch_isFullName(
    char_u *fname)
{
    char szName[_MAX_PATH+1];

    mch_FullName(fname, szName, _MAX_PATH, FALSE);

⌨️ 快捷键说明

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