[ACPPAGE] Make use of the PCH.
[reactos.git] / dll / cpl / console / options.c
index c5b0056..689553d 100644 (file)
@@ -1,9 +1,10 @@
 /*
  * PROJECT:         ReactOS Console Configuration DLL
  * LICENSE:         GPL - See COPYING in the top level directory
- * FILE:            dll/win32/console/options.c
+ * FILE:            dll/cpl/console/options.c
  * PURPOSE:         Options dialog
  * PROGRAMMERS:     Johannes Anderwald (johannes.anderwald@reactos.org)
+ *                  Hermes Belusca-Maito (hermes.belusca@sfr.fr)
  */
 
 #include "console.h"
 #define NDEBUG
 #include <debug.h>
 
-static void
-UpdateDialogElements(HWND hwndDlg, PCONSOLE_PROPS pConInfo)
+#define MAX_VALUE_NAME 16383
+
+
+static INT
+List_GetCount(IN PLIST_CTL ListCtl)
+{
+    return (INT)SendMessageW(ListCtl->hWndList, CB_GETCOUNT, 0, 0);
+}
+
+static ULONG_PTR
+List_GetData(IN PLIST_CTL ListCtl, IN INT Index)
+{
+    return (ULONG_PTR)SendMessageW(ListCtl->hWndList, CB_GETITEMDATA, (WPARAM)Index, 0);
+}
+
+static VOID
+AddCodePage(
+    IN PLIST_CTL ListCtl,
+    IN UINT CodePage)
 {
-    PGUI_CONSOLE_INFO GuiInfo = pConInfo->TerminalInfo.TermInfo;
-    HWND hDlgCtrl;
+    UINT iItem, iDupItem;
+    CPINFOEXW CPInfo;
 
-    /* Update cursor size */
-    if (pConInfo->ci.CursorSize <= 25)
+    /*
+     * Add only valid code pages, that is:
+     * - If the CodePage is one of the reserved (alias) values:
+     *   CP_ACP == 0 ; CP_OEMCP == 1 ; CP_MACCP == 2 ; CP_THREAD_ACP == 3 ;
+     *   or the deprecated CP_SYMBOL == 42 (see http://archives.miloush.net/michkap/archive/2005/11/08/490495.html)
+     *   it is considered invalid.
+     * - If IsValidCodePage() fails because the code page is listed but
+     *   not installed on the system, it is also considered invalid.
+     */
+    if (CodePage == CP_ACP || CodePage == CP_OEMCP || CodePage == CP_MACCP ||
+        CodePage == CP_THREAD_ACP || CodePage == CP_SYMBOL || !IsValidCodePage(CodePage))
     {
-        /* Small cursor */
-        hDlgCtrl = GetDlgItem(hwndDlg, IDC_RADIO_SMALL_CURSOR);
-        SendMessage(hDlgCtrl, BM_SETCHECK, (WPARAM)BST_CHECKED, 0);
+        return;
+    }
+
+    /* Retrieve the code page display name */
+    if (!GetCPInfoExW(CodePage, 0, &CPInfo))
+    {
+        /* We failed, just use the code page value as its name */
+        // _ultow(CodePage, CPInfo.CodePageName, 10);
+        StringCchPrintfW(CPInfo.CodePageName, ARRAYSIZE(CPInfo.CodePageName), L"%lu", CodePage);
+    }
+
+    /* Add the code page into the list, sorted by code page value. Avoid any duplicates. */
+    iDupItem = CB_ERR;
+    iItem = BisectListSortedByValue(ListCtl, CodePage, &iDupItem, TRUE);
+    if (iItem == CB_ERR)
+        iItem = 0;
+    if (iDupItem != CB_ERR)
+        return;
+    iItem = (UINT)SendMessageW(ListCtl->hWndList, CB_INSERTSTRING, iItem, (LPARAM)CPInfo.CodePageName);
+    if (iItem != CB_ERR && iItem != CB_ERRSPACE)
+        iItem = SendMessageW(ListCtl->hWndList, CB_SETITEMDATA, iItem, CodePage);
+}
 
