[CONSOLE.CPL][CONSRV]
[reactos.git] / dll / cpl / console / layout.c
index e6fd38e..fac40bb 100644 (file)
@@ -2,8 +2,9 @@
  * PROJECT:         ReactOS Console Configuration DLL
  * LICENSE:         GPL - See COPYING in the top level directory
  * FILE:            dll/win32/console/layout.c
- * PURPOSE:         displays layout dialog
- * PROGRAMMERS:     Johannes Anderwald (johannes.anderwald@student.tugraz.at)
+ * PURPOSE:         Layout dialog
+ * PROGRAMMERS:     Johannes Anderwald (johannes.anderwald@reactos.org)
+ *                  Hermes Belusca-Maito (hermes.belusca@sfr.fr)
  */
 
 #include "console.h"
 #define NDEBUG
 #include <debug.h>
 
-const TCHAR szPreviewText[] =
-    _T("C:\\ReactOS> dir                       \n") \
-    _T("SYSTEM       <DIR>      13-04-15  5:00a\n") \
-    _T("SYSTEM32     <DIR>      13-04-15  5:00a\n") \
-    _T("readme   txt       1739 13-04-15  5:00a\n") \
-    _T("explorer exe    3329536 13-04-15  5:00a\n") \
-    _T("vgafonts cab      18736 13-04-15  5:00a\n") \
-    _T("setuplog txt        313 13-04-15  5:00a\n") \
-    _T("win      ini       7005 13-04-15  5:00a\n");
+const WCHAR szPreviewText[] =
+    L"C:\\ReactOS> dir                       \n" \
+    L"SYSTEM       <DIR>      13-04-15  5:00a\n" \
+    L"SYSTEM32     <DIR>      13-04-15  5:00a\n" \
+    L"readme   txt       1739 13-04-15  5:00a\n" \
+    L"explorer exe    3329536 13-04-15  5:00a\n" \
+    L"vgafonts cab      18736 13-04-15  5:00a\n" \
+    L"setuplog txt        313 13-04-15  5:00a\n" \
+    L"win      ini       7005 13-04-15  5:00a\n" ;
 
 
 VOID
