diff --git a/src/gui_w32.c b/src/gui_w32.c
index feeb6d4..5129c5f 100644
--- a/src/gui_w32.c
+++ b/src/gui_w32.c
@@ -10,7 +10,7 @@
 /*
  * Windows GUI.
  *
- * GUI support for Microsoft Windows.  Win32 initially; maybe Win16 later
+ * GUI support for Microsoft Windows, aka Win32.  Also for Win64.
  *
  * George V. Reilly <george@reilly.org> wrote the original Win32 GUI.
  * Robert Webb reworked it to use the existing GUI stuff and added menu,
@@ -185,10 +185,4095 @@
    ((fn)((hwnd), TRUE, (int)(short)LOWORD(lParam), (int)(short)HIWORD(lParam), (UINT)(wParam)), 0L)
 #endif
 
+
+#include "version.h"	/* used by dialog box routine for default title */
+#ifdef DEBUG
+# include <tchar.h>
+#endif
+
+/* cproto fails on missing include files */
+#ifndef PROTO
+
+#ifndef __MINGW32__
+# include <shellapi.h>
+#endif
+#if defined(FEAT_TOOLBAR) || defined(FEAT_BEVAL) || defined(FEAT_GUI_TABLINE)
+# include <commctrl.h>
+#endif
+#include <windowsx.h>
+
+#ifdef GLOBAL_IME
+# include "glbl_ime.h"
+#endif
+
+#endif /* PROTO */
+
+#ifdef FEAT_MENU
+# define MENUHINTS		/* show menu hints in command line */
+#endif
+
+/* Some parameters for dialog boxes.  All in pixels. */
+#define DLG_PADDING_X		10
+#define DLG_PADDING_Y		10
+#define DLG_OLD_STYLE_PADDING_X	5
+#define DLG_OLD_STYLE_PADDING_Y	5
+#define DLG_VERT_PADDING_X	4	/* For vertical buttons */
+#define DLG_VERT_PADDING_Y	4
+#define DLG_ICON_WIDTH		34
+#define DLG_ICON_HEIGHT		34
+#define DLG_MIN_WIDTH		150
+#define DLG_FONT_NAME		"MS Sans Serif"
+#define DLG_FONT_POINT_SIZE	8
+#define DLG_MIN_MAX_WIDTH	400
+#define DLG_MIN_MAX_HEIGHT	400
+
+#define DLG_NONBUTTON_CONTROL	5000	/* First ID of non-button controls */
+
+#ifndef WM_XBUTTONDOWN /* For Win2K / winME ONLY */
+# define WM_XBUTTONDOWN		0x020B
+# define WM_XBUTTONUP		0x020C
+# define WM_XBUTTONDBLCLK	0x020D
+# define MK_XBUTTON1		0x0020
+# define MK_XBUTTON2		0x0040
+#endif
+
+#ifdef PROTO
 /*
- * Include the common stuff for MS-Windows GUI.
+ * Define a few things for generating prototypes.  This is just to avoid
+ * syntax errors, the defines do not need to be correct.
  */
