- allow to save/restore some properties into the registry (like font,
  cursor size...)
- implement the two sets of properties (default & current)
- fixed some bugs mainly in dialog
- enhanced font selection mechanisms,
- added and protected sub-menu for all operations (sysmenu is not
  avail in managed mode)
- better data separation for the backend(s)

diff --git a/programs/wineconsole/dialog.c b/programs/wineconsole/dialog.c
index 04220ac..4861254 100644
--- a/programs/wineconsole/dialog.c
+++ b/programs/wineconsole/dialog.c
@@ -1,28 +1,117 @@
 /* dialog management for wineconsole
+ * USER32 backend
  * (c) 2001 Eric Pouech
  */
 
 #include <stdio.h>
-#include "winecon_private.h"
 #include "commctrl.h"
 #include "prsht.h"
+#include "winecon_user.h"
 
 /* FIXME: so far, part of the code is made in ASCII because the Uncode property sheet functions
  * are not implemented yet
  */
+
+enum WCUSER_ApplyTo {
+    /* Prop sheet CFG */
+    WCUSER_ApplyToCursorSize, 
+    WCUSER_ApplyToHistorySize, WCUSER_ApplyToHistoryMode, WCUSER_ApplyToMenuMask,
+    /* Prop sheet FNT */
+    WCUSER_ApplyToFont, WCUSER_ApplyToAttribute,
+    /* Prop sheep CNF */
+    WCUSER_ApplyToBufferSize, WCUSER_ApplyToWindow
+};
+
 struct dialog_info 
 {
-    struct inner_data*	data;		/* pointer to current winecon info */
-    HWND		hDlg;		/* handle to window dialog */
+    struct config_data* config;         /* pointer to configuration used for dialog box */
+    struct inner_data*	data;	        /* pointer to current winecon info */
+    HWND		hDlg;		/* handle to active propsheet */
     int			nFont;		/* number of font size in size LB */
     struct font_info 
     {
 	TEXTMETRIC		tm;
 	LOGFONT			lf;
     } 			*font;		/* array of nFont. index sync'ed with SIZE LB */
+    void        (*apply)(struct dialog_info*, HWND, enum WCUSER_ApplyTo, DWORD);
 };
 
 /******************************************************************
+ *		WCUSER_ApplyDefault
+ *
+ *
+ */
+static void WCUSER_ApplyDefault(struct dialog_info* di, HWND hDlg, enum WCUSER_ApplyTo apply, DWORD val)
+{
+    switch (apply)
+    {
+    case WCUSER_ApplyToCursorSize:
+    case WCUSER_ApplyToHistorySize:
+    case WCUSER_ApplyToHistoryMode:
+    case WCUSER_ApplyToBufferSize:
+    case WCUSER_ApplyToWindow:
+        /* not saving those for now... */
+        break;
+    case WCUSER_ApplyToMenuMask:
+        di->config->menu_mask = val;
+        break;
+    case WCUSER_ApplyToFont:
+        WCUSER_CopyFont(di->config, &di->font[val].lf);
+        break;
+    case WCUSER_ApplyToAttribute:
+        di->config->def_attr = val;
+        break;
+    }
+    WINECON_RegSave(di->config);
+}
+
+/******************************************************************
+ *		WCUSER_ApplyCurrent
+ *
+ *
+ */
+static void WCUSER_ApplyCurrent(struct dialog_info* di, HWND hDlg, enum WCUSER_ApplyTo apply, DWORD val)
+{
+    switch (apply)
+    {
+    case WCUSER_ApplyToCursorSize:
+        {
+            CONSOLE_CURSOR_INFO cinfo;
+            cinfo.dwSize = val;
+            cinfo.bVisible = di->config->cursor_visible;
+            /* this shall update (through notif) curcfg */
+            SetConsoleCursorInfo(di->data->hConOut, &cinfo);
+        }
+        break;
+    case WCUSER_ApplyToHistorySize:
+        di->config->history_size = val;
+        WINECON_SetHistorySize(di->data->hConIn, val);
+        break;
+    case WCUSER_ApplyToHistoryMode:
+        WINECON_SetHistoryMode(di->data->hConIn, val);
+        break;
+    case WCUSER_ApplyToMenuMask:
+        di->config->menu_mask = val;
+        break;
+    case WCUSER_ApplyToFont:
+        WCUSER_SetFont(di->data, &di->font[val].lf);
+        break;
+    case WCUSER_ApplyToAttribute:
+        di->config->def_attr = val;
+        SetConsoleTextAttribute(di->data->hConOut, val);
+        break;
+    case WCUSER_ApplyToBufferSize:
+        /* this shall update (through notif) curcfg */
+        SetConsoleScreenBufferSize(di->data->hConOut, *(COORD*)val);
+        break;
+    case WCUSER_ApplyToWindow:
+        /* this shall update (through notif) curcfg */
+        SetConsoleWindowInfo(di->data->hConOut, FALSE, (SMALL_RECT*)val);
+        break;
+    }
+}
+
+/******************************************************************
  *		WCUSER_OptionDlgProc
  *
  * Dialog prop for the option property sheet
@@ -38,19 +127,25 @@
 	di = (struct dialog_info*)((PROPSHEETPAGEA*)lParam)->lParam;
 	di->hDlg = hDlg;
 	SetWindowLongA(hDlg, DWL_USER, (DWORD)di);
-	if (di->data->cursor_size < 33)		idc = IDC_OPT_CURSOR_SMALL;
-	else if (di->data->cursor_size < 66)	idc = IDC_OPT_CURSOR_MEDIUM;
-	else					idc = IDC_OPT_CURSOR_LARGE;
+	if (di->config->cursor_size <= 25)	idc = IDC_OPT_CURSOR_SMALL;
+	else if (di->config->cursor_size <= 50)	idc = IDC_OPT_CURSOR_MEDIUM;
+	else				        idc = IDC_OPT_CURSOR_LARGE;
 	SendDlgItemMessage(hDlg, idc, BM_SETCHECK, BST_CHECKED, 0L);
 	SetDlgItemInt(hDlg, IDC_OPT_HIST_SIZE, WINECON_GetHistorySize(di->data->hConIn),  FALSE);
 	if (WINECON_GetHistoryMode(di->data->hConIn))
 	    SendDlgItemMessage(hDlg, IDC_OPT_HIST_DOUBLE, BM_SETCHECK, BST_CHECKED, 0L);
+        SendDlgItemMessage(hDlg, IDC_OPT_CONF_CTRL, BM_SETCHECK, 
+                           (di->config->menu_mask & MK_CONTROL) ? BST_CHECKED : BST_UNCHECKED, 0L);
+        SendDlgItemMessage(hDlg, IDC_OPT_CONF_SHIFT, BM_SETCHECK, 
+                           (di->config->menu_mask & MK_SHIFT) ? BST_CHECKED : BST_UNCHECKED, 0L);
 	return FALSE; /* because we set the focus */
     case WM_COMMAND:
 	break;
     case WM_NOTIFY:
     {
 	NMHDR*	nmhdr = (NMHDR*)lParam;
+        DWORD   val;
+        BOOL	done;
 
 	di = (struct dialog_info*)GetWindowLongA(hDlg, DWL_USER);
 	switch (nmhdr->code) 
@@ -67,30 +162,26 @@
 	    else
 		idc = IDC_OPT_CURSOR_LARGE;
 	    PostMessage(hDlg, WM_NEXTDLGCTL, (WPARAM)GetDlgItem(hDlg, idc), TRUE);
+            di->hDlg = hDlg;
 	    break;
 	case PSN_APPLY:
-	{
-	    int		curs_size;
-	    int		hist_size;
-	    BOOL	done;
+	    if (IsDlgButtonChecked(hDlg, IDC_OPT_CURSOR_SMALL) == BST_CHECKED) val = 25;
+	    else if (IsDlgButtonChecked(hDlg, IDC_OPT_CURSOR_MEDIUM) == BST_CHECKED) val = 50;
+	    else val = 99;
+            (di->apply)(di, hDlg, WCUSER_ApplyToCursorSize, val);
 
-	    if (IsDlgButtonChecked(hDlg, IDC_OPT_CURSOR_SMALL) == BST_CHECKED)	curs_size = 33;
-	    else if (IsDlgButtonChecked(hDlg, IDC_OPT_CURSOR_MEDIUM) == BST_CHECKED) curs_size = 66;
-	    else curs_size = 99;
-	    if (curs_size != di->data->cursor_size)
-	    {
-		CONSOLE_CURSOR_INFO cinfo;
-		cinfo.dwSize = curs_size;
-		cinfo.bVisible = di->data->cursor_visible;
-		SetConsoleCursorInfo(di->data->hConOut, &cinfo);
-	    }
-	    hist_size = GetDlgItemInt(hDlg, IDC_OPT_HIST_SIZE, &done, FALSE);
-	    if (done) WINECON_SetHistorySize(di->data->hConIn, hist_size);
-	    SetWindowLong(hDlg, DWL_MSGRESULT, PSNRET_NOERROR);
-	    WINECON_SetHistoryMode(di->data->hConIn, 
-				   IsDlgButtonChecked(hDlg, IDC_OPT_HIST_DOUBLE) & BST_CHECKED);
+ 	    val = GetDlgItemInt(hDlg, IDC_OPT_HIST_SIZE, &done, FALSE);
+	    if (done) (di->apply)(di, hDlg, WCUSER_ApplyToHistorySize, val);
+
+	    (di->apply)(di, hDlg, WCUSER_ApplyToHistoryMode, 
+                        IsDlgButtonChecked(hDlg, IDC_OPT_HIST_DOUBLE) & BST_CHECKED);
+
+            val = 0;
+            if (IsDlgButtonChecked(hDlg, IDC_OPT_CONF_CTRL) & BST_CHECKED)  val |= MK_CONTROL;
+            if (IsDlgButtonChecked(hDlg, IDC_OPT_CONF_SHIFT) & BST_CHECKED) val |= MK_SHIFT;
+            (di->apply)(di, hDlg, WCUSER_ApplyToMenuMask, val);
+            SetWindowLong(hDlg, DWL_MSGRESULT, PSNRET_NOERROR);
 	    return TRUE;
-	}
 	default:
 	    return FALSE;
 	}
