diff --git a/src/Make_cyg_ming.mak b/src/Make_cyg_ming.mak
index 8dc7d00..f6ab0db 100644
--- a/src/Make_cyg_ming.mak
+++ b/src/Make_cyg_ming.mak
@@ -860,7 +860,7 @@
 $(OUTDIR)/ex_eval.o:	ex_eval.c $(INCL) ex_cmds.h
 	$(CC) -c $(CFLAGS) ex_eval.c -o $(OUTDIR)/ex_eval.o
 
-$(OUTDIR)/gui_w32.o:	gui_w32.c gui_w48.c $(INCL)
+$(OUTDIR)/gui_w32.o:	gui_w32.c $(INCL)
 	$(CC) -c $(CFLAGS) gui_w32.c -o $(OUTDIR)/gui_w32.o
 
 $(OUTDIR)/gui_dwrite.o:	gui_dwrite.cpp $(INCL) gui_dwrite.h
diff --git a/src/Make_mvc.mak b/src/Make_mvc.mak
index f1b1714..0843d25 100644
--- a/src/Make_mvc.mak
+++ b/src/Make_mvc.mak
@@ -1175,7 +1175,7 @@
 
 $(OUTDIR)/gui_beval.obj:	$(OUTDIR) gui_beval.c $(INCL) $(GUI_INCL)
 
-$(OUTDIR)/gui_w32.obj:	$(OUTDIR) gui_w32.c gui_w48.c $(INCL) $(GUI_INCL)
+$(OUTDIR)/gui_w32.obj:	$(OUTDIR) gui_w32.c $(INCL) $(GUI_INCL)
 
 $(OUTDIR)/gui_dwrite.obj:	$(OUTDIR) gui_dwrite.cpp $(INCL) $(GUI_INCL)
 
diff --git a/src/Make_w16.mak b/src/Make_w16.mak
deleted file mode 100644
index 04ec663..0000000
--- a/src/Make_w16.mak
+++ /dev/null
@@ -1,204 +0,0 @@
-#
-# Borland C++ 5.0[12] makefile for vim, 16-bit windows gui version
-# By Vince Negri
-#
-# NOTE: THIS IS OLD AND PROBABLY NO LONGER WORKS.
-#
-# *************************************************************
-# * WARNING!
-# * This was originally produced by the IDE, but has since been
-# * modified to make it work properly. Adjust with care!
-# * In particular, leave LinkerLocalOptsAtW16_gvim16dexe alone
-# * unless you are a guru.
-# *************************************************************
-#
-# Look for BOR below and either pass a different value or
-# adjust the path as required. For example
-#   make -fMake_w16.mak -DBOR=C:\PF\Borland\BC5.01 -B BccW16.cfg
-#   make -fMake_w16.mak
-# Note: $(BOR) is effectively ignored unless BccW16.cfg is rebuilt.
-#
-# Does not compile with Borland C++ 4.51 Walter Briscoe 2003-02-24
-# "out of memory" from compiler if gvim16 wildly wrong. WFB 2003-03-04
-#
-# vim16.def must be a DOS-formatted file. (\r\n line endings.)
-# It is a UNIX-formatted file (\n line endings) in vim-*-extra.tar.gz
-
-.AUTODEPEND
-
-#
-# Borland C++ tools
-#
-IMPLIB  = Implib
-BCC     = Bcc +BccW16.cfg
-TLINK   = TLink
-TLIB    = TLib
-BRC     = Brc
-TASM    = Tasm
-#
-# IDE macros
-#
-
-#
-# Options
-#
-!ifndef BOR
-BOR = D:\BC5
-!endif
-
-# !ifndef INTDIR is lethal considering CLEAN below. WFB 2003-03-13
-INTDIR=w16
-
-#  /Twe Make the target a Windows .EXE with explicit functions exportable +
-#  /x   Map file off
-#  /l   Include source line numbers in object map files`
-#  /c   case sensitive link
-#  /C   Case-sensitive exports and imports (16-bit only)
-#  /k   Produce "No Stack" warning.
-#  /Oa  Minimise segment alignment
-#  /Oc  Minimise Chain fixes
-#  /Oi  Minimise Iterated data
-#  /Or  Minimise resource alignment
-#  /P   -P=x  Code pack size
-#  /V   Windows version for application
-#  /L   Folder to search for library files
-LinkerLocalOptsAtW16_gvim16dexe =/Twe/x/l/c/C/k/Or/Oc/Oa/Oi/P=65535/V3.10
-
-CompInheritOptsAt_gvim16dexe = \
-   -I$(BOR)\INCLUDE;PROTO;. \
-   -DFEAT_GUI;FEAT_GUI_MSWIN;FEAT_GUI_W16;MSWIN;WIN16;MSWIN16_FASTTEXT \
-   -DFEAT_TOOLBAR;WIN16_3DLOOK
-
-#
-# Dependency List
-#
-Dep_Gvim16 = \
-   gvim16.exe
-
-ObjFiles = \
-   $(INTDIR)\buffer.obj\
-   $(INTDIR)\charset.obj\
-   $(INTDIR)\diff.obj\
-   $(INTDIR)\digraph.obj\
-   $(INTDIR)\edit.obj\
-   $(INTDIR)\eval.obj\
-   $(INTDIR)\ex_cmds.obj\
-   $(INTDIR)\ex_cmds2.obj\
-   $(INTDIR)\ex_docmd.obj\
-   $(INTDIR)\ex_eval.obj\
-   $(INTDIR)\ex_getln.obj\
-   $(INTDIR)\fileio.obj\
-   $(INTDIR)\fold.obj\
-   $(INTDIR)\getchar.obj\
-   $(INTDIR)\hardcopy.obj\
-   $(INTDIR)\hashtab.obj\
-   $(INTDIR)\gui.obj\
-   $(INTDIR)\gui_w16.obj\
-   $(INTDIR)\main.obj\
-   $(INTDIR)\mark.obj\
-   $(INTDIR)\mbyte.obj\
-   $(INTDIR)\memfile.obj\
-   $(INTDIR)\memline.obj\
-   $(INTDIR)\menu.obj\
-   $(INTDIR)\message.obj\
-   $(INTDIR)\misc1.obj\
-   $(INTDIR)\misc2.obj\
-   $(INTDIR)\move.obj\
-   $(INTDIR)\normal.obj\
-   $(INTDIR)\ops.obj\
-   $(INTDIR)\option.obj\
-   $(INTDIR)\os_win16.obj\
-   $(INTDIR)\os_msdos.obj\
-   $(INTDIR)\os_mswin.obj\
-   $(INTDIR)\winclip.obj\
-   $(INTDIR)\popupmnu.obj\
-   $(INTDIR)\quickfix.obj\
-   $(INTDIR)\regexp.obj\
-   $(INTDIR)\screen.obj\
-   $(INTDIR)\search.obj\
-   $(INTDIR)\spell.obj\
-   $(INTDIR)\syntax.obj\
-   $(INTDIR)\tag.obj\
-   $(INTDIR)\term.obj\
-   $(INTDIR)\ui.obj\
-   $(INTDIR)\undo.obj\
-   $(INTDIR)\version.obj\
-   $(INTDIR)\window.obj
-
-Dep_gvim16dexe = \
-   vimtbar.lib\
-   vim16.def\
-   $(INTDIR)\vim16.res\
-   $(ObjFiles)
-
-# Without the following, the implicit rule in BUILTINS.MAK is picked up
-# for a rule for .c.obj rather than the local implicit rule
-.SUFFIXES
-.SUFFIXES .c .obj
-.path.c = .
-
-# -P-	Force C++ compilation off
-# -c	Compilation only
-# -n    Place .OBJ files
-{.}.c{$(INTDIR)}.obj:
-  $(BCC) -P- -c -n$(INTDIR)\ {$< }
-
-Gvim16 : BccW16.cfg $(Dep_Gvim16)
-  echo MakeNode
-
-gvim16.exe : $(Dep_gvim16dexe)
-  $(TLINK)   $(LinkerLocalOptsAtW16_gvim16dexe) @&&|
-c0wl.obj $(ObjFiles)
-|,$*,,vimtbar ctl3dv2 import cwl, vim16.def,$(INTDIR)\vim16.res
-
-# Force objects to be built if $(BOR) changes
-$(ObjFiles) : Make_w16.mak BccW16.cfg
-
-$(INTDIR)\vim16.res : vim16.rc
-  $(BRC) -R @&&|
-  $(CompInheritOptsAt_gvim16dexe) -fo$*.res $?
-|
-
-
-# Compiler configuration file
-# There is no rule for $(INTDIR) as make always says it does not exist
-BccW16.cfg :
-	-@if not exist $(INTDIR)\$(NULL) mkdir $(INTDIR)
-	Copy &&|
--3		; Generate 80386 protected-mode compatible instructions
--a		; Byte alignment
--dc		; Move string literals from data segment to code segment
--ff		; Fast floating point
--H		; Generate and use precompiled headers
--H=$(INTDIR)\gvim16.csm	; gvim16.csm is the precompiled header filename
--k-		; No standard stack frame
--ml		; Large memory model
--OW		; Suppress the inc bp/dec bp on windows far functions
--O1		; Generate smallest possible code
--O2		; Generate fastest possible code (overrides prior -O1 control)
--pr		; Fastcall calling convention passing parameters in registers
--R-		; Exclude browser information in generated .OBJ files
--v-		; Turn off source debugging
--vi		; Turn inline function expansion on
--WE		; Only __far _export functions are exported
--w		; Display warnings
--w-par		; Suppress: Parameter 'parameter' is never used
--w-pch		; Cannot create pre-compiled header: initialized data in header
--w-sig		; identifier' declared but never used
--w-ucp		; Mixing pointers to different 'char' types
--wuse		; 'identifier' declared but never used
- $(CompInheritOptsAt_gvim16dexe)
-| $@
-
-!IF "$(OS)" == "Windows_NT"
-NULL=
-DEL_TREE = rmdir /s /q
-!ELSE
-NULL=nul
-DEL_TREE = deltree /y
-!ENDIF
-
-CLEAN:
-	-@if exist $(INTDIR)\$(NULL) $(DEL_TREE) $(INTDIR)
-	-@if exist BccW16.cfg erase BccW16.cfg
-	-@if exist gvim16.exe erase gvim16.exe
diff --git a/src/Makefile b/src/Makefile
index 8985e40..13c7bc6 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -1336,7 +1336,7 @@
 
 # All GUI files
 ALL_GUI_SRC  = gui.c gui_gtk.c gui_gtk_f.c gui_motif.c gui_xmdlg.c gui_xmebw.c gui_athena.c gui_gtk_x11.c gui_x11.c gui_at_sb.c gui_at_fs.c pty.c
-ALL_GUI_PRO  = gui.pro gui_gtk.pro gui_motif.pro gui_xmdlg.pro gui_athena.pro gui_gtk_x11.pro gui_x11.pro gui_w16.pro gui_w32.pro gui_photon.pro
+ALL_GUI_PRO  = gui.pro gui_gtk.pro gui_motif.pro gui_xmdlg.pro gui_athena.pro gui_gtk_x11.pro gui_x11.pro gui_w32.pro gui_photon.pro
 
 # }}}
 
@@ -1715,7 +1715,7 @@
 # Resources used for the Mac are in one directory.
 RSRC_DIR = os_mac_rsrc
 
-PRO_MANUAL = os_amiga.pro os_msdos.pro os_win16.pro os_win32.pro \
+PRO_MANUAL = os_amiga.pro os_msdos.pro os_win32.pro \
 	os_mswin.pro winclip.pro os_beos.pro os_vms.pro $(PERL_PRO)
 
 # Default target is making the executable and tools
@@ -1868,20 +1868,16 @@
 	$(CPROTO) -DMSDOS -UHAVE_CONFIG_H $< > proto/$@
 	echo "/* vim: set ft=c : */" >> proto/$@
 
-os_win16.pro: os_win16.c
-	$(CPROTO) -DWIN16 -UHAVE_CONFIG_H $< > proto/$@
-	echo "/* vim: set ft=c : */" >> proto/$@
-
 os_win32.pro: os_win32.c
 	$(CPROTO) -DWIN32 -UHAVE_CONFIG_H $< > proto/$@
 	echo "/* vim: set ft=c : */" >> proto/$@
 
 os_mswin.pro: os_mswin.c
-	$(CPROTO) -DWIN16 -DWIN32 -UHAVE_CONFIG_H $< > proto/$@
+	$(CPROTO) -DWIN32 -UHAVE_CONFIG_H $< > proto/$@
 	echo "/* vim: set ft=c : */" >> proto/$@
 
 winclip.pro: winclip.c
-	$(CPROTO) -DWIN16 -DWIN32 -UHAVE_CONFIG_H $< > proto/$@
+	$(CPROTO) -DWIN32 -UHAVE_CONFIG_H $< > proto/$@
 	echo "/* vim: set ft=c : */" >> proto/$@
 
 os_beos.pro: os_beos.c
@@ -2025,6 +2021,7 @@
 	test_menu \
 	test_perl \
 	test_quickfix \
+	test_reltime \
 	test_searchpos \
 	test_set \
 	test_sort \
diff --git a/src/eval.c b/src/eval.c
index 8afd52e..017decc 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -13235,9 +13235,6 @@
 #ifdef VMS
 	"vms",
 #endif
-#ifdef WIN16
-	"win16",
-#endif
 #ifdef WIN32
 	"win32",
 #endif
diff --git a/src/feature.h b/src/feature.h
index ca01b06..d7679e0 100644
--- a/src/feature.h
+++ b/src/feature.h
@@ -320,7 +320,7 @@
  *
  * Disabled for EBCDIC as it requires multibyte.
  */
-#if defined(FEAT_BIG) && !defined(WIN16) && VIM_SIZEOF_INT >= 4 && !defined(EBCDIC)
+#if defined(FEAT_BIG) && VIM_SIZEOF_INT >= 4 && !defined(EBCDIC)
 # define FEAT_ARABIC
 #endif
 #ifdef FEAT_ARABIC
@@ -624,8 +624,7 @@
  * Multibyte support doesn't work on z/OS Unix currently.
  */
 #if (defined(FEAT_NORMAL) || defined(FEAT_GUI_GTK) || defined(FEAT_ARABIC)) \
-	&& !defined(FEAT_MBYTE) && !defined(WIN16) \
-	&& VIM_SIZEOF_INT >= 4 && !defined(EBCDIC)
+	&& !defined(FEAT_MBYTE) && VIM_SIZEOF_INT >= 4 && !defined(EBCDIC)
 # define FEAT_MBYTE
 #endif
 