-#include "gui_w48.c"
+# define APIENTRY
+# define CALLBACK
+# define CONST
+# define FAR
+# define NEAR
+# define _cdecl
+typedef int BOOL;
+typedef int BYTE;
+typedef int DWORD;
+typedef int WCHAR;
+typedef int ENUMLOGFONT;
+typedef int FINDREPLACE;
+typedef int HANDLE;
+typedef int HBITMAP;
+typedef int HBRUSH;
+typedef int HDROP;
+typedef int INT;
+typedef int LOGFONT[];
+typedef int LPARAM;
+typedef int LPCREATESTRUCT;
+typedef int LPCSTR;
+typedef int LPCTSTR;
+typedef int LPRECT;
+typedef int LPSTR;
+typedef int LPWINDOWPOS;
+typedef int LPWORD;
+typedef int LRESULT;
+typedef int HRESULT;
+# undef MSG
+typedef int MSG;
+typedef int NEWTEXTMETRIC;
+typedef int OSVERSIONINFO;
+typedef int PWORD;
+typedef int RECT;
+typedef int UINT;
+typedef int WORD;
+typedef int WPARAM;
+typedef int POINT;
+typedef void *HINSTANCE;
+typedef void *HMENU;
+typedef void *HWND;
+typedef void *HDC;
+typedef void VOID;
+typedef int LPNMHDR;
+typedef int LONG;
+typedef int WNDPROC;
+#endif
+
+#ifndef GET_X_LPARAM
+# define GET_X_LPARAM(lp) ((int)(short)LOWORD(lp))
+#endif
+
+static void _OnPaint( HWND hwnd);
+static void clear_rect(RECT *rcp);
+
+static WORD		s_dlgfntheight;		/* height of the dialog font */
+static WORD		s_dlgfntwidth;		/* width of the dialog font */
+
+#ifdef FEAT_MENU
+static HMENU		s_menuBar = NULL;
+#endif
+#ifdef FEAT_TEAROFF
+static void rebuild_tearoff(vimmenu_T *menu);
+static HBITMAP	s_htearbitmap;	    /* bitmap used to indicate tearoff */
+#endif
+
+/* Flag that is set while processing a message that must not be interrupted by
+ * processing another message. */
+static int		s_busy_processing = FALSE;
+
+static int		destroying = FALSE;	/* call DestroyWindow() ourselves */
+
+#ifdef MSWIN_FIND_REPLACE
+static UINT		s_findrep_msg = 0;	/* set in gui_w[16/32].c */
+static FINDREPLACE	s_findrep_struct;
+# if defined(FEAT_MBYTE) && defined(WIN3264)
+static FINDREPLACEW	s_findrep_struct_w;
+# endif
+static HWND		s_findrep_hwnd = NULL;
+static int		s_findrep_is_find;	/* TRUE for find dialog, FALSE
+						   for find/replace dialog */
+#endif
+
+static HINSTANCE	s_hinst = NULL;
+#if !defined(FEAT_SNIFF) && !defined(FEAT_GUI)
+static
+#endif
+HWND			s_hwnd = NULL;
+static HDC		s_hdc = NULL;
+static HBRUSH	s_brush = NULL;
+
+#ifdef FEAT_TOOLBAR
+static HWND		s_toolbarhwnd = NULL;
+static WNDPROC		s_toolbar_wndproc = NULL;
+#endif
+
+#ifdef FEAT_GUI_TABLINE
+static HWND		s_tabhwnd = NULL;
+static WNDPROC		s_tabline_wndproc = NULL;
+static int		showing_tabline = 0;
+#endif
+
+static WPARAM		s_wParam = 0;
+static LPARAM		s_lParam = 0;
+
+static HWND		s_textArea = NULL;
+static UINT		s_uMsg = 0;
+
+static char_u		*s_textfield; /* Used by dialogs to pass back strings */
+
+static int		s_need_activate = FALSE;
+
+/* This variable is set when waiting for an event, which is the only moment
+ * scrollbar dragging can be done directly.  It's not allowed while commands
+ * are executed, because it may move the cursor and that may cause unexpected
+ * problems (e.g., while ":s" is working).
+ */
+static int allow_scrollbar = FALSE;
+
+#ifdef GLOBAL_IME
+# define MyTranslateMessage(x) global_ime_TranslateMessage(x)
+#else
+# define MyTranslateMessage(x) TranslateMessage(x)
+#endif
+
+#if (defined(WIN3264) && defined(FEAT_MBYTE)) || defined(GLOBAL_IME)
+  /* use of WindowProc depends on wide_WindowProc */
+# define MyWindowProc vim_WindowProc
+#else
+  /* use ordinary WindowProc */
+# define MyWindowProc DefWindowProc
+#endif
+
+extern int current_font_height;	    /* this is in os_mswin.c */
+
+static struct
+{
+    UINT    key_sym;
+    char_u  vim_code0;
+    char_u  vim_code1;
+} special_keys[] =
+{
+    {VK_UP,		'k', 'u'},
+    {VK_DOWN,		'k', 'd'},
+    {VK_LEFT,		'k', 'l'},
+    {VK_RIGHT,		'k', 'r'},
+
+    {VK_F1,		'k', '1'},
+    {VK_F2,		'k', '2'},
+    {VK_F3,		'k', '3'},
+    {VK_F4,		'k', '4'},
+    {VK_F5,		'k', '5'},
+    {VK_F6,		'k', '6'},
+    {VK_F7,		'k', '7'},
+    {VK_F8,		'k', '8'},
+    {VK_F9,		'k', '9'},
+    {VK_F10,		'k', ';'},
+
+    {VK_F11,		'F', '1'},
+    {VK_F12,		'F', '2'},
+    {VK_F13,		'F', '3'},
+    {VK_F14,		'F', '4'},
+    {VK_F15,		'F', '5'},
+    {VK_F16,		'F', '6'},
+    {VK_F17,		'F', '7'},
+    {VK_F18,		'F', '8'},
+    {VK_F19,		'F', '9'},
+    {VK_F20,		'F', 'A'},
+
+    {VK_F21,		'F', 'B'},
+#ifdef FEAT_NETBEANS_INTG
+    {VK_PAUSE,		'F', 'B'},	/* Pause == F21 (see gui_gtk_x11.c) */
+#endif
+    {VK_F22,		'F', 'C'},
+    {VK_F23,		'F', 'D'},
+    {VK_F24,		'F', 'E'},	/* winuser.h defines up to F24 */
+
+    {VK_HELP,		'%', '1'},
+    {VK_BACK,		'k', 'b'},
+    {VK_INSERT,		'k', 'I'},
+    {VK_DELETE,		'k', 'D'},
+    {VK_HOME,		'k', 'h'},
+    {VK_END,		'@', '7'},
+    {VK_PRIOR,		'k', 'P'},
+    {VK_NEXT,		'k', 'N'},
+    {VK_PRINT,		'%', '9'},
+    {VK_ADD,		'K', '6'},
+    {VK_SUBTRACT,	'K', '7'},
+    {VK_DIVIDE,		'K', '8'},
+    {VK_MULTIPLY,	'K', '9'},
+    {VK_SEPARATOR,	'K', 'A'},	/* Keypad Enter */
+    {VK_DECIMAL,	'K', 'B'},
+
+    {VK_NUMPAD0,	'K', 'C'},
+    {VK_NUMPAD1,	'K', 'D'},
+    {VK_NUMPAD2,	'K', 'E'},
+    {VK_NUMPAD3,	'K', 'F'},
+    {VK_NUMPAD4,	'K', 'G'},
+    {VK_NUMPAD5,	'K', 'H'},
+    {VK_NUMPAD6,	'K', 'I'},
+    {VK_NUMPAD7,	'K', 'J'},
+    {VK_NUMPAD8,	'K', 'K'},
+    {VK_NUMPAD9,	'K', 'L'},
+
+    /* Keys that we want to be able to use any modifier with: */
+    {VK_SPACE,		' ', NUL},
+    {VK_TAB,		TAB, NUL},
+    {VK_ESCAPE,		ESC, NUL},
+    {NL,		NL, NUL},
+    {CAR,		CAR, NUL},
+
+    /* End of list marker: */
+    {0,			0, 0}
+};
+
+/* Local variables */
+static int	s_button_pending = -1;
+
+/* s_getting_focus is set when we got focus but didn't see mouse-up event yet,
+ * so don't reset s_button_pending. */
+static int	s_getting_focus = FALSE;
+
+static int	s_x_pending;
+static int	s_y_pending;
+static UINT	s_kFlags_pending;
+static UINT	s_wait_timer = 0;   /* Timer for get char from user */
+static int	s_timed_out = FALSE;
+static int	dead_key = 0;	/* 0: no dead key, 1: dead key pressed */
+
+#ifdef WIN3264
+static OSVERSIONINFO os_version;    /* like it says.  Init in gui_mch_init() */
+#endif
+
+#ifdef FEAT_BEVAL
+/* balloon-eval WM_NOTIFY_HANDLER */
+static void Handle_WM_Notify(HWND hwnd, LPNMHDR pnmh);
+static void TrackUserActivity(UINT uMsg);
+#endif
+
+/*
+ * For control IME.
+ *
+ * These LOGFONT used for IME.
+ */
+#ifdef FEAT_MBYTE
+# ifdef USE_IM_CONTROL
+/* holds LOGFONT for 'guifontwide' if available, otherwise 'guifont' */
+static LOGFONT norm_logfont;
+/* holds LOGFONT for 'guifont' always. */
+static LOGFONT sub_logfont;
+# endif
+#endif
+
+#ifdef FEAT_MBYTE_IME
+static LRESULT _OnImeNotify(HWND hWnd, DWORD dwCommand, DWORD dwData);
+#endif
+
+#if defined(FEAT_BROWSE)
+static char_u *convert_filter(char_u *s);
+#endif
+
+#ifdef DEBUG_PRINT_ERROR
+/*
+ * Print out the last Windows error message
+ */
+    static void
+print_windows_error(void)
+{
+    LPVOID  lpMsgBuf;
+
+    FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
+		  NULL, GetLastError(),
+		  MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+		  (LPTSTR) &lpMsgBuf, 0, NULL);
+    TRACE1("Error: %s\n", lpMsgBuf);
+    LocalFree(lpMsgBuf);
+}
+#endif
+
+/*
+ * Cursor blink functions.
+ *
+ * This is a simple state machine:
+ * BLINK_NONE	not blinking at all
+ * BLINK_OFF	blinking, cursor is not shown
+ * BLINK_ON	blinking, cursor is shown
+ */
+
+#define BLINK_NONE  0
+#define BLINK_OFF   1
+#define BLINK_ON    2
+
+static int		blink_state = BLINK_NONE;
+static long_u		blink_waittime = 700;
+static long_u		blink_ontime = 400;
+static long_u		blink_offtime = 250;
+static UINT		blink_timer = 0;
+
+    void
+gui_mch_set_blinking(long wait, long on, long off)
+{
+    blink_waittime = wait;
+    blink_ontime = on;
+    blink_offtime = off;
+}
+
+/* ARGSUSED */
+    static VOID CALLBACK
+_OnBlinkTimer(
+    HWND hwnd,
+    UINT uMsg,
+    UINT idEvent,
+    DWORD dwTime)
+{
+    MSG msg;
+
+    /*
+    TRACE2("Got timer event, id %d, blink_timer %d\n", idEvent, blink_timer);
+    */
+
+    KillTimer(NULL, idEvent);
+
+    /* Eat spurious WM_TIMER messages */
+    while (pPeekMessage(&msg, hwnd, WM_TIMER, WM_TIMER, PM_REMOVE))
+	;
+
+    if (blink_state == BLINK_ON)
+    {
+	gui_undraw_cursor();
+	blink_state = BLINK_OFF;
+	blink_timer = (UINT) SetTimer(NULL, 0, (UINT)blink_offtime,
+						    (TIMERPROC)_OnBlinkTimer);
+    }
+    else
+    {
+	gui_update_cursor(TRUE, FALSE);
+	blink_state = BLINK_ON;
+	blink_timer = (UINT) SetTimer(NULL, 0, (UINT)blink_ontime,
+							 (TIMERPROC)_OnBlinkTimer);
+    }
+}
+
+    static void
+gui_mswin_rm_blink_timer(void)
+{
+    MSG msg;
+
+    if (blink_timer != 0)
+    {
+	KillTimer(NULL, blink_timer);
+	/* Eat spurious WM_TIMER messages */
+	while (pPeekMessage(&msg, s_hwnd, WM_TIMER, WM_TIMER, PM_REMOVE))
+	    ;
+	blink_timer = 0;
+    }
+}
+
+/*
+ * Stop the cursor blinking.  Show the cursor if it wasn't shown.
+ */
+    void
+gui_mch_stop_blink(void)
+{
+    gui_mswin_rm_blink_timer();
+    if (blink_state == BLINK_OFF)
+	gui_update_cursor(TRUE, FALSE);
+    blink_state = BLINK_NONE;
+}
+
+/*
+ * Start the cursor blinking.  If it was already blinking, this restarts the
+ * waiting time and shows the cursor.
+ */
+    void
+gui_mch_start_blink(void)
+{
+    gui_mswin_rm_blink_timer();
+
+    /* Only switch blinking on if none of the times is zero */
+    if (blink_waittime && blink_ontime && blink_offtime && gui.in_focus)
+    {
+	blink_timer = (UINT)SetTimer(NULL, 0, (UINT)blink_waittime,
+						    (TIMERPROC)_OnBlinkTimer);
+	blink_state = BLINK_ON;
+	gui_update_cursor(TRUE, FALSE);
+    }
+}
+
+/*
+ * Call-back routines.
+ */
+
+/*ARGSUSED*/
+    static VOID CALLBACK
+_OnTimer(
+    HWND hwnd,
+    UINT uMsg,
+    UINT idEvent,
+    DWORD dwTime)
+{
+    MSG msg;
+
+    /*
+    TRACE2("Got timer event, id %d, s_wait_timer %d\n", idEvent, s_wait_timer);
+    */
+    KillTimer(NULL, idEvent);
+    s_timed_out = TRUE;
+
+    /* Eat spurious WM_TIMER messages */
+    while (pPeekMessage(&msg, hwnd, WM_TIMER, WM_TIMER, PM_REMOVE))
+	;
+    if (idEvent == s_wait_timer)
+	s_wait_timer = 0;
+}
+
+/*ARGSUSED*/
+    static void
+_OnDeadChar(
+    HWND hwnd,
+    UINT ch,
+    int cRepeat)
+{
+    dead_key = 1;
+}
+
+/*
+ * Convert Unicode character "ch" to bytes in "string[slen]".
+ * When "had_alt" is TRUE the ALT key was included in "ch".
+ * Return the length.
+ */
+    static int
+char_to_string(int ch, char_u *string, int slen, int had_alt)
+{
+    int		len;
+    int		i;
+#ifdef FEAT_MBYTE
+    WCHAR	wstring[2];
+    char_u	*ws = NULL;;
+
+    if (os_version.dwPlatformId != VER_PLATFORM_WIN32_NT)
+    {
+	/* On Windows 95/98 we apparently get the character in the active
+	 * codepage, not in UCS-2.  If conversion is needed convert it to
+	 * UCS-2 first. */
+	if ((int)GetACP() == enc_codepage)
+	    len = 0;	    /* no conversion required */
+	else
+	{
+	    string[0] = ch;
+	    len = MultiByteToWideChar(GetACP(), 0, (LPCSTR)string,
+		    1, wstring, 2);
+	}
+    }
+    else
+    {
+	wstring[0] = ch;
+	len = 1;
+    }
+
+    if (len > 0)
+    {
+	/* "ch" is a UTF-16 character.  Convert it to a string of bytes.  When
+	 * "enc_codepage" is non-zero use the standard Win32 function,
+	 * otherwise use our own conversion function (e.g., for UTF-8). */
+	if (enc_codepage > 0)
+	{
+	    len = WideCharToMultiByte(enc_codepage, 0, wstring, len,
+					       (LPSTR)string, slen, 0, NULL);
+	    /* If we had included the ALT key into the character but now the
+	     * upper bit is no longer set, that probably means the conversion
+	     * failed.  Convert the original character and set the upper bit
+	     * afterwards. */
+	    if (had_alt && len == 1 && ch >= 0x80 && string[0] < 0x80)
+	    {
+		wstring[0] = ch & 0x7f;
+		len = WideCharToMultiByte(enc_codepage, 0, wstring, len,
+					       (LPSTR)string, slen, 0, NULL);
+		if (len == 1) /* safety check */
+		    string[0] |= 0x80;
+	    }
+	}
+	else
+	{
+	    len = 1;
+	    ws = utf16_to_enc(wstring, &len);
+	    if (ws == NULL)
+		len = 0;
+	    else
+	    {
+		if (len > slen)	/* just in case */
+		    len = slen;
+		mch_memmove(string, ws, len);
+		vim_free(ws);
+	    }
+	}
+    }
+
+    if (len == 0)
+#endif
+    {
+	string[0] = ch;
+	len = 1;
+    }
+
+    for (i = 0; i < len; ++i)
+	if (string[i] == CSI && len <= slen - 2)
+	{
+	    /* Insert CSI as K_CSI. */
+	    mch_memmove(string + i + 3, string + i + 1, len - i - 1);
+	    string[++i] = KS_EXTRA;
+	    string[++i] = (int)KE_CSI;
+	    len += 2;
+	}
+
+    return len;
+}
+
+/*
+ * Key hit, add it to the input buffer.
+ */
+/*ARGSUSED*/
+    static void
+_OnChar(
+    HWND hwnd,
+    UINT ch,
+    int cRepeat)
+{
+    char_u	string[40];
+    int		len = 0;
+
+    dead_key = 0;
+
+    len = char_to_string(ch, string, 40, FALSE);
+    if (len == 1 && string[0] == Ctrl_C && ctrl_c_interrupts)
+    {
+	trash_input_buf();
+	got_int = TRUE;
+    }
+
+    add_to_input_buf(string, len);
+}
+
+/*
+ * Alt-Key hit, add it to the input buffer.
+ */
+/*ARGSUSED*/
+    static void
+_OnSysChar(
+    HWND hwnd,
+    UINT cch,
+    int cRepeat)
+{
+    char_u	string[40]; /* Enough for multibyte character */
+    int		len;
+    int		modifiers;
+    int		ch = cch;   /* special keys are negative */
+
+    dead_key = 0;
+
+    /* TRACE("OnSysChar(%d, %c)\n", ch, ch); */
+
+    /* OK, we have a character key (given by ch) which was entered with the
+     * ALT key pressed. Eg, if the user presses Alt-A, then ch == 'A'. Note
+     * that the system distinguishes Alt-a and Alt-A (Alt-Shift-a unless
+     * CAPSLOCK is pressed) at this point.
+     */
+    modifiers = MOD_MASK_ALT;
+    if (GetKeyState(VK_SHIFT) & 0x8000)
+	modifiers |= MOD_MASK_SHIFT;
+    if (GetKeyState(VK_CONTROL) & 0x8000)
+	modifiers |= MOD_MASK_CTRL;
+
+    ch = simplify_key(ch, &modifiers);
+    /* remove the SHIFT modifier for keys where it's already included, e.g.,
+     * '(' and '*' */
+    if (ch < 0x100 && !isalpha(ch) && isprint(ch))
+	modifiers &= ~MOD_MASK_SHIFT;
+
+    /* Interpret the ALT key as making the key META, include SHIFT, etc. */
+    ch = extract_modifiers(ch, &modifiers);
+    if (ch == CSI)
+	ch = K_CSI;
+
+    len = 0;
+    if (modifiers)
+    {
+	string[len++] = CSI;
+	string[len++] = KS_MODIFIER;
+	string[len++] = modifiers;
+    }
+
+    if (IS_SPECIAL((int)ch))
+    {
+	string[len++] = CSI;
+	string[len++] = K_SECOND((int)ch);
+	string[len++] = K_THIRD((int)ch);
+    }
+    else
+    {
+	/* Although the documentation isn't clear about it, we assume "ch" is
+	 * a Unicode character. */
+	len += char_to_string(ch, string + len, 40 - len, TRUE);
+    }
+
+    add_to_input_buf(string, len);
+}
+
+    static void
+_OnMouseEvent(
+    int button,
+    int x,
+    int y,
+    int repeated_click,
+    UINT keyFlags)
+{
+    int vim_modifiers = 0x0;
+
+    s_getting_focus = FALSE;
+
+    if (keyFlags & MK_SHIFT)
+	vim_modifiers |= MOUSE_SHIFT;
+    if (keyFlags & MK_CONTROL)
+	vim_modifiers |= MOUSE_CTRL;
+    if (GetKeyState(VK_MENU) & 0x8000)
+	vim_modifiers |= MOUSE_ALT;
+
+    gui_send_mouse_event(button, x, y, repeated_click, vim_modifiers);
+}
+
+/*ARGSUSED*/
+    static void
+_OnMouseButtonDown(
+    HWND hwnd,
+    BOOL fDoubleClick,
+    int x,
+    int y,
+    UINT keyFlags)
+{
+    static LONG	s_prevTime = 0;
+
+    LONG    currentTime = GetMessageTime();
+    int	    button = -1;
+    int	    repeated_click;
+
+    /* Give main window the focus: this is so the cursor isn't hollow. */
+    (void)SetFocus(s_hwnd);
+
+    if (s_uMsg == WM_LBUTTONDOWN || s_uMsg == WM_LBUTTONDBLCLK)
+	button = MOUSE_LEFT;
+    else if (s_uMsg == WM_MBUTTONDOWN || s_uMsg == WM_MBUTTONDBLCLK)
+	button = MOUSE_MIDDLE;
+    else if (s_uMsg == WM_RBUTTONDOWN || s_uMsg == WM_RBUTTONDBLCLK)
+	button = MOUSE_RIGHT;
+    else if (s_uMsg == WM_XBUTTONDOWN || s_uMsg == WM_XBUTTONDBLCLK)
+    {
+#ifndef GET_XBUTTON_WPARAM
+# define GET_XBUTTON_WPARAM(wParam)	(HIWORD(wParam))
+#endif
+	button = ((GET_XBUTTON_WPARAM(s_wParam) == 1) ? MOUSE_X1 : MOUSE_X2);
+    }
+    else if (s_uMsg == WM_CAPTURECHANGED)
+    {
+	/* on W95/NT4, somehow you get in here with an odd Msg
+	 * if you press one button while holding down the other..*/
+	if (s_button_pending == MOUSE_LEFT)
+	    button = MOUSE_RIGHT;
+	else
+	    button = MOUSE_LEFT;
+    }
+    if (button >= 0)
+    {
+	repeated_click = ((int)(currentTime - s_prevTime) < p_mouset);
+
+	/*
+	 * Holding down the left and right buttons simulates pushing the middle
+	 * button.
+	 */
+	if (repeated_click
+		&& ((button == MOUSE_LEFT && s_button_pending == MOUSE_RIGHT)
+		    || (button == MOUSE_RIGHT
+					  && s_button_pending == MOUSE_LEFT)))
+	{
+	    /*
+	     * Hmm, gui.c will ignore more than one button down at a time, so
+	     * pretend we let go of it first.
+	     */
+	    gui_send_mouse_event(MOUSE_RELEASE, x, y, FALSE, 0x0);
+	    button = MOUSE_MIDDLE;
+	    repeated_click = FALSE;
+	    s_button_pending = -1;
+	    _OnMouseEvent(button, x, y, repeated_click, keyFlags);
+	}
+	else if ((repeated_click)
+		|| (mouse_model_popup() && (button == MOUSE_RIGHT)))
+	{
+	    if (s_button_pending > -1)
+	    {
+		    _OnMouseEvent(s_button_pending, x, y, FALSE, keyFlags);
+		    s_button_pending = -1;
+	    }
+	    /* TRACE("Button down at x %d, y %d\n", x, y); */
+	    _OnMouseEvent(button, x, y, repeated_click, keyFlags);
+	}
+	else
+	{
+	    /*
+	     * If this is the first press (i.e. not a multiple click) don't
+	     * action immediately, but store and wait for:
+	     * i) button-up
+	     * ii) mouse move
+	     * iii) another button press
+	     * before using it.
+	     * This enables us to make left+right simulate middle button,
+	     * without left or right being actioned first.  The side-effect is
+	     * that if you click and hold the mouse without dragging, the
+	     * cursor doesn't move until you release the button. In practice
+	     * this is hardly a problem.
+	     */
+	    s_button_pending = button;
+	    s_x_pending = x;
+	    s_y_pending = y;
+	    s_kFlags_pending = keyFlags;
+	}
+
+	s_prevTime = currentTime;
+    }
+}
+
+/*ARGSUSED*/
+    static void
+_OnMouseMoveOrRelease(
+    HWND hwnd,
+    int x,
+    int y,
+    UINT keyFlags)
+{
+    int button;
+
+    s_getting_focus = FALSE;
+    if (s_button_pending > -1)
+    {
+	/* Delayed action for mouse down event */
+	_OnMouseEvent(s_button_pending, s_x_pending,
+					s_y_pending, FALSE, s_kFlags_pending);
+	s_button_pending = -1;
+    }
+    if (s_uMsg == WM_MOUSEMOVE)
+    {
+	/*
+	 * It's only a MOUSE_DRAG if one or more mouse buttons are being held
+	 * down.
+	 */
+	if (!(keyFlags & (MK_LBUTTON | MK_MBUTTON | MK_RBUTTON
+						| MK_XBUTTON1 | MK_XBUTTON2)))
+	{
+	    gui_mouse_moved(x, y);
+	    return;
+	}
+
+	/*
+	 * While button is down, keep grabbing mouse move events when
+	 * the mouse goes outside the window
+	 */
+	SetCapture(s_textArea);
+	button = MOUSE_DRAG;
+	/* TRACE("  move at x %d, y %d\n", x, y); */
+    }
+    else
+    {
+	ReleaseCapture();
+	button = MOUSE_RELEASE;
+	/* TRACE("  up at x %d, y %d\n", x, y); */
+    }
+
+    _OnMouseEvent(button, x, y, FALSE, keyFlags);
+}
+
+#ifdef FEAT_MENU
+/*
+ * Find the vimmenu_T with the given id
+ */
+    static vimmenu_T *
+gui_mswin_find_menu(
+    vimmenu_T	*pMenu,
+    int		id)
+{
+    vimmenu_T	*pChildMenu;
+
+    while (pMenu)
+    {
+	if (pMenu->id == (UINT)id)
+	    break;
+	if (pMenu->children != NULL)
+	{
+	    pChildMenu = gui_mswin_find_menu(pMenu->children, id);
+	    if (pChildMenu)
+	    {
+		pMenu = pChildMenu;
+		break;
+	    }
+	}
+	pMenu = pMenu->next;
+    }
+    return pMenu;
+}
+
+/*ARGSUSED*/
+    static void
+_OnMenu(
+    HWND	hwnd,
+    int		id,
+    HWND	hwndCtl,
+    UINT	codeNotify)
+{
+    vimmenu_T	*pMenu;
+
+    pMenu = gui_mswin_find_menu(root_menu, id);
+    if (pMenu)
+	gui_menu_cb(pMenu);
+}
+#endif
+
+#ifdef MSWIN_FIND_REPLACE
+# if defined(FEAT_MBYTE) && defined(WIN3264)
+/*
+ * copy useful data from structure LPFINDREPLACE to structure LPFINDREPLACEW
+ */
+    static void
+findrep_atow(LPFINDREPLACEW lpfrw, LPFINDREPLACE lpfr)
+{
+    WCHAR *wp;
+
+    lpfrw->hwndOwner = lpfr->hwndOwner;
+    lpfrw->Flags = lpfr->Flags;
+
+    wp = enc_to_utf16((char_u *)lpfr->lpstrFindWhat, NULL);
+    wcsncpy(lpfrw->lpstrFindWhat, wp, lpfrw->wFindWhatLen - 1);
+    vim_free(wp);
+
+    /* the field "lpstrReplaceWith" doesn't need to be copied */
+}
+
+/*
+ * copy useful data from structure LPFINDREPLACEW to structure LPFINDREPLACE
+ */
+    static void
+findrep_wtoa(LPFINDREPLACE lpfr, LPFINDREPLACEW lpfrw)
+{
+    char_u *p;
+
+    lpfr->Flags = lpfrw->Flags;
+
+    p = utf16_to_enc((short_u*)lpfrw->lpstrFindWhat, NULL);
+    vim_strncpy((char_u *)lpfr->lpstrFindWhat, p, lpfr->wFindWhatLen - 1);
+    vim_free(p);
+
+    p = utf16_to_enc((short_u*)lpfrw->lpstrReplaceWith, NULL);
+    vim_strncpy((char_u *)lpfr->lpstrReplaceWith, p, lpfr->wReplaceWithLen - 1);
+    vim_free(p);
+}
+# endif
+
+/*
+ * Handle a Find/Replace window message.
+ */
+    static void
+_OnFindRepl(void)
+{
+    int	    flags = 0;
+    int	    down;
+
+# if defined(FEAT_MBYTE) && defined(WIN3264)
+    /* If the OS is Windows NT, and 'encoding' differs from active codepage:
+     * convert text from wide string. */
+    if (os_version.dwPlatformId == VER_PLATFORM_WIN32_NT
+			&& enc_codepage >= 0 && (int)GetACP() != enc_codepage)
+    {
+	findrep_wtoa(&s_findrep_struct, &s_findrep_struct_w);
+    }
+# endif
+
+    if (s_findrep_struct.Flags & FR_DIALOGTERM)
+	/* Give main window the focus back. */
+	(void)SetFocus(s_hwnd);
+
+    if (s_findrep_struct.Flags & FR_FINDNEXT)
+    {
+	flags = FRD_FINDNEXT;
+
+	/* 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)
+    {
+	flags = FRD_REPLACE;
+
+	/* 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_REPLACEALL)
+    {
+	flags = FRD_REPLACEALL;
+    }
+
+    if (flags != 0)
+    {
+	/* Call the generic GUI function to do the actual work. */
+	if (s_findrep_struct.Flags & FR_WHOLEWORD)
+	    flags |= FRD_WHOLE_WORD;
+	if (s_findrep_struct.Flags & FR_MATCHCASE)
+	    flags |= FRD_MATCH_CASE;
+	down = (s_findrep_struct.Flags & FR_DOWN) != 0;
+	gui_do_findrepl(flags, (char_u *)s_findrep_struct.lpstrFindWhat,
+			     (char_u *)s_findrep_struct.lpstrReplaceWith, down);
+    }
+}
+#endif
+
+    static void
+HandleMouseHide(UINT uMsg, LPARAM lParam)
+{
+    static LPARAM last_lParam = 0L;
+
+    /* We sometimes get a mousemove when the mouse didn't move... */
+    if (uMsg == WM_MOUSEMOVE || uMsg == WM_NCMOUSEMOVE)
+    {
+	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)
+    {
+    case WM_KEYUP:
+    case WM_CHAR:
+	/*
+	 * blank out the pointer if necessary
+	 */
+	if (p_mh)
+	    gui_mch_mousehide(TRUE);
+	break;
+
+    case WM_SYSKEYUP:	 /* show the pointer when a system-key is pressed */
+    case WM_SYSCHAR:
+    case WM_MOUSEMOVE:	 /* show the pointer on any mouse action */
+    case WM_LBUTTONDOWN:
+    case WM_LBUTTONUP:
+    case WM_MBUTTONDOWN:
+    case WM_MBUTTONUP:
+    case WM_RBUTTONDOWN:
+    case WM_RBUTTONUP:
+    case WM_XBUTTONDOWN:
+    case WM_XBUTTONUP:
+    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
+_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;
+
+#ifdef FEAT_BEVAL
+    TrackUserActivity(uMsg);
+#endif
+
+    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);
+	HANDLE_MSG(hwnd, WM_XBUTTONDBLCLK,_OnMouseButtonDown);
+	HANDLE_MSG(hwnd, WM_XBUTTONDOWN,_OnMouseButtonDown);
+	HANDLE_MSG(hwnd, WM_XBUTTONUP,	_OnMouseMoveOrRelease);
+
+#ifdef FEAT_BEVAL
+	case WM_NOTIFY: Handle_WM_Notify(hwnd, (LPNMHDR)lParam);
+	    return TRUE;
+#endif
+	default:
+	    return MyWindowProc(hwnd, uMsg, wParam, lParam);
+    }
+}
+
+#if (defined(WIN3264) && defined(FEAT_MBYTE)) \
+	|| defined(GLOBAL_IME) \
+	|| defined(PROTO)
+# ifdef PROTO
+typedef int WINAPI;
+# endif
+
+    LRESULT WINAPI
+vim_WindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+# ifdef GLOBAL_IME
+    return global_ime_DefWindowProc(hwnd, message, wParam, lParam);
+# else
+    if (wide_WindowProc)
+	return DefWindowProcW(hwnd, message, wParam, lParam);
+    return DefWindowProc(hwnd, message, wParam, lParam);
+#endif
+}
+#endif
+
+/*
+ * Called when the foreground or background color has been changed.
+ */
+    void
+gui_mch_new_colors(void)
+{
+    /* nothing to do? */
+}
+
+/*
+ * Set the colors to their default values.
+ */
+    void
+gui_mch_def_colors(void)
+{
+    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;
+}
+
+/*
+ * Open the GUI window which was created by a call to gui_mch_init().
+ */
+    int
+gui_mch_open(void)
+{
+#ifndef SW_SHOWDEFAULT
+# define SW_SHOWDEFAULT 10	/* Borland 5.0 doesn't have it */
+#endif
+    /* Actually open the window, if not already visible
+     * (may be done already in gui_mch_set_shellsize) */
+    if (!IsWindowVisible(s_hwnd))
+	ShowWindow(s_hwnd, SW_SHOWDEFAULT);
+
+#ifdef MSWIN_FIND_REPLACE
+    /* Init replace string here, so that we keep it when re-opening the
+     * dialog. */
+    s_findrep_struct.lpstrReplaceWith[0] = NUL;
+#endif
+
+    return OK;
+}
+
+/*
+ * Get the position of the top left corner of the window.
+ */
+    int
+gui_mch_get_winpos(int *x, int *y)
+{
+    RECT    rect;
+
+    GetWindowRect(s_hwnd, &rect);
+    *x = rect.left;
+    *y = rect.top;
+    return OK;
+}
+
+/*
+ * Set the position of the top left corner of the window to the given
+ * coordinates.
+ */
+    void
+gui_mch_set_winpos(int x, int y)
+{
+    SetWindowPos(s_hwnd, NULL, x, y, 0, 0,
+		 SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE);
+}
+    void
+gui_mch_set_text_area_pos(int x, int y, int w, int h)
+{
+    static int oldx = 0;
+    static int oldy = 0;
+
+    SetWindowPos(s_textArea, NULL, x, y, w, h, SWP_NOZORDER | SWP_NOACTIVATE);
+
+#ifdef FEAT_TOOLBAR
+    if (vim_strchr(p_go, GO_TOOLBAR) != NULL)
+	SendMessage(s_toolbarhwnd, WM_SIZE,
+	      (WPARAM)0, (LPARAM)(w + ((long)(TOOLBAR_BUTTON_HEIGHT+8)<<16)));
+#endif
+#if defined(FEAT_GUI_TABLINE)
+    if (showing_tabline)
+    {
+	int	top = 0;
+	RECT	rect;
+
+# ifdef FEAT_TOOLBAR
+	if (vim_strchr(p_go, GO_TOOLBAR) != NULL)
+	    top = TOOLBAR_BUTTON_HEIGHT + TOOLBAR_BORDER_HEIGHT;
+# endif
+	GetClientRect(s_hwnd, &rect);
+	MoveWindow(s_tabhwnd, 0, top, rect.right, gui.tabline_height, TRUE);
+    }
+#endif
+
+    /* When side scroll bar is unshown, the size of window will change.
+     * then, the text area move left or right. thus client rect should be
+     * forcedly redrawn. (Yasuhiro Matsumoto) */
+    if (oldx != x || oldy != y)
+    {
+	InvalidateRect(s_hwnd, NULL, FALSE);
+	oldx = x;
+	oldy = y;
+    }
+}
+
+
+/*
+ * Scrollbar stuff:
+ */
+
+    void
+gui_mch_enable_scrollbar(
+    scrollbar_T     *sb,
+    int		    flag)
+{
+    ShowScrollBar(sb->id, SB_CTL, flag);
+
+    /* TODO: When the window is maximized, the size of the window stays the
+     * same, thus the size of the text area changes.  On Win98 it's OK, on Win
+     * NT 4.0 it's not... */
+}
+
+    void
+gui_mch_set_scrollbar_pos(
+    scrollbar_T *sb,
+    int		x,
+    int		y,
+    int		w,
+    int		h)
+{
+    SetWindowPos(sb->id, NULL, x, y, w, h,
+			      SWP_NOZORDER | SWP_NOACTIVATE | SWP_SHOWWINDOW);
+}
+
+    void
+gui_mch_create_scrollbar(
+    scrollbar_T *sb,
+    int		orient)	/* SBAR_VERT or SBAR_HORIZ */
+{
+    sb->id = CreateWindow(
+	"SCROLLBAR", "Scrollbar",
+	WS_CHILD | ((orient == SBAR_VERT) ? SBS_VERT : SBS_HORZ), 0, 0,
+	10,				/* Any value will do for now */
+	10,				/* Any value will do for now */
+	s_hwnd, NULL,
+	s_hinst, NULL);
+}
+
+/*
+ * Find the scrollbar with the given hwnd.
+ */
+	 static scrollbar_T *
+gui_mswin_find_scrollbar(HWND hwnd)
+{
+    win_T	*wp;
+
+    if (gui.bottom_sbar.id == hwnd)
+	return &gui.bottom_sbar;
+    FOR_ALL_WINDOWS(wp)
+    {
+	if (wp->w_scrollbars[SBAR_LEFT].id == hwnd)
+	    return &wp->w_scrollbars[SBAR_LEFT];
+	if (wp->w_scrollbars[SBAR_RIGHT].id == hwnd)
+	    return &wp->w_scrollbars[SBAR_RIGHT];
+    }
+    return NULL;
+}
+
+/*
+ * Get the character size of a font.
+ */
+    static void
+GetFontSize(GuiFont font)
+{
+    HWND    hwnd = GetDesktopWindow();
+    HDC	    hdc = GetWindowDC(hwnd);
+    HFONT   hfntOld = SelectFont(hdc, (HFONT)font);
+    TEXTMETRIC tm;
+
+    GetTextMetrics(hdc, &tm);
+    gui.char_width = tm.tmAveCharWidth + tm.tmOverhang;
+
+    gui.char_height = tm.tmHeight + p_linespace;
+
+    SelectFont(hdc, hfntOld);
+
+    ReleaseDC(hwnd, hdc);
+}
+
+/*
+ * Adjust gui.char_height (after 'linespace' was changed).
+ */
+    int
+gui_mch_adjust_charheight(void)
+{
+    GetFontSize(gui.norm_font);
+    return OK;
+}
+
+    static GuiFont
+get_font_handle(LOGFONT *lf)
+{
+    HFONT   font = NULL;
+
+    /* Load the font */
+    font = CreateFontIndirect(lf);
+
+    if (font == NULL)
+	return NOFONT;
+
+    return (GuiFont)font;
+}
+
+    static int
+pixels_to_points(int pixels, int vertical)
+{
+    int		points;
+    HWND	hwnd;
+    HDC		hdc;
+
+    hwnd = GetDesktopWindow();
+    hdc = GetWindowDC(hwnd);
+
+    points = MulDiv(pixels, 72,
+		    GetDeviceCaps(hdc, vertical ? LOGPIXELSY : LOGPIXELSX));
+
+    ReleaseDC(hwnd, hdc);
+
+    return points;
+}
+
+    GuiFont
+gui_mch_get_font(
+    char_u	*name,
+    int		giveErrorIfMissing)
+{
+    LOGFONT	lf;
+    GuiFont	font = NOFONT;
+
+    if (get_logfont(&lf, name, NULL, giveErrorIfMissing) == OK)
+	font = get_font_handle(&lf);
+    if (font == NOFONT && giveErrorIfMissing)
+	EMSG2(_(e_font), name);
+    return font;
+}
+
+#if defined(FEAT_EVAL) || defined(PROTO)
+/*
+ * Return the name of font "font" in allocated memory.
+ * Don't know how to get the actual name, thus use the provided name.
+ */
+/*ARGSUSED*/
+    char_u *
+gui_mch_get_fontname(GuiFont font, char_u *name)
+{
+    if (name == NULL)
+	return NULL;
+    return vim_strsave(name);
+}
+#endif
+
+    void
+gui_mch_free_font(GuiFont font)
+{
+    if (font)
+	DeleteObject((HFONT)font);
+}
+
+    static int
+hex_digit(int c)
+{
+    if (VIM_ISDIGIT(c))
+	return c - '0';
+    c = TOLOWER_ASC(c);
+    if (c >= 'a' && c <= 'f')
+	return c - 'a' + 10;
+    return -1000;
+}
+/*
+ * Return the Pixel value (color) for the given color name.
+ * Return INVALCOLOR for error.
+ */
+    guicolor_T
+gui_mch_get_color(char_u *name)
+{
+    typedef struct guicolor_tTable
+    {
+	char	    *name;
+	COLORREF    color;
+    } guicolor_tTable;
+
+    static guicolor_tTable table[] =
+    {
+	{"Black",		RGB(0x00, 0x00, 0x00)},
+	{"DarkGray",		RGB(0xA9, 0xA9, 0xA9)},
+	{"DarkGrey",		RGB(0xA9, 0xA9, 0xA9)},
+	{"Gray",		RGB(0xC0, 0xC0, 0xC0)},
+	{"Grey",		RGB(0xC0, 0xC0, 0xC0)},
+	{"LightGray",		RGB(0xD3, 0xD3, 0xD3)},
+	{"LightGrey",		RGB(0xD3, 0xD3, 0xD3)},
+	{"Gray10",		RGB(0x1A, 0x1A, 0x1A)},
+	{"Grey10",		RGB(0x1A, 0x1A, 0x1A)},
+	{"Gray20",		RGB(0x33, 0x33, 0x33)},
+	{"Grey20",		RGB(0x33, 0x33, 0x33)},
+	{"Gray30",		RGB(0x4D, 0x4D, 0x4D)},
+	{"Grey30",		RGB(0x4D, 0x4D, 0x4D)},
+	{"Gray40",		RGB(0x66, 0x66, 0x66)},
+	{"Grey40",		RGB(0x66, 0x66, 0x66)},
+	{"Gray50",		RGB(0x7F, 0x7F, 0x7F)},
+	{"Grey50",		RGB(0x7F, 0x7F, 0x7F)},
+	{"Gray60",		RGB(0x99, 0x99, 0x99)},
+	{"Grey60",		RGB(0x99, 0x99, 0x99)},
+	{"Gray70",		RGB(0xB3, 0xB3, 0xB3)},
+	{"Grey70",		RGB(0xB3, 0xB3, 0xB3)},
+	{"Gray80",		RGB(0xCC, 0xCC, 0xCC)},
+	{"Grey80",		RGB(0xCC, 0xCC, 0xCC)},
+	{"Gray90",		RGB(0xE5, 0xE5, 0xE5)},
+	{"Grey90",		RGB(0xE5, 0xE5, 0xE5)},
+	{"White",		RGB(0xFF, 0xFF, 0xFF)},
+	{"DarkRed",		RGB(0x80, 0x00, 0x00)},
+	{"Red",			RGB(0xFF, 0x00, 0x00)},
+	{"LightRed",		RGB(0xFF, 0xA0, 0xA0)},
+	{"DarkBlue",		RGB(0x00, 0x00, 0x80)},
+	{"Blue",		RGB(0x00, 0x00, 0xFF)},
+	{"LightBlue",		RGB(0xAD, 0xD8, 0xE6)},
+	{"DarkGreen",		RGB(0x00, 0x80, 0x00)},
+	{"Green",		RGB(0x00, 0xFF, 0x00)},
+	{"LightGreen",		RGB(0x90, 0xEE, 0x90)},
+	{"DarkCyan",		RGB(0x00, 0x80, 0x80)},
+	{"Cyan",		RGB(0x00, 0xFF, 0xFF)},
+	{"LightCyan",		RGB(0xE0, 0xFF, 0xFF)},
+	{"DarkMagenta",		RGB(0x80, 0x00, 0x80)},
+	{"Magenta",		RGB(0xFF, 0x00, 0xFF)},
+	{"LightMagenta",	RGB(0xFF, 0xA0, 0xFF)},
+	{"Brown",		RGB(0x80, 0x40, 0x40)},
+	{"Yellow",		RGB(0xFF, 0xFF, 0x00)},
+	{"LightYellow",		RGB(0xFF, 0xFF, 0xE0)},
+	{"DarkYellow",		RGB(0xBB, 0xBB, 0x00)},
+	{"SeaGreen",		RGB(0x2E, 0x8B, 0x57)},
+	{"Orange",		RGB(0xFF, 0xA5, 0x00)},
+	{"Purple",		RGB(0xA0, 0x20, 0xF0)},
+	{"SlateBlue",		RGB(0x6A, 0x5A, 0xCD)},
+	{"Violet",		RGB(0xEE, 0x82, 0xEE)},
+    };
+
+    typedef struct SysColorTable
+    {
+	char	    *name;
+	int	    color;
+    } SysColorTable;
+
+    static SysColorTable sys_table[] =
+    {
+#ifdef WIN3264
+	{"SYS_3DDKSHADOW", COLOR_3DDKSHADOW},
+	{"SYS_3DHILIGHT", COLOR_3DHILIGHT},
+#ifndef __MINGW32__
+	{"SYS_3DHIGHLIGHT", COLOR_3DHIGHLIGHT},
+#endif
+	{"SYS_BTNHILIGHT", COLOR_BTNHILIGHT},
+	{"SYS_BTNHIGHLIGHT", COLOR_BTNHIGHLIGHT},
+	{"SYS_3DLIGHT", COLOR_3DLIGHT},
+	{"SYS_3DSHADOW", COLOR_3DSHADOW},
+	{"SYS_DESKTOP", COLOR_DESKTOP},
+	{"SYS_INFOBK", COLOR_INFOBK},
+	{"SYS_INFOTEXT", COLOR_INFOTEXT},
+	{"SYS_3DFACE", COLOR_3DFACE},
+#endif
+	{"SYS_BTNFACE", COLOR_BTNFACE},
+	{"SYS_BTNSHADOW", COLOR_BTNSHADOW},
+	{"SYS_ACTIVEBORDER", COLOR_ACTIVEBORDER},
+	{"SYS_ACTIVECAPTION", COLOR_ACTIVECAPTION},
+	{"SYS_APPWORKSPACE", COLOR_APPWORKSPACE},
+	{"SYS_BACKGROUND", COLOR_BACKGROUND},
+	{"SYS_BTNTEXT", COLOR_BTNTEXT},
+	{"SYS_CAPTIONTEXT", COLOR_CAPTIONTEXT},
+	{"SYS_GRAYTEXT", COLOR_GRAYTEXT},
+	{"SYS_HIGHLIGHT", COLOR_HIGHLIGHT},
+	{"SYS_HIGHLIGHTTEXT", COLOR_HIGHLIGHTTEXT},
+	{"SYS_INACTIVEBORDER", COLOR_INACTIVEBORDER},
+	{"SYS_INACTIVECAPTION", COLOR_INACTIVECAPTION},
+	{"SYS_INACTIVECAPTIONTEXT", COLOR_INACTIVECAPTIONTEXT},
+	{"SYS_MENU", COLOR_MENU},
+	{"SYS_MENUTEXT", COLOR_MENUTEXT},
+	{"SYS_SCROLLBAR", COLOR_SCROLLBAR},
+	{"SYS_WINDOW", COLOR_WINDOW},
+	{"SYS_WINDOWFRAME", COLOR_WINDOWFRAME},
+	{"SYS_WINDOWTEXT", COLOR_WINDOWTEXT}
+    };
+
+    int		    r, g, b;
+    int		    i;
+
+    if (name[0] == '#' && STRLEN(name) == 7)
+    {
+	/* Name is in "#rrggbb" format */
+	r = hex_digit(name[1]) * 16 + hex_digit(name[2]);
+	g = hex_digit(name[3]) * 16 + hex_digit(name[4]);
+	b = hex_digit(name[5]) * 16 + hex_digit(name[6]);
+	if (r < 0 || g < 0 || b < 0)
+	    return INVALCOLOR;
+	return RGB(r, g, b);
+    }
+    else
+    {
+	/* Check if the name is one of the colors we know */
+	for (i = 0; i < sizeof(table) / sizeof(table[0]); i++)
+	    if (STRICMP(name, table[i].name) == 0)
+		return table[i].color;
+    }
+
+    /*
+     * Try to look up a system colour.
+     */
+    for (i = 0; i < sizeof(sys_table) / sizeof(sys_table[0]); i++)
+	if (STRICMP(name, sys_table[i].name) == 0)
+	    return GetSysColor(sys_table[i].color);
+
+    /*
+     * Last attempt. Look in the file "$VIMRUNTIME/rgb.txt".
+     */
+    {
+#define LINE_LEN 100
+	FILE	*fd;
+	char	line[LINE_LEN];
+	char_u	*fname;
+
+	fname = expand_env_save((char_u *)"$VIMRUNTIME/rgb.txt");
+	if (fname == NULL)
+	    return INVALCOLOR;
+
+	fd = mch_fopen((char *)fname, "rt");
+	vim_free(fname);
+	if (fd == NULL)
+	    return INVALCOLOR;
+
+	while (!feof(fd))
+	{
+	    int	    len;
+	    int	    pos;
+	    char    *color;
+
+	    fgets(line, LINE_LEN, fd);
+	    len = (int)STRLEN(line);
+
+	    if (len <= 1 || line[len-1] != '\n')
+		continue;
+
+	    line[len-1] = '\0';
+
+	    i = sscanf(line, "%d %d %d %n", &r, &g, &b, &pos);
+	    if (i != 3)
+		continue;
+
+	    color = line + pos;
+
+	    if (STRICMP(color, name) == 0)
+	    {
+		fclose(fd);
+		return (guicolor_T) RGB(r, g, b);
+	    }
+	}
+
+	fclose(fd);
+    }
+
+    return INVALCOLOR;
+}
+/*
+ * Return OK if the key with the termcap name "name" is supported.
+ */
+    int
+gui_mch_haskey(char_u *name)
+{
+    int i;
+
+    for (i = 0; special_keys[i].vim_code1 != NUL; i++)
+	if (name[0] == special_keys[i].vim_code0 &&
+					 name[1] == special_keys[i].vim_code1)
+	    return OK;
+    return FAIL;
+}
+
+    void
+gui_mch_beep(void)
+{
+    MessageBeep(MB_OK);
+}
+/*
+ * Invert a rectangle from row r, column c, for nr rows and nc columns.
+ */
+    void
+gui_mch_invert_rectangle(
+    int	    r,
+    int	    c,
+    int	    nr,
+    int	    nc)
+{
+    RECT    rc;
+
+    /*
+     * Note: InvertRect() excludes right and bottom of rectangle.
+     */
+    rc.left = FILL_X(c);
+    rc.top = FILL_Y(r);
+    rc.right = rc.left + nc * gui.char_width;
+    rc.bottom = rc.top + nr * gui.char_height;
+    InvertRect(s_hdc, &rc);
+}
+
+/*
+ * Iconify the GUI window.
+ */
+    void
+gui_mch_iconify(void)
+{
+    ShowWindow(s_hwnd, SW_MINIMIZE);
+}
+
+/*
+ * Draw a cursor without focus.
+ */
+    void
+gui_mch_draw_hollow_cursor(guicolor_T color)
+{
+    HBRUSH  hbr;
+    RECT    rc;
+
+    /*
+     * Note: FrameRect() excludes right and bottom of rectangle.
+     */
+    rc.left = FILL_X(gui.col);
+    rc.top = FILL_Y(gui.row);
+    rc.right = rc.left + gui.char_width;
+#ifdef FEAT_MBYTE
+    if (mb_lefthalve(gui.row, gui.col))
+	rc.right += gui.char_width;
+#endif
+    rc.bottom = rc.top + gui.char_height;
+    hbr = CreateSolidBrush(color);
+    FrameRect(s_hdc, &rc, hbr);
+    DeleteBrush(hbr);
+}
+/*
+ * Draw part of a cursor, "w" pixels wide, and "h" pixels high, using
+ * color "color".
+ */
+    void
+gui_mch_draw_part_cursor(
+    int		w,
+    int		h,
+    guicolor_T	color)
+{
+    HBRUSH	hbr;
+    RECT	rc;
+
+    /*
+     * Note: FillRect() excludes right and bottom of rectangle.
+     */
+    rc.left =
+#ifdef FEAT_RIGHTLEFT
+		/* vertical line should be on the right of current point */
+		CURSOR_BAR_RIGHT ? FILL_X(gui.col + 1) - w :
+#endif
+		    FILL_X(gui.col);
+    rc.top = FILL_Y(gui.row) + gui.char_height - h;
+    rc.right = rc.left + w;
+    rc.bottom = rc.top + h;
+    hbr = CreateSolidBrush(color);
+    FillRect(s_hdc, &rc, hbr);
+    DeleteBrush(hbr);
+}
+
+
+/*
+ * Generates a VK_SPACE when the internal dead_key flag is set to output the
+ * dead key's nominal character and re-post the original message.
+ */
+    static void
+outputDeadKey_rePost(MSG originalMsg)
+{
+    static MSG deadCharExpel;
+
+    if (!dead_key)
+	return;
+
+    dead_key = 0;
+
+    /* Make Windows generate the dead key's character */
+    deadCharExpel.message = originalMsg.message;
+    deadCharExpel.hwnd    = originalMsg.hwnd;
+    deadCharExpel.wParam  = VK_SPACE;
+
+    MyTranslateMessage(&deadCharExpel);
+
+    /* re-generate the current character free of the dead char influence */
+    PostMessage(originalMsg.hwnd, originalMsg.message, originalMsg.wParam,
+							  originalMsg.lParam);
+}
+
+
+/*
+ * Process a single Windows message.
+ * If one is not available we hang until one is.
+ */
+    static void
+process_message(void)
+{
+    MSG		msg;
+    UINT	vk = 0;		/* Virtual key */
+    char_u	string[40];
+    int		i;
+    int		modifiers = 0;
+    int		key;
+#ifdef FEAT_MENU
+    static char_u k10[] = {K_SPECIAL, 'k', ';', 0};
+#endif
+
+    pGetMessage(&msg, NULL, 0, 0);
+
+#ifdef FEAT_OLE
+    /* Look after OLE Automation commands */
+    if (msg.message == WM_OLE)
+    {
+	char_u *str = (char_u *)msg.lParam;
+	if (str == NULL || *str == NUL)
+	{
+	    /* Message can't be ours, forward it.  Fixes problem with Ultramon
+	     * 3.0.4 */
+	    pDispatchMessage(&msg);
+	}
+	else
+	{
+	    add_to_input_buf(str, (int)STRLEN(str));
+	    vim_free(str);  /* was allocated in CVim::SendKeys() */
+	}
+	return;
+    }
+#endif
+
+#ifdef FEAT_CHANNEL
+    if (msg.message == WM_NETBEANS)
+    {
+	int	    what;
+	channel_T   *channel = channel_fd2channel((sock_T)msg.wParam, &what);
+
+	if (channel != NULL)
+	{
+	    /* Disable error messages, they can mess up the display and throw
+	     * an exception. */
+	    ++emsg_off;
+	    channel_read(channel, what, "process_message");
+	    --emsg_off;
+	}
+	return;
+    }
+#endif
+
+#ifdef FEAT_SNIFF
+    if (sniff_request_waiting && want_sniff_request)
+    {
+	static char_u bytes[3] = {CSI, (char_u)KS_EXTRA, (char_u)KE_SNIFF};
+	add_to_input_buf(bytes, 3); /* K_SNIFF */
+	sniff_request_waiting = 0;
+	want_sniff_request = 0;
+	/* request is handled in normal.c */
+    }
+    if (msg.message == WM_USER)
+    {
+	MyTranslateMessage(&msg);
+	pDispatchMessage(&msg);
+	return;
+    }
+#endif
+
+#ifdef MSWIN_FIND_REPLACE
+    /* Don't process messages used by the dialog */
+    if (s_findrep_hwnd != NULL && pIsDialogMessage(s_findrep_hwnd, &msg))
+    {
+	HandleMouseHide(msg.message, msg.lParam);
+	return;
+    }
+#endif
+
+    /*
+     * Check if it's a special key that we recognise.  If not, call
+     * TranslateMessage().
+     */
+    if (msg.message == WM_KEYDOWN || msg.message == WM_SYSKEYDOWN)
+    {
+	vk = (int) msg.wParam;
+
+	/*
+	 * Handle dead keys in special conditions in other cases we let Windows
+	 * handle them and do not interfere.
+	 *
+	 * The dead_key flag must be reset on several occasions:
+	 * - in _OnChar() (or _OnSysChar()) as any dead key was necessarily
+	 *   consumed at that point (This is when we let Windows combine the
+	 *   dead character on its own)
+	 *
+	 * - Before doing something special such as regenerating keypresses to
+	 *   expel the dead character as this could trigger an infinite loop if
+	 *   for some reason MyTranslateMessage() do not trigger a call
+	 *   immediately to _OnChar() (or _OnSysChar()).
+	 */
+	if (dead_key)
+	{
+	    /*
+	     * If a dead key was pressed and the user presses VK_SPACE,
+	     * VK_BACK, or VK_ESCAPE it means that he actually wants to deal
+	     * with the dead char now, so do nothing special and let Windows
+	     * handle it.
+	     *
+	     * Note that VK_SPACE combines with the dead_key's character and
+	     * only one WM_CHAR will be generated by TranslateMessage(), in
+	     * the two other cases two WM_CHAR will be generated: the dead
+	     * char and VK_BACK or VK_ESCAPE. That is most likely what the
+	     * user expects.
+	     */
+	    if ((vk == VK_SPACE || vk == VK_BACK || vk == VK_ESCAPE))
+	    {
+		dead_key = 0;
+		MyTranslateMessage(&msg);
+		return;
+	    }
+	    /* In modes where we are not typing, dead keys should behave
+	     * normally */
+	    else if (!(get_real_state() & (INSERT | CMDLINE | SELECTMODE)))
+	    {
+		outputDeadKey_rePost(msg);
+		return;
+	    }
+	}
+
+	/* Check for CTRL-BREAK */
+	if (vk == VK_CANCEL)
+	{
+	    trash_input_buf();
+	    got_int = TRUE;
+	    string[0] = Ctrl_C;
+	    add_to_input_buf(string, 1);
+	}
+
+	for (i = 0; special_keys[i].key_sym != 0; i++)
+	{
+	    /* ignore VK_SPACE when ALT key pressed: system menu */
+	    if (special_keys[i].key_sym == vk
+		    && (vk != VK_SPACE || !(GetKeyState(VK_MENU) & 0x8000)))
+	    {
+		/*
+		 * Behave as exected if we have a dead key and the special key
+		 * is a key that would normally trigger the dead key nominal
+		 * character output (such as a NUMPAD printable character or
+		 * the TAB key, etc...).
+		 */
+		if (dead_key && (special_keys[i].vim_code0 == 'K'
+						|| vk == VK_TAB || vk == CAR))
+		{
+		    outputDeadKey_rePost(msg);
+		    return;
+		}
+
+#ifdef FEAT_MENU
+		/* Check for <F10>: Windows selects the menu.  When <F10> is
+		 * mapped we want to use the mapping instead. */
+		if (vk == VK_F10
+			&& gui.menu_is_active
+			&& check_map(k10, State, FALSE, TRUE, FALSE,
+							  NULL, NULL) == NULL)
+		    break;
+#endif
+		if (GetKeyState(VK_SHIFT) & 0x8000)
+		    modifiers |= MOD_MASK_SHIFT;
+		/*
+		 * Don't use caps-lock as shift, because these are special keys
+		 * being considered here, and we only want letters to get
+		 * shifted -- webb
+		 */
+		/*
+		if (GetKeyState(VK_CAPITAL) & 0x0001)
+		    modifiers ^= MOD_MASK_SHIFT;
+		*/
+		if (GetKeyState(VK_CONTROL) & 0x8000)
+		    modifiers |= MOD_MASK_CTRL;
+		if (GetKeyState(VK_MENU) & 0x8000)
+		    modifiers |= MOD_MASK_ALT;
+
+		if (special_keys[i].vim_code1 == NUL)
+		    key = special_keys[i].vim_code0;
+		else
+		    key = TO_SPECIAL(special_keys[i].vim_code0,
+						   special_keys[i].vim_code1);
+		key = simplify_key(key, &modifiers);
+		if (key == CSI)
+		    key = K_CSI;
+
+		if (modifiers)
+		{
+		    string[0] = CSI;
+		    string[1] = KS_MODIFIER;
+		    string[2] = modifiers;
+		    add_to_input_buf(string, 3);
+		}
+
+		if (IS_SPECIAL(key))
+		{
+		    string[0] = CSI;
+		    string[1] = K_SECOND(key);
+		    string[2] = K_THIRD(key);
+		    add_to_input_buf(string, 3);
+		}
+		else
+		{
+		    int	len;
+
+		    /* Handle "key" as a Unicode character. */
+		    len = char_to_string(key, string, 40, FALSE);
+		    add_to_input_buf(string, len);
+		}
+		break;
+	    }
+	}
+	if (special_keys[i].key_sym == 0)
+	{
+	    /* Some keys need C-S- where they should only need C-.
+	     * Ignore 0xff, Windows XP sends it when NUMLOCK has changed since
+	     * system startup (Helmut Stiegler, 2003 Oct 3). */
+	    if (vk != 0xff
+		    && (GetKeyState(VK_CONTROL) & 0x8000)
+		    && !(GetKeyState(VK_SHIFT) & 0x8000)
+		    && !(GetKeyState(VK_MENU) & 0x8000))
+	    {
+		/* CTRL-6 is '^'; Japanese keyboard maps '^' to vk == 0xDE */
+		if (vk == '6' || MapVirtualKey(vk, 2) == (UINT)'^')
+		{
+		    string[0] = Ctrl_HAT;
+		    add_to_input_buf(string, 1);
+		}
+		/* vk == 0xBD AZERTY for CTRL-'-', but CTRL-[ for * QWERTY! */
+		else if (vk == 0xBD)	/* QWERTY for CTRL-'-' */
+		{
+		    string[0] = Ctrl__;
+		    add_to_input_buf(string, 1);
+		}
+		/* CTRL-2 is '@'; Japanese keyboard maps '@' to vk == 0xC0 */
+		else if (vk == '2' || MapVirtualKey(vk, 2) == (UINT)'@')
+		{
+		    string[0] = Ctrl_AT;
+		    add_to_input_buf(string, 1);
+		}
+		else
+		    MyTranslateMessage(&msg);
+	    }
+	    else
+		MyTranslateMessage(&msg);
+	}
+    }
+#ifdef FEAT_MBYTE_IME
+    else if (msg.message == WM_IME_NOTIFY)
+	_OnImeNotify(msg.hwnd, (DWORD)msg.wParam, (DWORD)msg.lParam);
+    else if (msg.message == WM_KEYUP && im_get_status())
+	/* added for non-MS IME (Yasuhiro Matsumoto) */
+	MyTranslateMessage(&msg);
+#endif
+#if !defined(FEAT_MBYTE_IME) && defined(GLOBAL_IME)
+/* GIME_TEST */
+    else if (msg.message == WM_IME_STARTCOMPOSITION)
+    {
+	POINT point;
+
+	global_ime_set_font(&norm_logfont);
+	point.x = FILL_X(gui.col);
+	point.y = FILL_Y(gui.row);
+	MapWindowPoints(s_textArea, s_hwnd, &point, 1);
+	global_ime_set_position(&point);
+    }
+#endif
+
+#ifdef FEAT_MENU
+    /* Check for <F10>: Default effect is to select the menu.  When <F10> is
+     * mapped we need to stop it here to avoid strange effects (e.g., for the
+     * key-up event) */
+    if (vk != VK_F10 || check_map(k10, State, FALSE, TRUE, FALSE,
+							  NULL, NULL) == NULL)
+#endif
+	pDispatchMessage(&msg);
+}
+
+/*
+ * Catch up with any queued events.  This may put keyboard input into the
+ * input buffer, call resize call-backs, trigger timers etc.  If there is
+ * nothing in the event queue (& no timers pending), then we return
+ * immediately.
+ */
+    void
+gui_mch_update(void)
+{
+    MSG	    msg;
+
+    if (!s_busy_processing)
+	while (pPeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)
+						  && !vim_is_input_buf_full())
+	    process_message();
+}
+
+/*
+ * GUI input routine called by gui_wait_for_chars().  Waits for a character
+ * from the keyboard.
+ *  wtime == -1	    Wait forever.
+ *  wtime == 0	    This should never happen.
+ *  wtime > 0	    Wait wtime milliseconds for a character.
+ * Returns OK if a character was found to be available within the given time,
+ * or FAIL otherwise.
+ */
+    int
+gui_mch_wait_for_chars(int wtime)
+{
+    MSG		msg;
+    int		focus;
+
+    s_timed_out = FALSE;
+
+    if (wtime > 0)
+    {
+	/* Don't do anything while processing a (scroll) message. */
+	if (s_busy_processing)
+	    return FAIL;
+	s_wait_timer = (UINT)SetTimer(NULL, 0, (UINT)wtime,
+							 (TIMERPROC)_OnTimer);
+    }
+
+    allow_scrollbar = TRUE;
+
+    focus = gui.in_focus;
+    while (!s_timed_out)
+    {
+	/* Stop or start blinking when focus changes */
+	if (gui.in_focus != focus)
+	{
+	    if (gui.in_focus)
+		gui_mch_start_blink();
+	    else
+		gui_mch_stop_blink();
+	    focus = gui.in_focus;
+	}
+
+	if (s_need_activate)
+	{
+#ifdef WIN32
+	    (void)SetForegroundWindow(s_hwnd);
+#else
+	    (void)SetActiveWindow(s_hwnd);
+#endif
+	    s_need_activate = FALSE;
+	}
+
+#ifdef MESSAGE_QUEUE
+	parse_queued_messages();
+#endif
+
+#ifdef FEAT_CHANNEL
+	channel_handle_events();
+#endif
+
+	/*
+	 * Don't use gui_mch_update() because then we will spin-lock until a
+	 * char arrives, instead we use GetMessage() to hang until an
+	 * event arrives.  No need to check for input_buf_full because we are
+	 * returning as soon as it contains a single char -- webb
+	 */
+	process_message();
+
+	if (input_available())
+	{
+	    if (s_wait_timer != 0 && !s_timed_out)
+	    {
+		KillTimer(NULL, s_wait_timer);
+
+		/* Eat spurious WM_TIMER messages */
+		while (pPeekMessage(&msg, s_hwnd, WM_TIMER, WM_TIMER, PM_REMOVE))
+		    ;
+		s_wait_timer = 0;
+	    }
+	    allow_scrollbar = FALSE;
+
+	    /* Clear pending mouse button, the release event may have been
+	     * taken by the dialog window.  But don't do this when getting
+	     * focus, we need the mouse-up event then. */
+	    if (!s_getting_focus)
+		s_button_pending = -1;
+
+	    return OK;
+	}
+    }
+    allow_scrollbar = FALSE;
+    return FAIL;
+}
+
+/*
+ * Clear a rectangular region of the screen from text pos (row1, col1) to
+ * (row2, col2) inclusive.
+ */
+    void
+gui_mch_clear_block(
+    int		row1,
+    int		col1,
+    int		row2,
+    int		col2)
+{
+    RECT	rc;
+
+    /*
+     * Clear one extra pixel at the far right, for when bold characters have
+     * spilled over to the window border.
+     * Note: FillRect() excludes right and bottom of rectangle.
+     */
+    rc.left = FILL_X(col1);
+    rc.top = FILL_Y(row1);
+    rc.right = FILL_X(col2 + 1) + (col2 == Columns - 1);
+    rc.bottom = FILL_Y(row2 + 1);
+    clear_rect(&rc);
+}
+
+/*
+ * Clear the whole text window.
+ */
+    void
+gui_mch_clear_all(void)
+{
+    RECT    rc;
+
+    rc.left = 0;
+    rc.top = 0;
+    rc.right = Columns * gui.char_width + 2 * gui.border_width;
+    rc.bottom = Rows * gui.char_height + 2 * gui.border_width;
+    clear_rect(&rc);
+}
+/*
+ * Menu stuff.
+ */
+
+    void
+gui_mch_enable_menu(int flag)
+{
+#ifdef FEAT_MENU
+    SetMenu(s_hwnd, flag ? s_menuBar : NULL);
+#endif
+}
+
+/*ARGSUSED*/
+    void
+gui_mch_set_menu_pos(
+    int	    x,
+    int	    y,
+    int	    w,
+    int	    h)
+{
+    /* It will be in the right place anyway */
+}
+
+#if defined(FEAT_MENU) || defined(PROTO)
+/*
+ * Make menu item hidden or not hidden
+ */
+    void
+gui_mch_menu_hidden(
+    vimmenu_T	*menu,
+    int		hidden)
+{
+    /*
+     * This doesn't do what we want.  Hmm, just grey the menu items for now.
+     */
+    /*
+    if (hidden)
+	EnableMenuItem(s_menuBar, menu->id, MF_BYCOMMAND | MF_DISABLED);
+    else
+	EnableMenuItem(s_menuBar, menu->id, MF_BYCOMMAND | MF_ENABLED);
+    */
+    gui_mch_menu_grey(menu, hidden);
+}
+
+/*
+ * This is called after setting all the menus to grey/hidden or not.
+ */
+    void
+gui_mch_draw_menubar(void)
+{
+    DrawMenuBar(s_hwnd);
+}
+#endif /*FEAT_MENU*/
+
+#ifndef PROTO
+void
+#ifdef VIMDLL
+_export
+#endif
+_cdecl
+SaveInst(HINSTANCE hInst)
+{
+    s_hinst = hInst;
+}
+#endif
+
+/*
+ * Return the RGB value of a pixel as a long.
+ */
+    long_u
+gui_mch_get_rgb(guicolor_T pixel)
+{
+    return (GetRValue(pixel) << 16) + (GetGValue(pixel) << 8)
+							   + GetBValue(pixel);
+}
+
+#if defined(FEAT_GUI_DIALOG) || defined(PROTO)
+/* Convert pixels in X to dialog units */
+    static WORD
+PixelToDialogX(int numPixels)
+{
+    return (WORD)((numPixels * 4) / s_dlgfntwidth);
+}
+
+/* Convert pixels in Y to dialog units */
+    static WORD
+PixelToDialogY(int numPixels)
+{
+    return (WORD)((numPixels * 8) / s_dlgfntheight);
+}
+
+/* Return the width in pixels of the given text in the given DC. */
+    static int
+GetTextWidth(HDC hdc, char_u *str, int len)
+{
+    SIZE    size;
+
+    GetTextExtentPoint(hdc, (LPCSTR)str, len, &size);
+    return size.cx;
+}
+
+#ifdef FEAT_MBYTE
+/*
+ * Return the width in pixels of the given text in the given DC, taking care
+ * of 'encoding' to active codepage conversion.
+ */
+    static int
+GetTextWidthEnc(HDC hdc, char_u *str, int len)
+{
+    SIZE	size;
+    WCHAR	*wstr;
+    int		n;
+    int		wlen = len;
+
+    if (enc_codepage >= 0 && (int)GetACP() != enc_codepage)
+    {
+	/* 'encoding' differs from active codepage: convert text and use wide
+	 * function */
+	wstr = enc_to_utf16(str, &wlen);
+	if (wstr != NULL)
+	{
+	    n = GetTextExtentPointW(hdc, wstr, wlen, &size);
+	    vim_free(wstr);
+	    if (n)
+		return size.cx;
+	}
+    }
+
+    return GetTextWidth(hdc, str, len);
+}
+#else
+# define GetTextWidthEnc(h, s, l) GetTextWidth((h), (s), (l))
+#endif
+
+/*
+ * A quick little routine that will center one window over another, handy for
+ * dialog boxes.  Taken from the Win32SDK samples.
+ */
+    static BOOL
+CenterWindow(
+    HWND hwndChild,
+    HWND hwndParent)
+{
+    RECT    rChild, rParent;
+    int     wChild, hChild, wParent, hParent;
+    int     wScreen, hScreen, xNew, yNew;
+    HDC     hdc;
+
+    GetWindowRect(hwndChild, &rChild);
+    wChild = rChild.right - rChild.left;
+    hChild = rChild.bottom - rChild.top;
+
+    /* If Vim is minimized put the window in the middle of the screen. */
+    if (hwndParent == NULL || IsMinimized(hwndParent))
+	SystemParametersInfo(SPI_GETWORKAREA, 0, &rParent, 0);
+    else
+	GetWindowRect(hwndParent, &rParent);
+    wParent = rParent.right - rParent.left;
+    hParent = rParent.bottom - rParent.top;
+
+    hdc = GetDC(hwndChild);
+    wScreen = GetDeviceCaps (hdc, HORZRES);
+    hScreen = GetDeviceCaps (hdc, VERTRES);
+    ReleaseDC(hwndChild, hdc);
+
+    xNew = rParent.left + ((wParent - wChild) /2);
+    if (xNew < 0)
+    {
+	xNew = 0;
+    }
+    else if ((xNew+wChild) > wScreen)
+    {
+	xNew = wScreen - wChild;
+    }
+
+    yNew = rParent.top	+ ((hParent - hChild) /2);
+    if (yNew < 0)
+	yNew = 0;
+    else if ((yNew+hChild) > hScreen)
+	yNew = hScreen - hChild;
+
+    return SetWindowPos(hwndChild, NULL, xNew, yNew, 0, 0,
+						   SWP_NOSIZE | SWP_NOZORDER);
+}
+#endif /* FEAT_GUI_DIALOG */
+
+void
+gui_mch_activate_window(void)
+{
+    (void)SetActiveWindow(s_hwnd);
+}
+
+#if defined(FEAT_TOOLBAR) || defined(PROTO)
+    void
+gui_mch_show_toolbar(int showit)
+{
+    if (s_toolbarhwnd == NULL)
+	return;
+
+    if (showit)
+    {
+# ifdef FEAT_MBYTE
+#  ifndef TB_SETUNICODEFORMAT
+    /* For older compilers.  We assume this never changes. */
+#   define TB_SETUNICODEFORMAT 0x2005
+#  endif
+	/* Enable/disable unicode support */
+	int uu = (enc_codepage >= 0 && (int)GetACP() != enc_codepage);
+	SendMessage(s_toolbarhwnd, TB_SETUNICODEFORMAT, (WPARAM)uu, (LPARAM)0);
+# endif
+	ShowWindow(s_toolbarhwnd, SW_SHOW);
+    }
+    else
+	ShowWindow(s_toolbarhwnd, SW_HIDE);
+}
+
+/* Then number of bitmaps is fixed.  Exit is missing! */
+#define TOOLBAR_BITMAP_COUNT 31
+
+#endif
+
+#if defined(FEAT_GUI_TABLINE) || defined(PROTO)
+    static void
+add_tabline_popup_menu_entry(HMENU pmenu, UINT item_id, char_u *item_text)
+{
+#ifdef FEAT_MBYTE
+    WCHAR	*wn = NULL;
+    int		n;
+
+    if (enc_codepage >= 0 && (int)GetACP() != enc_codepage)
+    {
+	/* 'encoding' differs from active codepage: convert menu name
+	 * and use wide function */
+	wn = enc_to_utf16(item_text, NULL);
+	if (wn != NULL)
+	{
+	    MENUITEMINFOW	infow;
+
+	    infow.cbSize = sizeof(infow);
+	    infow.fMask = MIIM_TYPE | MIIM_ID;
+	    infow.wID = item_id;
+	    infow.fType = MFT_STRING;
+	    infow.dwTypeData = wn;
+	    infow.cch = (UINT)wcslen(wn);
+	    n = InsertMenuItemW(pmenu, item_id, FALSE, &infow);
+	    vim_free(wn);
+	    if (n == 0 && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
+		/* Failed, try using non-wide function. */
+		wn = NULL;
+	}
+    }
+
+    if (wn == NULL)
+#endif
+    {
+	MENUITEMINFO	info;
+
+	info.cbSize = sizeof(info);
+	info.fMask = MIIM_TYPE | MIIM_ID;
+	info.wID = item_id;
+	info.fType = MFT_STRING;
+	info.dwTypeData = (LPTSTR)item_text;
+	info.cch = (UINT)STRLEN(item_text);
+	InsertMenuItem(pmenu, item_id, FALSE, &info);
+    }
+}
+
+    static void
+show_tabline_popup_menu(void)
+{
+    HMENU	    tab_pmenu;
+    long	    rval;
+    POINT	    pt;
+
+    /* When ignoring events don't show the menu. */
+    if (hold_gui_events
+# ifdef FEAT_CMDWIN
+	    || cmdwin_type != 0
+# endif
+       )
+	return;
+
+    tab_pmenu = CreatePopupMenu();
+    if (tab_pmenu == NULL)
+	return;
+
+    if (first_tabpage->tp_next != NULL)
+	add_tabline_popup_menu_entry(tab_pmenu,
+				TABLINE_MENU_CLOSE, (char_u *)_("Close tab"));
+    add_tabline_popup_menu_entry(tab_pmenu,
+				TABLINE_MENU_NEW, (char_u *)_("New tab"));
+    add_tabline_popup_menu_entry(tab_pmenu,
+				TABLINE_MENU_OPEN, (char_u *)_("Open tab..."));
+
+    GetCursorPos(&pt);
+    rval = TrackPopupMenuEx(tab_pmenu, TPM_RETURNCMD, pt.x, pt.y, s_tabhwnd,
+									NULL);
+
+    DestroyMenu(tab_pmenu);
+
+    /* Add the string cmd into input buffer */
+    if (rval > 0)
+    {
+	TCHITTESTINFO htinfo;
+	int idx;
+
+	if (ScreenToClient(s_tabhwnd, &pt) == 0)
+	    return;
+
+	htinfo.pt.x = pt.x;
+	htinfo.pt.y = pt.y;
+	idx = TabCtrl_HitTest(s_tabhwnd, &htinfo);
+	if (idx == -1)
+	    idx = 0;
+	else
+	    idx += 1;
+
+	send_tabline_menu_event(idx, (int)rval);
+    }
+}
+
+/*
+ * Show or hide the tabline.
+ */
+    void
+gui_mch_show_tabline(int showit)
+{
+    if (s_tabhwnd == NULL)
+	return;
+
+    if (!showit != !showing_tabline)
+    {
+	if (showit)
+	    ShowWindow(s_tabhwnd, SW_SHOW);
+	else
+	    ShowWindow(s_tabhwnd, SW_HIDE);
+	showing_tabline = showit;
+    }
+}
+
+/*
+ * Return TRUE when tabline is displayed.
+ */
+    int
+gui_mch_showing_tabline(void)
+{
+    return s_tabhwnd != NULL && showing_tabline;
+}
+
+/*
+ * Update the labels of the tabline.
+ */
+    void
+gui_mch_update_tabline(void)
+{
+    tabpage_T	*tp;
+    TCITEM	tie;
+    int		nr = 0;
+    int		curtabidx = 0;
+    int		tabadded = 0;
+#ifdef FEAT_MBYTE
+    static int	use_unicode = FALSE;
+    int		uu;
+    WCHAR	*wstr = NULL;
+#endif
+
+    if (s_tabhwnd == NULL)
+	return;
+
+#if defined(FEAT_MBYTE)
+# ifndef CCM_SETUNICODEFORMAT
+    /* For older compilers.  We assume this never changes. */
+#  define CCM_SETUNICODEFORMAT 0x2005
+# endif
+    uu = (enc_codepage >= 0 && (int)GetACP() != enc_codepage);
+    if (uu != use_unicode)
+    {
+	/* Enable/disable unicode support */
+	SendMessage(s_tabhwnd, CCM_SETUNICODEFORMAT, (WPARAM)uu, (LPARAM)0);
+	use_unicode = uu;
+    }
+#endif
+
+    tie.mask = TCIF_TEXT;
+    tie.iImage = -1;
+
+    /* Disable redraw for tab updates to eliminate O(N^2) draws. */
+    SendMessage(s_tabhwnd, WM_SETREDRAW, (WPARAM)FALSE, 0);
+
+    /* Add a label for each tab page.  They all contain the same text area. */
+    for (tp = first_tabpage; tp != NULL; tp = tp->tp_next, ++nr)
+    {
+	if (tp == curtab)
+	    curtabidx = nr;
+
+	if (nr >= TabCtrl_GetItemCount(s_tabhwnd))
+	{
+	    /* Add the tab */
+	    tie.pszText = "-Empty-";
+	    TabCtrl_InsertItem(s_tabhwnd, nr, &tie);
+	    tabadded = 1;
+	}
+
+	get_tabline_label(tp, FALSE);
+	tie.pszText = (LPSTR)NameBuff;
+#ifdef FEAT_MBYTE
+	wstr = NULL;
+	if (use_unicode)
+	{
+	    /* Need to go through Unicode. */
+	    wstr = enc_to_utf16(NameBuff, NULL);
+	    if (wstr != NULL)
+	    {
+		TCITEMW		tiw;
+
+		tiw.mask = TCIF_TEXT;
+		tiw.iImage = -1;
+		tiw.pszText = wstr;
+		SendMessage(s_tabhwnd, TCM_SETITEMW, (WPARAM)nr, (LPARAM)&tiw);
+		vim_free(wstr);
+	    }
+	}
+	if (wstr == NULL)
+#endif
+	{
+	    TabCtrl_SetItem(s_tabhwnd, nr, &tie);
+	}
+    }
+
+    /* Remove any old labels. */
+    while (nr < TabCtrl_GetItemCount(s_tabhwnd))
+	TabCtrl_DeleteItem(s_tabhwnd, nr);
+
+    if (!tabadded && TabCtrl_GetCurSel(s_tabhwnd) != curtabidx)
+	TabCtrl_SetCurSel(s_tabhwnd, curtabidx);
+
+    /* Re-enable redraw and redraw. */
+    SendMessage(s_tabhwnd, WM_SETREDRAW, (WPARAM)TRUE, 0);
+    RedrawWindow(s_tabhwnd, NULL, NULL,
+		    RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN);
+
+    if (tabadded && TabCtrl_GetCurSel(s_tabhwnd) != curtabidx)
+	TabCtrl_SetCurSel(s_tabhwnd, curtabidx);
+}
+
+/*
+ * Set the current tab to "nr".  First tab is 1.
+ */
+    void
+gui_mch_set_curtab(int nr)
+{
+    if (s_tabhwnd == NULL)
+	return;
+
+    if (TabCtrl_GetCurSel(s_tabhwnd) != nr - 1)
+	TabCtrl_SetCurSel(s_tabhwnd, nr - 1);
+}
+
+#endif
+
+/*
+ * ":simalt" command.
+ */
+    void
+ex_simalt(exarg_T *eap)
+{
+    char_u *keys = eap->arg;
+
+    PostMessage(s_hwnd, WM_SYSCOMMAND, (WPARAM)SC_KEYMENU, (LPARAM)0);
+    while (*keys)
+    {
+	if (*keys == '~')
+	    *keys = ' ';	    /* for showing system menu */
+	PostMessage(s_hwnd, WM_CHAR, (WPARAM)*keys, (LPARAM)0);
+	keys++;
+    }
+}
+
+/*
+ * Create the find & replace dialogs.
+ * You can't have both at once: ":find" when replace is showing, destroys
+ * the replace dialog first, and the other way around.
+ */
+#ifdef MSWIN_FIND_REPLACE
+    static void
+initialise_findrep(char_u *initial_string)
+{
+    int		wword = FALSE;
+    int		mcase = !p_ic;
+    char_u	*entry_text;
+
+    /* Get the search string to use. */
+    entry_text = get_find_dialog_text(initial_string, &wword, &mcase);
+
+    s_findrep_struct.hwndOwner = s_hwnd;
+    s_findrep_struct.Flags = FR_DOWN;
+    if (mcase)
+	s_findrep_struct.Flags |= FR_MATCHCASE;
+    if (wword)
+	s_findrep_struct.Flags |= FR_WHOLEWORD;
+    if (entry_text != NULL && *entry_text != NUL)
+	vim_strncpy((char_u *)s_findrep_struct.lpstrFindWhat, entry_text,
+					   s_findrep_struct.wFindWhatLen - 1);
+    vim_free(entry_text);
+}
+#endif
+
+    static void
+set_window_title(HWND hwnd, char *title)
+{
+#ifdef FEAT_MBYTE
+    if (title != NULL && enc_codepage >= 0 && enc_codepage != (int)GetACP())
+    {
+	WCHAR	*wbuf;
+	int	n;
+
+	/* Convert the title from 'encoding' to UTF-16. */
+	wbuf = (WCHAR *)enc_to_utf16((char_u *)title, NULL);
+	if (wbuf != NULL)
+	{
+	    n = SetWindowTextW(hwnd, wbuf);
+	    vim_free(wbuf);
+	    if (n != 0 || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
+		return;
+	    /* Retry with non-wide function (for Windows 98). */
+	}
+    }
+#endif
+    (void)SetWindowText(hwnd, (LPCSTR)title);
+}
+
+    void
+gui_mch_find_dialog(exarg_T *eap)
+{
+#ifdef MSWIN_FIND_REPLACE
+    if (s_findrep_msg != 0)
+    {
+	if (IsWindow(s_findrep_hwnd) && !s_findrep_is_find)
+	    DestroyWindow(s_findrep_hwnd);
+
+	if (!IsWindow(s_findrep_hwnd))
+	{
+	    initialise_findrep(eap->arg);
+# if defined(FEAT_MBYTE) && defined(WIN3264)
+	    /* If the OS is Windows NT, and 'encoding' differs from active
+	     * codepage: convert text and use wide function. */
+	    if (os_version.dwPlatformId == VER_PLATFORM_WIN32_NT
+		    && enc_codepage >= 0 && (int)GetACP() != enc_codepage)
+	    {
+		findrep_atow(&s_findrep_struct_w, &s_findrep_struct);
+		s_findrep_hwnd = FindTextW(
+					(LPFINDREPLACEW) &s_findrep_struct_w);
+	    }
+	    else
+# endif
+		s_findrep_hwnd = FindText((LPFINDREPLACE) &s_findrep_struct);
+	}
+
+	set_window_title(s_findrep_hwnd,
+			       _("Find string (use '\\\\' to find  a '\\')"));
+	(void)SetFocus(s_findrep_hwnd);
+
+	s_findrep_is_find = TRUE;
+    }
+#endif
+}
+
+
+    void
+gui_mch_replace_dialog(exarg_T *eap)
+{
+#ifdef MSWIN_FIND_REPLACE
+    if (s_findrep_msg != 0)
+    {
+	if (IsWindow(s_findrep_hwnd) && s_findrep_is_find)
+	    DestroyWindow(s_findrep_hwnd);
+
+	if (!IsWindow(s_findrep_hwnd))
+	{
+	    initialise_findrep(eap->arg);
+# if defined(FEAT_MBYTE) && defined(WIN3264)
+	    if (os_version.dwPlatformId == VER_PLATFORM_WIN32_NT
+		    && enc_codepage >= 0 && (int)GetACP() != enc_codepage)
+	    {
+		findrep_atow(&s_findrep_struct_w, &s_findrep_struct);
+		s_findrep_hwnd = ReplaceTextW(
+					(LPFINDREPLACEW) &s_findrep_struct_w);
+	    }
+	    else
+# endif
+		s_findrep_hwnd = ReplaceText(
+					   (LPFINDREPLACE) &s_findrep_struct);
+	}
+
+	set_window_title(s_findrep_hwnd,
+			    _("Find & Replace (use '\\\\' to find  a '\\')"));
+	(void)SetFocus(s_findrep_hwnd);
+
+	s_findrep_is_find = FALSE;
+    }
+#endif
+}
+
+
+/*
+ * Set visibility of the pointer.
+ */
+    void
+gui_mch_mousehide(int hide)
+{
+    if (hide != gui.pointer_hidden)
+    {
+	ShowCursor(!hide);
+	gui.pointer_hidden = hide;
+    }
+}
+
+#ifdef FEAT_MENU
+    static void
+gui_mch_show_popupmenu_at(vimmenu_T *menu, int x, int y)
+{
+    /* Unhide the mouse, we don't get move events here. */
+    gui_mch_mousehide(FALSE);
+
+    (void)TrackPopupMenu(
+	(HMENU)menu->submenu_id,
+	TPM_LEFTALIGN | TPM_LEFTBUTTON,
+	x, y,
+	(int)0,	    /*reserved param*/
+	s_hwnd,
+	NULL);
+    /*
+     * NOTE: The pop-up menu can eat the mouse up event.
+     * We deal with this in normal.c.
+     */
+}
+#endif
+
+/*
+ * Got a message when the system will go down.
+ */
+    static void
+_OnEndSession(void)
+{
+    getout_preserve_modified(1);
+}
+
+/*
+ * Get this message when the user clicks on the cross in the top right corner
+ * of a Windows95 window.
+ */
+/*ARGSUSED*/
+    static void
+_OnClose(
+    HWND hwnd)
+{
+    gui_shell_closed();
+}
+
+/*
+ * Get a message when the window is being destroyed.
+ */
+    static void
+_OnDestroy(
+    HWND hwnd)
+{
+    if (!destroying)
+	_OnClose(hwnd);
+}
+
+    static void
+_OnPaint(
+    HWND hwnd)
+{
+    if (!IsMinimized(hwnd))
+    {
+	PAINTSTRUCT ps;
+
+	out_flush();	    /* make sure all output has been processed */
+	(void)BeginPaint(hwnd, &ps);
+#if defined(FEAT_DIRECTX)
+	if (IS_ENABLE_DIRECTX())
+	    DWriteContext_BeginDraw(s_dwc);
+#endif
+
+#ifdef FEAT_MBYTE
+	/* prevent multi-byte characters from misprinting on an invalid
+	 * rectangle */
+	if (has_mbyte)
+	{
+	    RECT rect;
+
+	    GetClientRect(hwnd, &rect);
+	    ps.rcPaint.left = rect.left;
+	    ps.rcPaint.right = rect.right;
+	}
+#endif
+
+	if (!IsRectEmpty(&ps.rcPaint))
+	{
+#if defined(FEAT_DIRECTX)
+	    if (IS_ENABLE_DIRECTX())
+		DWriteContext_BindDC(s_dwc, s_hdc, &ps.rcPaint);
+#endif
+	    gui_redraw(ps.rcPaint.left, ps.rcPaint.top,
+		    ps.rcPaint.right - ps.rcPaint.left + 1,
+		    ps.rcPaint.bottom - ps.rcPaint.top + 1);
+	}
+
+#if defined(FEAT_DIRECTX)
+	if (IS_ENABLE_DIRECTX())
+	    DWriteContext_EndDraw(s_dwc);
+#endif
+	EndPaint(hwnd, &ps);
+    }
+}
+
+/*ARGSUSED*/
+    static void
+_OnSize(
+    HWND hwnd,
+    UINT state,
+    int cx,
+    int cy)
+{
+    if (!IsMinimized(hwnd))
+    {
+	gui_resize_shell(cx, cy);
+
+#ifdef FEAT_MENU
+	/* Menu bar may wrap differently now */
+	gui_mswin_get_menu_height(TRUE);
+#endif
+    }
+}
+
+    static void
+_OnSetFocus(
+    HWND hwnd,
+    HWND hwndOldFocus)
+{
+    gui_focus_change(TRUE);
+    s_getting_focus = TRUE;
+    (void)MyWindowProc(hwnd, WM_SETFOCUS, (WPARAM)hwndOldFocus, 0);
+}
+
+    static void
+_OnKillFocus(
+    HWND hwnd,
+    HWND hwndNewFocus)
+{
+    gui_focus_change(FALSE);
+    s_getting_focus = FALSE;
+    (void)MyWindowProc(hwnd, WM_KILLFOCUS, (WPARAM)hwndNewFocus, 0);
+}
+
+/*
+ * Get a message when the user switches back to vim
+ */
+    static LRESULT
+_OnActivateApp(
+    HWND hwnd,
+    BOOL fActivate,
+    DWORD dwThreadId)
+{
+    /* we call gui_focus_change() in _OnSetFocus() */
+    /* gui_focus_change((int)fActivate); */
+    return MyWindowProc(hwnd, WM_ACTIVATEAPP, fActivate, (DWORD)dwThreadId);
+}
+
+#if defined(FEAT_WINDOWS) || defined(PROTO)
+    void
+gui_mch_destroy_scrollbar(scrollbar_T *sb)
+{
+    DestroyWindow(sb->id);
+}
+#endif
+
+/*
+ * Get current mouse coordinates in text window.
+ */
+    void
+gui_mch_getmouse(int *x, int *y)
+{
+    RECT rct;
+    POINT mp;
+
+    (void)GetWindowRect(s_textArea, &rct);
+    (void)GetCursorPos((LPPOINT)&mp);
+    *x = (int)(mp.x - rct.left);
+    *y = (int)(mp.y - rct.top);
+}
+
+/*
+ * Move mouse pointer to character at (x, y).
+ */
+    void
+gui_mch_setmouse(int x, int y)
+{
+    RECT rct;
+
+    (void)GetWindowRect(s_textArea, &rct);
+    (void)SetCursorPos(x + gui.border_offset + rct.left,
+		       y + gui.border_offset + rct.top);
+}
+
+    static void
+gui_mswin_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_CXFRAME) +
+	   GetSystemMetrics(SM_CXPADDEDBORDER)) * 2;
+    base_height = gui_get_base_height()
+	+ (GetSystemMetrics(SM_CYFRAME) +
+	   GetSystemMetrics(SM_CXPADDEDBORDER)) * 2
+	+ GetSystemMetrics(SM_CYCAPTION)
+#ifdef FEAT_MENU
+	+ gui_mswin_get_menu_height(FALSE)
+#endif
+	;
+    *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;
+}
+
+    void
+gui_mch_flash(int msec)
+{
+    RECT    rc;
+
+    /*
+     * Note: InvertRect() excludes right and bottom of rectangle.
+     */
+    rc.left = 0;
+    rc.top = 0;
+    rc.right = gui.num_cols * gui.char_width;
+    rc.bottom = gui.num_rows * gui.char_height;
+    InvertRect(s_hdc, &rc);
+    gui_mch_flush();			/* make sure it's displayed */
+
+    ui_delay((long)msec, TRUE);	/* wait for a few msec */
+
+    InvertRect(s_hdc, &rc);
+}
+
+/*
+ * Return flags used for scrolling.
+ * The SW_INVALIDATE is required when part of the window is covered or
+ * off-screen. Refer to MS KB Q75236.
+ */
+    static int
+get_scroll_flags(void)
+{
+    HWND	hwnd;
+    RECT	rcVim, rcOther, rcDest;
+
+    GetWindowRect(s_hwnd, &rcVim);
+
+    /* Check if the window is partly above or below the screen.  We don't care
+     * about partly left or right of the screen, it is not relevant when
+     * scrolling up or down. */
+    if (rcVim.top < 0 || rcVim.bottom > GetSystemMetrics(SM_CYFULLSCREEN))
+	return SW_INVALIDATE;
+
+    /* Check if there is an window (partly) on top of us. */
+    for (hwnd = s_hwnd; (hwnd = GetWindow(hwnd, GW_HWNDPREV)) != (HWND)0; )
+	if (IsWindowVisible(hwnd))
+	{
+	    GetWindowRect(hwnd, &rcOther);
+	    if (IntersectRect(&rcDest, &rcVim, &rcOther))
+		return SW_INVALIDATE;
+	}
+    return 0;
+}
+
+/*
+ * On some Intel GPUs, the regions drawn just prior to ScrollWindowEx()
+ * may not be scrolled out properly.
+ * For gVim, when _OnScroll() is repeated, the character at the
+ * previous cursor position may be left drawn after scroll.
+ * The problem can be avoided by calling GetPixel() to get a pixel in
+ * the region before ScrollWindowEx().
+ */
+    static void
+intel_gpu_workaround(void)
+{
+    GetPixel(s_hdc, FILL_X(gui.col), FILL_Y(gui.row));
+}
+
+/*
+ * Delete the given number of lines from the given row, scrolling up any
+ * text further down within the scroll region.
+ */
+    void
+gui_mch_delete_lines(
+    int	    row,
+    int	    num_lines)
+{
+    RECT	rc;
+
+    intel_gpu_workaround();
+
+    rc.left = FILL_X(gui.scroll_region_left);
+    rc.right = FILL_X(gui.scroll_region_right + 1);
+    rc.top = FILL_Y(row);
+    rc.bottom = FILL_Y(gui.scroll_region_bot + 1);
+
+    ScrollWindowEx(s_textArea, 0, -num_lines * gui.char_height,
+				    &rc, &rc, NULL, NULL, get_scroll_flags());
+
+    UpdateWindow(s_textArea);
+    /* This seems to be required to avoid the cursor disappearing when
+     * scrolling such that the cursor ends up in the top-left character on
+     * the screen...   But why?  (Webb) */
+    /* It's probably fixed by disabling drawing the cursor while scrolling. */
+    /* gui.cursor_is_valid = FALSE; */
+
+    gui_clear_block(gui.scroll_region_bot - num_lines + 1,
+						       gui.scroll_region_left,
+	gui.scroll_region_bot, gui.scroll_region_right);
+}
+
+/*
+ * Insert the given number of lines before the given row, scrolling down any
+ * following text within the scroll region.
+ */
+    void
+gui_mch_insert_lines(
+    int		row,
+    int		num_lines)
+{
+    RECT	rc;
+
+    intel_gpu_workaround();
+
+    rc.left = FILL_X(gui.scroll_region_left);
+    rc.right = FILL_X(gui.scroll_region_right + 1);
+    rc.top = FILL_Y(row);
+    rc.bottom = FILL_Y(gui.scroll_region_bot + 1);
+    /* The SW_INVALIDATE is required when part of the window is covered or
+     * off-screen.  How do we avoid it when it's not needed? */
+    ScrollWindowEx(s_textArea, 0, num_lines * gui.char_height,
+				    &rc, &rc, NULL, NULL, get_scroll_flags());
+
+    UpdateWindow(s_textArea);
+
+    gui_clear_block(row, gui.scroll_region_left,
+				row + num_lines - 1, gui.scroll_region_right);
+}
+
+
+/*ARGSUSED*/
+    void
+gui_mch_exit(int rc)
+{
+#if defined(FEAT_DIRECTX)
+    DWriteContext_Close(s_dwc);
+    DWrite_Final();
+    s_dwc = NULL;
+#endif
+
+    ReleaseDC(s_textArea, s_hdc);
+    DeleteObject(s_brush);
+
+#ifdef FEAT_TEAROFF
+    /* Unload the tearoff bitmap */
+    (void)DeleteObject((HGDIOBJ)s_htearbitmap);
+#endif
+
+    /* Destroy our window (if we have one). */
+    if (s_hwnd != NULL)
+    {
+	destroying = TRUE;	/* ignore WM_DESTROY message now */
+	DestroyWindow(s_hwnd);
+    }
+
+#ifdef GLOBAL_IME
+    global_ime_end();
+#endif
+}
+
+    static char_u *
+logfont2name(LOGFONT lf)
+{
+    char	*p;
+    char	*res;
+    char	*charset_name;
+    char	*font_name = lf.lfFaceName;
+
+    charset_name = charset_id2name((int)lf.lfCharSet);
+#ifdef FEAT_MBYTE
+    /* Convert a font name from the current codepage to 'encoding'.
+     * TODO: Use Wide APIs (including LOGFONTW) instead of ANSI APIs. */
+    if (enc_codepage >= 0 && (int)GetACP() != enc_codepage)
+    {
+	int	len;
+	acp_to_enc((char_u *)lf.lfFaceName, (int)strlen(lf.lfFaceName),
+						(char_u **)&font_name, &len);
+    }
+#endif
+    res = (char *)alloc((unsigned)(strlen(font_name) + 20
+		    + (charset_name == NULL ? 0 : strlen(charset_name) + 2)));
+    if (res != NULL)
+    {
+	p = res;
+	/* make a normal font string out of the lf thing:*/
+	sprintf((char *)p, "%s:h%d", font_name, pixels_to_points(
+			 lf.lfHeight < 0 ? -lf.lfHeight : lf.lfHeight, TRUE));
+	while (*p)
+	{
+	    if (*p == ' ')
+		*p = '_';
+	    ++p;
+	}
+	if (lf.lfItalic)
+	    STRCAT(p, ":i");
+	if (lf.lfWeight >= FW_BOLD)
+	    STRCAT(p, ":b");
+	if (lf.lfUnderline)
+	    STRCAT(p, ":u");
+	if (lf.lfStrikeOut)
+	    STRCAT(p, ":s");
+	if (charset_name != NULL)
+	{
+	    STRCAT(p, ":c");
+	    STRCAT(p, charset_name);
+	}
+    }
+
+#ifdef FEAT_MBYTE
+    if (font_name != lf.lfFaceName)
+	vim_free(font_name);
+#endif
+    return (char_u *)res;
+}
+
+
+#ifdef FEAT_MBYTE_IME
+/*
+ * Set correct LOGFONT to IME.  Use 'guifontwide' if available, otherwise use
+ * 'guifont'
+ */
+    static void
+update_im_font(void)
+{
+    LOGFONT	lf_wide;
+
+    if (p_guifontwide != NULL && *p_guifontwide != NUL
+	    && gui.wide_font != NOFONT
+	    && GetObject((HFONT)gui.wide_font, sizeof(lf_wide), &lf_wide))
+	norm_logfont = lf_wide;
+    else
+	norm_logfont = sub_logfont;
+    im_set_font(&norm_logfont);
+}
+#endif
+
+#ifdef FEAT_MBYTE
+/*
+ * Handler of gui.wide_font (p_guifontwide) changed notification.
+ */
+    void
+gui_mch_wide_font_changed(void)
+{
+    LOGFONT lf;
+
+# ifdef FEAT_MBYTE_IME
+    update_im_font();
+# endif
+
+    gui_mch_free_font(gui.wide_ital_font);
+    gui.wide_ital_font = NOFONT;
+    gui_mch_free_font(gui.wide_bold_font);
+    gui.wide_bold_font = NOFONT;
+    gui_mch_free_font(gui.wide_boldital_font);
+    gui.wide_boldital_font = NOFONT;
+
+    if (gui.wide_font
+	&& GetObject((HFONT)gui.wide_font, sizeof(lf), &lf))
+    {
+	if (!lf.lfItalic)
+	{
+	    lf.lfItalic = TRUE;
+	    gui.wide_ital_font = get_font_handle(&lf);
+	    lf.lfItalic = FALSE;
+	}
+	if (lf.lfWeight < FW_BOLD)
+	{
+	    lf.lfWeight = FW_BOLD;
+	    gui.wide_bold_font = get_font_handle(&lf);
+	    if (!lf.lfItalic)
+	    {
+		lf.lfItalic = TRUE;
+		gui.wide_boldital_font = get_font_handle(&lf);
+	    }
+	}
+    }
+}
+#endif
+
+/*
+ * Initialise vim to use the font with the given name.
+ * Return FAIL if the font could not be loaded, OK otherwise.
+ */
+/*ARGSUSED*/
+    int
+gui_mch_init_font(char_u *font_name, int fontset)
+{
+    LOGFONT	lf;
+    GuiFont	font = NOFONT;
+    char_u	*p;
+
+    /* Load the font */
+    if (get_logfont(&lf, font_name, NULL, TRUE) == OK)
+	font = get_font_handle(&lf);
+    if (font == NOFONT)
+	return FAIL;
+
+    if (font_name == NULL)
+	font_name = (char_u *)lf.lfFaceName;
+#if defined(FEAT_MBYTE_IME) || defined(GLOBAL_IME)
+    norm_logfont = lf;
+    sub_logfont = lf;
+#endif
+#ifdef FEAT_MBYTE_IME
+    update_im_font();
+#endif
+    gui_mch_free_font(gui.norm_font);
+    gui.norm_font = font;
+    current_font_height = lf.lfHeight;
+    GetFontSize(font);
+
+    p = logfont2name(lf);
+    if (p != NULL)
+    {
+	hl_set_font_name(p);
+
+	/* When setting 'guifont' to "*" replace it with the actual font name.
+	 * */
+	if (STRCMP(font_name, "*") == 0 && STRCMP(p_guifont, "*") == 0)
+	{
+	    vim_free(p_guifont);
+	    p_guifont = p;
+	}
+	else
+	    vim_free(p);
+    }
+
+    gui_mch_free_font(gui.ital_font);
+    gui.ital_font = NOFONT;
+    gui_mch_free_font(gui.bold_font);
+    gui.bold_font = NOFONT;
+    gui_mch_free_font(gui.boldital_font);
+    gui.boldital_font = NOFONT;
+
+    if (!lf.lfItalic)
+    {
+	lf.lfItalic = TRUE;
+	gui.ital_font = get_font_handle(&lf);
+	lf.lfItalic = FALSE;
+    }
+    if (lf.lfWeight < FW_BOLD)
+    {
+	lf.lfWeight = FW_BOLD;
+	gui.bold_font = get_font_handle(&lf);
+	if (!lf.lfItalic)
+	{
+	    lf.lfItalic = TRUE;
+	    gui.boldital_font = get_font_handle(&lf);
+	}
+    }
+
+    return OK;
+}
+
+#ifndef WPF_RESTORETOMAXIMIZED
+# define WPF_RESTORETOMAXIMIZED 2   /* just in case someone doesn't have it */
+#endif
+
+/*
+ * Return TRUE if the GUI window is maximized, filling the whole screen.
+ */
+    int
+gui_mch_maximized(void)
+{
+    WINDOWPLACEMENT wp;
+
+    wp.length = sizeof(WINDOWPLACEMENT);
+    if (GetWindowPlacement(s_hwnd, &wp))
+	return wp.showCmd == SW_SHOWMAXIMIZED
+	    || (wp.showCmd == SW_SHOWMINIMIZED
+		    && wp.flags == WPF_RESTORETOMAXIMIZED);
+
+    return 0;
+}
+
+/*
+ * Called when the font changed while the window is maximized.  Compute the
+ * new Rows and Columns.  This is like resizing the window.
+ */
+    void
+gui_mch_newfont(void)
+{
+    RECT	rect;
+
+    GetWindowRect(s_hwnd, &rect);
+    if (win_socket_id == 0)
+    {
+	gui_resize_shell(rect.right - rect.left
+	    - (GetSystemMetrics(SM_CXFRAME) +
+	       GetSystemMetrics(SM_CXPADDEDBORDER)) * 2,
+	    rect.bottom - rect.top
+	    - (GetSystemMetrics(SM_CYFRAME) +
+	       GetSystemMetrics(SM_CXPADDEDBORDER)) * 2
+	    - GetSystemMetrics(SM_CYCAPTION)
+#ifdef FEAT_MENU
+	    - gui_mswin_get_menu_height(FALSE)
+#endif
+	);
+    }
+    else
+    {
+	/* Inside another window, don't use the frame and border. */
+	gui_resize_shell(rect.right - rect.left,
+	    rect.bottom - rect.top
+#ifdef FEAT_MENU
+			- gui_mswin_get_menu_height(FALSE)
+#endif
+	);
+    }
+}
+
+/*
+ * Set the window title
+ */
+/*ARGSUSED*/
+    void
+gui_mch_settitle(
+    char_u  *title,
+    char_u  *icon)
+{
+    set_window_title(s_hwnd, (title == NULL ? "VIM" : (char *)title));
+}
+
+#ifdef FEAT_MOUSESHAPE
+/* Table for shape IDCs.  Keep in sync with the mshape_names[] table in
+ * misc2.c! */
+static LPCSTR mshape_idcs[] =
+{
+    IDC_ARROW,			/* arrow */
+    MAKEINTRESOURCE(0),		/* blank */
+    IDC_IBEAM,			/* beam */
+    IDC_SIZENS,			/* updown */
+    IDC_SIZENS,			/* udsizing */
+    IDC_SIZEWE,			/* leftright */
+    IDC_SIZEWE,			/* lrsizing */
+    IDC_WAIT,			/* busy */
+#ifdef WIN3264
+    IDC_NO,			/* no */
+#else
+    IDC_ICON,			/* no */
+#endif
+    IDC_ARROW,			/* crosshair */
+    IDC_ARROW,			/* hand1 */
+    IDC_ARROW,			/* hand2 */
+    IDC_ARROW,			/* pencil */
+    IDC_ARROW,			/* question */
+    IDC_ARROW,			/* right-arrow */
+    IDC_UPARROW,		/* up-arrow */
+    IDC_ARROW			/* last one */
+};
+
+    void
+mch_set_mouse_shape(int shape)
+{
+    LPCSTR idc;
+
+    if (shape == MSHAPE_HIDE)
+	ShowCursor(FALSE);
+    else
+    {
+	if (shape >= MSHAPE_NUMBERED)
+	    idc = IDC_ARROW;
+	else
+	    idc = mshape_idcs[shape];
+#ifdef SetClassLongPtr
+	SetClassLongPtr(s_textArea, GCLP_HCURSOR, (__int3264)(LONG_PTR)LoadCursor(NULL, idc));
+#else
+# ifdef WIN32
+	SetClassLong(s_textArea, GCL_HCURSOR, (long_u)LoadCursor(NULL, idc));
+# else /* Win16 */
+	SetClassWord(s_textArea, GCW_HCURSOR, (WORD)LoadCursor(NULL, idc));
+# endif
+#endif
+	if (!p_mh)
+	{
+	    POINT mp;
+
+	    /* Set the position to make it redrawn with the new shape. */
+	    (void)GetCursorPos((LPPOINT)&mp);
+	    (void)SetCursorPos(mp.x, mp.y);
+	    ShowCursor(TRUE);
+	}
+    }
+}
+#endif
+
+#ifdef FEAT_BROWSE
+/*
+ * The file browser exists in two versions: with "W" uses wide characters,
+ * without "W" the current codepage.  When FEAT_MBYTE is defined and on
+ * Windows NT/2000/XP the "W" functions are used.
+ */
+
+# if defined(FEAT_MBYTE) && defined(WIN3264)
+/*
+ * Wide version of convert_filter().
+ */
+    static WCHAR *
+convert_filterW(char_u *s)
+{
+    char_u *tmp;
+    int len;
+    WCHAR *res;
+
+    tmp = convert_filter(s);
+    if (tmp == NULL)
+	return NULL;
+    len = (int)STRLEN(s) + 3;
+    res = enc_to_utf16(tmp, &len);
+    vim_free(tmp);
+    return res;
+}
+
+/*
+ * Wide version of gui_mch_browse().  Keep in sync!
+ */
+    static char_u *
+gui_mch_browseW(
+	int saving,
+	char_u *title,
+	char_u *dflt,
+	char_u *ext,
+	char_u *initdir,
+	char_u *filter)
+{
+    /* We always use the wide function.  This means enc_to_utf16() must work,
+     * otherwise it fails miserably! */
+    OPENFILENAMEW	fileStruct;
+    WCHAR		fileBuf[MAXPATHL];
+    WCHAR		*wp;
+    int			i;
+    WCHAR		*titlep = NULL;
+    WCHAR		*extp = NULL;
+    WCHAR		*initdirp = NULL;
+    WCHAR		*filterp;
+    char_u		*p;
+
+    if (dflt == NULL)
+	fileBuf[0] = NUL;
+    else
+    {
+	wp = enc_to_utf16(dflt, NULL);
+	if (wp == NULL)
+	    fileBuf[0] = NUL;
+	else
+	{
+	    for (i = 0; wp[i] != NUL && i < MAXPATHL - 1; ++i)
+		fileBuf[i] = wp[i];
+	    fileBuf[i] = NUL;
+	    vim_free(wp);
+	}
+    }
+
+    /* Convert the filter to Windows format. */
+    filterp = convert_filterW(filter);
+
+    vim_memset(&fileStruct, 0, sizeof(OPENFILENAMEW));
+#ifdef OPENFILENAME_SIZE_VERSION_400
+    /* be compatible with Windows NT 4.0 */
+    /* TODO: what to use for OPENFILENAMEW??? */
+    fileStruct.lStructSize = OPENFILENAME_SIZE_VERSION_400;
+#else
+    fileStruct.lStructSize = sizeof(fileStruct);
+#endif
+
+    if (title != NULL)
+	titlep = enc_to_utf16(title, NULL);
+    fileStruct.lpstrTitle = titlep;
+
+    if (ext != NULL)
+	extp = enc_to_utf16(ext, NULL);
+    fileStruct.lpstrDefExt = extp;
+
+    fileStruct.lpstrFile = fileBuf;
+    fileStruct.nMaxFile = MAXPATHL;
+    fileStruct.lpstrFilter = filterp;
+    fileStruct.hwndOwner = s_hwnd;		/* main Vim window is owner*/
+    /* has an initial dir been specified? */
+    if (initdir != NULL && *initdir != NUL)
+    {
+	/* Must have backslashes here, no matter what 'shellslash' says */
+	initdirp = enc_to_utf16(initdir, NULL);
+	if (initdirp != NULL)
+	{
+	    for (wp = initdirp; *wp != NUL; ++wp)
+		if (*wp == '/')
+		    *wp = '\\';
+	}
+	fileStruct.lpstrInitialDir = initdirp;
+    }
+
+    /*
+     * TODO: Allow selection of multiple files.  Needs another arg to this
+     * function to ask for it, and need to use OFN_ALLOWMULTISELECT below.
+     * Also, should we use OFN_FILEMUSTEXIST when opening?  Vim can edit on
+     * files that don't exist yet, so I haven't put it in.  What about
+     * OFN_PATHMUSTEXIST?
+     * Don't use OFN_OVERWRITEPROMPT, Vim has its own ":confirm" dialog.
+     */
+    fileStruct.Flags = (OFN_NOCHANGEDIR | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY);
+#ifdef FEAT_SHORTCUT
+    if (curbuf->b_p_bin)
+	fileStruct.Flags |= OFN_NODEREFERENCELINKS;
+#endif
+    if (saving)
+    {
+	if (!GetSaveFileNameW(&fileStruct))
+	    return NULL;
+    }
+    else
+    {
+	if (!GetOpenFileNameW(&fileStruct))
+	    return NULL;
+    }
+
+    vim_free(filterp);
+    vim_free(initdirp);
+    vim_free(titlep);
+    vim_free(extp);
+
+    /* Convert from UCS2 to 'encoding'. */
+    p = utf16_to_enc(fileBuf, NULL);
+    if (p != NULL)
+	/* when out of memory we get garbage for non-ASCII chars */
+	STRCPY(fileBuf, p);
+    vim_free(p);
+
+    /* Give focus back to main window (when using MDI). */
+    SetFocus(s_hwnd);
+
+    /* Shorten the file name if possible */
+    return vim_strsave(shorten_fname1((char_u *)fileBuf));
+}
+# endif /* FEAT_MBYTE */
+
+
+/*
+ * Convert the string s to the proper format for a filter string by replacing
+ * the \t and \n delimiters with \0.
+ * Returns the converted string in allocated memory.
+ *
+ * Keep in sync with convert_filterW() above!
+ */
+    static char_u *
+convert_filter(char_u *s)
+{
+    char_u	*res;
+    unsigned	s_len = (unsigned)STRLEN(s);
+    unsigned	i;
+
+    res = alloc(s_len + 3);
+    if (res != NULL)
+    {
+	for (i = 0; i < s_len; ++i)
+	    if (s[i] == '\t' || s[i] == '\n')
+		res[i] = '\0';
+	    else
+		res[i] = s[i];
+	res[s_len] = NUL;
+	/* Add two extra NULs to make sure it's properly terminated. */
+	res[s_len + 1] = NUL;
+	res[s_len + 2] = NUL;
+    }
+    return res;
+}
+
+/*
+ * Select a directory.
+ */
+    char_u *
+gui_mch_browsedir(char_u *title, char_u *initdir)
+{
+    /* We fake this: Use a filter that doesn't select anything and a default
+     * file name that won't be used. */
+    return gui_mch_browse(0, title, (char_u *)_("Not Used"), NULL,
+			      initdir, (char_u *)_("Directory\t*.nothing\n"));
+}
+
+/*
+ * Pop open a file browser and return the file selected, in allocated memory,
+ * or NULL if Cancel is hit.
+ *  saving  - TRUE if the file will be saved to, FALSE if it will be opened.
+ *  title   - Title message for the file browser dialog.
+ *  dflt    - Default name of file.
+ *  ext     - Default extension to be added to files without extensions.
+ *  initdir - directory in which to open the browser (NULL = current dir)
+ *  filter  - Filter for matched files to choose from.
+ *
+ * Keep in sync with gui_mch_browseW() above!
+ */
+    char_u *
+gui_mch_browse(
+	int saving,
+	char_u *title,
+	char_u *dflt,
+	char_u *ext,
+	char_u *initdir,
+	char_u *filter)
+{
+    OPENFILENAME	fileStruct;
+    char_u		fileBuf[MAXPATHL];
+    char_u		*initdirp = NULL;
+    char_u		*filterp;
+    char_u		*p;
+
+# if defined(FEAT_MBYTE) && defined(WIN3264)
+    if (os_version.dwPlatformId == VER_PLATFORM_WIN32_NT)
+	return gui_mch_browseW(saving, title, dflt, ext, initdir, filter);
+# endif
+
+    if (dflt == NULL)
+	fileBuf[0] = NUL;
+    else
+	vim_strncpy(fileBuf, dflt, MAXPATHL - 1);
+
+    /* Convert the filter to Windows format. */
+    filterp = convert_filter(filter);
+
+    vim_memset(&fileStruct, 0, sizeof(OPENFILENAME));
+#ifdef OPENFILENAME_SIZE_VERSION_400
+    /* be compatible with Windows NT 4.0 */
+    fileStruct.lStructSize = OPENFILENAME_SIZE_VERSION_400;
+#else
+    fileStruct.lStructSize = sizeof(fileStruct);
+#endif
+
+    fileStruct.lpstrTitle = (LPSTR)title;
+    fileStruct.lpstrDefExt = (LPSTR)ext;
+
+    fileStruct.lpstrFile = (LPSTR)fileBuf;
+    fileStruct.nMaxFile = MAXPATHL;
+    fileStruct.lpstrFilter = (LPSTR)filterp;
+    fileStruct.hwndOwner = s_hwnd;		/* main Vim window is owner*/
+    /* has an initial dir been specified? */
+    if (initdir != NULL && *initdir != NUL)
+    {
+	/* Must have backslashes here, no matter what 'shellslash' says */
+	initdirp = vim_strsave(initdir);
+	if (initdirp != NULL)
+	    for (p = initdirp; *p != NUL; ++p)
+		if (*p == '/')
+		    *p = '\\';
+	fileStruct.lpstrInitialDir = (LPSTR)initdirp;
+    }
+
+    /*
+     * TODO: Allow selection of multiple files.  Needs another arg to this
+     * function to ask for it, and need to use OFN_ALLOWMULTISELECT below.
+     * Also, should we use OFN_FILEMUSTEXIST when opening?  Vim can edit on
+     * files that don't exist yet, so I haven't put it in.  What about
+     * OFN_PATHMUSTEXIST?
+     * Don't use OFN_OVERWRITEPROMPT, Vim has its own ":confirm" dialog.
+     */
+    fileStruct.Flags = (OFN_NOCHANGEDIR | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY);
+#ifdef FEAT_SHORTCUT
+    if (curbuf->b_p_bin)
+	fileStruct.Flags |= OFN_NODEREFERENCELINKS;
+#endif
+    if (saving)
+    {
+	if (!GetSaveFileName(&fileStruct))
+	    return NULL;
+    }
+    else
+    {
+	if (!GetOpenFileName(&fileStruct))
+	    return NULL;
+    }
+
+    vim_free(filterp);
+    vim_free(initdirp);
+
+    /* Give focus back to main window (when using MDI). */
+    SetFocus(s_hwnd);
+
+    /* Shorten the file name if possible */
+    return vim_strsave(shorten_fname1((char_u *)fileBuf));
+}
+#endif /* FEAT_BROWSE */
+
+/*ARGSUSED*/
+    static void
+_OnDropFiles(
+    HWND hwnd,
+    HDROP hDrop)
+{
+#ifdef FEAT_WINDOWS
+#ifdef WIN3264
+# define BUFPATHLEN _MAX_PATH
+# define DRAGQVAL 0xFFFFFFFF
+#else
+# define BUFPATHLEN MAXPATHL
+# define DRAGQVAL 0xFFFF
+#endif
+#ifdef FEAT_MBYTE
+    WCHAR   wszFile[BUFPATHLEN];
+#endif
+    char    szFile[BUFPATHLEN];
+    UINT    cFiles = DragQueryFile(hDrop, DRAGQVAL, NULL, 0);
+    UINT    i;
+    char_u  **fnames;
+    POINT   pt;
+    int_u   modifiers = 0;
+
+    /* TRACE("_OnDropFiles: %d files dropped\n", cFiles); */
+
+    /* Obtain dropped position */
+    DragQueryPoint(hDrop, &pt);
+    MapWindowPoints(s_hwnd, s_textArea, &pt, 1);
+
+    reset_VIsual();
+
+    fnames = (char_u **)alloc(cFiles * sizeof(char_u *));
+
+    if (fnames != NULL)
+	for (i = 0; i < cFiles; ++i)
+	{
+#ifdef FEAT_MBYTE
+	    if (DragQueryFileW(hDrop, i, wszFile, BUFPATHLEN) > 0)
+		fnames[i] = utf16_to_enc(wszFile, NULL);
+	    else
+#endif
+	    {
+		DragQueryFile(hDrop, i, szFile, BUFPATHLEN);
+		fnames[i] = vim_strsave((char_u *)szFile);
+	    }
+	}
+
+    DragFinish(hDrop);
+
+    if (fnames != NULL)
+    {
+	if ((GetKeyState(VK_SHIFT) & 0x8000) != 0)
+	    modifiers |= MOUSE_SHIFT;
+	if ((GetKeyState(VK_CONTROL) & 0x8000) != 0)
+	    modifiers |= MOUSE_CTRL;
+	if ((GetKeyState(VK_MENU) & 0x8000) != 0)
+	    modifiers |= MOUSE_ALT;
+
+	gui_handle_drop(pt.x, pt.y, modifiers, fnames, cFiles);
+
+	s_need_activate = TRUE;
+    }
+#endif
+}
+
+/*ARGSUSED*/
+    static int
+_OnScroll(
+    HWND hwnd,
+    HWND hwndCtl,
+    UINT code,
+    int pos)
+{
+    static UINT	prev_code = 0;   /* code of previous call */
+    scrollbar_T *sb, *sb_info;
+    long	val;
+    int		dragging = FALSE;
+    int		dont_scroll_save = dont_scroll;
+#ifndef WIN3264
+    int		nPos;
+#else
+    SCROLLINFO	si;
+
+    si.cbSize = sizeof(si);
+    si.fMask = SIF_POS;
+#endif
+
+    sb = gui_mswin_find_scrollbar(hwndCtl);
+    if (sb == NULL)
+	return 0;
+
+    if (sb->wp != NULL)		/* Left or right scrollbar */
+    {
+	/*
+	 * Careful: need to get scrollbar info out of first (left) scrollbar
+	 * for window, but keep real scrollbar too because we must pass it to
+	 * gui_drag_scrollbar().
+	 */
+	sb_info = &sb->wp->w_scrollbars[0];
+    }
+    else	    /* Bottom scrollbar */
+	sb_info = sb;
+    val = sb_info->value;
+
+    switch (code)
+    {
+	case SB_THUMBTRACK:
+	    val = pos;
+	    dragging = TRUE;
+	    if (sb->scroll_shift > 0)
+		val <<= sb->scroll_shift;
+	    break;
+	case SB_LINEDOWN:
+	    val++;
+	    break;
+	case SB_LINEUP:
+	    val--;
+	    break;
+	case SB_PAGEDOWN:
+	    val += (sb_info->size > 2 ? sb_info->size - 2 : 1);
+	    break;
+	case SB_PAGEUP:
+	    val -= (sb_info->size > 2 ? sb_info->size - 2 : 1);
+	    break;
+	case SB_TOP:
+	    val = 0;
+	    break;
+	case SB_BOTTOM:
+	    val = sb_info->max;
+	    break;
+	case SB_ENDSCROLL:
+	    if (prev_code == SB_THUMBTRACK)
+	    {
+		/*
+		 * "pos" only gives us 16-bit data.  In case of large file,
+		 * use GetScrollPos() which returns 32-bit.  Unfortunately it
+		 * is not valid while the scrollbar is being dragged.
+		 */
+		val = GetScrollPos(hwndCtl, SB_CTL);
+		if (sb->scroll_shift > 0)
+		    val <<= sb->scroll_shift;
+	    }
+	    break;
+
+	default:
+	    /* TRACE("Unknown scrollbar event %d\n", code); */
+	    return 0;
+    }
+    prev_code = code;
+
+#ifdef WIN3264
+    si.nPos = (sb->scroll_shift > 0) ? val >> sb->scroll_shift : val;
+    SetScrollInfo(hwndCtl, SB_CTL, &si, TRUE);
+#else
+    nPos = (sb->scroll_shift > 0) ? val >> sb->scroll_shift : val;
+    SetScrollPos(hwndCtl, SB_CTL, nPos, TRUE);
+#endif
+
+    /*
+     * When moving a vertical scrollbar, move the other vertical scrollbar too.
+     */
+    if (sb->wp != NULL)
+    {
+	scrollbar_T *sba = sb->wp->w_scrollbars;
+	HWND    id = sba[ (sb == sba + SBAR_LEFT) ? SBAR_RIGHT : SBAR_LEFT].id;
+
+#ifdef WIN3264
+	SetScrollInfo(id, SB_CTL, &si, TRUE);
+#else
+	SetScrollPos(id, SB_CTL, nPos, TRUE);
+#endif
+    }
+
+    /* Don't let us be interrupted here by another message. */
+    s_busy_processing = TRUE;
+
+    /* When "allow_scrollbar" is FALSE still need to remember the new
+     * position, but don't actually scroll by setting "dont_scroll". */
+    dont_scroll = !allow_scrollbar;
+
+    gui_drag_scrollbar(sb, val, dragging);
+
+    s_busy_processing = FALSE;
+    dont_scroll = dont_scroll_save;
+
+    return 0;
+}
+
+
+/*
+ * Get command line arguments.
+ * Use "prog" as the name of the program and "cmdline" as the arguments.
+ * Copy the arguments to allocated memory.
+ * Return the number of arguments (including program name).
+ * Return pointers to the arguments in "argvp".  Memory is allocated with
+ * malloc(), use free() instead of vim_free().
+ * Return pointer to buffer in "tofree".
+ * Returns zero when out of memory.
+ */
+/*ARGSUSED*/
+    int
+get_cmd_args(char *prog, char *cmdline, char ***argvp, char **tofree)
+{
+    int		i;
+    char	*p;
+    char	*progp;
+    char	*pnew = NULL;
+    char	*newcmdline;
+    int		inquote;
+    int		argc;
+    char	**argv = NULL;
+    int		round;
+
+    *tofree = NULL;
+
+#ifdef FEAT_MBYTE
+    /* Try using the Unicode version first, it takes care of conversion when
+     * 'encoding' is changed. */
+    argc = get_cmd_argsW(&argv);
+    if (argc != 0)
+	goto done;
+#endif
+
+    /* Handle the program name.  Remove the ".exe" extension, and find the 1st
+     * non-space. */
+    p = strrchr(prog, '.');
+    if (p != NULL)
+	*p = NUL;
+    for (progp = prog; *progp == ' '; ++progp)
+	;
+
+    /* The command line is copied to allocated memory, so that we can change
+     * it.  Add the size of the string, the separating NUL and a terminating
+     * NUL. */
+    newcmdline = malloc(STRLEN(cmdline) + STRLEN(progp) + 2);
+    if (newcmdline == NULL)
+	return 0;
+
+    /*
+     * First round: count the number of arguments ("pnew" == NULL).
+     * Second round: produce the arguments.
+     */
+    for (round = 1; round <= 2; ++round)
+    {
+	/* First argument is the program name. */
+	if (pnew != NULL)
+	{
+	    argv[0] = pnew;
+	    strcpy(pnew, progp);
+	    pnew += strlen(pnew);
+	    *pnew++ = NUL;
+	}
+
+	/*
+	 * Isolate each argument and put it in argv[].
+	 */
+	p = cmdline;
+	argc = 1;
+	while (*p != NUL)
+	{
+	    inquote = FALSE;
+	    if (pnew != NULL)
+		argv[argc] = pnew;
+	    ++argc;
+	    while (*p != NUL && (inquote || (*p != ' ' && *p != '\t')))
+	    {
+		/* Backslashes are only special when followed by a double
+		 * quote. */
+		i = (int)strspn(p, "\\");
+		if (p[i] == '"')
+		{
+		    /* Halve the number of backslashes. */
+		    if (i > 1 && pnew != NULL)
+		    {
+			vim_memset(pnew, '\\', i / 2);
+			pnew += i / 2;
+		    }
+
+		    /* Even nr of backslashes toggles quoting, uneven copies
+		     * the double quote. */
+		    if ((i & 1) == 0)
+			inquote = !inquote;
+		    else if (pnew != NULL)
+			*pnew++ = '"';
+		    p += i + 1;
+		}
+		else if (i > 0)
+		{
+		    /* Copy span of backslashes unmodified. */
+		    if (pnew != NULL)
+		    {
+			vim_memset(pnew, '\\', i);
+			pnew += i;
+		    }
+		    p += i;
+		}
+		else
+		{
+		    if (pnew != NULL)
+			*pnew++ = *p;
+#ifdef FEAT_MBYTE
+		    /* Can't use mb_* functions, because 'encoding' is not
+		     * initialized yet here. */
+		    if (IsDBCSLeadByte(*p))
+		    {
+			++p;
+			if (pnew != NULL)
+			    *pnew++ = *p;
+		    }
+#endif
+		    ++p;
+		}
+	    }
+
+	    if (pnew != NULL)
+		*pnew++ = NUL;
+	    while (*p == ' ' || *p == '\t')
+		++p;		    /* advance until a non-space */
+	}
+
+	if (round == 1)
+	{
+	    argv = (char **)malloc((argc + 1) * sizeof(char *));
+	    if (argv == NULL )
+	    {
+		free(newcmdline);
+		return 0;		   /* malloc error */
+	    }
+	    pnew = newcmdline;
+	    *tofree = newcmdline;
+	}
+    }
+
+#ifdef FEAT_MBYTE
+done:
+#endif
+    argv[argc] = NULL;		/* NULL-terminated list */
+    *argvp = argv;
+    return argc;
+}
 
 #ifdef FEAT_XPM_W32
 # include "xpm_w32.h"