@@ -112,45 +203,121 @@
     switch (msg)
     {
     case WM_PAINT:
-    {
-	PAINTSTRUCT	ps;
-	int		font_idx;
-	int		size_idx;
-	struct dialog_info*	di;
+        {
+            PAINTSTRUCT	        ps;
+            int		        font_idx;
+            int		        size_idx;
+            struct dialog_info*	di;
+            
+            di = (struct dialog_info*)GetWindowLong(GetParent(hWnd), DWL_USER);
+            BeginPaint(hWnd, &ps);
 
-	di = (struct dialog_info*)GetWindowLong(GetParent(hWnd), DWL_USER);
-	BeginPaint(hWnd, &ps);
-	
-	font_idx = SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_FONT, LB_GETCURSEL, 0L, 0L);
-	size_idx = SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_SIZE, LB_GETCURSEL, 0L, 0L);
-
-	if (font_idx >= 0 && size_idx >= 0 && size_idx < di->nFont)
-	{
-	    HFONT	hFont, hOldFont;
-	    WCHAR	buf1[256];
-	    WCHAR	buf2[256];
-	    int		len1, len2;
-
-	    hFont = CreateFontIndirect(&di->font[size_idx].lf);
-	    len1 = LoadString(GetModuleHandle(NULL), IDS_FNT_PREVIEW_1, 
-			      buf1, sizeof(buf1) / sizeof(WCHAR));
-	    len2 = LoadString(GetModuleHandle(NULL), IDS_FNT_PREVIEW_2,
-			      buf2, sizeof(buf2) / sizeof(WCHAR));
-	    if (hFont && len1)
-	    {
-		hOldFont = SelectObject(ps.hdc, hFont);
-		SetBkColor(ps.hdc, RGB(0x00, 0x00, 0x00));
-		SetTextColor(ps.hdc, RGB(0xFF, 0xFF, 0xFF));
-		TextOut(ps.hdc, 0, 0, buf1, len1);
-		if (len2)
-		    TextOut(ps.hdc, 0, di->font[size_idx].tm.tmHeight, buf2, len2);
-		SelectObject(ps.hdc, hOldFont);
-		DeleteObject(hFont);
-	    }
-	}
-	EndPaint(hWnd, &ps);
-	break;
+            font_idx = SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_FONT, LB_GETCURSEL, 0L, 0L);
+            size_idx = SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_SIZE, LB_GETCURSEL, 0L, 0L);
+            
+            if (font_idx >= 0 && size_idx >= 0 && size_idx < di->nFont)
+            {
+                HFONT	hFont, hOldFont;
+                WCHAR	buf1[256];
+                WCHAR	buf2[256];
+                int	len1, len2;
+                
+                hFont = CreateFontIndirect(&di->font[size_idx].lf);
+                len1 = LoadString(GetModuleHandle(NULL), IDS_FNT_PREVIEW_1, 
+                                  buf1, sizeof(buf1) / sizeof(WCHAR));
+                len2 = LoadString(GetModuleHandle(NULL), IDS_FNT_PREVIEW_2,
+                                  buf2, sizeof(buf2) / sizeof(WCHAR));
+                buf1[len1] = buf2[len2] = 0;
+                if (hFont && len1)
+                {
+                    hOldFont = SelectObject(ps.hdc, hFont);
+                    SetBkColor(ps.hdc, WCUSER_ColorMap[GetWindowLong(GetDlgItem(di->hDlg, IDC_FNT_COLOR_BK), 0)]);
+                    SetTextColor(ps.hdc, WCUSER_ColorMap[GetWindowLong(GetDlgItem(di->hDlg, IDC_FNT_COLOR_FG), 0)]);
+                    TextOut(ps.hdc, 0, 0, buf1, len1);
+                    if (len2)
+                        TextOut(ps.hdc, 0, di->font[size_idx].tm.tmHeight, buf2, len2);
+                    SelectObject(ps.hdc, hOldFont);
+                    DeleteObject(hFont);
+                }
+            }
+            EndPaint(hWnd, &ps);
+        }
+        break;
+    default:
+	return DefWindowProc(hWnd, msg, wParam, lParam);
     }