@@ -35,8 +36,10 @@ PaintConsole(LPDRAWITEMSTRUCT drawItem,
 
     FillRect(drawItem->hDC, &drawItem->rcItem, GetSysColorBrush(COLOR_BACKGROUND));
 
-    sizex = drawItem->rcItem.right - drawItem->rcItem.left;
-    sizey = drawItem->rcItem.bottom - drawItem->rcItem.top;
+    // FIXME: Use: SM_CXSIZE, SM_CYSIZE, SM_CXVSCROLL, SM_CYHSCROLL, SM_CXMIN, SM_CYMIN, SM_CXFRAME, SM_CYFRAME
+    /* Use it for scaling */
+    sizex = drawItem->rcItem.right  - drawItem->rcItem.left;
+    sizey = drawItem->rcItem.bottom - drawItem->rcItem.top ;
 
     if ( GuiInfo->WindowOrigin.x == MAXDWORD &&
          GuiInfo->WindowOrigin.y == MAXDWORD )
@@ -48,14 +51,14 @@ PaintConsole(LPDRAWITEMSTRUCT drawItem,
     {
         // TODO:
         // Calculate pos correctly when console centered
-        startx = sizex / 3;
-        starty = sizey / 3;
+        startx = GuiInfo->WindowOrigin.x;
+        starty = GuiInfo->WindowOrigin.y;
     }
 
     // TODO:
-    // Strech console when bold fonts are selected
-    endx = drawItem->rcItem.right - startx + 15;
-    endy = starty + sizey / 3;
+    // Stretch console when bold fonts are selected
+    endx = startx + pConInfo->ci.ConsoleSize.X; // drawItem->rcItem.right - startx + 15;
+    endy = starty + pConInfo->ci.ConsoleSize.Y; // starty + sizey / 3;
 
     /* Draw console size */
     SetRect(&cRect, startx, starty, endx, endy);
@@ -92,39 +95,71 @@ PaintConsole(LPDRAWITEMSTRUCT drawItem,
     DeleteObject((HGDIOBJ)hBrush);
 }
 
-VOID PaintText(LPDRAWITEMSTRUCT drawItem,
-               PCONSOLE_PROPS pConInfo)
+BOOL
+PaintText(LPDRAWITEMSTRUCT drawItem,
+          PCONSOLE_PROPS pConInfo,
+          TEXT_TYPE TextMode)
 {
+    PGUI_CONSOLE_INFO GuiInfo = pConInfo->TerminalInfo.TermInfo;
+    USHORT CurrentAttrib;
     COLORREF pbkColor, ptColor;
     COLORREF nbkColor, ntColor;
-    HBRUSH hBrush = NULL;
+    HBRUSH hBrush;
+    HFONT Font, OldFont;
 
-    if (drawItem->CtlID == IDC_STATIC_SCREEN_COLOR)
-    {
-        nbkColor = pConInfo->ci.Colors[BkgdAttribFromAttrib(pConInfo->ci.ScreenAttrib)];
-        hBrush = CreateSolidBrush(nbkColor);
-        ntColor = pConInfo->ci.Colors[TextAttribFromAttrib(pConInfo->ci.ScreenAttrib)];
-    }
-    else if (drawItem->CtlID == IDC_STATIC_POPUP_COLOR)
+    if (TextMode == Screen)
+        CurrentAttrib = pConInfo->ci.ScreenAttrib;
+    else if (TextMode == Popup)
+        CurrentAttrib = pConInfo->ci.PopupAttrib;
+    else
+        return FALSE;
+
+    nbkColor = pConInfo->ci.Colors[BkgdAttribFromAttrib(CurrentAttrib)];
+    ntColor  = pConInfo->ci.Colors[TextAttribFromAttrib(CurrentAttrib)];
+
+    hBrush = CreateSolidBrush(nbkColor);
+    if (!hBrush) return FALSE;
+
+    Font = CreateFontW(GuiInfo->FontSize.Y,
+                       0, // GuiInfo->FontSize.X,
+                       0,
+                       TA_BASELINE,
+                       GuiInfo->FontWeight,
+                       FALSE,
+                       FALSE,
+                       FALSE,
+                       OEM_CHARSET,
+                       OUT_DEFAULT_PRECIS,
+                       CLIP_DEFAULT_PRECIS,
+                       NONANTIALIASED_QUALITY,
+                       FIXED_PITCH | GuiInfo->FontFamily /* FF_DONTCARE */,
+                       GuiInfo->FaceName);
+    if (Font == NULL)
     {
-        nbkColor = pConInfo->ci.Colors[BkgdAttribFromAttrib(pConInfo->ci.PopupAttrib)];
-        hBrush = CreateSolidBrush(nbkColor);
-        ntColor = pConInfo->ci.Colors[TextAttribFromAttrib(pConInfo->ci.PopupAttrib)];
+        DPRINT1("PaintText: CreateFont failed\n");
+        return FALSE;
     }
 
-    if (!hBrush)
+    OldFont = SelectObject(drawItem->hDC, Font);
+    if (OldFont == NULL)
     {
-        return;
+        DeleteObject(Font);
+        return FALSE;
     }
 
     FillRect(drawItem->hDC, &drawItem->rcItem, hBrush);
 
     ptColor = SetTextColor(drawItem->hDC, ntColor);
     pbkColor = SetBkColor(drawItem->hDC, nbkColor);
-    DrawText(drawItem->hDC, szPreviewText, _tcslen(szPreviewText), &drawItem->rcItem, 0);
+    DrawTextW(drawItem->hDC, szPreviewText, wcslen(szPreviewText), &drawItem->rcItem, 0);
     SetTextColor(drawItem->hDC, ptColor);
     SetBkColor(drawItem->hDC, pbkColor);
     DeleteObject((HGDIOBJ)hBrush);
+
+    SelectObject(drawItem->hDC, OldFont);
+    DeleteObject(Font);
+
+    return TRUE;
 }
 
 INT_PTR
@@ -134,8 +169,6 @@ LayoutProc(HWND hwndDlg,
            WPARAM wParam,
            LPARAM lParam)
 {
-    LPNMUPDOWN lpnmud;
-    LPPSHNOTIFY lppsn;
     PCONSOLE_PROPS pConInfo = (PCONSOLE_PROPS)GetWindowLongPtr(hwndDlg, DWLP_USER);
     PGUI_CONSOLE_INFO GuiInfo = (pConInfo ? pConInfo->TerminalInfo.TermInfo : NULL);
 
@@ -146,57 +179,64 @@ LayoutProc(HWND hwndDlg,
     {
         case WM_INITDIALOG:
         {
-            DWORD xres, yres;
-            HDC hDC;
+            /* Multi-monitor support */
+            LONG  xVirtScr,  yVirtScr; // Coordinates of the top-left virtual screen
+            LONG cxVirtScr, cyVirtScr; // Width and Height of the virtual screen
+            LONG cxFrame  , cyFrame  ; // Thickness of the window frame
+
             pConInfo = (PCONSOLE_PROPS)((LPPROPSHEETPAGE)lParam)->lParam;
             GuiInfo  = pConInfo->TerminalInfo.TermInfo;
             SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pConInfo);
 
-            SendMessage(GetDlgItem(hwndDlg, IDC_UPDOWN_SCREEN_BUFFER_HEIGHT), UDM_SETRANGE, 0, (LPARAM)MAKELONG(9999, 1));
-            SendMessage(GetDlgItem(hwndDlg, IDC_UPDOWN_SCREEN_BUFFER_WIDTH), UDM_SETRANGE, 0, (LPARAM)MAKELONG(9999, 1));
-            SendMessage(GetDlgItem(hwndDlg, IDC_UPDOWN_WINDOW_SIZE_HEIGHT), UDM_SETRANGE, 0, (LPARAM)MAKELONG(9999, 1));
-            SendMessage(GetDlgItem(hwndDlg, IDC_UPDOWN_WINDOW_SIZE_WIDTH), UDM_SETRANGE, 0, (LPARAM)MAKELONG(9999, 1));
+            /* Multi-monitor support */
+            xVirtScr  = GetSystemMetrics(SM_XVIRTUALSCREEN);
+            yVirtScr  = GetSystemMetrics(SM_YVIRTUALSCREEN);
+            cxVirtScr = GetSystemMetrics(SM_CXVIRTUALSCREEN);
+            cyVirtScr = GetSystemMetrics(SM_CYVIRTUALSCREEN);
+            cxFrame   = GetSystemMetrics(SM_CXFRAME);
+            cyFrame   = GetSystemMetrics(SM_CYFRAME);
+
+            SendDlgItemMessageW(hwndDlg, IDC_UPDOWN_SCREEN_BUFFER_HEIGHT, UDM_SETRANGE, 0, (LPARAM)MAKELONG(9999, 1));
+            SendDlgItemMessageW(hwndDlg, IDC_UPDOWN_SCREEN_BUFFER_WIDTH , UDM_SETRANGE, 0, (LPARAM)MAKELONG(9999, 1));
+            SendDlgItemMessageW(hwndDlg, IDC_UPDOWN_WINDOW_SIZE_HEIGHT, UDM_SETRANGE, 0, (LPARAM)MAKELONG(9999, 1));
+            SendDlgItemMessageW(hwndDlg, IDC_UPDOWN_WINDOW_SIZE_WIDTH , UDM_SETRANGE, 0, (LPARAM)MAKELONG(9999, 1));
 
             SetDlgItemInt(hwndDlg, IDC_EDIT_SCREEN_BUFFER_HEIGHT, pConInfo->ci.ScreenBufferSize.Y, FALSE);
-            SetDlgItemInt(hwndDlg, IDC_EDIT_SCREEN_BUFFER_WIDTH, pConInfo->ci.ScreenBufferSize.X, FALSE);
+            SetDlgItemInt(hwndDlg, IDC_EDIT_SCREEN_BUFFER_WIDTH , pConInfo->ci.ScreenBufferSize.X, FALSE);
             SetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_SIZE_HEIGHT, pConInfo->ci.ConsoleSize.Y, FALSE);
-            SetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_SIZE_WIDTH, pConInfo->ci.ConsoleSize.X, FALSE);
+            SetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_SIZE_WIDTH , pConInfo->ci.ConsoleSize.X, FALSE);
 
-            hDC = GetDC(NULL);
-            xres = GetDeviceCaps(hDC, HORZRES);
-            yres = GetDeviceCaps(hDC, VERTRES);
-            SendMessage(GetDlgItem(hwndDlg, IDC_UPDOWN_WINDOW_POS_LEFT), UDM_SETRANGE, 0, (LPARAM)MAKELONG(xres, 0));
-            SendMessage(GetDlgItem(hwndDlg, IDC_UPDOWN_WINDOW_POS_TOP), UDM_SETRANGE, 0, (LPARAM)MAKELONG(yres, 0));
+            SendDlgItemMessageW(hwndDlg, IDC_UPDOWN_WINDOW_POS_LEFT, UDM_SETRANGE, 0,
+                                (LPARAM)MAKELONG(xVirtScr + cxVirtScr - cxFrame, xVirtScr - cxFrame));
+            SendDlgItemMessageW(hwndDlg, IDC_UPDOWN_WINDOW_POS_TOP , UDM_SETRANGE, 0,
+                                (LPARAM)MAKELONG(yVirtScr + cyVirtScr - cyFrame, yVirtScr - cyFrame));
 
-            if ( GuiInfo->WindowOrigin.x != MAXDWORD &&
-                 GuiInfo->WindowOrigin.y != MAXDWORD )
-            {
-                SetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_POS_LEFT, GuiInfo->WindowOrigin.x, FALSE);
-                SetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_POS_TOP, GuiInfo->WindowOrigin.y, FALSE);
-            }
-            else
+            SetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_POS_LEFT, GuiInfo->WindowOrigin.x, TRUE);
+            SetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_POS_TOP , GuiInfo->WindowOrigin.y, TRUE);
+
+            if (GuiInfo->AutoPosition)
             {
-                // FIXME: Calculate window pos from xres, yres
-                SetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_POS_LEFT, 88, FALSE);
-                SetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_POS_TOP, 88, FALSE);
-                EnableWindow(GetDlgItem(hwndDlg, IDC_EDIT_WINDOW_POS_LEFT), FALSE);
-                EnableWindow(GetDlgItem(hwndDlg, IDC_EDIT_WINDOW_POS_TOP), FALSE);
-                EnableWindow(GetDlgItem(hwndDlg, IDC_UPDOWN_WINDOW_POS_LEFT), FALSE);
-                EnableWindow(GetDlgItem(hwndDlg, IDC_UPDOWN_WINDOW_POS_TOP), FALSE);
-                SendMessage(GetDlgItem(hwndDlg, IDC_CHECK_SYSTEM_POS_WINDOW), BM_SETCHECK, (WPARAM)BST_CHECKED, 0);
+                EnableDlgItem(hwndDlg, IDC_EDIT_WINDOW_POS_LEFT, FALSE);
+                EnableDlgItem(hwndDlg, IDC_EDIT_WINDOW_POS_TOP , FALSE);
+                EnableDlgItem(hwndDlg, IDC_UPDOWN_WINDOW_POS_LEFT, FALSE);
+                EnableDlgItem(hwndDlg, IDC_UPDOWN_WINDOW_POS_TOP , FALSE);
             }