-        hDlgCtrl = GetDlgItem(hwndDlg, IDC_RADIO_MEDIUM_CURSOR);
-        SendMessage(hDlgCtrl, BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0);
-        hDlgCtrl = GetDlgItem(hwndDlg, IDC_RADIO_LARGE_CURSOR);
-        SendMessage(hDlgCtrl, BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0);
+static VOID
+BuildCodePageList(
+    IN HWND hDlg)
+{
+    LIST_CTL ListCtl;
+    HKEY hKey;
+    DWORD dwIndex, dwSize, dwType;
+    UINT CodePage;
+    WCHAR szValueName[MAX_VALUE_NAME];
+
+    // #define REGSTR_PATH_CODEPAGE    TEXT("System\\CurrentControlSet\\Control\\Nls\\CodePage")
+    /* Open the Nls\CodePage key */
+    if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,
+                      L"System\\CurrentControlSet\\Control\\Nls\\CodePage",
+                      0,
+                      KEY_ENUMERATE_SUB_KEYS | KEY_QUERY_VALUE,
+                      &hKey) != ERROR_SUCCESS)
+    {
+        return;
     }
-    else if (pConInfo->ci.CursorSize <= 50)
+
+    ListCtl.hWndList = GetDlgItem(hDlg, IDL_CODEPAGE);
+    ListCtl.GetCount = List_GetCount;
+    ListCtl.GetData  = List_GetData;
+
+    /* Enumerate all the available code pages on the system */
+    dwSize  = ARRAYSIZE(szValueName);
+    dwIndex = 0;
+    while (RegEnumValueW(hKey, dwIndex, szValueName, &dwSize,
+                         NULL, &dwType, NULL, NULL) == ERROR_SUCCESS) // != ERROR_NO_MORE_ITEMS
     {
-        hDlgCtrl = GetDlgItem(hwndDlg, IDC_RADIO_MEDIUM_CURSOR);
-        SendMessage(hDlgCtrl, BM_SETCHECK, (WPARAM)BST_CHECKED, 0);
+        /* Ignore these parameters, prepare for next iteration */
+        dwSize = ARRAYSIZE(szValueName);
+        ++dwIndex;
+
+        /* Check the value type validity */
+        if (dwType != REG_SZ)
+            continue;
 
-        hDlgCtrl = GetDlgItem(hwndDlg, IDC_RADIO_SMALL_CURSOR);
-        SendMessage(hDlgCtrl, BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0);
-        hDlgCtrl = GetDlgItem(hwndDlg, IDC_RADIO_LARGE_CURSOR);
-        SendMessage(hDlgCtrl, BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0);
+        /*
+         * Add the code page into the list.
+         * If _wtol fails and returns 0, the code page is considered invalid
+         * (and indeed this value corresponds to the CP_ACP alias too).
+         */
+        CodePage = (UINT)_wtol(szValueName);
+        if (CodePage == 0) continue;
+        AddCodePage(&ListCtl, CodePage);
     }
-    else /* if (pConInfo->ci.CursorSize <= 100) */
+
+    RegCloseKey(hKey);
+
+    /* Add the special UTF-7 (CP_UTF7 65000) and UTF-8 (CP_UTF8 65001) code pages */
+    AddCodePage(&ListCtl, CP_UTF7);
+    AddCodePage(&ListCtl, CP_UTF8);
+
+    /* Find and select the current code page in the sorted list */
+    if (BisectListSortedByValue(&ListCtl, ConInfo->CodePage, &CodePage, FALSE) == CB_ERR ||
+        CodePage == CB_ERR)
     {
-        hDlgCtrl = GetDlgItem(hwndDlg, IDC_RADIO_LARGE_CURSOR);
-        SendMessage(hDlgCtrl, BM_SETCHECK, (WPARAM)BST_CHECKED, 0);
+        /* Not found, select the first element */
+        CodePage = 0;
+    }
+    SendMessageW(ListCtl.hWndList, CB_SETCURSEL, (WPARAM)CodePage, 0);
+}
 