+    return 0L;
+}
+
+/******************************************************************
+ *		WCUSER_ColorPreviewProc
+ *
+ * Window proc for color previewer in font property sheet
+ */
+static LRESULT WINAPI WCUSER_ColorPreviewProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+    switch (msg)
+    {
+    case WM_PAINT:
+        {
+            PAINTSTRUCT     ps;
+            int             i, step;
+            RECT            client, r;
+            HBRUSH          hbr;
+            
+            BeginPaint(hWnd, &ps);
+            GetClientRect(hWnd, &client);
+            step = client.right / 8;
+            
+            for (i = 0; i < 16; i++)
+            {
+                r.top = (i / 8) * (client.bottom / 2);
+                r.bottom = r.top + client.bottom / 2;
+                r.left = (i & 7) * step;
+                r.right = r.left + step;
+                hbr = CreateSolidBrush(WCUSER_ColorMap[i]);
+                FillRect(ps.hdc, &r, hbr);
+                DeleteObject(hbr);
+                if (GetWindowLong(hWnd, 0) == i)
+                {
+                    HPEN        hOldPen;
+                    int         i = 2;
+
+                    hOldPen = SelectObject(ps.hdc, GetStockObject(WHITE_PEN));
+                    r.right--; r.bottom--;
+                    for (;;)
+                    {
+                        MoveToEx(ps.hdc, r.left, r.bottom, NULL);
+                        LineTo(ps.hdc, r.left, r.top);
+                        LineTo(ps.hdc, r.right, r.top);
+                        SelectObject(ps.hdc, GetStockObject(BLACK_PEN));
+                        LineTo(ps.hdc, r.right, r.bottom);
+                        LineTo(ps.hdc, r.left, r.bottom);
+
+                        if (--i == 0) break;
+                        r.left++; r.top++; r.right--; r.bottom--;
+                        SelectObject(ps.hdc, GetStockObject(WHITE_PEN));
+                    }
+                    SelectObject(ps.hdc, hOldPen);
+                }
+            }
+            EndPaint(hWnd, &ps);
+            break;
+        }
+    case WM_LBUTTONDOWN:
+        {
+            int             i, step;
+            RECT            client;
+            
+            GetClientRect(hWnd, &client);
+            step = client.right / 8;
+            i = (HIWORD(lParam) >= client.bottom / 2) ? 8 : 0;
+            i += LOWORD(lParam) / step;
+            SetWindowLong(hWnd, 0, i);
+            InvalidateRect(GetDlgItem(GetParent(hWnd), IDC_FNT_PREVIEW), NULL, FALSE);
+            InvalidateRect(hWnd, NULL, FALSE);
+        }
+        break;
     default:
 	return DefWindowProc(hWnd, msg, wParam, lParam);
     }