+            CheckDlgButton(hwndDlg, IDC_CHECK_SYSTEM_POS_WINDOW,
+                           GuiInfo->AutoPosition ? BST_CHECKED : BST_UNCHECKED);
 
             return TRUE;
         }
+
         case WM_DRAWITEM:
         {
             PaintConsole((LPDRAWITEMSTRUCT)lParam, pConInfo);
             return TRUE;
         }
+
         case WM_NOTIFY:
         {
-            lpnmud = (LPNMUPDOWN) lParam;
-            lppsn = (LPPSHNOTIFY) lParam;
+            LPNMUPDOWN  lpnmud =  (LPNMUPDOWN)lParam;
+            LPPSHNOTIFY lppsn  = (LPPSHNOTIFY)lParam;
 
             if (lppsn->hdr.code == UDN_DELTAPOS)
             {
@@ -246,7 +286,7 @@ LayoutProc(HWND hwndDlg,
                 }
                 else
                 {
-                    left = GetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_POS_LEFT, NULL, FALSE);
+                    left = GetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_POS_LEFT, NULL, TRUE);
                 }
 
                 if (lppsn->hdr.idFrom == IDC_UPDOWN_WINDOW_POS_TOP)
@@ -255,7 +295,7 @@ LayoutProc(HWND hwndDlg,
                 }
                 else
                 {
-                    top = GetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_POS_TOP, NULL, FALSE);
+                    top = GetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_POS_TOP, NULL, TRUE);
                 }
 
                 if (lppsn->hdr.idFrom == IDC_UPDOWN_WINDOW_SIZE_WIDTH || lppsn->hdr.idFrom == IDC_UPDOWN_WINDOW_SIZE_HEIGHT)