-        hDlgCtrl = GetDlgItem(hwndDlg, IDC_RADIO_SMALL_CURSOR);
-        SendMessage(hDlgCtrl, BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0);
-        hDlgCtrl = GetDlgItem(hwndDlg, IDC_RADIO_MEDIUM_CURSOR);
-        SendMessage(hDlgCtrl, BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0);
+static VOID
+UpdateDialogElements(
+    IN HWND hDlg,
+    IN PCONSOLE_STATE_INFO pConInfo)
+{
+    /* Update the cursor size */
+    if (pConInfo->CursorSize <= 25)
+    {
+        /* Small cursor */
+        CheckRadioButton(hDlg, IDC_RADIO_SMALL_CURSOR, IDC_RADIO_LARGE_CURSOR, IDC_RADIO_SMALL_CURSOR);
+        // CheckDlgButton(hDlg, IDC_RADIO_SMALL_CURSOR , BST_CHECKED);
+        // CheckDlgButton(hDlg, IDC_RADIO_MEDIUM_CURSOR, BST_UNCHECKED);
+        // CheckDlgButton(hDlg, IDC_RADIO_LARGE_CURSOR , BST_UNCHECKED);
+    }
+    else if (pConInfo->CursorSize <= 50)
+    {
+        /* Medium cursor */
+        CheckRadioButton(hDlg, IDC_RADIO_SMALL_CURSOR, IDC_RADIO_LARGE_CURSOR, IDC_RADIO_MEDIUM_CURSOR);
+        // CheckDlgButton(hDlg, IDC_RADIO_SMALL_CURSOR , BST_UNCHECKED);
+        // CheckDlgButton(hDlg, IDC_RADIO_MEDIUM_CURSOR, BST_CHECKED);
+        // CheckDlgButton(hDlg, IDC_RADIO_LARGE_CURSOR , BST_UNCHECKED);
+    }
+    else /* if (pConInfo->CursorSize <= 100) */
+    {
+        /* Large cursor */
+        CheckRadioButton(hDlg, IDC_RADIO_SMALL_CURSOR, IDC_RADIO_LARGE_CURSOR, IDC_RADIO_LARGE_CURSOR);
+        // CheckDlgButton(hDlg, IDC_RADIO_SMALL_CURSOR , BST_UNCHECKED);
+        // CheckDlgButton(hDlg, IDC_RADIO_MEDIUM_CURSOR, BST_UNCHECKED);
+        // CheckDlgButton(hDlg, IDC_RADIO_LARGE_CURSOR , BST_CHECKED);
     }
 
-    /* Update num buffers */
-    hDlgCtrl = GetDlgItem(hwndDlg, IDC_UPDOWN_NUM_BUFFER);
-    SendMessage(hDlgCtrl, UDM_SETRANGE, 0, MAKELONG(999, 1));
-    SetDlgItemInt(hwndDlg, IDC_EDIT_NUM_BUFFER, pConInfo->ci.NumberOfHistoryBuffers, FALSE);
+    /* Update the number of history buffers */
+    SendDlgItemMessageW(hDlg, IDC_UPDOWN_NUM_BUFFER, UDM_SETRANGE, 0, MAKELONG(999, 1));
+    SetDlgItemInt(hDlg, IDC_EDIT_NUM_BUFFER, pConInfo->NumberOfHistoryBuffers, FALSE);
 
-    /* Update buffer size */
-    hDlgCtrl = GetDlgItem(hwndDlg, IDC_UPDOWN_BUFFER_SIZE);
-    SendMessage(hDlgCtrl, UDM_SETRANGE, 0, MAKELONG(999, 1));
-    SetDlgItemInt(hwndDlg, IDC_EDIT_BUFFER_SIZE, pConInfo->ci.HistoryBufferSize, FALSE);
+    /* Update the history buffer size */
+    SendDlgItemMessageW(hDlg, IDC_UPDOWN_BUFFER_SIZE, UDM_SETRANGE, 0, MAKELONG(999, 1));
+    SetDlgItemInt(hDlg, IDC_EDIT_BUFFER_SIZE, pConInfo->HistoryBufferSize, FALSE);
 
     /* Update discard duplicates */
-    CheckDlgButton(hwndDlg, IDC_CHECK_DISCARD_DUPLICATES,
-                   pConInfo->ci.HistoryNoDup ? BST_CHECKED : BST_UNCHECKED);
+    CheckDlgButton(hDlg, IDC_CHECK_DISCARD_DUPLICATES,
+                   pConInfo->HistoryNoDup ? BST_CHECKED : BST_UNCHECKED);
 
-    /* Update full/window screen */
-    if (GuiInfo->FullScreen)
+    /* Update full/window screen state */
+    if (pConInfo->FullScreen)
     {
-        hDlgCtrl = GetDlgItem(hwndDlg, IDC_RADIO_DISPLAY_FULL);
-        SendMessage(hDlgCtrl, BM_SETCHECK, (WPARAM)BST_CHECKED, 0);
-
-        hDlgCtrl = GetDlgItem(hwndDlg, IDC_RADIO_DISPLAY_WINDOW);
-        SendMessage(hDlgCtrl, BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0);
+        CheckRadioButton(hDlg, IDC_RADIO_DISPLAY_WINDOW, IDC_RADIO_DISPLAY_FULL, IDC_RADIO_DISPLAY_FULL);
+        // CheckDlgButton(hDlg, IDC_RADIO_DISPLAY_WINDOW, BST_UNCHECKED);
+        // CheckDlgButton(hDlg, IDC_RADIO_DISPLAY_FULL  , BST_CHECKED);
     }
     else
     {
-        hDlgCtrl = GetDlgItem(hwndDlg, IDC_RADIO_DISPLAY_WINDOW);
-        SendMessage(hDlgCtrl, BM_SETCHECK, (WPARAM)BST_CHECKED, 0);
-
-        hDlgCtrl = GetDlgItem(hwndDlg, IDC_RADIO_DISPLAY_FULL);
-        SendMessage(hDlgCtrl, BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0);
+        CheckRadioButton(hDlg, IDC_RADIO_DISPLAY_WINDOW, IDC_RADIO_DISPLAY_FULL, IDC_RADIO_DISPLAY_WINDOW);
+        // CheckDlgButton(hDlg, IDC_RADIO_DISPLAY_WINDOW, BST_CHECKED);
+        // CheckDlgButton(hDlg, IDC_RADIO_DISPLAY_FULL  , BST_UNCHECKED);
     }
 
-    /* Update quick edit */
-    CheckDlgButton(hwndDlg, IDC_CHECK_QUICK_EDIT,
-                   pConInfo->ci.QuickEdit ? BST_CHECKED : BST_UNCHECKED);
+    /* Update "Quick-edit" state */
+    CheckDlgButton(hDlg, IDC_CHECK_QUICK_EDIT,
+                   pConInfo->QuickEdit ? BST_CHECKED : BST_UNCHECKED);
 
-    /* Update insert mode */
-    CheckDlgButton(hwndDlg, IDC_CHECK_INSERT_MODE,
-                   pConInfo->ci.InsertMode ? BST_CHECKED : BST_UNCHECKED);
+    /* Update "Insert mode" state */
+    CheckDlgButton(hDlg, IDC_CHECK_INSERT_MODE,
+                   pConInfo->InsertMode ? BST_CHECKED : BST_UNCHECKED);
 }
 
 INT_PTR
 CALLBACK