@@ -160,7 +327,7 @@
 /******************************************************************
  *		font_enum
  *
- *
+ * enumerates all the font names with at least one valid font
  */
 static int CALLBACK font_enum_size2(const LOGFONT* lf, const TEXTMETRIC* tm, 
 				    DWORD FontType, LPARAM lParam)
@@ -208,24 +375,44 @@
     if (WCUSER_ValidateFontMetric(di->data, tm))
     {
 	WCHAR	buf[32];
-	WCHAR	fmt[] = {'%','l','d',0};
+        static const WCHAR fmt[] = {'%','l','d',0};
 	int	idx;
 
 	/* we want the string to be sorted with a numeric order, not a lexicographic...
 	 * do the job by hand... get where to insert the new string
 	 */
 	for (idx = 0; idx < di->nFont && tm->tmHeight > di->font[idx].tm.tmHeight; idx++);
-	wsprintfW(buf, fmt, tm->tmHeight);
-	SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_SIZE, LB_INSERTSTRING, idx, (LPARAM)buf);
+        if (idx < di->nFont &&
+            tm->tmHeight == di->font[idx].tm.tmHeight && 
+            tm->tmMaxCharWidth == di->font[idx].tm.tmMaxCharWidth)
+        {
+            /* we already have an entry with the same width & height...
+             * try to see which TEXTMETRIC (old or new) we should keep... 
+             */
+            if (di->font[idx].tm.tmWeight != tm->tmWeight)
+            {
+                /* get the weight closer to 400, the default value */
+                if (abs(tm->tmWeight - 400) < abs(di->font[idx].tm.tmWeight - 400))
+                {
+                    di->font[idx].tm = *tm;
+                }
+            }
+            /* else FIXME: skip the new tm for now */
+        }
+        else
+        {
+            /* here we need to add the new entry */
+            wsprintfW(buf, fmt, tm->tmHeight);
+            SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_SIZE, LB_INSERTSTRING, idx, (LPARAM)buf);
 