@@ -266,15 +306,16 @@ LayoutProc(HWND hwndDlg,
                         SetDlgItemInt(hwndDlg, IDC_EDIT_SCREEN_BUFFER_WIDTH, wwidth, TRUE);
                         swidth = wwidth;
                     }
-
                     if (wheight >= sheight)
                     {
                         SetDlgItemInt(hwndDlg, IDC_EDIT_SCREEN_BUFFER_HEIGHT, wheight, TRUE);
                         sheight = wheight;
                     }
                 }
-                swidth = max(swidth, 1);
-                sheight = max(sheight, 1);
+
+                /* Be sure that the (new) screen buffer sizes are in the correct range */
+                swidth  = min(max(swidth , 1), 0xFFFF);
+                sheight = min(max(sheight, 1), 0xFFFF);
 
                 if (lppsn->hdr.idFrom == IDC_UPDOWN_SCREEN_BUFFER_WIDTH || lppsn->hdr.idFrom == IDC_UPDOWN_SCREEN_BUFFER_HEIGHT)
                 {
@@ -284,7 +325,6 @@ LayoutProc(HWND hwndDlg,
                         SetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_SIZE_WIDTH, swidth, TRUE);
                         wwidth = swidth;
                     }
-
                     if (wheight > sheight)
                     {
                         SetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_SIZE_HEIGHT, sheight, TRUE);