-OptionsProc(HWND hwndDlg,
+OptionsProc(HWND hDlg,
             UINT uMsg,
             WPARAM wParam,
             LPARAM lParam)
 {
-    PCONSOLE_PROPS pConInfo;
-    PGUI_CONSOLE_INFO GuiInfo;
-
-    pConInfo = (PCONSOLE_PROPS)GetWindowLongPtr(hwndDlg, DWLP_USER);
-
     switch (uMsg)
     {
         case WM_INITDIALOG:
         {
-            pConInfo = (PCONSOLE_PROPS)((LPPROPSHEETPAGE)lParam)->lParam;
-            SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pConInfo);
-            UpdateDialogElements(hwndDlg, pConInfo);
+            BuildCodePageList(hDlg);
+            UpdateDialogElements(hDlg, ConInfo);
             return TRUE;
         }
 
         case WM_NOTIFY:
         {
-            LPNMUPDOWN  lpnmud =  (LPNMUPDOWN)lParam;
-            LPPSHNOTIFY lppsn  = (LPPSHNOTIFY)lParam;
-
-            // if (!pConInfo) break;
+            LPPSHNOTIFY lppsn = (LPPSHNOTIFY)lParam;
 
             if (lppsn->hdr.code == UDN_DELTAPOS)
             {
+                LPNMUPDOWN lpnmud = (LPNMUPDOWN)lParam;
+
                 if (lppsn->hdr.idFrom == IDC_UPDOWN_BUFFER_SIZE)
                 {
                     lpnmud->iPos = min(max(lpnmud->iPos + lpnmud->iDelta, 1), 999);
-                    pConInfo->ci.HistoryBufferSize = lpnmud->iPos;
-                    PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
+                    ConInfo->HistoryBufferSize = lpnmud->iPos;
+                    PropSheet_Changed(GetParent(hDlg), hDlg);
                 }
                 else if (lppsn->hdr.idFrom == IDC_UPDOWN_NUM_BUFFER)
                 {
                     lpnmud->iPos = min(max(lpnmud->iPos + lpnmud->iDelta, 1), 999);
-                    pConInfo->ci.NumberOfHistoryBuffers = lpnmud->iPos;
-                    PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
+                    ConInfo->NumberOfHistoryBuffers = lpnmud->iPos;
+                    PropSheet_Changed(GetParent(hDlg), hDlg);
                 }
             }
             else if (lppsn->hdr.code == PSN_APPLY)
             {
-                if (!pConInfo->AppliedConfig)
-                {
-                    return ApplyConsoleInfo(hwndDlg, pConInfo);
-                }
-                else
-                {
-                    /* Options have already been applied */
-                    SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_NOERROR);
-                    return TRUE;
-                }
+                ApplyConsoleInfo(hDlg);
+                return TRUE;
             }
             break;
         }
 
         case WM_COMMAND:
         {
-            LRESULT lResult;
-
-            if (!pConInfo) break;
-            GuiInfo = pConInfo->TerminalInfo.TermInfo;
-
-            switch (LOWORD(wParam))
+            if (HIWORD(wParam) == BN_CLICKED)
             {
+                switch (LOWORD(wParam))
+                {
                 case IDC_RADIO_SMALL_CURSOR:
                 {
-                    pConInfo->ci.CursorSize = 25;
-                    PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
+                    ConInfo->CursorSize = 25;
+                    PropSheet_Changed(GetParent(hDlg), hDlg);
                     break;
                 }
                 case IDC_RADIO_MEDIUM_CURSOR:
                 {
-                    pConInfo->ci.CursorSize = 50;
-                    PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
+                    ConInfo->CursorSize = 50;
+                    PropSheet_Changed(GetParent(hDlg), hDlg);
                     break;
                 }
                 case IDC_RADIO_LARGE_CURSOR:
                 {
-                    pConInfo->ci.CursorSize = 100;
-                    PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
+                    ConInfo->CursorSize = 100;
+                    PropSheet_Changed(GetParent(hDlg), hDlg);
                     break;
                 }
                 case IDC_RADIO_DISPLAY_WINDOW:
                 {
-                    GuiInfo->FullScreen = FALSE;
-                    PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
+                    ConInfo->FullScreen = FALSE;
+                    PropSheet_Changed(GetParent(hDlg), hDlg);
                     break;
                 }
                 case IDC_RADIO_DISPLAY_FULL:
                 {
-                    GuiInfo->FullScreen = TRUE;
-                    PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
+                    ConInfo->FullScreen = TRUE;
+                    PropSheet_Changed(GetParent(hDlg), hDlg);
                     break;
                 }
                 case IDC_CHECK_QUICK_EDIT:
                 {
-                    lResult = SendMessage((HWND)lParam, BM_GETCHECK, 0, 0);
-                    if (lResult == BST_CHECKED)
-                    {
-                        pConInfo->ci.QuickEdit = FALSE;
-                        SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0);
-                    }
-                    else if (lResult == BST_UNCHECKED)
-                    {
-                        pConInfo->ci.QuickEdit = TRUE;
-                        SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_CHECKED, 0);
-                    }
-                    PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
+                    ConInfo->QuickEdit = (IsDlgButtonChecked(hDlg, IDC_CHECK_QUICK_EDIT) == BST_CHECKED); // BST_UNCHECKED or BST_INDETERMINATE => FALSE
+                    PropSheet_Changed(GetParent(hDlg), hDlg);
                     break;
                 }
                 case IDC_CHECK_INSERT_MODE:
                 {
-                    lResult = SendMessage((HWND)lParam, BM_GETCHECK, 0, 0);
-                    if (lResult == BST_CHECKED)
-                    {
-                        pConInfo->ci.InsertMode = FALSE;
-                        SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0);
-                    }
-                    else if (lResult == BST_UNCHECKED)
-                    {
-                        pConInfo->ci.InsertMode = TRUE;
-                        SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_CHECKED, 0);
-                    }
-                    PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
+                    ConInfo->InsertMode = (IsDlgButtonChecked(hDlg, IDC_CHECK_INSERT_MODE) == BST_CHECKED); // BST_UNCHECKED or BST_INDETERMINATE => FALSE
+                    PropSheet_Changed(GetParent(hDlg), hDlg);
                     break;
                 }
                 case IDC_CHECK_DISCARD_DUPLICATES:
                 {
-                   lResult = SendMessage((HWND)lParam, BM_GETCHECK, 0, 0);
-                    if (lResult == BST_CHECKED)
-                    {
-                        pConInfo->ci.HistoryNoDup = FALSE;
-                        SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0);
-                    }
-                    else if (lResult == BST_UNCHECKED)
-                    {
-                        pConInfo->ci.HistoryNoDup = TRUE;
-                        SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_CHECKED, 0);
-                    }
-                    PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
+                    ConInfo->HistoryNoDup = (IsDlgButtonChecked(hDlg, IDC_CHECK_DISCARD_DUPLICATES) == BST_CHECKED); // BST_UNCHECKED or BST_INDETERMINATE => FALSE
+                    PropSheet_Changed(GetParent(hDlg), hDlg);
                     break;
                 }