-	/* now grow our arrays and insert to values at the same index than in the list box */
-	di->font = HeapReAlloc(GetProcessHeap(), 0, di->font, sizeof(*di->font) * (di->nFont + 1));
-	if (idx != di->nFont)
-	    memmove(&di->font[idx + 1], &di->font[idx], (di->nFont - idx) * sizeof(*di->font));
-	di->font[idx].tm = *tm;
-	di->font[idx].lf = *lf;
-	di->nFont++;
-
+            /* now grow our arrays and insert to values at the same index than in the list box */
+            di->font = HeapReAlloc(GetProcessHeap(), 0, di->font, sizeof(*di->font) * (di->nFont + 1));
+            if (idx != di->nFont)
+                memmove(&di->font[idx + 1], &di->font[idx], (di->nFont - idx) * sizeof(*di->font));
+            di->font[idx].tm = *tm;
+            di->font[idx].lf = *lf;
+            di->nFont++;
+        }
     }
     return 1;
 }
@@ -283,7 +470,7 @@
     {
 	for (idx = 0; idx < di->nFont; idx++)
 	{
-	    if (memcmp(&di->data->logFont, &di->font[idx].lf, sizeof(LOGFONT)) == 0)
+	    if (WCUSER_AreFontsEqual(di->config, &di->font[idx].lf))
 		break;
 	}
 	if (idx == di->nFont) idx = 0;
@@ -311,7 +498,7 @@
     EnumFontFamilies(hdc, NULL, font_enum, (LPARAM)di);
     ReleaseDC(di->hDlg, hdc);
     if (SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_FONT, LB_SELECTSTRING, 
-			   (WPARAM)-1, (LPARAM)di->data->logFont.lfFaceName) == LB_ERR)
+			   (WPARAM)-1, (LPARAM)di->config->face_name) == LB_ERR)
 	SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_FONT, LB_SETCURSEL, 0L, 0L);
     fill_list_size(di, TRUE);
     return TRUE;