@@ -292,60 +332,137 @@ LayoutProc(HWND hwndDlg,
                     }
                 }
 
-                pConInfo->ci.ScreenBufferSize.X = swidth;
-                pConInfo->ci.ScreenBufferSize.Y = sheight;
-                pConInfo->ci.ConsoleSize.X = wwidth;
-                pConInfo->ci.ConsoleSize.Y = wheight;
+                pConInfo->ci.ScreenBufferSize.X = (SHORT)swidth;
+                pConInfo->ci.ScreenBufferSize.Y = (SHORT)sheight;
+                pConInfo->ci.ConsoleSize.X = (SHORT)wwidth;
+                pConInfo->ci.ConsoleSize.Y = (SHORT)wheight;
                 GuiInfo->WindowOrigin.x = left;
                 GuiInfo->WindowOrigin.y = top;
                 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
             }
             break;
         }
+
         case WM_COMMAND:
         {
             switch (LOWORD(wParam))
             {
                 case IDC_EDIT_SCREEN_BUFFER_WIDTH:
-                case IDC_EDIT_SCREEN_BUFFER_HEIGHT:
-                case IDC_EDIT_WINDOW_SIZE_WIDTH:
-                case IDC_UPDOWN_WINDOW_SIZE_HEIGHT:
-                case IDC_EDIT_WINDOW_POS_LEFT:
-                case IDC_EDIT_WINDOW_POS_TOP:
                 {
                     if (HIWORD(wParam) == EN_KILLFOCUS)
                     {
-                        DWORD wheight, wwidth;
-                        DWORD sheight, swidth;
-                        DWORD left, top;
+                        DWORD swidth, wwidth;
 
-                        wwidth = GetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_SIZE_WIDTH, NULL, FALSE);
-                        wheight = GetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_SIZE_HEIGHT, NULL, FALSE);
                         swidth = GetDlgItemInt(hwndDlg, IDC_EDIT_SCREEN_BUFFER_WIDTH, NULL, FALSE);
-                        sheight = GetDlgItemInt(hwndDlg, IDC_EDIT_SCREEN_BUFFER_HEIGHT, NULL, FALSE);
-                        left = GetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_POS_LEFT, NULL, FALSE);
-                        top = GetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_POS_TOP, NULL, FALSE);
+                        wwidth = GetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_SIZE_WIDTH  , NULL, FALSE);
 