@@ -763,7 +762,7 @@
     && (defined(FEAT_GUI_GTK) \
 	|| (defined(FEAT_GUI_MOTIF) && defined(HAVE_XM_NOTEBOOK_H)) \
 	|| defined(FEAT_GUI_MAC) \
-	|| (defined(FEAT_GUI_MSWIN) && !defined(WIN16) \
+	|| (defined(FEAT_GUI_MSWIN) \
 	    && (!defined(_MSC_VER) || _MSC_VER > 1020)))
 # define FEAT_GUI_TABLINE
 #endif
diff --git a/src/gui.c b/src/gui.c
index d6b9eb1..f7ec508 100644
--- a/src/gui.c
+++ b/src/gui.c
@@ -2184,7 +2184,7 @@
     guicolor_T	fg_color;
     guicolor_T	bg_color;
     guicolor_T	sp_color;
-#if !defined(MSWIN16_FASTTEXT) && !defined(FEAT_GUI_GTK)
+#if !defined(FEAT_GUI_GTK)
     GuiFont	font = NOFONT;
 # ifdef FEAT_MBYTE
     GuiFont	wide_font = NOFONT;
@@ -2241,7 +2241,7 @@
 	highlight_mask = gui.highlight_mask;
     hl_mask_todo = highlight_mask;
 
-#if !defined(MSWIN16_FASTTEXT) && !defined(FEAT_GUI_GTK)
+#if !defined(FEAT_GUI_GTK)
     /* Set the font */
     if (aep != NULL && aep->ae_u.gui.font != NOFONT)
 	font = aep->ae_u.gui.font;
@@ -2358,11 +2358,9 @@
 	clip_may_clear_selection(gui.row, gui.row);
 
 
-#ifndef MSWIN16_FASTTEXT
     /* If there's no bold font, then fake it */
     if (hl_mask_todo & (HL_BOLD | HL_STANDOUT))
 	draw_flags |= DRAW_BOLD;
-#endif
 
     /*
      * When drawing bold or italic characters the spill-over from the left
@@ -2383,11 +2381,7 @@
 	draw_flags |= DRAW_UNDERL;
 #else
     /* Do we underline the text? */
-    if ((hl_mask_todo & HL_UNDERLINE)
-# ifndef MSWIN16_FASTTEXT
-	    || (hl_mask_todo & HL_ITALIC)
-# endif
-       )
+    if ((hl_mask_todo & HL_UNDERLINE) || (hl_mask_todo & HL_ITALIC))
 	draw_flags |= DRAW_UNDERL;
 #endif
     /* Do we undercurl the text? */
@@ -3338,7 +3332,7 @@
     static int	prev_footer = -1;
     int		using_footer = FALSE;
 #endif
-#if defined(FEAT_MENU) && !defined(WIN16)
+#if defined(FEAT_MENU)
     static int	prev_tearoff = -1;
     int		using_tearoff = FALSE;
 #endif
@@ -3415,7 +3409,7 @@
 		break;
 #endif
 	    case GO_TEAROFF:
-#if defined(FEAT_MENU) && !defined(WIN16)
+#if defined(FEAT_MENU)
 		using_tearoff = TRUE;
 #endif
 		break;
@@ -3522,7 +3516,7 @@
 		fix_size = TRUE;
 	}
 #endif