+                }
+            }
+            else
+            if (HIWORD(wParam) == EN_KILLFOCUS)
+            {
+                switch (LOWORD(wParam))
+                {
                 case IDC_EDIT_BUFFER_SIZE:
                 {
-                    if (HIWORD(wParam) == EN_KILLFOCUS)
-                    {
-                        DWORD sizeBuff;
+                    DWORD sizeBuff;
 
-                        sizeBuff = GetDlgItemInt(hwndDlg, IDC_EDIT_BUFFER_SIZE, NULL, FALSE);
-                        sizeBuff = min(max(sizeBuff, 1), 999);
+                    sizeBuff = GetDlgItemInt(hDlg, IDC_EDIT_BUFFER_SIZE, NULL, FALSE);
+                    sizeBuff = min(max(sizeBuff, 1), 999);
 
-                        pConInfo->ci.HistoryBufferSize = sizeBuff;
-                        PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
-                    }
+                    ConInfo->HistoryBufferSize = sizeBuff;
+                    PropSheet_Changed(GetParent(hDlg), hDlg);
                     break;
                 }
                 case IDC_EDIT_NUM_BUFFER:
                 {
-                    if (HIWORD(wParam) == EN_KILLFOCUS)
-                    {
-                        DWORD numBuff;
+                    DWORD numBuff;
 
-                        numBuff = GetDlgItemInt(hwndDlg, IDC_EDIT_NUM_BUFFER, NULL, FALSE);
-                        numBuff = min(max(numBuff, 1), 999);
+                    numBuff = GetDlgItemInt(hDlg, IDC_EDIT_NUM_BUFFER, NULL, FALSE);
+                    numBuff = min(max(numBuff, 1), 999);
 
-                        pConInfo->ci.NumberOfHistoryBuffers = numBuff;
-                        PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
-                    }
+                    ConInfo->NumberOfHistoryBuffers = numBuff;
+                    PropSheet_Changed(GetParent(hDlg), hDlg);
                     break;
                 }
-                default:
+                }
+            }
+            else
+            if ((HIWORD(wParam) == CBN_SELCHANGE || HIWORD(wParam) == CBN_SELENDOK) &&
+                (LOWORD(wParam) == IDL_CODEPAGE))
+            {
+                HWND hWndList = GetDlgItem(hDlg, IDL_CODEPAGE);
+                INT iItem;
+                UINT CodePage;
+
+                iItem = (INT)SendMessageW(hWndList, CB_GETCURSEL, 0, 0);
+                if (iItem == CB_ERR)
+                    break;
+
+                CodePage = (UINT)SendMessageW(hWndList, CB_GETITEMDATA, iItem, 0);
+                if (CodePage == CB_ERR)
                     break;
+
+                ConInfo->CodePage = CodePage;
+
+                /* Change the property sheet state only if the user validated */
+                if (HIWORD(wParam) == CBN_SELENDOK)
+                    PropSheet_Changed(GetParent(hDlg), hDlg);
             }
+
             break;
         }