-                        swidth = max(swidth, 1);
-                        sheight = max(sheight, 1);
+                        /* Be sure that the (new) screen buffer width is in the correct range */
+                        swidth = min(max(swidth, 1), 0xFFFF);
 
                         /* Automatically adjust window size when screen buffer decreases */
                         if (wwidth > swidth)
                         {
-                            SetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_SIZE_WIDTH, swidth, TRUE);
                             wwidth = swidth;
+                            SetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_SIZE_WIDTH, wwidth, TRUE);
                         }
 
+                        pConInfo->ci.ScreenBufferSize.X = (SHORT)swidth;
+                        pConInfo->ci.ConsoleSize.X      = (SHORT)wwidth;
+                        PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
+                    }
+                    break;
+                }
+
+                case IDC_EDIT_WINDOW_SIZE_WIDTH:
+                {
+                    if (HIWORD(wParam) == EN_KILLFOCUS)
+                    {
+                        DWORD swidth, wwidth;
+
+                        swidth = GetDlgItemInt(hwndDlg, IDC_EDIT_SCREEN_BUFFER_WIDTH, NULL, FALSE);
+                        wwidth = GetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_SIZE_WIDTH  , NULL, FALSE);
+
+                        /* Automatically adjust screen buffer size when window size enlarges */
+                        if (wwidth >= swidth)
+                        {
+                            swidth = wwidth;
+
+                            /* Be sure that the (new) screen buffer width is in the correct range */
+                            swidth = min(max(swidth, 1), 0xFFFF);
+
+                            SetDlgItemInt(hwndDlg, IDC_EDIT_SCREEN_BUFFER_WIDTH, swidth, TRUE);
+                        }
+
+                        pConInfo->ci.ScreenBufferSize.X = (SHORT)swidth;
+                        pConInfo->ci.ConsoleSize.X      = (SHORT)wwidth;
+                        PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
+                    }
+                    break;
+                }
+
+                case IDC_EDIT_SCREEN_BUFFER_HEIGHT:
+                {
+                    if (HIWORD(wParam) == EN_KILLFOCUS)
+                    {
+                        DWORD sheight, wheight;
+
+                        sheight = GetDlgItemInt(hwndDlg, IDC_EDIT_SCREEN_BUFFER_HEIGHT, NULL, FALSE);
+                        wheight = GetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_SIZE_HEIGHT  , NULL, FALSE);
+
+                        /* Be sure that the (new) screen buffer width is in the correct range */
+                        sheight = min(max(sheight, 1), 0xFFFF);
+
+                        /* Automatically adjust window size when screen buffer decreases */
                         if (wheight > sheight)
                         {
-                            SetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_SIZE_HEIGHT, sheight, TRUE);
                             wheight = sheight;
+                            SetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_SIZE_HEIGHT, wheight, TRUE);
+                        }
+
+                        pConInfo->ci.ScreenBufferSize.Y = (SHORT)sheight;
+                        pConInfo->ci.ConsoleSize.Y      = (SHORT)wheight;
+                        PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
+                    }
+                    break;
+                }
+
+                case IDC_EDIT_WINDOW_SIZE_HEIGHT:
+                {
+                    if (HIWORD(wParam) == EN_KILLFOCUS)
+                    {
+                        DWORD sheight, wheight;
+
+                        sheight = GetDlgItemInt(hwndDlg, IDC_EDIT_SCREEN_BUFFER_HEIGHT, NULL, FALSE);
+                        wheight = GetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_SIZE_HEIGHT  , NULL, FALSE);
+
+                        /* Automatically adjust screen buffer size when window size enlarges */
+                        if (wheight >= sheight)
+                        {
+                            sheight = wheight;
+
+                            /* Be sure that the (new) screen buffer width is in the correct range */
+                            sheight = min(max(sheight, 1), 0xFFFF);
+
+                            SetDlgItemInt(hwndDlg, IDC_EDIT_SCREEN_BUFFER_HEIGHT, sheight, TRUE);
                         }
 
-                        pConInfo->ci.ScreenBufferSize.X = swidth;
-                        pConInfo->ci.ScreenBufferSize.Y = sheight;
-                        pConInfo->ci.ConsoleSize.X = wwidth;
-                        pConInfo->ci.ConsoleSize.Y = wheight;
+                        pConInfo->ci.ScreenBufferSize.Y = (SHORT)sheight;
+                        pConInfo->ci.ConsoleSize.Y      = (SHORT)wheight;
+                        PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
+                    }
+                    break;
+                }
+
+                case IDC_EDIT_WINDOW_POS_LEFT:
+                case IDC_EDIT_WINDOW_POS_TOP:
+                {
+                    if (HIWORD(wParam) == EN_KILLFOCUS)
+                    {
+                        DWORD left, top;
+
+                        left = GetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_POS_LEFT, NULL, TRUE);
+                        top  = GetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_POS_TOP , NULL, TRUE);
+
                         GuiInfo->WindowOrigin.x = left;
                         GuiInfo->WindowOrigin.y = top;
                         PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