-#if defined(FEAT_MENU) && !defined(WIN16) && !(defined(WIN3264) && !defined(FEAT_TEAROFF))
+#if defined(FEAT_MENU) && !(defined(WIN3264) && !defined(FEAT_TEAROFF))
 	if (using_tearoff != prev_tearoff)
 	{
 	    gui_mch_toggle_tearoffs(using_tearoff);
diff --git a/src/gui_w16.c b/src/gui_w16.c
deleted file mode 100644
index a0a3996..0000000
--- a/src/gui_w16.c
+++ /dev/null
@@ -1,1564 +0,0 @@
-/* vi:set ts=8 sts=4 sw=4:
- *
- * VIM - Vi IMproved		by Bram Moolenaar
- *				GUI support by Robert Webb
- *
- * Do ":help uganda"  in Vim to read copying and usage conditions.
- * Do ":help credits" in Vim to see a list of people who contributed.
- * See README.txt for an overview of the Vim source code.
- */
-/*
- * gui_w16.c
- *
- * GUI support for Microsoft Windows 3.1x
- *
- * George V. Reilly <george@reilly.org> wrote the original Win32 GUI.
- * Robert Webb reworked it to use the existing GUI stuff and added menu,
- * scrollbars, etc.
- *
- * Vince Negri then butchered the code to get it compiling for
- * 16-bit windows.
- *
- */
-
-/* Win16 doesn't use the "W" methods. */
-#define pDispatchMessage DispatchMessage
-#define pGetMessage GetMessage
-#define pIsDialogMessage IsDialogMessage
-#define pPeekMessage PeekMessage
-
-/*
- * Include the common stuff for MS-Windows GUI.
- */
-#include "gui_w48.c"
-
-#include "guiw16rc.h"
-
-/* Undocumented Windows Message - not even defined in some SDK headers */
-#define WM_EXITSIZEMOVE			0x0232
-
-
-#ifdef FEAT_TOOLBAR
-# define CMD_TB_BASE (99)
-# include <vimtbar.h>
-#endif
-
-#ifdef PROTO
-# define WINAPI
-#endif
-
-#define HANDLE_WM_DROPFILES(hwnd, wParam, lParam, fn) \
-    ((fn)((hwnd), (HDROP)(wParam)), 0L)
-
-
-/* Local variables: */
-
-#ifdef FEAT_MENU
-static UINT	s_menu_id = 100;
-#endif
-
-
-#define VIM_NAME	"vim"
-#define VIM_CLASS	"Vim"
-
-#define DLG_ALLOC_SIZE 16 * 1024
-
-/*
- * stuff for dialogs, menus, tearoffs etc.
- */
-#if defined(FEAT_GUI_DIALOG) || defined(PROTO)
-static BOOL CALLBACK dialog_callback(HWND, UINT, WPARAM, LPARAM);
-
-static LPWORD
-add_dialog_element(
-	LPWORD p,
-	DWORD lStyle,
-	WORD x,
-	WORD y,
-	WORD w,
-	WORD h,
-	WORD Id,
-	BYTE clss,
-	const char *caption);
-
-static int dialog_default_button = -1;
-#endif
-
-static void get_dialog_font_metrics(void);
-
-#ifdef FEAT_TOOLBAR
-static void initialise_toolbar(void);
-#endif
-
-
-#ifdef FEAT_MENU
-/*
- * Figure out how high the menu bar is at the moment.
- */
-    static int
-gui_mswin_get_menu_height(
-    int	    fix_window)	    /* If TRUE, resize window if menu height changed */
-{
-    static int	old_menu_height = -1;
-
-    int	    num;
-    int	    menu_height;
-
-    if (gui.menu_is_active)
-	num = GetMenuItemCount(s_menuBar);
-    else
-	num = 0;
-
-    if (num == 0)
-	menu_height = 0;
-    else if (gui.starting)
-	menu_height = GetSystemMetrics(SM_CYMENU);
-    else
-    {
-	RECT r1, r2;
-	int frameht = GetSystemMetrics(SM_CYFRAME);
-	int capht = GetSystemMetrics(SM_CYCAPTION);
-
-	/*	get window rect of s_hwnd
-		 * get client rect of s_hwnd
-		 * get cap height
-		 * subtract from window rect, the sum of client height,
-		 * (if not maximized)frame thickness, and caption height.
-	 */
-	GetWindowRect(s_hwnd, &r1);
-	GetClientRect(s_hwnd, &r2);
-	menu_height = r1.bottom - r1.top - (r2.bottom-r2.top +
-			       2 * frameht * (!IsZoomed(s_hwnd)) + capht);
-    }
-
-    if (fix_window && menu_height != old_menu_height)
-    {
-	old_menu_height = menu_height;
-	gui_set_shellsize(FALSE, FALSE, RESIZE_VERT);
-    }
-
-    return menu_height;
-}
-#endif /*FEAT_MENU*/
-
-
-/*
- * Even though we have _DuringSizing() which makes the rubber band a valid
- * size, we need this for when the user maximises the window.
- * TODO: Doesn't seem to adjust the width though for some reason.
- */
-    static BOOL
-_OnWindowPosChanging(
-    HWND hwnd,
-    LPWINDOWPOS lpwpos)
-{
-
-    if (!IsIconic(hwnd) && !(lpwpos->flags & SWP_NOSIZE))
-    {
-	gui_mswin_get_valid_dimensions(lpwpos->cx, lpwpos->cy,
-				     &lpwpos->cx, &lpwpos->cy);
-    }
-    return 0;
-}
-
-
-
-
-
-    static LRESULT CALLBACK
-_WndProc(
-    HWND hwnd,
-    UINT uMsg,
-    WPARAM wParam,
-    LPARAM lParam)
-{
-    /*
-    TRACE("WndProc: hwnd = %08x, msg = %x, wParam = %x, lParam = %x\n",
-	  hwnd, uMsg, wParam, lParam);
-    */
-
-    HandleMouseHide(uMsg, lParam);
-
-    s_uMsg = uMsg;
-    s_wParam = wParam;
-    s_lParam = lParam;
-
-    switch (uMsg)
-    {
-	HANDLE_MSG(hwnd, WM_DEADCHAR,	_OnDeadChar);
-	HANDLE_MSG(hwnd, WM_SYSDEADCHAR, _OnDeadChar);
-	/* HANDLE_MSG(hwnd, WM_ACTIVATE,    _OnActivate); */
-	HANDLE_MSG(hwnd, WM_CHAR,	_OnChar);
-	HANDLE_MSG(hwnd, WM_CLOSE,	_OnClose);
-	/* HANDLE_MSG(hwnd, WM_COMMAND,	_OnCommand); */
-	HANDLE_MSG(hwnd, WM_DESTROY,	_OnDestroy);
-	HANDLE_MSG(hwnd, WM_DROPFILES,	_OnDropFiles);
-	HANDLE_MSG(hwnd, WM_HSCROLL,	_OnScroll);
-	HANDLE_MSG(hwnd, WM_KILLFOCUS,	_OnKillFocus);
-#ifdef FEAT_MENU
-	HANDLE_MSG(hwnd, WM_COMMAND,	_OnMenu);
-#endif
-	/* HANDLE_MSG(hwnd, WM_MOVE,	    _OnMove); */
-	/* HANDLE_MSG(hwnd, WM_NCACTIVATE,  _OnNCActivate); */
-	HANDLE_MSG(hwnd, WM_SETFOCUS,	_OnSetFocus);
-	HANDLE_MSG(hwnd, WM_SIZE,	_OnSize);
-	/* HANDLE_MSG(hwnd, WM_SYSCOMMAND,  _OnSysCommand); */
-	/* HANDLE_MSG(hwnd, WM_SYSKEYDOWN,  _OnAltKey); */
-	HANDLE_MSG(hwnd, WM_VSCROLL,	_OnScroll);
-	HANDLE_MSG(hwnd, WM_WINDOWPOSCHANGING,	_OnWindowPosChanging);
-	HANDLE_MSG(hwnd, WM_ACTIVATEAPP, _OnActivateApp);
-
-    case WM_QUERYENDSESSION:	/* System wants to go down. */
-	gui_shell_closed();	/* Will exit when no changed buffers. */
-	return FALSE;		/* Do NOT allow system to go down. */
-
-    case WM_ENDSESSION:
-	if (wParam)	/* system only really goes down when wParam is TRUE */
-	    _OnEndSession();
-	break;
-
-    case WM_SYSCHAR:
-	/*
-	 * if 'winaltkeys' is "no", or it's "menu" and it's not a menu
-	 * shortcut key, handle like a typed ALT key, otherwise call Windows
-	 * ALT key handling.
-	 */
-#ifdef FEAT_MENU
-	if (	!gui.menu_is_active
-		|| p_wak[0] == 'n'
-		|| (p_wak[0] == 'm' && !gui_is_menu_shortcut((int)wParam))
-		)
-#endif
-	    return HANDLE_WM_SYSCHAR((hwnd), (wParam), (lParam), (_OnSysChar));
-#ifdef FEAT_MENU
-	else
-	    return MyWindowProc(hwnd, uMsg, wParam, lParam);
-#endif
-
-    case WM_SYSKEYUP:
-#ifdef FEAT_MENU
-	/* Only when menu is active, ALT key is used for that. */
-	if (gui.menu_is_active)
-	{
-	    return MyWindowProc(hwnd, uMsg, wParam, lParam);
-	}
-	else
-#endif
-	    return 0;
-
-#if defined(MENUHINTS) && defined(FEAT_MENU)
-    case WM_MENUSELECT:
-	if (((UINT) LOWORD(lParam)
-		    & (0xffff ^ (MF_MOUSESELECT + MF_BITMAP + MF_POPUP)))
-		== MF_HILITE
-		&& (State & CMDLINE) == 0)
-	{
-	    UINT idButton;
-	    int	idx;
-	    vimmenu_T *pMenu;
-
-	    idButton = (UINT)LOWORD(wParam);
-	    pMenu = gui_mswin_find_menu(root_menu, idButton);
-	    if (pMenu)
-	    {
-		idx = MENU_INDEX_TIP;
-		msg_clr_cmdline();
-		if (pMenu->strings[idx])
-		    msg(pMenu->strings[idx]);
-		else
-		    msg("");
-		setcursor();
-		out_flush();
-	    }
-	}
-	break;
-#endif
-    case WM_NCHITTEST:
-	{
-	    LRESULT	result;
-	    int x, y;
-	    int xPos = GET_X_LPARAM(lParam);
-
-	    result = MyWindowProc(hwnd, uMsg, wParam, lParam);
-	    if (result == HTCLIENT)
-	    {
-		(void)gui_mch_get_winpos(&x, &y);
-		xPos -= x;
-
-		if (xPos < 48) /*<VN> TODO should use system metric?*/
-		    return HTBOTTOMLEFT;
-		else
-		    return HTBOTTOMRIGHT;
-		}
-	    else
-		return result;
-	}
-	/* break; */
-    default:
-#ifdef MSWIN_FIND_REPLACE
-	if (uMsg == s_findrep_msg && s_findrep_msg != 0)
-	{
-	    _OnFindRepl();
-	}
-#endif
-	return MyWindowProc(hwnd, uMsg, wParam, lParam);
-    }
-
-    return 1;
-}
-
-
-
-/*
- * End of call-back routines
- */
-
-
-/*
- * Parse the GUI related command-line arguments.  Any arguments used are
- * deleted from argv, and *argc is decremented accordingly.  This is called
- * when vim is started, whether or not the GUI has been started.
- */
-    void
-gui_mch_prepare(int *argc, char **argv)
-{
-    /* No special args for win16 GUI at the moment. */
-
-}
-
-/*
- * Initialise the GUI.	Create all the windows, set up all the call-backs
- * etc.
- */
-    int
-gui_mch_init(void)
-{
-    const char szVimWndClass[] = VIM_CLASS;
-    const char szTextAreaClass[] = "VimTextArea";
-    WNDCLASS wndclass;
-
-#ifdef WIN16_3DLOOK
-    Ctl3dRegister(s_hinst);
-    Ctl3dAutoSubclass(s_hinst);
-#endif
-
-    /* Display any pending error messages */
-    display_errors();
-
-    gui.scrollbar_width = GetSystemMetrics(SM_CXVSCROLL);
-    gui.scrollbar_height = GetSystemMetrics(SM_CYHSCROLL);
-#ifdef FEAT_MENU
-    gui.menu_height = 0;	/* Windows takes care of this */
-#endif
-    gui.border_width = 0;
-
-    gui.currBgColor = INVALCOLOR;
-
-    s_brush = CreateSolidBrush(GetSysColor(COLOR_BTNFACE));
-
-    if (GetClassInfo(s_hinst, szVimWndClass, &wndclass) == 0) {
-	wndclass.style = 0;
-	wndclass.lpfnWndProc = _WndProc;
-	wndclass.cbClsExtra = 0;
-	wndclass.cbWndExtra = 0;
-	wndclass.hInstance = s_hinst;
-	wndclass.hIcon = LoadIcon(wndclass.hInstance, MAKEINTRESOURCE(IDR_VIM));
-	wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
-	wndclass.hbrBackground = s_brush;
-	wndclass.lpszMenuName = NULL;
-	wndclass.lpszClassName = szVimWndClass;
-
-    if ((
-#ifdef GLOBAL_IME
-	atom =
-#endif
-		RegisterClass(&wndclass)) == 0)
-	    return FAIL;
-    }
-
-    s_hwnd = CreateWindow(
-	szVimWndClass, "Vim MSWindows GUI",
-	WS_OVERLAPPEDWINDOW,
-	gui_win_x == -1 ? CW_USEDEFAULT : gui_win_x,
-	gui_win_y == -1 ? CW_USEDEFAULT : gui_win_y,
-	100,				/* Any value will do */
-	100,				/* Any value will do */
-	NULL, NULL,
-	s_hinst, NULL);
-
-    if (s_hwnd == NULL)
-	return FAIL;
-
-#ifdef GLOBAL_IME
-    global_ime_init(atom, s_hwnd);
-#endif
-
-    /* Create the text area window */
-    if (GetClassInfo(s_hinst, szTextAreaClass, &wndclass) == 0) {
-	wndclass.style = CS_OWNDC;
-	wndclass.lpfnWndProc = _TextAreaWndProc;
-	wndclass.cbClsExtra = 0;
-	wndclass.cbWndExtra = 0;
-	wndclass.hInstance = s_hinst;
-	wndclass.hIcon = NULL;
-	wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
-	wndclass.hbrBackground = NULL;
-	wndclass.lpszMenuName = NULL;
-	wndclass.lpszClassName = szTextAreaClass;
-
-	if (RegisterClass(&wndclass) == 0)
-	    return FAIL;
-    }
-    s_textArea = CreateWindow(
-	szTextAreaClass, "Vim text area",
-	WS_CHILD | WS_VISIBLE, 0, 0,
-	100,				/* Any value will do for now */
-	100,				/* Any value will do for now */
-	s_hwnd, NULL,
-	s_hinst, NULL);
-
-    if (s_textArea == NULL)
-	return FAIL;
-
-#ifdef FEAT_MENU
-    s_menuBar = CreateMenu();
-#endif
-    s_hdc = GetDC(s_textArea);
-
-#ifdef MSWIN16_FASTTEXT
-    SetBkMode(s_hdc, OPAQUE);
-#endif
-
-    DragAcceptFiles(s_hwnd, TRUE);
-
-    /* Do we need to bother with this? */
-    /* m_fMouseAvail = GetSystemMetrics(SM_MOUSEPRESENT); */
-
-    /* Get background/foreground colors from the system */
-    gui_mch_def_colors();
-
-    /* Get the colors from the "Normal" group (set in syntax.c or in a vimrc
-     * file) */
-    set_normal_colors();
-
-    /*
-     * Check that none of the colors are the same as the background color.
-     * Then store the current values as the defaults.
-     */
-    gui_check_colors();
-    gui.def_norm_pixel = gui.norm_pixel;
-    gui.def_back_pixel = gui.back_pixel;
-
-    /* Get the colors for the highlight groups (gui_check_colors() might have
-     * changed them) */
-    highlight_gui_started();
-
-    /*
-     * Start out by adding the configured border width into the border offset
-     */
-    gui.border_offset = gui.border_width;
-
-
-    /*
-     * compute a couple of metrics used for the dialogs
-     */
-    get_dialog_font_metrics();
-#ifdef FEAT_TOOLBAR
-    /*
-     * Create the toolbar
-     */
-    initialise_toolbar();
-#endif
-#ifdef MSWIN_FIND_REPLACE
-    /*
-     * Initialise the dialog box stuff
-     */
-    s_findrep_msg = RegisterWindowMessage(FINDMSGSTRING);
-
-    /* Initialise the struct */
-    s_findrep_struct.lStructSize = sizeof(s_findrep_struct);
-    s_findrep_struct.lpstrFindWhat = alloc(MSWIN_FR_BUFSIZE);
-    s_findrep_struct.lpstrFindWhat[0] = NUL;
-    s_findrep_struct.lpstrReplaceWith = alloc(MSWIN_FR_BUFSIZE);
-    s_findrep_struct.lpstrReplaceWith[0] = NUL;
-    s_findrep_struct.wFindWhatLen = MSWIN_FR_BUFSIZE;
-    s_findrep_struct.wReplaceWithLen = MSWIN_FR_BUFSIZE;
-#endif
-
-    return OK;
-}
-
-
-/*
- * Set the size of the window to the given width and height in pixels.
- */
-    void
-gui_mch_set_shellsize(int width, int height,
-	int min_width, int min_height, int base_width, int base_height,
-	int direction)
-{
-    RECT	workarea_rect;
-    int		win_width, win_height;
-    int		win_xpos, win_ypos;
-    WINDOWPLACEMENT wndpl;
-
-    /* try to keep window completely on screen */
-    /* get size of the screen work area - use SM_CYFULLSCREEN
-     * instead of SM_CYSCREEN so that we don't overlap the
-     * taskbar if someone fires us up on Win95/NT */
-    workarea_rect.left = 0;
-    workarea_rect.top = 0;
-    workarea_rect.right = GetSystemMetrics(SM_CXSCREEN);
-    workarea_rect.bottom = GetSystemMetrics(SM_CYFULLSCREEN);
-
-    /* get current position of our window */
-    wndpl.length = sizeof(WINDOWPLACEMENT);
-    GetWindowPlacement(s_hwnd, &wndpl);
-    if (wndpl.showCmd == SW_SHOWNORMAL)
-    {
-	win_xpos = wndpl.rcNormalPosition.left;
-	win_ypos = wndpl.rcNormalPosition.top;
-    }
-    else
-    {
-	win_xpos = workarea_rect.left;
-	win_ypos = workarea_rect.top;
-    }
-
-    /* compute the size of the outside of the window */
-    win_width = width + GetSystemMetrics(SM_CXFRAME) * 2;
-    win_height = height + GetSystemMetrics(SM_CYFRAME) * 2
-			+ GetSystemMetrics(SM_CYCAPTION)
-#ifdef FEAT_MENU
-			+ gui_mswin_get_menu_height(FALSE)
-#endif
-			;
-
-    /* if the window is going off the screen, move it on to the screen */
-    if ((direction & RESIZE_HOR) && win_xpos + win_width > workarea_rect.right)
-	win_xpos = workarea_rect.right - win_width;
-
-    if ((direction & RESIZE_HOR) && win_xpos < workarea_rect.left)
-	win_xpos = workarea_rect.left;
-
-    if ((direction & RESIZE_VERT)
-			       && win_ypos + win_height > workarea_rect.bottom)
-	win_ypos = workarea_rect.bottom - win_height;
-
-    if ((direction & RESIZE_VERT) && win_ypos < workarea_rect.top)
-	win_ypos = workarea_rect.top;
-
-    /* set window position */
-    SetWindowPos(s_hwnd, NULL, win_xpos, win_ypos, win_width, win_height,
-		 SWP_NOZORDER | SWP_NOACTIVATE);
-
-#ifdef FEAT_MENU
-    /* Menu may wrap differently now */
-    gui_mswin_get_menu_height(!gui.starting);
-#endif
-}
-
-    void
-gui_mch_set_scrollbar_thumb(
-    scrollbar_T     *sb,
-    long	    val,
-    long	    size,
-    long	    max)
-{
-    sb->scroll_shift = 0;
-    while (max > 32767)
-    {
-	max = (max + 1) >> 1;
-	val  >>= 1;
-	size >>= 1;
-	++sb->scroll_shift;
-    }
-
-    if (sb->scroll_shift > 0)
-	++size;
-
-    SetScrollRange(sb->id, SB_CTL, 0, (int) max, FALSE);
-    SetScrollPos(sb->id, SB_CTL, (int) val, TRUE);
-}
-
-
-/*
- * Set the current text font.
- */
-    void
-gui_mch_set_font(GuiFont font)
-{
-    gui.currFont = font;
-    SelectFont(s_hdc, gui.currFont);
-}
-
-/*
- * Set the current text foreground color.
- */
-    void
-gui_mch_set_fg_color(guicolor_T color)
-{
-    gui.currFgColor = color;
-    SetTextColor(s_hdc, gui.currFgColor);
-}
-
-/*
- * Set the current text background color.
- */
-    void
-gui_mch_set_bg_color(guicolor_T color)
-{
-    if (gui.currBgColor == color)
-	return;
-
-    gui.currBgColor = color;
-    SetBkColor(s_hdc, gui.currBgColor);
-}
-
-/*
- * Set the current text special color.
- */
-    void
-gui_mch_set_sp_color(guicolor_T color)
-{
-    /* TODO */
-}
-
-
-
-    void
-gui_mch_draw_string(
-    int		row,
-    int		col,
-    char_u	*text,
-    int		len,
-    int		flags)
-{
-#ifndef MSWIN16_FASTTEXT
-    static int	*padding = NULL;
-    static int	pad_size = 0;
-    int		i;
-#endif
-    HPEN	hpen, old_pen;
-    int		y;
-
-#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
-     * characters with a solid background, the top row of pixels in the
-     * character below will be overwritten.  We can fix this by filling in the
-     * background ourselves, to the correct character proportions, and then
-     * writing the character in transparent mode.  Still have a problem when
-     * the character is "_", which gets written on to the character below.
-     * New fix: set gui.char_ascent to -1.  This shifts all characters up one
-     * pixel in their slots, which fixes the problem with the bottom row of
-     * pixels.	We still need this code because otherwise the top row of pixels
-     * becomes a problem. - webb.
-     */
-    HBRUSH	hbr;
-    RECT	rc;
-
-    if (!(flags & DRAW_TRANSP))
-    {
-	/*
-	 * Clear background first.
-	 * Note: FillRect() excludes right and bottom of rectangle.
-	 */
-	rc.left = FILL_X(col);
-	rc.top = FILL_Y(row);
-#ifdef FEAT_MBYTE
-	if (has_mbyte)
-	{
-	    /* Compute the length in display cells. */
-	    rc.right = FILL_X(col + mb_string2cells(text, len));
-	}
-	else
-#endif
-	    rc.right = FILL_X(col + len);
-	rc.bottom = FILL_Y(row + 1);
-	hbr = CreateSolidBrush(gui.currBgColor);
-	FillRect(s_hdc, &rc, hbr);
-	DeleteBrush(hbr);
-
-	SetBkMode(s_hdc, TRANSPARENT);
-
-	/*
-	 * When drawing block cursor, prevent inverted character spilling
-	 * over character cell (can happen with bold/italic)
-	 */
-	if (flags & DRAW_CURSOR)
-	{
-	    pcliprect = &rc;
-	    foptions = ETO_CLIPPED;
-	}
-    }
-#else
-    /*
-     * Alternative: write the characters in opaque mode, since we have blocked
-     * bold or italic fonts.
-     */
-    /* The OPAQUE mode and backcolour have already been set */
-#endif
-    /* The forecolor and font have already been set */
-
-#ifndef MSWIN16_FASTTEXT
-
-    if (pad_size != Columns || padding == NULL || padding[0] != gui.char_width)
-    {
-	vim_free(padding);
-	pad_size = Columns;
-
-	padding = (int *)alloc(pad_size * sizeof(int));
-	if (padding != NULL)
-	    for (i = 0; i < pad_size; i++)
-		padding[i] = gui.char_width;
-    }
-#endif
-
-    /*
-     * We have to provide the padding argument because italic and bold versions
-     * of fixed-width fonts are often one pixel or so wider than their normal
-     * versions.
-     * No check for DRAW_BOLD, Windows will have done it already.
-     */
-#ifndef MSWIN16_FASTTEXT
-    ExtTextOut(s_hdc, TEXT_X(col), TEXT_Y(row), 0, NULL,
-						     (char *)text, len, padding);
-#else
-    TextOut(s_hdc, TEXT_X(col), TEXT_Y(row), (char *)text, len);
-#endif
-
-    if (flags & DRAW_UNDERL)
-    {
-	hpen = CreatePen(PS_SOLID, 1, gui.currFgColor);
-	old_pen = SelectObject(s_hdc, hpen);
-	/* 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);
-	DeleteObject(SelectObject(s_hdc, old_pen));
-    }
-}
-
-
-/*
- * Output routines.
- */
-
-/* Flush any output to the screen */
-    void
-gui_mch_flush(void)
-{
-    /* Is anything needed here? */
-}
-
-    static void
-clear_rect(RECT *rcp)
-{
-    /* Use trick for fast rect clear */
-    gui_mch_set_bg_color(gui.back_pixel);
-    ExtTextOut(s_hdc, 0, 0, ETO_CLIPPED | ETO_OPAQUE, rcp, NULL, 0, NULL);
-}
-
-
-    void
-gui_mch_get_screen_dimensions(int *screen_w, int *screen_h)
-{
-
-    *screen_w = GetSystemMetrics(SM_CXFULLSCREEN)
-	      - GetSystemMetrics(SM_CXFRAME) * 2;
-    /* FIXME: dirty trick: Because the gui_get_base_height() doesn't include
-     * the menubar for MSwin, we subtract it from the screen height, so that
-     * the window size can be made to fit on the screen. */
-    *screen_h = GetSystemMetrics(SM_CYFULLSCREEN)
-	      - GetSystemMetrics(SM_CYFRAME) * 2
-#ifdef FEAT_MENU
-	      - gui_mswin_get_menu_height(FALSE)
-#endif
-	      ;
-}
-
-
-#if defined(FEAT_MENU) || defined(PROTO)
-/*
- * Add a sub menu to the menu bar.
- */
-    void
-gui_mch_add_menu(
-    vimmenu_T	*menu,
-    int		pos)
-{
-    vimmenu_T	*parent = menu->parent;
-
-    menu->submenu_id = CreatePopupMenu();
-    menu->id = s_menu_id++;
-
-    if (menu_is_menubar(menu->name))
-    {
-	InsertMenu((parent == NULL) ? s_menuBar : parent->submenu_id,
-		(UINT)pos, MF_POPUP | MF_STRING | MF_BYPOSITION,
-		(UINT)menu->submenu_id,  menu->name);
-    }
-
-    /* Fix window size if menu may have wrapped */
-    if (parent == NULL)
-	gui_mswin_get_menu_height(!gui.starting);
-}
-
-    void
-gui_mch_show_popupmenu(vimmenu_T *menu)
-{
-    POINT mp;
-
-    (void)GetCursorPos((LPPOINT)&mp);
-    gui_mch_show_popupmenu_at(menu, (int)mp.x, (int)mp.y);
-}
-
-    void
-gui_make_popup(char_u *path_name, int mouse_pos)
-{
-    vimmenu_T	*menu = gui_find_menu(path_name);
-
-    if (menu != NULL)
-    {
-	/* Find the position of the current cursor */
-	DWORD	temp_p;
-	POINT	p;
-	temp_p = GetDCOrg(s_hdc);
-	p.x = LOWORD(temp_p);
-	p.y = HIWORD(temp_p);
-	if (mouse_pos)
-	{
-	    int	mx, my;
-
-	    gui_mch_getmouse(&mx, &my);
-	    p.x += mx;
-	    p.y += my;
-	}
-	else if (curwin != NULL)
-	{
-	    p.x += TEXT_X(W_WINCOL(curwin) + curwin->w_wcol + 1);
-	    p.y += TEXT_Y(W_WINROW(curwin) + curwin->w_wrow + 1);
-	}
-	msg_scroll = FALSE;
-	gui_mch_show_popupmenu_at(menu, (int)p.x, (int)p.y);
-    }
-}
-
-/*
- * Add a menu item to a menu
- */
-    void
-gui_mch_add_menu_item(
-    vimmenu_T	*menu,
-    int		idx)
-{
-    vimmenu_T	*parent = menu->parent;
-
-    menu->id = s_menu_id++;
-    menu->submenu_id = NULL;
-
-#ifdef FEAT_TOOLBAR
-    if (menu_is_toolbar(parent->name))
-    {
-	TBBUTTON newtb;
-
-	vim_memset(&newtb, 0, sizeof(newtb));
-	if (menu_is_separator(menu->name))
-	{
-	    newtb.iBitmap = 0;
-	    newtb.fsStyle = TBSTYLE_SEP;
-	}
-	else
-	{
-	    if (menu->iconidx >= TOOLBAR_BITMAP_COUNT)
-		newtb.iBitmap = -1;
-	    else
-		newtb.iBitmap = menu->iconidx;
-	    newtb.fsStyle = TBSTYLE_BUTTON;
-	}
-	newtb.idCommand = menu->id;
-	newtb.fsState = TBSTATE_ENABLED;
-	SendMessage(s_toolbarhwnd, TB_INSERTBUTTON, (WPARAM)idx,
-							     (LPARAM)&newtb);
-	menu->submenu_id = (HMENU)-1;
-    }
-    else
-#endif
-    {
-	InsertMenu(parent->submenu_id, (UINT)idx,
-		(menu_is_separator(menu->name) ? MF_SEPARATOR : MF_STRING)
-							      | MF_BYPOSITION,
-		(UINT)menu->id, menu->name);
-    }
-}
-
-/*
- * Destroy the machine specific menu widget.
- */
-    void
-gui_mch_destroy_menu(vimmenu_T *menu)
-{
-    UINT i, j;
-    char pants[80]; /*<VN> hack*/
-#ifdef FEAT_TOOLBAR
-    /*
-     * is this a toolbar button?
-     */
-    if (menu->submenu_id == (HMENU)-1)
-    {
-	int iButton;
-
-	iButton = SendMessage(s_toolbarhwnd, TB_COMMANDTOINDEX, (WPARAM)menu->id, 0);
-	SendMessage(s_toolbarhwnd, TB_DELETEBUTTON, (WPARAM)iButton, 0);
-    }
-    else
-#endif
-    {
-	/*
-	 * negri: horrible API bug when running 16-bit programs under Win9x or
-	 * NT means that we can't use MF_BYCOMMAND for menu items which have
-	 * submenus, including the top-level headings. We have to find the menu
-	 * item and use MF_BYPOSITION instead. :-p
-	 */
-    if (menu->parent != NULL
-	    && menu_is_popup(menu->parent->dname)
-	    && menu->parent->submenu_id != NULL)
-	RemoveMenu(menu->parent->submenu_id, menu->id, MF_BYCOMMAND);
-    else if (menu->submenu_id == NULL)
-	RemoveMenu(s_menuBar, menu->id, MF_BYCOMMAND);
-    else if (menu->parent != NULL)
-    {
-	i = GetMenuItemCount(menu->parent->submenu_id);
-	for (j = 0; j < i; ++j)
-	{
-	    GetMenuString(menu->parent->submenu_id, j,
-		    pants, 80, MF_BYPOSITION);
-	    if (strcmp(pants, menu->name) == 0)
-	    {
-		RemoveMenu(menu->parent->submenu_id, j, MF_BYPOSITION);
-		break;
-	    }
-	}
-    }
-    else
-    {
-	i = GetMenuItemCount(s_menuBar);
-	for (j = 0; j < i; ++j)
-	{
-	    GetMenuString(s_menuBar, j, pants, 80, MF_BYPOSITION);
-	    if (strcmp(pants, menu->name) == 0)
-	    {
-		RemoveMenu(s_menuBar, j, MF_BYPOSITION);
-		break;
-	    }
-	}
-    }
-
-    if (menu->submenu_id != NULL)
-	DestroyMenu(menu->submenu_id);
-    }
-    DrawMenuBar(s_hwnd);
-}
-
-
-/*
- * Make a menu either grey or not grey.
- */
-    void
-gui_mch_menu_grey(
-    vimmenu_T *menu,
-    int	    grey)
-{
-#ifdef FEAT_TOOLBAR
-    /*
-     * is this a toolbar button?
-     */
-    if (menu->submenu_id == (HMENU)-1)
-    {
-	SendMessage(s_toolbarhwnd, TB_ENABLEBUTTON,
-	    (WPARAM)menu->id, (LPARAM) MAKELONG((grey ? FALSE : TRUE), 0) );
-    }
-    else
-#endif
-    if (grey)
-	EnableMenuItem(s_menuBar, menu->id, MF_BYCOMMAND | MF_GRAYED);
-    else
-	EnableMenuItem(s_menuBar, menu->id, MF_BYCOMMAND | MF_ENABLED);
-
-}
-
-
-#endif /*FEAT_MENU*/
-
-
-/* define some macros used to make the dialogue creation more readable */
-
-#define add_string(s) strcpy((LPSTR)p, s); (LPSTR)p += (strlen((LPSTR)p) + 1)
-#define add_word(x)		*p++ = (x)
-#define add_byte(x)		*((LPSTR)p)++ = (x)
-#define add_long(x)		*((LPDWORD)p)++ = (x)
-
-#if defined(FEAT_GUI_DIALOG) || defined(PROTO)
-/*
- * stuff for dialogs
- */
-
-/*
- * The callback routine used by all the dialogs.  Very simple.  First,
- * acknowledges the INITDIALOG message so that Windows knows to do standard
- * dialog stuff (Return = default, Esc = cancel....) Second, if a button is
- * pressed, return that button's ID - IDCANCEL (2), which is the button's
- * number.
- */
-	 static BOOL CALLBACK
-dialog_callback(
-	 HWND hwnd,
-	 UINT message,
-	 WPARAM wParam,
-	 LPARAM lParam)
-{
-    if (message == WM_INITDIALOG)
-    {
-	CenterWindow(hwnd, GetWindow(hwnd, GW_OWNER));
-	/* Set focus to the dialog.  Set the default button, if specified. */
-	(void)SetFocus(hwnd);
-	if (dialog_default_button > IDCANCEL)
-	    (void)SetFocus(GetDlgItem(hwnd, dialog_default_button));
-//	if (dialog_default_button > 0)
-//	    (void)SetFocus(GetDlgItem(hwnd, dialog_default_button + IDCANCEL));
-	return FALSE;
-    }
-
-    if (message == WM_COMMAND)
-    {
-	int	button = LOWORD(wParam);
-
-	/* Don't end the dialog if something was selected that was
-	 * not a button.
-	 */
-	if (button >= DLG_NONBUTTON_CONTROL)
-	    return TRUE;
-
-	/* If the edit box exists, copy the string. */
-	if (s_textfield != NULL)
-	    GetDlgItemText(hwnd, DLG_NONBUTTON_CONTROL + 2,
-							 s_textfield, IOSIZE);
-
-	/*
-	 * Need to check for IDOK because if the user just hits Return to
-	 * accept the default value, some reason this is what we get.
-	 */
-	if (button == IDOK)
-	    EndDialog(hwnd, dialog_default_button);
-	else
-	    EndDialog(hwnd, button - IDCANCEL);
-	return TRUE;
-    }
-
-    if ((message == WM_SYSCOMMAND) && (wParam == SC_CLOSE))
-    {
-	EndDialog(hwnd, 0);
-	return TRUE;
-    }
-    return FALSE;
-}
-
-/*
- * Create a dialog dynamically from the parameter strings.
- * type		= type of dialog (question, alert, etc.)
- * title	= dialog title. may be NULL for default title.
- * message	= text to display. Dialog sizes to accommodate it.
- * buttons	= '\n' separated list of button captions, default first.
- * dfltbutton	= number of default button.
- *
- * This routine returns 1 if the first button is pressed,
- *			2 for the second, etc.
- *
- *			0 indicates Esc was pressed.
- *			-1 for unexpected error
- *
- * If stubbing out this fn, return 1.
- */
-
-static const char_u dlg_icons[] = /* must match names in resource file */
-{
-    IDR_VIM,
-    IDR_VIM_ERROR,
-    IDR_VIM_ALERT,
-    IDR_VIM_INFO,
-    IDR_VIM_QUESTION
-};
-
-    int
-gui_mch_dialog(
-    int		 type,
-    char_u	*title,
-    char_u	*message,
-    char_u	*buttons,
-    int		 dfltbutton,
-    char_u	*textfield,
-    int		ex_cmd)
-{
-    FARPROC	dp;
-    LPWORD	p, pnumitems;
-    int		numButtons;
-    int		*buttonWidths, *buttonPositions;
-    int		buttonYpos;
-    int		nchar, i;
-    DWORD	lStyle;
-    int		dlgwidth = 0;
-    int		dlgheight;
-    int		editboxheight;
-    int		horizWidth;
-    int		msgheight;
-    char_u	*pstart;
-    char_u	*pend;
-    char_u	*tbuffer;
-    RECT	rect;
-    HWND	hwnd;
-    HDC		hdc;
-    HFONT	oldFont;
-    TEXTMETRIC	fontInfo;
-    int		fontHeight;
-    int		textWidth, minButtonWidth, messageWidth;
-    int		maxDialogWidth;
-    int		vertical;
-    int		dlgPaddingX;
-    int		dlgPaddingY;
-    HGLOBAL	hglbDlgTemp;
-
-#ifndef NO_CONSOLE
-    /* Don't output anything in silent mode ("ex -s") */
-    if (silent_mode)
-	return dfltbutton;   /* return default option */
-#endif
-
-    /* If there is no window yet, open it. */
-    if (s_hwnd == NULL && gui_mch_init() == FAIL)
-	return dfltbutton;
-
-    if ((type < 0) || (type > VIM_LAST_TYPE))
-	type = 0;
-
-    /* allocate some memory for dialog template */
-    /* TODO should compute this really*/
-
-    hglbDlgTemp = GlobalAlloc(GHND,  DLG_ALLOC_SIZE);
-    if (hglbDlgTemp == NULL)
-	return -1;
-
-    p = (LPWORD) GlobalLock(hglbDlgTemp);
-
-    if (p == NULL)
-	return -1;
-
-    /*
-     * make a copy of 'buttons' to fiddle with it.  compiler grizzles because
-     * vim_strsave() doesn't take a const arg (why not?), so cast away the
-     * const.
-     */
-    tbuffer = vim_strsave(buttons);
-    if (tbuffer == NULL)
-	return -1;
-
-    --dfltbutton;   /* Change from one-based to zero-based */
-
-    /* Count buttons */
-    numButtons = 1;
-    for (i = 0; tbuffer[i] != '\0'; i++)
-    {
-	if (tbuffer[i] == DLG_BUTTON_SEP)
-	    numButtons++;
-    }
-    if (dfltbutton >= numButtons)
-	dfltbutton = 0;
-
-    /* Allocate array to hold the width of each button */
-    buttonWidths = (int *) lalloc(numButtons * sizeof(int), TRUE);
-    if (buttonWidths == NULL)
-	return -1;
-
-    /* Allocate array to hold the X position of each button */
-    buttonPositions = (int *) lalloc(numButtons * sizeof(int), TRUE);
-    if (buttonPositions == NULL)
-	return -1;
-
-    /*
-     * Calculate how big the dialog must be.
-     */
-    hwnd = GetDesktopWindow();
-    hdc = GetWindowDC(hwnd);
-    oldFont = SelectFont(hdc, GetStockObject(SYSTEM_FONT));
-    dlgPaddingX = DLG_OLD_STYLE_PADDING_X;
-    dlgPaddingY = DLG_OLD_STYLE_PADDING_Y;
-
-    GetTextMetrics(hdc, &fontInfo);
-    fontHeight = fontInfo.tmHeight;
-
-    /* Minimum width for horizontal button */
-    minButtonWidth = GetTextWidth(hdc, "Cancel", 6);
-
-    /* Maximum width of a dialog, if possible */
-    GetWindowRect(s_hwnd, &rect);
-    maxDialogWidth = rect.right - rect.left
-		     - GetSystemMetrics(SM_CXFRAME) * 2;
-    if (maxDialogWidth < DLG_MIN_MAX_WIDTH)
-	maxDialogWidth = DLG_MIN_MAX_WIDTH;
-
-    /* Set dlgwidth to width of message */
-    pstart = message;
-    messageWidth = 0;
-    msgheight = 0;
-    do
-    {
-	pend = vim_strchr(pstart, DLG_BUTTON_SEP);
-	if (pend == NULL)
-	    pend = pstart + STRLEN(pstart);	/* Last line of message. */
-	msgheight += fontHeight;
-	textWidth = GetTextWidth(hdc, pstart, pend - pstart);
-	if (textWidth > messageWidth)
-	    messageWidth = textWidth;
-	pstart = pend + 1;
-    } while (*pend != NUL);
-    dlgwidth = messageWidth;
-
-    /* Add width of icon to dlgwidth, and some space */
-    dlgwidth += DLG_ICON_WIDTH + 3 * dlgPaddingX;
-
-    if (msgheight < DLG_ICON_HEIGHT)
-	msgheight = DLG_ICON_HEIGHT;
-
-    /*
-     * Check button names.  A long one will make the dialog wider.
-     */
-	 vertical = (vim_strchr(p_go, GO_VERTICAL) != NULL);
-    if (!vertical)
-    {
-	// Place buttons horizontally if they fit.
-	horizWidth = dlgPaddingX;
-	pstart = tbuffer;
-	i = 0;
-	do
-	{
-	    pend = vim_strchr(pstart, DLG_BUTTON_SEP);
-	    if (pend == NULL)
-		pend = pstart + STRLEN(pstart);	// Last button name.
-	    textWidth = GetTextWidth(hdc, pstart, pend - pstart);
-	    if (textWidth < minButtonWidth)
-		textWidth = minButtonWidth;
-	    textWidth += dlgPaddingX;	    /* Padding within button */
-	    buttonWidths[i] = textWidth;
-	    buttonPositions[i++] = horizWidth;
-	    horizWidth += textWidth + dlgPaddingX; /* Pad between buttons */
-	    pstart = pend + 1;
-	} while (*pend != NUL);
-
-	if (horizWidth > maxDialogWidth)
-	    vertical = TRUE;	// Too wide to fit on the screen.
-	else if (horizWidth > dlgwidth)
-	    dlgwidth = horizWidth;
-    }
-
-    if (vertical)
-    {
-	// Stack buttons vertically.
-	pstart = tbuffer;
-	do
-	{
-	    pend = vim_strchr(pstart, DLG_BUTTON_SEP);
-	    if (pend == NULL)
-		pend = pstart + STRLEN(pstart);	// Last button name.
-	    textWidth = GetTextWidth(hdc, pstart, pend - pstart);
-	    textWidth += dlgPaddingX;		/* Padding within button */
-	    textWidth += DLG_VERT_PADDING_X * 2; /* Padding around button */
-	    if (textWidth > dlgwidth)
-		dlgwidth = textWidth;
-	    pstart = pend + 1;
-	} while (*pend != NUL);
-    }
-
-    if (dlgwidth < DLG_MIN_WIDTH)
-	dlgwidth = DLG_MIN_WIDTH;	/* Don't allow a really thin dialog!*/
-
-    /* start to fill in the dlgtemplate information.  addressing by WORDs */
-    lStyle = DS_MODALFRAME | WS_CAPTION | WS_VISIBLE ;
-
-    add_long(lStyle);
-    pnumitems = p;	/*save where the number of items must be stored*/
-    add_byte(0);	// NumberOfItems(will change later)
-    add_word(10);	// x
-    add_word(10);	// y
-    add_word(PixelToDialogX(dlgwidth));
-
-    // Dialog height.
-    if (vertical)
-	dlgheight = msgheight + 2 * dlgPaddingY +
-			      DLG_VERT_PADDING_Y + 2 * fontHeight * numButtons;
-    else
-	dlgheight = msgheight + 3 * dlgPaddingY + 2 * fontHeight;
-
-    // Dialog needs to be taller if contains an edit box.
-    editboxheight = fontHeight + dlgPaddingY + 4 * DLG_VERT_PADDING_Y;
-    if (textfield != NULL)
-	dlgheight += editboxheight;
-
-    add_word(PixelToDialogY(dlgheight));
-
-    add_byte(0);	//menu
-    add_byte(0);	//class
-
-    /* copy the title of the dialog */
-    add_string(title ? title : ("Vim"VIM_VERSION_MEDIUM));
-
-    buttonYpos = msgheight + 2 * dlgPaddingY;
-
-    if (textfield != NULL)
-	buttonYpos += editboxheight;
-
-    pstart = tbuffer; //dflt_text
-    horizWidth = (dlgwidth - horizWidth) / 2;	/* Now it's X offset */
-    for (i = 0; i < numButtons; i++)
-    {
-	/* get end of this button. */
-	for (	pend = pstart;
-		*pend && (*pend != DLG_BUTTON_SEP);
-		pend++)
-	    ;
-
-	if (*pend)
-	    *pend = '\0';
-
-	/*
-	 * NOTE:
-	 * setting the BS_DEFPUSHBUTTON style doesn't work because Windows sets
-	 * the focus to the first tab-able button and in so doing makes that
-	 * the default!! Grrr.  Workaround: Make the default button the only
-	 * one with WS_TABSTOP style. Means user can't tab between buttons, but
-	 * he/she can use arrow keys.
-	 *
-	 * NOTE (Thore): Setting BS_DEFPUSHBUTTON works fine when it's the
-	 * first one, so I changed the correct button to be this style. This
-	 * is necessary because when an edit box is added, we need a button to
-	 * be default.  The edit box will be the default control, and when the
-	 * user presses enter from the edit box we want the default button to
-	 * be pressed.
-	 */
-	if (vertical)
-	{
-	    p = add_dialog_element(p,
-		    ((i == dfltbutton || dfltbutton < 0) && textfield != NULL
-			    ?  BS_DEFPUSHBUTTON : BS_PUSHBUTTON) | WS_TABSTOP,
-		    PixelToDialogX(DLG_VERT_PADDING_X),
-		    PixelToDialogY(buttonYpos /* TBK */
-				   + 2 * fontHeight * i),
-		    PixelToDialogX(dlgwidth - 2 * DLG_VERT_PADDING_X),
-		    (WORD)(PixelToDialogY(2 * fontHeight) - 1),
-		    (WORD)(IDCANCEL + 1 + i), (BYTE)0x80, pstart);
-	}
-	else
-	{
-	    p = add_dialog_element(p,
-		    ((i == dfltbutton || dfltbutton < 0) && textfield != NULL
-			     ? BS_DEFPUSHBUTTON : BS_PUSHBUTTON) | WS_TABSTOP,
-		    PixelToDialogX(horizWidth + buttonPositions[i]),
-		    PixelToDialogY(buttonYpos), /* TBK */
-		    PixelToDialogX(buttonWidths[i]),
-		    (WORD)(PixelToDialogY(2 * fontHeight) - 1),
-		    (WORD)(IDCANCEL + 1 + i), (BYTE)0x80, pstart);
-	}
-
-	pstart = pend + 1;	/*next button*/
-
-    }
-    *pnumitems += numButtons;
-
-    /* Vim icon */
-    p = add_dialog_element(p, SS_ICON,
-	    PixelToDialogX(dlgPaddingX),
-	    PixelToDialogY(dlgPaddingY),
-	    PixelToDialogX(DLG_ICON_WIDTH),
-	    PixelToDialogY(DLG_ICON_HEIGHT),
-	    DLG_NONBUTTON_CONTROL + 0, (BYTE)0x82,
-	    &dlg_icons[type]);
-
-
-    /* Dialog message */
-    p = add_dialog_element(p, SS_LEFT,
-	    PixelToDialogX(2 * dlgPaddingX + DLG_ICON_WIDTH),
-	    PixelToDialogY(dlgPaddingY),
-	    (WORD)(PixelToDialogX(messageWidth) + 1),
-	    PixelToDialogY(msgheight),
-	    DLG_NONBUTTON_CONTROL + 1, (BYTE)0x82, message);
-
-    /* Edit box */
-    if (textfield != NULL)
-    {
-	p = add_dialog_element(p, ES_LEFT | ES_AUTOHSCROLL | WS_TABSTOP | WS_BORDER,
-		PixelToDialogX(2 * dlgPaddingX),
-		PixelToDialogY(2 * dlgPaddingY + msgheight),
-		PixelToDialogX(dlgwidth - 4 * dlgPaddingX),
-		PixelToDialogY(fontHeight + dlgPaddingY),
-		DLG_NONBUTTON_CONTROL + 2, (BYTE)0x81, textfield);
-	*pnumitems += 1;
-    }
-
-    *pnumitems += 2;
-
-    SelectFont(hdc, oldFont);
-    ReleaseDC(hwnd, hdc);
-    dp = MakeProcInstance((FARPROC)dialog_callback, s_hinst);
-
-
-    /* Let the dialog_callback() function know which button to make default
-     * If we have an edit box, make that the default. We also need to tell
-     * dialog_callback() if this dialog contains an edit box or not. We do
-     * this by setting s_textfield if it does.
-     */
-    if (textfield != NULL)
-    {
-	dialog_default_button = DLG_NONBUTTON_CONTROL + 2;
-	s_textfield = textfield;
-    }
-    else
-    {
-	dialog_default_button = IDCANCEL + 1 + dfltbutton;
-	s_textfield = NULL;
-    }
-
-    /*show the dialog box modally and get a return value*/
-    nchar = DialogBoxIndirect(
-	    s_hinst,
-	    (HGLOBAL) hglbDlgTemp,
-	    s_hwnd,
-	    (DLGPROC)dp);
-
-    FreeProcInstance( dp );
-    GlobalUnlock(hglbDlgTemp);
-    GlobalFree(hglbDlgTemp);
-    vim_free(tbuffer);
-    vim_free(buttonWidths);
-    vim_free(buttonPositions);
-
-
-    return nchar;
-}
-
-/*
- * Put a simple element (basic class) onto a dialog template in memory.
- * return a pointer to where the next item should be added.
- *
- * parameters:
- *  lStyle = additional style flags
- *  x,y = x & y positions IN DIALOG UNITS
- *  w,h = width and height IN DIALOG UNITS
- *  Id	= ID used in messages
- *  clss  = class ID, e.g 0x80 for a button, 0x82 for a static
- *  caption = usually text or resource name
- *
- *  TODO: use the length information noted here to enable the dialog creation
- *  routines to work out more exactly how much memory they need to alloc.
- */
-    static LPWORD
-add_dialog_element(
-    LPWORD p,
-    DWORD lStyle,
-    WORD x,
-    WORD y,
-    WORD w,
-    WORD h,
-    WORD Id,
-    BYTE clss,
-    const char *caption)
-{
-
-    lStyle = lStyle | WS_VISIBLE | WS_CHILD;
-
-    add_word(x);
-    add_word(y);
-    add_word(w);
-    add_word(h);
-    add_word(Id);
-    add_long(lStyle);
-    add_byte(clss);
-    if (((lStyle & SS_ICON) != 0) && (clss == 0x82))
-    {
-	/* Use resource ID */
-	add_byte(0xff);
-	add_byte(*caption);
-    }
-    else
-	add_string(caption);
-
-    add_byte(0);    //# of extra bytes following
-
-
-    return p;
-}
-
-#undef add_byte
-#undef add_string
-#undef add_long
-#undef add_word
-
-#endif /* FEAT_GUI_DIALOG */
-
-    static void
-get_dialog_font_metrics(void)
-{
-    DWORD	    dlgFontSize;
-	dlgFontSize = GetDialogBaseUnits();	/* fall back to big old system*/
-	s_dlgfntwidth = LOWORD(dlgFontSize);
-	s_dlgfntheight = HIWORD(dlgFontSize);
-}
-
-
-#if defined(FEAT_TOOLBAR) || defined(PROTO)
-
-/* cproto fails on missing include files */
-#ifndef PROTO
-# include "gui_w3~1.h"
-#endif
-
-/*
- * Create the toolbar, initially unpopulated.
- *  (just like the menu, there are no defaults, it's all
- *  set up through menu.vim)
- */
-    static void
-initialise_toolbar(void)
-{
-    s_toolbarhwnd = CreateToolbar(
-		    s_hwnd,
-		    WS_CHILD | WS_VISIBLE,
-		    CMD_TB_BASE, /*<vn>*/
-		    31,			//number of images in initial bitmap
-		    s_hinst,
-		    IDR_TOOLBAR1,	// id of initial bitmap
-		    NULL,
-		    0			// initial number of buttons
-		    );
-
-    gui_mch_show_toolbar(vim_strchr(p_go, GO_TOOLBAR) != NULL);
-}
-#endif
-
-#if defined(FEAT_OLE) || defined(FEAT_EVAL) || defined(PROTO)
-/*
- * Make the GUI window come to the foreground.
- */
-    void
-gui_mch_set_foreground(void)
-{
-    if (IsIconic(s_hwnd))
-	 SendMessage(s_hwnd, WM_SYSCOMMAND, SC_RESTORE, 0);
-    SetActiveWindow(s_hwnd);
-}
-#endif
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);
diff --git a/src/gui_w48.c b/src/gui_w48.c
deleted file mode 100644
index eff3f3f..0000000
--- a/src/gui_w48.c
+++ /dev/null
@@ -1,4155 +0,0 @@
-/* vi:set ts=8 sts=4 sw=4:
- *
- * VIM - Vi IMproved		by Bram Moolenaar
- *				GUI support by Robert Webb
- *
- * Do ":help uganda"  in Vim to read copying and usage conditions.
- * Do ":help credits" in Vim to see a list of people who contributed.
- * See README.txt for an overview of the Vim source code.
- */
-/*
- * gui_w48.c:  This file is included in gui_w16.c and gui_w32.c.
- *
- * GUI support for Microsoft Windows (Win16 + Win32 = Win48 :-)
- *
- * The combined efforts of:
- * George V. Reilly <george@reilly.org>
- * Robert Webb
- * Vince Negri
- * ...and contributions from many others
- *
- */
-
-#include "vim.h"
-#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
-#ifdef WIN16
-# include <commdlg.h>
-# include <shellapi.h>
-# ifdef WIN16_3DLOOK
-#  include <ctl3d.h>
-# endif
-#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
-/*
- * Define a few things for generating prototypes.  This is just to avoid
- * syntax errors, the defines do not need to be correct.
- */
-# 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;
-#ifndef WIN16 /*<VN>*/
-    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;
-    }
-#endif
-    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);
-#ifndef WIN16 /*<VN>*/
-	HANDLE_MSG(hwnd, WM_XBUTTONDBLCLK,_OnMouseButtonDown);
-	HANDLE_MSG(hwnd, WM_XBUTTONDOWN,_OnMouseButtonDown);
-	HANDLE_MSG(hwnd, WM_XBUTTONUP,	_OnMouseMoveOrRelease);
-#endif
-
-#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
-#ifndef MSWIN16_FASTTEXT
-				+ p_linespace
-#endif
-				;
-
-    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))
-    {
-#ifdef WIN16
-	rParent.left = 0;
-	rParent.top = 0;
-	rParent.right = GetSystemMetrics(SM_CXSCREEN);
-	rParent.bottom = GetSystemMetrics(SM_CYFULLSCREEN);
-#else
-	SystemParametersInfo(SPI_GETWORKAREA, 0, &rParent, 0);
-#endif
-    }
-    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)
-{
-#ifdef WIN16_3DLOOK
-    Ctl3dUnregister(s_hinst);
-#endif
-    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
- */
-#ifdef WIN16
-    static BOOL
-#else
-    static LRESULT
-#endif
-_OnActivateApp(
-    HWND hwnd,
-    BOOL fActivate,
-#ifdef WIN16
-    HTASK dwThreadId
-#else
-    DWORD dwThreadId
-#endif
-	)
-{
-    /* 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;
-	}
-#ifndef MSWIN16_FASTTEXT
-	if (lf.lfItalic)
-	    STRCAT(p, ":i");
-	if (lf.lfWeight >= FW_BOLD)
-	    STRCAT(p, ":b");
-#endif
-	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)
-{
-# ifndef MSWIN16_FASTTEXT
-    LOGFONT lf;
-# endif
-
-# ifdef FEAT_MBYTE_IME
-    update_im_font();
-# endif
-
-# ifndef MSWIN16_FASTTEXT
-    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
-}
-#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);
-    }
-
-#ifndef MSWIN16_FASTTEXT
-    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);
-	}
-    }
-#endif
-
-    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;
-}
diff --git a/src/guiw16rc.h b/src/guiw16rc.h
deleted file mode 100644
index 1e55200..0000000
--- a/src/guiw16rc.h
+++ /dev/null
@@ -1,17 +0,0 @@
-
-#define	IDR_VIM 150
-
-#define IDR_VIM_ERROR	151
-#define IDR_VIM_ALERT	152
-#define IDR_VIM_INFO	153
-#define IDR_VIM_QUESTION 154
-
-#define IDR_ICOBUDDYBASE			200
-
-#define IDR_ICOBUDDY_DEF1			(IDR_ICOBUDDYBASE + 3)
-#define IDR_ICOBUDDY_DEF2			(IDR_ICOBUDDYBASE + 0)
-#define IDR_ICOBUDDY_DEF3			(IDR_ICOBUDDYBASE + 1)
-#define IDR_ICOBUDDY_DEF4			(IDR_ICOBUDDYBASE + 2)
-
-#define IDR_ICOBUDDY_GRIN			(IDR_ICOBUDDYBASE + 4)
-#define IDR_ICOBUDDY_ALARM			(IDR_ICOBUDDYBASE + 5)
diff --git a/src/misc2.c b/src/misc2.c
index 7f33ffa..9cfb118 100644
--- a/src/misc2.c
+++ b/src/misc2.c
@@ -1400,7 +1400,7 @@
     length = (unsigned)STRLEN(string) + 3;  /* two quotes and a trailing NUL */
     for (p = string; *p != NUL; mb_ptr_adv(p))
     {
-# if defined(WIN32) || defined(WIN16) || defined(DOS)
+# if defined(WIN32) || defined(DOS)
 	if (!p_ssl)
 	{
 	    if (*p == '"')
@@ -1431,7 +1431,7 @@
 	d = escaped_string;
 
 	/* add opening quote */
-# if defined(WIN32) || defined(WIN16) || defined(DOS)
+# if defined(WIN32) || defined(DOS)
 	if (!p_ssl)
 	    *d++ = '"';
 	else
@@ -1440,7 +1440,7 @@
 
 	for (p = string; *p != NUL; )
 	{
-# if defined(WIN32) || defined(WIN16) || defined(DOS)
+# if defined(WIN32) || defined(DOS)
 	    if (!p_ssl)
 	    {
 		if (*p == '"')
@@ -1483,7 +1483,7 @@
 	}
 
 	/* add terminating quote and finish with a NUL */
-# if defined(WIN32) || defined(WIN16) || defined(DOS)
+# if defined(WIN32) || defined(DOS)
 	if (!p_ssl)
 	    *d++ = '"';
 	else
diff --git a/src/option.c b/src/option.c
index 6554fcd..6645cb2 100644
--- a/src/option.c
+++ b/src/option.c
@@ -2296,14 +2296,10 @@
 # if defined(MSDOS)
 			    (char_u *)"command",
 # else
-#  if defined(WIN16)
-			    (char_u *)"command.com",
-#  else
-#   if defined(WIN3264)
+#  if defined(WIN3264)
 			    (char_u *)"",	/* set in set_init_1() */
-#   else
+#  else
 			    (char_u *)"sh",
-#   endif
 #  endif
 # endif
 #endif /* VMS */
@@ -2367,7 +2363,7 @@
     {"shellxescape", "sxe", P_STRING|P_VI_DEF|P_SECURE,
 			    (char_u *)&p_sxe, PV_NONE,
 			    {
-#if defined(MSDOS) || defined(WIN16) || defined(WIN3264)
+#if defined(MSDOS) || defined(WIN3264)
 			    (char_u *)"\"&|<>()@^",
 #else
 			    (char_u *)"",
diff --git a/src/os_msdos.c b/src/os_msdos.c
index 840f654..5596e34 100644
--- a/src/os_msdos.c
+++ b/src/os_msdos.c
@@ -28,12 +28,6 @@
 # include <conio.h>
 #endif
 
-/*
- * MS-DOS only code, not used for Win16.
- */
-#ifndef WIN16
-
-
 #ifndef PROTO
 # include <bios.h>
 # ifdef DJGPP
@@ -2850,11 +2844,6 @@
 #endif	/* FEAT_CLIPBOARD */
 #endif /* DJGPP */
 
-/*
- * End of MS-DOS only code
- */
-#endif /* WIN16 */
-
 /* common MS-DOS and Win16 code follows */
 
     static int
diff --git a/src/os_mswin.c b/src/os_mswin.c
index 3a5922b..46b3780 100644
--- a/src/os_mswin.c
+++ b/src/os_mswin.c
@@ -10,28 +10,11 @@
 /*
  * os_mswin.c
  *
- * Routines common to both Win16 and Win32.
+ * Routines for Win32.
  */
 
-#ifdef WIN16
-# ifdef __BORLANDC__
-#  pragma warn -par
-#  pragma warn -ucp
-#  pragma warn -use
-#  pragma warn -aus
-# endif
-#endif
-
 #include "vim.h"
 
-#ifdef WIN16
-# define SHORT_FNAME		/* always 8.3 file name */
-/* cproto fails on missing include files */
-# ifndef PROTO
-#  include <dos.h>
-# endif
-# include <string.h>
-#endif
 #include <sys/types.h>
 #include <signal.h>
 #include <limits.h>
@@ -904,7 +887,6 @@
 typedef int (*MYINTPROCINT)(int);
 # endif
 
-# ifndef WIN16
 /*
  * Check if a pointer points to a valid NUL terminated string.
  * Return the length of the string, including terminating NUL.
@@ -944,7 +926,6 @@
 
     return 0;
 }
-# endif
 
 /*
  * Passed to do_in_runtimepath() to load a vim.ico file.
@@ -991,11 +972,7 @@
     BOOL fRunTimeLinkSuccess = FALSE;
 
     // Get a handle to the DLL module.
-# ifdef WIN16
-    hinstLib = LoadLibrary(libname);
-# else
     hinstLib = vimLoadLib((char *)libname);
-# endif
 
     // If the handle is valid, try to get the function address.
     if (hinstLib != NULL)
@@ -1034,15 +1011,7 @@
 	if (string_result == NULL)
 	    *number_result = retval_int;
 	else if (retval_str != NULL
-# ifdef WIN16
-		&& retval_str != (char_u *)1
-		&& retval_str != (char_u *)-1
-		&& !IsBadStringPtr(retval_str, INT_MAX)
-		&& (len = strlen(retval_str) + 1) > 0
-# else
-		&& (len = check_str_len(retval_str)) > 0
-# endif
-		)
+		&& (len = check_str_len(retval_str)) > 0)
 	{
 	    *string_result = lalloc((long_u)len, TRUE);
 	    if (*string_result != NULL)
@@ -1184,9 +1153,6 @@
 
 #if (defined(FEAT_PRINTER) && !defined(FEAT_POSTSCRIPT)) || defined(PROTO)
 
-# ifdef WIN16
-#  define TEXT(a) a
-# endif
 /*=================================================================
  * Win32 printer stuff
  */
@@ -1211,7 +1177,7 @@
 #define IDC_PRINTTEXT2		402
 #define IDC_PROGRESS		403
 
-#if !defined(FEAT_MBYTE) || defined(WIN16)
+#if !defined(FEAT_MBYTE)
 # define vimSetDlgItemText(h, i, s) SetDlgItemText(h, i, s)
 #else
     static BOOL
@@ -1456,23 +1422,13 @@
     int		dvoff;
     int		rev_offset;
     int		dpi;
-#ifdef WIN16
-    POINT	pagesize;
-#endif
 
     GetTextMetrics(prt_dlg.hDC, &prt_tm);
     prt_line_height = prt_tm.tmHeight + prt_tm.tmExternalLeading;
 
     hr	    = GetDeviceCaps(prt_dlg.hDC, HORZRES);
-#ifdef WIN16
-    Escape(prt_dlg.hDC, GETPHYSPAGESIZE, NULL, NULL, &pagesize);
-    phyw    = pagesize.x;
-    Escape(prt_dlg.hDC, GETPRINTINGOFFSET, NULL, NULL, &pagesize);
-    dvoff   = pagesize.x;
-#else
     phyw    = GetDeviceCaps(prt_dlg.hDC, PHYSICALWIDTH);
     dvoff   = GetDeviceCaps(prt_dlg.hDC, PHYSICALOFFSETX);
-#endif
     dpi	    = GetDeviceCaps(prt_dlg.hDC, LOGPIXELSX);
 
     rev_offset = phyw - (dvoff + hr);
@@ -1501,20 +1457,10 @@
     int rev_offset;
     int	bottom_margin;
     int	dpi;
-#ifdef WIN16
-    POINT pagesize;
-#endif
 
     vr	    = GetDeviceCaps(prt_dlg.hDC, VERTRES);
-#ifdef WIN16
-    Escape(prt_dlg.hDC, GETPHYSPAGESIZE, NULL, NULL, &pagesize);
-    phyw    = pagesize.y;
-    Escape(prt_dlg.hDC, GETPRINTINGOFFSET, NULL, NULL, &pagesize);
-    dvoff   = pagesize.y;
-#else
     phyw    = GetDeviceCaps(prt_dlg.hDC, PHYSICALHEIGHT);
     dvoff   = GetDeviceCaps(prt_dlg.hDC, PHYSICALOFFSETY);
-#endif
     dpi	    = GetDeviceCaps(prt_dlg.hDC, LOGPIXELSY);
 
     rev_offset = phyw - (dvoff + vr);
@@ -1741,12 +1687,6 @@
 
 	if (err)
 	{
-#ifdef WIN16
-	    char buf[20];
-
-	    sprintf(buf, "%ld", err);
-	    EMSG2(_("E238: Print error: %s"), buf);
-#else
 	    char_u *buf;
 
 	    /* I suspect FormatMessage() doesn't work for values returned by
@@ -1758,7 +1698,6 @@
 	    EMSG2(_("E238: Print error: %s"),
 				  buf == NULL ? (char_u *)_("Unknown") : buf);
 	    LocalFree((LPVOID)(buf));
-#endif
 	}
 	else
 	    msg_clr_eos(); /* Maybe canceled */
@@ -1778,11 +1717,7 @@
 
     hDlgPrint = CreateDialog(GetModuleHandle(NULL), TEXT("PrintDlgBox"),
 					     prt_dlg.hwndOwner, PrintDlgProc);
-#ifdef WIN16
-    Escape(prt_dlg.hDC, SETABORTPROC, 0, (LPSTR)AbortProc, NULL);
-#else
     SetAbortProc(prt_dlg.hDC, AbortProc);
-#endif
     wsprintf(szBuffer, _("Printing '%s'"), gettail(psettings->jobname));
     vimSetDlgItemText(hDlgPrint, IDC_PRINTTEXT1, (char_u *)szBuffer);
 
@@ -1845,10 +1780,10 @@
     int
 mch_print_text_out(char_u *p, int len)
 {
-#if defined(FEAT_PROPORTIONAL_FONTS) || (defined(FEAT_MBYTE) && !defined(WIN16))
+#if defined(FEAT_PROPORTIONAL_FONTS) || defined(FEAT_MBYTE)
     SIZE	sz;
 #endif
-#if defined(FEAT_MBYTE) && !defined(WIN16)
+#if defined(FEAT_MBYTE)
     WCHAR	*wp = NULL;
     int		wlen = len;
 
@@ -1888,20 +1823,12 @@
     return (prt_pos_x + prt_left_margin + prt_tm.tmAveCharWidth
 				     + prt_tm.tmOverhang > prt_right_margin);
 #else
-# ifdef WIN16
-    GetTextExtentPoint(prt_dlg.hDC, (LPCSTR)p, len, &sz);
-# else
     GetTextExtentPoint32(prt_dlg.hDC, (LPCSTR)p, len, &sz);
-# endif
     prt_pos_x += (sz.cx - prt_tm.tmOverhang);
     /* This is wrong when printing spaces for a TAB. */
     if (p[len] == NUL)
 	return FALSE;
-# ifdef WIN16
-    GetTextExtentPoint(prt_dlg.hDC, p + len, 1, &sz);
-# else
     GetTextExtentPoint32(prt_dlg.hDC, p + len, 1, &sz);
-# endif
     return (prt_pos_x + prt_left_margin + sz.cx > prt_right_margin);
 #endif
 }
@@ -3027,14 +2954,10 @@
 		lf->lfWidth = points_to_pixels(p, &p, FALSE, (long_i)printer_dc);
 		break;
 	    case 'b':
-#ifndef MSWIN16_FASTTEXT
 		lf->lfWeight = FW_BOLD;
-#endif
 		break;
 	    case 'i':
-#ifndef MSWIN16_FASTTEXT
 		lf->lfItalic = TRUE;
-#endif
 		break;
 	    case 'u':
 		lf->lfUnderline = TRUE;
diff --git a/src/os_win16.c b/src/os_win16.c
deleted file mode 100644
index 92367ee..0000000
--- a/src/os_win16.c
+++ /dev/null
@@ -1,427 +0,0 @@
-/* vi:set ts=8 sts=4 sw=4:
- *
- * VIM - Vi IMproved	by Bram Moolenaar
- *
- * Do ":help uganda"  in Vim to read copying and usage conditions.
- * Do ":help credits" in Vim to see a list of people who contributed.
- * See README.txt for an overview of the Vim source code.
- */
-/*
- * os_win16.c
- *
- * Win16 (Windows 3.1x) system-dependent routines.
- * Carved brutally from os_win32.c by Vince Negri <vn@aslnet.co.uk>
- */
-#ifdef __BORLANDC__
-# pragma warn -par
-# pragma warn -ucp
-# pragma warn -use
-# pragma warn -aus
-# pragma warn -obs
-#endif
-
-#include "vim.h"
-
-/* cproto fails on missing include files */
-#ifndef PROTO
-# include <dos.h>
-#endif
-
-#include <string.h>
-#include <sys/types.h>
-#include <signal.h>
-#include <limits.h>
-
-#ifndef PROTO
-# include <process.h>
-
-# undef chdir
-# include <direct.h>
-# include <shellapi.h>	/* required for FindExecutable() */
-#endif
-
-
-/* Record all output and all keyboard & mouse input */
-/* #define MCH_WRITE_DUMP */
-
-#ifdef MCH_WRITE_DUMP
-FILE* fdDump = NULL;
-#endif
-
-
-/*
- * When generating prototypes for Win32 on Unix, these lines make the syntax
- * errors disappear.  They do not need to be correct.
- */
-#ifdef PROTO
-typedef int HANDLE;
-typedef int SMALL_RECT;
-typedef int COORD;
-typedef int SHORT;
-typedef int WORD;
-typedef int DWORD;
-typedef int BOOL;
-typedef int LPSTR;
-typedef int LPTSTR;
-typedef int KEY_EVENT_RECORD;
-typedef int MOUSE_EVENT_RECORD;
-# define WINAPI
-typedef int CONSOLE_CURSOR_INFO;
-typedef char * LPCSTR;
-# define WINBASEAPI
-typedef int INPUT_RECORD;
-# define _cdecl
-#endif
-
-#ifdef __BORLANDC__
-/* being a more ANSI compliant compiler, BorlandC doesn't define _stricoll:
- * but it does in BC 5.02! */
-# if __BORLANDC__ < 0x502
-int _stricoll(char *a, char *b);
-# endif
-#endif
-
-/* cproto doesn't create a prototype for main() */
-int _cdecl
-VimMain
-    (int argc, char **argv);
-static int (_cdecl *pmain)(int, char **);
-
-#ifndef PROTO
-void _cdecl SaveInst(HINSTANCE hInst);
-static void (_cdecl *pSaveInst)(HINSTANCE);
-
-int WINAPI
-WinMain(
-    HINSTANCE	hInstance,
-    HINSTANCE	hPrevInst,
-    LPSTR	lpszCmdLine,
-    int		nCmdShow)
-{
-    int		argc;
-    char	**argv;
-    char	*tofree;
-    char	prog[256];
-
-    /*
-     * Ron: added full path name so that the $VIM variable will get set to our
-     * startup path (so the .vimrc file can be found w/o a VIM env. var.)
-     * Remove the ".exe" extension, and find the 1st non-space.
-     */
-    GetModuleFileName(hInstance, prog, 255);
-    if (*prog != NUL)
-	exe_name = FullName_save((char_u *)prog, FALSE);
-
-    /* Separate the command line into arguments. */
-    argc = get_cmd_args(prog, (char *)lpszCmdLine, &argv, &tofree);
-    if (argc == 0)
-    {
-	/* Error message? */
-	return 0;
-    }
-
-    pSaveInst = SaveInst;
-    pmain = VimMain;
-    pSaveInst(hInstance);
-    pmain(argc, argv);
-
-    free(argv);
-    if (tofree != NULL)
-	free(tofree);
-
-    return 0;
-}
-#endif
-
-
-
-
-
-
-#ifdef FEAT_MOUSE
-
-/*
- * For the GUI the mouse handling is in gui_w32.c.
- */
-    void
-mch_setmouse(
-    int on)
-{
-}
-#endif /* FEAT_MOUSE */
-
-
-
-/*
- * GUI version of mch_init().
- */
-    void
-mch_init(void)
-{
-    extern int _fmode;
-
-
-    /* Let critical errors result in a failure, not in a dialog box.  Required
-     * for the timestamp test to work on removed floppies. */
-    SetErrorMode(SEM_FAILCRITICALERRORS);
-
-    _fmode = O_BINARY;		/* we do our own CR-LF translation */
-
-    /* Specify window size.  Is there a place to get the default from? */
-    Rows = 25;
-    Columns = 80;
-
-
-    set_option_value((char_u *)"grepprg", 0, (char_u *)"grep -n", 0);
-
-#ifdef FEAT_CLIPBOARD
-    clip_init(TRUE);
-
-    /*
-     * Vim's own clipboard format recognises whether the text is char, line,
-     * or rectangular block.  Only useful for copying between two Vims.
-     * "VimClipboard" was used for previous versions, using the first
-     * character to specify MCHAR, MLINE or MBLOCK.
-     */
-    clip_star.format = RegisterClipboardFormat("VimClipboard2");
-    clip_star.format_raw = RegisterClipboardFormat("VimRawBytes");
-#endif
-}
-
-
-
-/*
- * Do we have an interactive window?
- */
-    int
-mch_check_win(
-    int argc,
-    char **argv)
-{
-    return OK;	    /* GUI always has a tty */
-}
-
-
-/*
- * return process ID
- */
-    long
-mch_get_pid(void)
-{
-    return (long)GetCurrentTask();
-}
-
-
-/*
- * Specialised version of system().
- * This version proceeds as follows:
- *    1. Start the program with WinExec
- *    2. Wait for the module use count of the program to go to 0
- *	 (This is the best way of detecting the program has finished)
- */
-
-    static int
-mch_system(char *cmd, int options)
-{
-    DWORD		ret = 0;
-    UINT		wShowWindow;
-    UINT		h_module;
-    MSG			msg;
-    BOOL		again = TRUE;
-
-    /*
-     * It's nicer to run a filter command in a minimized window, but in
-     */
-    if (options & SHELL_DOOUT)
-	wShowWindow = SW_SHOWMINIMIZED;
-    else
-	wShowWindow = SW_SHOWNORMAL;
-
-    /* Now, run the command */
-    h_module = WinExec((LPCSTR)cmd, wShowWindow);
-
-    if (h_module < 32)
-    {
-	/*error*/
-	ret = -h_module;
-    }
-    else
-    {
-	/* Wait for the command to terminate before continuing */
-	while (GetModuleUsage((HINSTANCE)h_module) > 0 && again )
-	{
-	    while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) && again)
-	    {
-		if (msg.message == WM_QUIT)
-
-		{
-		    PostQuitMessage(msg.wParam);
-		    again = FALSE;
-		}
-		TranslateMessage(&msg);
-		DispatchMessage(&msg);
-	    }
-	}
-    }
-
-    return ret;
-}
-
-/*
- * Either execute a command by calling the shell or start a new shell
- */
-    int
-mch_call_shell(
-    char_u *cmd,
-    int options)	    /* SHELL_, see vim.h */
-{
-    int		x;
-    int		tmode = cur_tmode;
-
-    out_flush();
-
-
-#ifdef MCH_WRITE_DUMP
-    if (fdDump)
-    {
-	fprintf(fdDump, "mch_call_shell(\"%s\", %d)\n", cmd, options);
-	fflush(fdDump);
-    }
-#endif
-
-    /*
-     * Catch all deadly signals while running the external command, because a
-     * CTRL-C, Ctrl-Break or illegal instruction  might otherwise kill us.
-     */
-    signal(SIGINT, SIG_IGN);
-    signal(SIGILL, SIG_IGN);
-    signal(SIGFPE, SIG_IGN);
-    signal(SIGSEGV, SIG_IGN);
-    signal(SIGTERM, SIG_IGN);
-    signal(SIGABRT, SIG_IGN);
-
-    if (options & SHELL_COOKED)
-	settmode(TMODE_COOK);	/* set to normal mode */
-
-    if (cmd == NULL)
-    {
-	x = mch_system(p_sh, options);
-    }
-    else
-    {
-	/* we use "command" or "cmd" to start the shell; slow but easy */
-	char_u *newcmd;
-
-	newcmd = lalloc(
-		STRLEN(p_sh) + STRLEN(p_shcf) + STRLEN(cmd) + 10, TRUE);
-	if (newcmd != NULL)
-	{
-	    if (STRNICMP(cmd, "start ", 6) == 0)
-	    {
-		sprintf((char *)newcmd, "%s\0", cmd+6);
-		if (WinExec((LPCSTR)newcmd, SW_SHOWNORMAL) > 31)
-		    x = 0;
-		else
-		    x = -1;
-	    }
-	    else
-	    {
-		sprintf((char *)newcmd, "%s%s %s %s",
-			"",
-			p_sh,
-			p_shcf,
-			cmd);
-		x = mch_system((char *)newcmd, options);
-	    }
-	    vim_free(newcmd);
-	}
-    }
-
-    if (tmode == TMODE_RAW)
-	settmode(TMODE_RAW);	/* set to raw mode */
-
-    if (x && !(options & SHELL_SILENT) && !emsg_silent)
-    {
-	smsg(_("shell returned %d"), x);
-	msg_putchar('\n');
-    }
-#ifdef FEAT_TITLE
-    resettitle();
-#endif
-
-    signal(SIGINT, SIG_DFL);
-    signal(SIGILL, SIG_DFL);
-    signal(SIGFPE, SIG_DFL);
-    signal(SIGSEGV, SIG_DFL);
-    signal(SIGTERM, SIG_DFL);
-    signal(SIGABRT, SIG_DFL);
-
-
-    return x;
-}
-
-
-/*
- * Delay for half a second.
- */
-    void
-mch_delay(
-    long    msec,
-    int	    ignoreinput)
-{
-#ifdef MUST_FIX
-    Sleep((int)msec);	    /* never wait for input */
-#endif
-}
-
-
-/*
- * check for an "interrupt signal": CTRL-break or CTRL-C
- */
-    void
-mch_breakcheck(void)
-{
-    /* never used */
-}
-
-
-/*
- * How much memory is available in Kbyte?
- */
-    long_u
-mch_avail_mem(
-    int special)
-{
-    return GetFreeSpace(0) >> 10;
-}
-
-
-/*
- * Like rename(), returns 0 upon success, non-zero upon failure.
- * Should probably set errno appropriately when errors occur.
- */
-    int
-mch_rename(
-    const char	*pszOldFile,
-    const char	*pszNewFile)
-{
-
-    /*
-     * No need to play tricks, this isn't rubbish like Windows 95 <g>
-     */
-    return rename(pszOldFile, pszNewFile);
-
-}
-
-/*
- * Get the default shell for the current hardware platform
- */
-    char*
-default_shell(void)
-{
-    char* psz = NULL;
-
-    psz = "command.com";
-
-    return psz;
-}
diff --git a/src/os_win16.h b/src/os_win16.h
deleted file mode 100644
index 4c26772..0000000
--- a/src/os_win16.h
+++ /dev/null
@@ -1,143 +0,0 @@
-/* vi:set ts=8 sts=4 sw=4:
- *
- * VIM - Vi IMproved	by Bram Moolenaar
- *
- * Do ":help uganda"  in Vim to read copying and usage conditions.
- * Do ":help credits" in Vim to see a list of people who contributed.
- */
-
-/*
- * Win16 (Windows 3.1x) machine-dependent things.
- */
-
-#include "os_dos.h"		/* common MS-DOS and Windows stuff */
-
-#define BINARY_FILE_IO
-#define USE_EXE_NAME		/* use argv[0] for $VIM */
-#define SYNC_DUP_CLOSE		/* sync() a file with dup() and close() */
-#define USE_TERM_CONSOLE
-#define HAVE_STRING_H
-#define HAVE_STRCSPN
-#define HAVE_STRICMP
-#define HAVE_STRNICMP
-#define HAVE_STRFTIME		/* guessed */
-#define HAVE_MEMSET
-#define USE_TMPNAM		/* use tmpnam() instead of mktemp() */
-#define HAVE_LOCALE_H
-#define HAVE_FCNTL_H
-#define HAVE_QSORT
-#define HAVE_ST_MODE		/* have stat.st_mode */
-#define HAVE_MATH_H
-//#define USE_FNAME_CASE	/* adjust case of file names */
-#ifndef FEAT_CLIPBOARD
-# define FEAT_CLIPBOARD		/* include clipboard support */
-#endif
-#if defined(__DATE__) && defined(__TIME__)
-# define HAVE_DATE_TIME
-#endif
-#define HAVE_AVAIL_MEM
-
-#define SHORT_FNAME		/* always 8.3 file name */
-
-#define SMALL_MALLOC		/* 16 bit storage allocation */
-
-#ifdef __BORLANDC__
-# define HAVE_PUTENV		/* at least Bcc 5.2 has it */
-#endif
-
-#ifdef FEAT_GUI_W16
-# define NO_CONSOLE		/* don't included console-only code */
-#endif
-
-/* toupper() is not really broken, but it's very slow.	Probably because of
- * using unicode characters on Windows NT */
-#define BROKEN_TOUPPER
-
-#define FNAME_ILLEGAL "\"*?><|" /* illegal characters in a file name */
-
-#ifndef VIM_SIZEOF_INT
-# define VIM_SIZEOF_INT 2
-#endif
-
-typedef long off_t;
-
-#include <stdlib.h>
-#include <time.h>
-
-/* cproto fails on missing include files */
-#ifndef PROTO
-# include <dos.h>
-# include <dir.h>
-
-# ifndef STRICT
-#  define STRICT
-# endif
-# ifndef COBJMACROS
-#  define COBJMACROS	/* For OLE: Enable "friendlier" access to objects */
-# endif
-# include <windows.h>
-
-#endif /* PROTO */
-
-/*
- *  plenty of memory, use large buffers
- */
-#define CMDBUFFSIZE 1024	/* size of the command processing buffer */
-
-
-#define BASENAMELEN	(MAXPATHL-5)	/* length of base of file name */
-
-#ifndef DFLT_MAXMEM
-# define DFLT_MAXMEM	(256)    /* use up to 256K for a buffer*/
-#endif
-
-#ifndef DFLT_MAXMEMTOT
-# define DFLT_MAXMEMTOT	(5*1024)    /* use up to 5 Mbyte for Vim */
-#endif
-
-/*
- * Some simple debugging macros that look and behave a lot like their
- * namesakes in MFC.
- */
-
-#ifdef _DEBUG
-
-# if defined(_MSC_VER)	&&  (_MSC_VER >= 1000)
-   /* Use the new debugging tools in Visual C++ 4.x */
-#  include <crtdbg.h>
-#  define ASSERT(f) _ASSERT(f)
-# else
-#  include <assert.h>
-#  define ASSERT(f) assert(f)
-# endif
-
-# define TRACE			Trace
-# define TRACE0(sz)		Trace(_T("%s"), _T(sz))
-# define TRACE1(sz, p1)		Trace(_T(sz), p1)
-# define TRACE2(sz, p1, p2)	Trace(_T(sz), p1, p2)
-# define TRACE3(sz, p1, p2, p3) Trace(_T(sz), p1, p2, p3)
-
-/* In debug version, writes trace messages to debug stream */
-void __cdecl
-Trace(char *pszFormat, ...);
-
-#else /* !_DEBUG */
-
-  /* These macros should all compile away to nothing */
-# define ASSERT(f)		((void)0)
-# define TRACE			1 ? (void)0 : printf
-# define TRACE0(sz)
-# define TRACE1(sz, p1)
-# define TRACE2(sz, p1, p2)
-# define TRACE3(sz, p1, p2, p3)
-
-#endif /* !_DEBUG */
-
-
-#define ASSERT_POINTER(p, type) \
-    ASSERT(((p) != NULL)  &&  IsValidAddress((p), sizeof(type), FALSE))
-
-#define ASSERT_NULL_OR_POINTER(p, type) \
-    ASSERT(((p) == NULL)  ||  IsValidAddress((p), sizeof(type), FALSE))
-
-#define mch_setenv(name, val, x) setenv(name, val, x)
diff --git a/src/proto.h b/src/proto.h
index 1f68b21..a7b7838 100644
--- a/src/proto.h
+++ b/src/proto.h
@@ -38,17 +38,9 @@
 # if defined(UNIX) || defined(__EMX__) || defined(VMS)
 #  include "os_unix.pro"
 # endif
-# if defined(MSDOS) || defined(WIN16)
+# if defined(MSDOS)
 #  include "os_msdos.pro"
 # endif
-# ifdef WIN16
-   typedef LPSTR LPWSTR;
-   typedef LPCSTR LPCWSTR;
-   typedef int LPBOOL;
-#  include "os_win16.pro"
-#  include "os_mswin.pro"
-#  include "winclip.pro"
-# endif
 # ifdef WIN3264
 #  include "os_win32.pro"
 #  include "os_mswin.pro"
diff --git a/src/proto/gui_w16.pro b/src/proto/gui_w16.pro
deleted file mode 100644
index 0a0c496..0000000
--- a/src/proto/gui_w16.pro
+++ /dev/null
@@ -1,80 +0,0 @@
-/* gui_w16.c */
-void gui_mch_set_blinking(long wait, long on, long off);
-void gui_mch_stop_blink(void);
-void gui_mch_start_blink(void);
-LRESULT WINAPI vim_WindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
-void gui_mch_new_colors(void);
-void gui_mch_def_colors(void);
-int gui_mch_open(void);
-int gui_mch_get_winpos(int *x, int *y);
-void gui_mch_set_winpos(int x, int y);
-void gui_mch_set_text_area_pos(int x, int y, int w, int h);
-void gui_mch_enable_scrollbar(scrollbar_T *sb, int flag);
-void gui_mch_set_scrollbar_pos(scrollbar_T *sb, int x, int y, int w, int h);
-void gui_mch_create_scrollbar(scrollbar_T *sb, int orient);
-int gui_mch_adjust_charheight(void);
-GuiFont gui_mch_get_font(char_u *name, int giveErrorIfMissing);
-char_u *gui_mch_get_fontname(GuiFont font, char_u *name);
-void gui_mch_free_font(GuiFont font);
-guicolor_T gui_mch_get_color(char_u *name);
-int gui_mch_haskey(char_u *name);
-void gui_mch_beep(void);
-void gui_mch_invert_rectangle(int r, int c, int nr, int nc);
-void gui_mch_iconify(void);
-void gui_mch_draw_hollow_cursor(guicolor_T color);
-void gui_mch_draw_part_cursor(int w, int h, guicolor_T color);
-void gui_mch_update(void);
-int gui_mch_wait_for_chars(int wtime);
-void gui_mch_clear_block(int row1, int col1, int row2, int col2);
-void gui_mch_clear_all(void);
-void gui_mch_enable_menu(int flag);
-void gui_mch_set_menu_pos(int x, int y, int w, int h);
-void gui_mch_menu_hidden(vimmenu_T *menu, int hidden);
-void gui_mch_draw_menubar(void);
-long_u gui_mch_get_rgb(guicolor_T pixel);
-void gui_mch_activate_window(void);
-void gui_mch_show_toolbar(int showit);
-void gui_mch_show_tabline(int showit);
-int gui_mch_showing_tabline(void);
-void gui_mch_update_tabline(void);
-void gui_mch_set_curtab(int nr);
-void ex_simalt(exarg_T *eap);
-void gui_mch_find_dialog(exarg_T *eap);
-void gui_mch_replace_dialog(exarg_T *eap);
-void gui_mch_mousehide(int hide);
-void gui_mch_destroy_scrollbar(scrollbar_T *sb);
-void gui_mch_getmouse(int *x, int *y);
-void gui_mch_setmouse(int x, int y);
-void gui_mch_flash(int msec);
-void gui_mch_delete_lines(int row, int num_lines);
-void gui_mch_insert_lines(int row, int num_lines);
-void gui_mch_exit(int rc);
-void gui_mch_wide_font_changed(void);
-int gui_mch_init_font(char_u *font_name, int fontset);
-int gui_mch_maximized(void);
-void gui_mch_newfont(void);
-void gui_mch_settitle(char_u *title, char_u *icon);
-void mch_set_mouse_shape(int shape);
-char_u *gui_mch_browsedir(char_u *title, char_u *initdir);
-char_u *gui_mch_browse(int saving, char_u *title, char_u *dflt, char_u *ext, char_u *initdir, char_u *filter);
-int get_cmd_args(char *prog, char *cmdline, char ***argvp, char **tofree);
-void gui_mch_prepare(int *argc, char **argv);
-int gui_mch_init(void);
-void gui_mch_set_shellsize(int width, int height, int min_width, int min_height, int base_width, int base_height, int direction);
-void gui_mch_set_scrollbar_thumb(scrollbar_T *sb, long val, long size, long max);
-void gui_mch_set_font(GuiFont font);
-void gui_mch_set_fg_color(guicolor_T color);
-void gui_mch_set_bg_color(guicolor_T color);
-void gui_mch_set_sp_color(guicolor_T color);
-void gui_mch_draw_string(int row, int col, char_u *text, int len, int flags);
-void gui_mch_flush(void);
-void gui_mch_get_screen_dimensions(int *screen_w, int *screen_h);
-void gui_mch_add_menu(vimmenu_T *menu, int pos);
-void gui_mch_show_popupmenu(vimmenu_T *menu);
-void gui_make_popup(char_u *path_name, int mouse_pos);
-void gui_mch_add_menu_item(vimmenu_T *menu, int idx);
-void gui_mch_destroy_menu(vimmenu_T *menu);
-void gui_mch_menu_grey(vimmenu_T *menu, int grey);
-int gui_mch_dialog(int type, char_u *title, char_u *message, char_u *buttons, int dfltbutton, char_u *textfield, int ex_cmd);
-void gui_mch_set_foreground(void);
-/* vim: set ft=c : */
diff --git a/src/version.c b/src/version.c
index d2ae1ae..38d6a1d 100644
--- a/src/version.c
+++ b/src/version.c
@@ -748,6 +748,8 @@
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    1364,
+/**/
     1363,
 /**/
     1362,
@@ -3638,9 +3640,6 @@
 #  endif
 # endif
 #endif
-#ifdef WIN16
-    MSG_PUTS(_("\nMS-Windows 16-bit version"));
-#endif
 #ifdef MSDOS
 # ifdef DJGPP
     MSG_PUTS(_("\n32-bit MS-DOS version"));
diff --git a/src/vim.h b/src/vim.h
index 52eebab..97155d2 100644
--- a/src/vim.h
+++ b/src/vim.h
@@ -27,7 +27,7 @@
 # endif
 #endif
 
-#if defined(MSDOS) || defined(WIN16) || defined(WIN32) || defined(_WIN64) \
+#if defined(MSDOS) || defined(WIN32) || defined(_WIN64) \
 	|| defined(__EMX__)
 # include "vimio.h"
 #endif
@@ -150,7 +150,7 @@
 #if defined(FEAT_GUI_W32) || defined(FEAT_GUI_W16)
 # define FEAT_GUI_MSWIN
 #endif
-#if defined(WIN16) || defined(WIN32) || defined(_WIN64)
+#if defined(WIN32) || defined(_WIN64)
 # define MSWIN
 #endif
 /* Practically everything is common to both Win32 and Win64 */
@@ -308,10 +308,6 @@
 # include "os_msdos.h"
 #endif
 
-#ifdef WIN16
-# include "os_win16.h"
-#endif
-
 #ifdef WIN3264
 # include "os_win32.h"
 #endif
@@ -471,7 +467,7 @@
 # include <sys/stat.h>
 #endif
 
-#if defined(HAVE_ERRNO_H) || defined(DJGPP) || defined(WIN16) \
+#if defined(HAVE_ERRNO_H) || defined(DJGPP) \
 	|| defined(WIN32) || defined(_WIN64) || defined(__EMX__)
 # include <errno.h>
 #endif
diff --git a/src/vim16.def b/src/vim16.def
deleted file mode 100644
index c982c0f..0000000
--- a/src/vim16.def
+++ /dev/null
@@ -1,5 +0,0 @@
-CODE PRELOAD EXECUTEONLY
-DATA MULTIPLE SHARED
-DESCRIPTION 'Vim 7.4'
-STACKSIZE 16000
-HEAPSIZE 10000
diff --git a/src/vim16.rc b/src/vim16.rc
deleted file mode 100644
index 00395e8..0000000
--- a/src/vim16.rc
+++ /dev/null
@@ -1,81 +0,0 @@
-// vim:ts=8:sw=4:sts=4:
-//
-// VIM - Vi IMproved	by Bram Moolenaar
-//
-// Do ":help uganda"  in Vim to read copying and usage conditions.
-// Do ":help credits" in Vim to see a list of people who contributed.
-
-// vim.rc
-//   Icon and version information for the Win32 version of Vim
-//   Must be in DOS format <CR><NL>!
-
-#include "version.h"
-#include "gui_w3~1.h"
-#include "guiw16rc.h"
-
-//
-// Icons
-//
-IDR_VIM ICON "VIM.ICO"
-
-#ifndef FEAT_TINY
-IDR_VIM_ERROR	ICON "VIM_ER~1.ICO"
-IDR_VIM_ALERT	ICON "VIM_AL~1.ICO"
-IDR_VIM_INFO	ICON "VIM_INFO.ICO"
-IDR_VIM_QUESTION ICON "VIM_QU~1.ICO"
-#endif
-
-//
-// Bitmaps
-//
-#ifdef FEAT_TOOLBAR
-IDR_TOOLBAR1	BITMAP  DISCARDABLE  "tools16.bmp"
-#endif
-//
-// Version
-//
-
-VS_VERSION_INFO		VERSIONINFO
-  FILEVERSION		VIM_VERSION_MAJOR,VIM_VERSION_MINOR,VIM_VERSION_BUILD,VIM_VERSION_PATCHLEVEL
-  PRODUCTVERSION	VIM_VERSION_MAJOR,VIM_VERSION_MINOR,VIM_VERSION_BUILD,VIM_VERSION_PATCHLEVEL
-  FILEFLAGSMASK		VS_FFI_FILEFLAGSMASK
-
-#if VIM_VERSION_PATCHLEVEL > 0
- #ifdef _DEBUG
-  FILEFLAGS		VS_FF_PRERELEASE | VS_FF_DEBUG | VS_FF_PATCHED
- #else
-  FILEFLAGS		VS_FF_PRERELEASE | VS_FF_PATCHED
- #endif
-#else
- #ifdef _DEBUG
-  FILEFLAGS		VS_FF_PRERELEASE | VS_FF_DEBUG
- #else
-  FILEFLAGS		VS_FF_PRERELEASE
- #endif
-#endif
-
-  FILEOS		VOS__WINDOWS32
-  FILETYPE		VFT_APP
-  FILESUBTYPE		0x0L
-BEGIN
-  BLOCK "StringFileInfo"
-  BEGIN
-    // 0x0409 == U.S. English; 0x04E4 => Windows Multilingual
-    BLOCK "040904E4"
-    BEGIN
-	VALUE "CompanyName",		"Vim Developers\0"
-	VALUE "FileDescription",	"Vi Improved - A Text Editor\0"
-	VALUE "FileVersion",		VIM_VERSION_MAJOR_STR ", " VIM_VERSION_MINOR_STR ", " VIM_VERSION_BUILD_STR ", " VIM_VERSION_PATCHLEVEL_STR  "\0"
-	VALUE "InternalName",		"VIM\0"
-	VALUE "LegalCopyright",		"Copyright \251 1996\0"
-	VALUE "LegalTrademarks",	"Vim\0"
-	VALUE "OriginalFilename",	"VIM.EXE\0"
-	VALUE "ProductName",		"Vim\0"
-	VALUE "ProductVersion",		VIM_VERSION_MAJOR_STR ", " VIM_VERSION_MINOR_STR ", " VIM_VERSION_BUILD_STR ", " VIM_VERSION_PATCHLEVEL_STR "\0"
-    END
-  END
-  BLOCK "VarFileInfo"
-  BEGIN
-	VALUE "Translation", 0x409, 0x4E4
-  END
-END
diff --git a/src/winclip.c b/src/winclip.c
index 8ab723f..880e2c6 100644
--- a/src/winclip.c
+++ b/src/winclip.c
@@ -14,15 +14,6 @@
  * Also used by Cygwin, using os_unix.c.
  */
 
-#ifdef WIN16
-# ifdef __BORLANDC__
-#  pragma warn -par
-#  pragma warn -ucp
-#  pragma warn -use
-#  pragma warn -aus
-# endif
-#endif
-
 #include "vimio.h"
 #include "vim.h"
 
