diff --git a/src/gui_w16.c b/src/gui_w16.c
new file mode 100644
index 0000000..e6aa850
--- /dev/null
+++ b/src/gui_w16.c
@@ -0,0 +1,1524 @@
+/* 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.
+ *
+ */
+
+/*
+ * 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);
+    }
+
+    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)
+	    {
+		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)
+{
+    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 posision of our window */
+    wndpl.length = sizeof(WINDOWPLACEMENT);
+    GetWindowPlacement(s_hwnd, &wndpl);
+    if (wndpl.showCmd == SW_SHOWNORMAL)
+    {
+	win_xpos = wndpl.rcNormalPosition.left;
+	win_ypos = wndpl.rcNormalPosition.top;
+    }
+    else
+    {
+	win_xpos = workarea_rect.left;
+	win_ypos = workarea_rect.top;
+    }
+
+    /* compute the size of the outside of the window */
+    win_width = width + GetSystemMetrics(SM_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 (win_xpos + win_width > workarea_rect.right)
+	win_xpos = workarea_rect.right - win_width;
+
+    if (win_xpos < workarea_rect.left)
+	win_xpos = workarea_rect.left;
+
+    if (win_ypos + win_height > workarea_rect.bottom)
+	win_ypos = workarea_rect.bottom - win_height;
+
+    if (win_ypos < workarea_rect.top)
+	win_ypos = workarea_rect.top;
+
+    /* set window position */
+    SetWindowPos(s_hwnd, NULL, win_xpos, win_ypos, win_width, win_height,
+		 SWP_NOZORDER | SWP_NOACTIVATE);
+
+#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);
+}
+
+
+
+    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)
+	{
+	    int cell_len = 0;
+
+	    /* Compute the length in display cells. */
+	    for (n = 0; n < len; n += MB_BYTE2LEN(text[n]))
+		cell_len += (*mb_ptr2cells)(text + n);
+	    rc.right = FILL_X(col + cell_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);
+}
+
+
+
+
+#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)
+{
+    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 (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)
+{
+    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.  complier 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)
+#include "gui_w3~1.h"
+/*
+ * 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 inital 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