@@ -360,29 +477,36 @@ LayoutProc(HWND hwndDlg,
                     {
                         ULONG left, top;
 
-                        left = GetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_POS_LEFT, NULL, FALSE);
-                        top = GetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_POS_TOP, NULL, FALSE);
+                        left = GetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_POS_LEFT, NULL, TRUE);
+                        top  = GetDlgItemInt(hwndDlg, IDC_EDIT_WINDOW_POS_TOP , NULL, TRUE);
+
+                        GuiInfo->AutoPosition   = FALSE;
                         GuiInfo->WindowOrigin.x = left;
                         GuiInfo->WindowOrigin.y = top;
+                        PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
+
                         SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0);
-                        EnableWindow(GetDlgItem(hwndDlg, IDC_EDIT_WINDOW_POS_LEFT), TRUE);
-                        EnableWindow(GetDlgItem(hwndDlg, IDC_EDIT_WINDOW_POS_TOP), TRUE);
-                        EnableWindow(GetDlgItem(hwndDlg, IDC_UPDOWN_WINDOW_POS_LEFT), TRUE);
-                        EnableWindow(GetDlgItem(hwndDlg, IDC_UPDOWN_WINDOW_POS_TOP), TRUE);
+                        EnableDlgItem(hwndDlg, IDC_EDIT_WINDOW_POS_LEFT, TRUE);
+                        EnableDlgItem(hwndDlg, IDC_EDIT_WINDOW_POS_TOP , TRUE);
+                        EnableDlgItem(hwndDlg, IDC_UPDOWN_WINDOW_POS_LEFT, TRUE);
+                        EnableDlgItem(hwndDlg, IDC_UPDOWN_WINDOW_POS_TOP , TRUE);
                     }
                     else if (res == BST_UNCHECKED)
                     {
-                        GuiInfo->WindowOrigin.x = UINT_MAX;
-                        GuiInfo->WindowOrigin.y = UINT_MAX;
+                        GuiInfo->AutoPosition = TRUE;
+                        // Do not touch GuiInfo->WindowOrigin !!
+                        PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
+
                         SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_CHECKED, 0);
-                        EnableWindow(GetDlgItem(hwndDlg, IDC_EDIT_WINDOW_POS_LEFT), FALSE);
-                        EnableWindow(GetDlgItem(hwndDlg, IDC_EDIT_WINDOW_POS_TOP), FALSE);
-                        EnableWindow(GetDlgItem(hwndDlg, IDC_UPDOWN_WINDOW_POS_LEFT), FALSE);
-                        EnableWindow(GetDlgItem(hwndDlg, IDC_UPDOWN_WINDOW_POS_TOP), FALSE);
+                        EnableDlgItem(hwndDlg, IDC_EDIT_WINDOW_POS_LEFT, FALSE);
+                        EnableDlgItem(hwndDlg, IDC_EDIT_WINDOW_POS_TOP , FALSE);
+                        EnableDlgItem(hwndDlg, IDC_UPDOWN_WINDOW_POS_LEFT, FALSE);
+                        EnableDlgItem(hwndDlg, IDC_UPDOWN_WINDOW_POS_TOP , FALSE);
                     }
                 }
             }
         }
+
         default:
             break;
     }