@@ -1692,10 +5777,6 @@
 #endif
     s_hdc = GetDC(s_textArea);
 
-#ifdef MSWIN16_FASTTEXT
-    SetBkMode(s_hdc, OPAQUE);
-#endif
-
 #ifdef FEAT_WINDOWS
     DragAcceptFiles(s_hwnd, TRUE);
 #endif
@@ -2410,7 +6491,6 @@
     int		font_is_ttf_or_vector = 0;
 #endif
 
-#ifndef MSWIN16_FASTTEXT
     /*
      * Italic and bold text seems to have an extra row of pixels at the bottom
      * (below where the bottom of the character should be).  If we draw the
@@ -2484,15 +6564,6 @@
 	    foptions = ETO_CLIPPED;
 	}
     }
-#else
-    /*
-     * The alternative would be to write the characters in opaque mode, but
-     * when the text is not exactly the same proportions as normal text, too
-     * big or too little a rectangle gets drawn for the background.
-     */
-    SetBkMode(s_hdc, OPAQUE);
-    SetBkColor(s_hdc, gui.currBgColor);
-#endif
     SetTextColor(s_hdc, gui.currFgColor);
     SelectFont(s_hdc, gui.currFont);
 
@@ -2677,10 +6748,8 @@
 	/* When p_linespace is 0, overwrite the bottom row of pixels.
 	 * Otherwise put the line just below the character. */
 	y = FILL_Y(row + 1) - 1;
-#ifndef MSWIN16_FASTTEXT
 	if (p_linespace > 1)
 	    y -= p_linespace - 1;
-#endif
 	MoveToEx(s_hdc, FILL_X(col), y, NULL);
 	/* Note: LineTo() excludes the last pixel in the line. */
 	LineTo(s_hdc, FILL_X(col + len), y);