@@ -333,6 +520,8 @@
 	di->hDlg = hDlg;
 	SetWindowLong(hDlg, DWL_USER, (DWORD)di);
 	fill_list_font(di);
+        SetWindowLong(GetDlgItem(hDlg, IDC_FNT_COLOR_BK), 0, di->config->def_attr & 0x0F);
+        SetWindowLong(GetDlgItem(hDlg, IDC_FNT_COLOR_FG), 0, (di->config->def_attr >> 4) & 0x0F);
 	break;
     case WM_COMMAND:
 	di = (struct dialog_info*)GetWindowLong(hDlg, DWL_USER);
@@ -355,21 +544,25 @@
     case WM_NOTIFY:
     {
 	NMHDR*	nmhdr = (NMHDR*)lParam;
+        DWORD   val;
 
 	di = (struct dialog_info*)GetWindowLong(hDlg, DWL_USER);
 	switch (nmhdr->code) 
 	{
+        case PSN_SETACTIVE:
+            di->hDlg = hDlg;
+            break;
 	case PSN_APPLY:
-	{
-	    int idx = SendDlgItemMessage(di->hDlg, IDC_FNT_LIST_SIZE, LB_GETCURSEL, 0L, 0L);
+ 	    val = SendDlgItemMessage(hDlg, IDC_FNT_LIST_SIZE, LB_GETCURSEL, 0L, 0L);
 
-	    if (idx >= 0 && idx < di->nFont)
-	    {
-		WCUSER_SetFont(di->data, &di->font[idx].lf, &di->font[idx].tm);
-	    }
-	    SetWindowLong(hDlg, DWL_MSGRESULT, PSNRET_NOERROR);
+	    if (val < di->nFont) (di->apply)(di, hDlg, WCUSER_ApplyToFont, val);
+
+            (di->apply)(di, hDlg, WCUSER_ApplyToAttribute, 
+                        GetWindowLong(GetDlgItem(hDlg, IDC_FNT_COLOR_BK), 0) | 
+                        (GetWindowLong(GetDlgItem(hDlg, IDC_FNT_COLOR_FG), 0) << 4));
+
+            SetWindowLong(hDlg, DWL_MSGRESULT, PSNRET_NOERROR);
 	    return TRUE;
-	}
 	default:
 	    return FALSE;
 	}
@@ -396,10 +589,10 @@
 	di = (struct dialog_info*)((PROPSHEETPAGEA*)lParam)->lParam;
 	di->hDlg = hDlg;
 	SetWindowLong(hDlg, DWL_USER, (DWORD)di);
-	SetDlgItemInt(hDlg, IDC_CNF_SB_WIDTH,   di->data->sb_width,   FALSE);
-	SetDlgItemInt(hDlg, IDC_CNF_SB_HEIGHT,  di->data->sb_height,  FALSE);
-	SetDlgItemInt(hDlg, IDC_CNF_WIN_WIDTH,  di->data->win_width,  FALSE);
-	SetDlgItemInt(hDlg, IDC_CNF_WIN_HEIGHT, di->data->win_height, FALSE);
+	SetDlgItemInt(hDlg, IDC_CNF_SB_WIDTH,   di->config->sb_width,   FALSE);
+	SetDlgItemInt(hDlg, IDC_CNF_SB_HEIGHT,  di->config->sb_height,  FALSE);
+	SetDlgItemInt(hDlg, IDC_CNF_WIN_WIDTH,  di->config->win_width,  FALSE);
+	SetDlgItemInt(hDlg, IDC_CNF_WIN_HEIGHT, di->config->win_height, FALSE);
 	break;
     case WM_COMMAND:
 	di = (struct dialog_info*)GetWindowLong(hDlg, DWL_USER);
@@ -409,37 +602,36 @@
 	break;
     case WM_NOTIFY:
     {
-	NMHDR*	nmhdr = (NMHDR*)lParam;
+	NMHDR*	        nmhdr = (NMHDR*)lParam;
+        COORD           sb;
+        SMALL_RECT	pos;
+        BOOL	        st_w, st_h;
 
 	di = (struct dialog_info*)GetWindowLong(hDlg, DWL_USER);
 	switch (nmhdr->code) 
 	{
+        case PSN_SETACTIVE:
+            di->hDlg = hDlg;
+            break;
 	case PSN_APPLY:
-	{
-	    COORD	sb;
-	    SMALL_RECT	pos;
-	    BOOL	st_w, st_h;
-
-	    sb.X = GetDlgItemInt(hDlg, IDC_CNF_SB_WIDTH,  &st_w, FALSE);
-	    sb.Y = GetDlgItemInt(hDlg, IDC_CNF_SB_HEIGHT, &st_h, FALSE);
-	    if (st_w && st_h && (sb.X != di->data->sb_width || sb.Y != di->data->sb_height))
-	    {
-		SetConsoleScreenBufferSize(di->data->hConOut, sb);
-	    }
-
-	    pos.Right  = GetDlgItemInt(hDlg, IDC_CNF_WIN_WIDTH,  &st_w, FALSE);
-	    pos.Bottom = GetDlgItemInt(hDlg, IDC_CNF_WIN_HEIGHT, &st_h, FALSE);
-	    if (st_w && st_h && 
-		(pos.Right != di->data->win_width || pos.Bottom != di->data->win_height))
-	    {
-		pos.Left = pos.Top = 0;
-		pos.Right--; pos.Bottom--;
-		SetConsoleWindowInfo(di->data->hConOut, FALSE, &pos);
-	    }
-
-	    SetWindowLong(hDlg, DWL_MSGRESULT, PSNRET_NOERROR);
+            sb.X = GetDlgItemInt(hDlg, IDC_CNF_SB_WIDTH,  &st_w, FALSE);
+            sb.Y = GetDlgItemInt(hDlg, IDC_CNF_SB_HEIGHT, &st_h, FALSE);
+            if (st_w && st_h && (sb.X != di->config->sb_width || sb.Y != di->config->sb_height))
+            {
+                (di->apply)(di, hDlg, WCUSER_ApplyToBufferSize, (DWORD)&sb);
+            }
+            
+            pos.Right  = GetDlgItemInt(hDlg, IDC_CNF_WIN_WIDTH,  &st_w, FALSE);
+            pos.Bottom = GetDlgItemInt(hDlg, IDC_CNF_WIN_HEIGHT, &st_h, FALSE);
+            if (st_w && st_h && 
+                (pos.Right != di->config->win_width || pos.Bottom != di->config->win_height))
+            {
+                pos.Left = pos.Top = 0;
+                pos.Right--; pos.Bottom--;
+                (di->apply)(di, hDlg, WCUSER_ApplyToWindow, (DWORD)&pos);
+            }
+            SetWindowLong(hDlg, DWL_MSGRESULT, PSNRET_NOERROR);
 	    return TRUE;
-	}
 	default:
 	    return FALSE;
 	}
@@ -456,18 +648,30 @@
  *
  * Runs the dialog box to set up the winconsole options
  */
-BOOL WCUSER_GetProperties(struct inner_data* data)
+BOOL WCUSER_GetProperties(struct inner_data* data, BOOL current)
 {
     HPROPSHEETPAGE	psPage[3];
     PROPSHEETPAGEA	psp;
     PROPSHEETHEADERA	psHead;
     WNDCLASS		wndclass;
-    static WCHAR	szFntPreview[] = {'W','i','n','e','C','o','n','F','o','n','t','P','r','e','v','i','e','w',0};
+    static const WCHAR szFntPreview[] = {'W','i','n','e','C','o','n','F','o','n','t','P','r','e','v','i','e','w',0};
+    static const WCHAR szColorPreview[] = {'W','i','n','e','C','o','n','C','o','l','o','r','P','r','e','v','i','e','w',0};
     struct dialog_info	di;
+    CHAR		buff[256];
 
     InitCommonControls();
 
     di.data = data;
+    if (current)
+    {
+        di.config = &data->curcfg;
+        di.apply = WCUSER_ApplyCurrent;
+    }
+    else
+    {
+        di.config = &data->defcfg;
+        di.apply = WCUSER_ApplyDefault;
+    }
     di.nFont = 0;
     di.font = NULL;
 
@@ -483,6 +687,18 @@
     wndclass.lpszClassName = szFntPreview;
     RegisterClass(&wndclass);
 
+    wndclass.style         = 0;
+    wndclass.lpfnWndProc   = WCUSER_ColorPreviewProc;
+    wndclass.cbClsExtra    = 0;
+    wndclass.cbWndExtra    = sizeof(DWORD);
+    wndclass.hInstance     = GetModuleHandle(NULL);
+    wndclass.hIcon         = 0;
+    wndclass.hCursor       = LoadCursor(0, IDC_ARROW);
+    wndclass.hbrBackground = GetStockObject(BLACK_BRUSH);
+    wndclass.lpszMenuName  = NULL;
+    wndclass.lpszClassName = szColorPreview;
+    RegisterClass(&wndclass);
+
     memset(&psp, 0, sizeof(psp));
     psp.dwSize = sizeof(psp);
     psp.dwFlags = 0;
@@ -503,9 +719,14 @@
 
     memset(&psHead, 0, sizeof(psHead));
     psHead.dwSize = sizeof(psHead);
-    psHead.pszCaption = "Setup";
+
+    if (!LoadStringA(GetModuleHandle(NULL), 
+                     (current) ? IDS_DLG_TIT_CURRENT : IDS_DLG_TIT_DEFAULT, 
+                     buff, sizeof(buff)))
+        strcpy(buff, "Setup");
+    psHead.pszCaption = buff;
     psHead.nPages = 3;
-    psHead.hwndParent = data->hWnd;
+    psHead.hwndParent = PRIVATE(data)->hWnd;
     psHead.u3.phpage = psPage;
  
     PropertySheetA(&psHead);
@@ -513,3 +734,4 @@
     return TRUE;
 }
 
+