[CONSOLE.CPL]: Add a list of available code pages in the console properties dialog.

Display a list of available code pages, as done on Windows (NT/2k/2k3/Vista/7/8, when a CJK language is selected, and as always done on Windows 10 for all languages).
But contrary to Windows, do not limit this list to only CJK + CP-437 codepages, but list *all* the available CPs, retrieved from the registry. These CPs are also those available when using the "chcp" or "mode con cp" commands.
And contrary to Windows (where this is done only for the general console properties), always allow the user to view or change the code page even from the console properties dialog.

[CONSRV]: Support changing the current code page from the console properties dialog.

CORE-12451

svn path=/trunk/; revision=74397
This commit is contained in:
Hermès Bélusca-Maïto 2017-04-24 00:24:34 +00:00
parent d1ad859a6e
commit 34a71f27fc
26 changed files with 331 additions and 29 deletions

View file

@ -25,6 +25,8 @@ BEGIN
GROUPBOX "Промяна на настройките", -1, 143, 85, 130, 77, BS_GROUPBOX | WS_CHILD | WS_VISIBLE | WS_GROUP
CHECKBOX "Режим &бърза обработка", IDC_CHECK_QUICK_EDIT, 150, 97, 102, 15, WS_CHILD | WS_VISIBLE | WS_TABSTOP
CHECKBOX "Режим &вмъкване", IDC_CHECK_INSERT_MODE, 150, 113, 76, 15, WS_CHILD | WS_VISIBLE | WS_TABSTOP
GROUPBOX "Code Page", -1, 7, 170, 238, 31
COMBOBOX IDL_CODEPAGE, 13, 181, 224, 58, CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
END
IDD_PROPPAGEFONT DIALOGEX 0, 0, 253, 220

View file

@ -31,6 +31,8 @@ BEGIN
GROUPBOX "Možnosti úprav", -1, 133, 85, 112, 77, BS_GROUPBOX | WS_CHILD | WS_VISIBLE | WS_GROUP
CHECKBOX "Režim &rychlých úprav", IDC_CHECK_QUICK_EDIT, 140, 97, 102, 15, WS_CHILD | WS_VISIBLE | WS_TABSTOP
CHECKBOX "Režim v&kládání", IDC_CHECK_INSERT_MODE, 140, 113, 76, 15, WS_CHILD | WS_VISIBLE | WS_TABSTOP
GROUPBOX "Code Page", -1, 7, 170, 238, 31
COMBOBOX IDL_CODEPAGE, 13, 181, 224, 58, CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
END
IDD_PROPPAGEFONT DIALOGEX 0, 0, 253, 220

View file

@ -27,6 +27,8 @@ BEGIN
GROUPBOX "Bearbeitungsoptionen", -1, 140, 90, 100, 70, BS_GROUPBOX | WS_CHILD | WS_VISIBLE | WS_GROUP
CHECKBOX "&QuickEdit-Modus", IDC_CHECK_QUICK_EDIT, 150, 100, 70, 15, WS_CHILD | WS_VISIBLE | WS_TABSTOP
CHECKBOX "&Einfügemodus", IDC_CHECK_INSERT_MODE, 150, 120, 70, 15, WS_CHILD | WS_VISIBLE | WS_TABSTOP
GROUPBOX "Code Page", -1, 7, 170, 238, 31
COMBOBOX IDL_CODEPAGE, 13, 181, 224, 58, CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
END
IDD_PROPPAGEFONT DIALOGEX 0, 0, 250, 220

View file

@ -25,6 +25,8 @@ BEGIN
GROUPBOX "Edit Options", -1, 133, 85, 112, 77, BS_GROUPBOX | WS_CHILD | WS_VISIBLE | WS_GROUP
CHECKBOX "&QuickEdit Mode", IDC_CHECK_QUICK_EDIT, 140, 97, 102, 15, WS_CHILD | WS_VISIBLE | WS_TABSTOP
CHECKBOX "&Insert Mode", IDC_CHECK_INSERT_MODE, 140, 113, 76, 15, WS_CHILD | WS_VISIBLE | WS_TABSTOP
GROUPBOX "Code Page", -1, 7, 170, 238, 31
COMBOBOX IDL_CODEPAGE, 13, 181, 224, 58, CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
END
IDD_PROPPAGEFONT DIALOGEX 0, 0, 253, 220

View file

@ -27,6 +27,8 @@ BEGIN
GROUPBOX "Editar Opciones", -1, 140, 90, 100, 70, BS_GROUPBOX | WS_CHILD | WS_VISIBLE | WS_GROUP
CHECKBOX "Modo &Edición rápida", IDC_CHECK_QUICK_EDIT, 150, 100, 60, 15, WS_CHILD | WS_VISIBLE | WS_TABSTOP
CHECKBOX "Modo &Insertar", IDC_CHECK_INSERT_MODE, 150, 120, 60, 15, WS_CHILD | WS_VISIBLE | WS_TABSTOP
GROUPBOX "Code Page", -1, 7, 170, 238, 31
COMBOBOX IDL_CODEPAGE, 13, 181, 224, 58, CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
END
IDD_PROPPAGEFONT DIALOGEX 0, 0, 250, 220

View file

@ -27,6 +27,8 @@ BEGIN
GROUPBOX "Options d'édition", -1, 133, 85, 112, 77, BS_GROUPBOX | WS_CHILD | WS_VISIBLE | WS_GROUP
CHECKBOX "M&ode d'édition rapide", IDC_CHECK_QUICK_EDIT, 140, 97, 102, 15, WS_CHILD | WS_VISIBLE | WS_TABSTOP
CHECKBOX "Mode &insertion", IDC_CHECK_INSERT_MODE, 140, 113, 76, 15, WS_CHILD | WS_VISIBLE | WS_TABSTOP
GROUPBOX "Page de codes", -1, 7, 170, 238, 31
COMBOBOX IDL_CODEPAGE, 13, 181, 224, 58, CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
END
IDD_PROPPAGEFONT DIALOGEX 0, 0, 253, 220

View file

@ -27,6 +27,8 @@ BEGIN
GROUPBOX "אפשרויות עריכה", -1, 133, 85, 112, 77, BS_GROUPBOX | WS_CHILD | WS_VISIBLE | WS_GROUP
CHECKBOX "&QuickEdit Mode", IDC_CHECK_QUICK_EDIT, 140, 97, 102, 15, WS_CHILD | WS_VISIBLE | WS_TABSTOP
CHECKBOX "&Insert Mode", IDC_CHECK_INSERT_MODE, 140, 113, 76, 15, WS_CHILD | WS_VISIBLE | WS_TABSTOP
GROUPBOX "Code Page", -1, 7, 170, 238, 31
COMBOBOX IDL_CODEPAGE, 13, 181, 224, 58, CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
END
IDD_PROPPAGEFONT DIALOGEX 0, 0, 253, 220

View file

@ -27,6 +27,8 @@ BEGIN
GROUPBOX "Opsi Edit", -1, 140, 90, 100, 70, BS_GROUPBOX | WS_CHILD | WS_VISIBLE | WS_GROUP
CHECKBOX "Mode Edit&Cepat", IDC_CHECK_QUICK_EDIT, 150, 100, 60, 15, WS_CHILD | WS_VISIBLE | WS_TABSTOP
CHECKBOX "Mode S&isip", IDC_CHECK_INSERT_MODE, 150, 120, 60, 15, WS_CHILD | WS_VISIBLE | WS_TABSTOP
GROUPBOX "Code Page", -1, 7, 170, 238, 31
COMBOBOX IDL_CODEPAGE, 13, 181, 224, 58, CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
END
IDD_PROPPAGEFONT DIALOGEX 0, 0, 250, 220

View file

@ -27,6 +27,8 @@ BEGIN
GROUPBOX "Opzioni di modifica", -1, 140, 90, 100, 70, BS_GROUPBOX | WS_CHILD | WS_VISIBLE | WS_GROUP
CHECKBOX "Modalità &Modifica rapida", IDC_CHECK_QUICK_EDIT, 150, 100, 60, 15, WS_CHILD | WS_VISIBLE | WS_TABSTOP
CHECKBOX "Modalità &Inserimento", IDC_CHECK_INSERT_MODE, 150, 120, 60, 15, WS_CHILD | WS_VISIBLE | WS_TABSTOP
GROUPBOX "Code Page", -1, 7, 170, 238, 31
COMBOBOX IDL_CODEPAGE, 13, 181, 224, 58, CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
END
IDD_PROPPAGEFONT DIALOGEX 0, 0, 250, 220

View file

@ -25,6 +25,8 @@ BEGIN
GROUPBOX "オプションの編集", -1, 133, 85, 112, 77, BS_GROUPBOX | WS_CHILD | WS_VISIBLE | WS_GROUP
CHECKBOX "&Quick編集モード", IDC_CHECK_QUICK_EDIT, 140, 97, 102, 15, WS_CHILD | WS_VISIBLE | WS_TABSTOP
CHECKBOX "挿入モード(&I)", IDC_CHECK_INSERT_MODE, 140, 113, 76, 15, WS_CHILD | WS_VISIBLE | WS_TABSTOP
GROUPBOX "Code Page", -1, 7, 170, 238, 31
COMBOBOX IDL_CODEPAGE, 13, 181, 224, 58, CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
END
IDD_PROPPAGEFONT DIALOGEX 0, 0, 253, 220

View file

@ -25,6 +25,8 @@ BEGIN
GROUPBOX "Rediger valg", -1, 133, 85, 112, 77, BS_GROUPBOX | WS_CHILD | WS_VISIBLE | WS_GROUP
CHECKBOX "&Hurtigredigeringsmodus", IDC_CHECK_QUICK_EDIT, 140, 97, 102, 15, WS_CHILD | WS_VISIBLE | WS_TABSTOP
CHECKBOX "&Innsettingsmodus", IDC_CHECK_INSERT_MODE, 140, 113, 76, 15, WS_CHILD | WS_VISIBLE | WS_TABSTOP
GROUPBOX "Code Page", -1, 7, 170, 238, 31
COMBOBOX IDL_CODEPAGE, 13, 181, 224, 58, CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
END
IDD_PROPPAGEFONT DIALOGEX 0, 0, 253, 220

View file

@ -32,6 +32,8 @@ BEGIN
GROUPBOX "Edytuj opcje", -1, 140, 90, 100, 70, BS_GROUPBOX | WS_CHILD | WS_VISIBLE | WS_GROUP
CHECKBOX "&Tryb szybkiej edycji", IDC_CHECK_QUICK_EDIT, 150, 100, 60, 15, WS_CHILD | WS_VISIBLE | WS_TABSTOP
CHECKBOX "&Wstaw tryb", IDC_CHECK_INSERT_MODE, 150, 120, 60, 15, WS_CHILD | WS_VISIBLE | WS_TABSTOP
GROUPBOX "Code Page", -1, 7, 170, 238, 31
COMBOBOX IDL_CODEPAGE, 13, 181, 224, 58, CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
END
IDD_PROPPAGEFONT DIALOGEX 0, 0, 250, 220

View file

@ -25,6 +25,8 @@ BEGIN
GROUPBOX "Opções de edição", -1, 133, 85, 112, 77, BS_GROUPBOX | WS_CHILD | WS_VISIBLE | WS_GROUP
CHECKBOX "Modo de edição &rápida", IDC_CHECK_QUICK_EDIT, 140, 97, 102, 15, WS_CHILD | WS_VISIBLE | WS_TABSTOP
CHECKBOX "Modo de &inserção", IDC_CHECK_INSERT_MODE, 140, 113, 76, 15, WS_CHILD | WS_VISIBLE | WS_TABSTOP
GROUPBOX "Code Page", -1, 7, 170, 238, 31
COMBOBOX IDL_CODEPAGE, 13, 181, 224, 58, CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
END
IDD_PROPPAGEFONT DIALOGEX 0, 0, 253, 220

View file

@ -34,6 +34,8 @@ BEGIN
GROUPBOX "Opțiuni de editare", -1, 133, 85, 112, 77, BS_GROUPBOX | WS_CHILD | WS_VISIBLE | WS_GROUP
CHECKBOX "Mod de &editare rapidă”", IDC_CHECK_QUICK_EDIT, 140, 97, 102, 15, WS_CHILD | WS_VISIBLE | WS_TABSTOP
CHECKBOX "Mod de inse&rție”", IDC_CHECK_INSERT_MODE, 140, 113, 76, 15, WS_CHILD | WS_VISIBLE | WS_TABSTOP
GROUPBOX "Code Page", -1, 7, 170, 238, 31
COMBOBOX IDL_CODEPAGE, 13, 181, 224, 58, CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
END
IDD_PROPPAGEFONT DIALOGEX 0, 0, 253, 220

View file

@ -27,6 +27,8 @@ BEGIN
GROUPBOX "Редактирование", -1, 133, 85, 112, 77, BS_GROUPBOX | WS_CHILD | WS_VISIBLE | WS_GROUP
CHECKBOX "&Быстрое редактирование", IDC_CHECK_QUICK_EDIT, 140, 97, 102, 15, WS_CHILD | WS_VISIBLE | WS_TABSTOP
CHECKBOX "&Режим вставки", IDC_CHECK_INSERT_MODE, 140, 113, 76, 15, WS_CHILD | WS_VISIBLE | WS_TABSTOP
GROUPBOX "Code Page", -1, 7, 170, 238, 31
COMBOBOX IDL_CODEPAGE, 13, 181, 224, 58, CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
END
IDD_PROPPAGEFONT DIALOGEX 0, 0, 253, 220

View file

@ -29,6 +29,8 @@ BEGIN
GROUPBOX "Možnosti úprav", -1, 133, 85, 112, 77, BS_GROUPBOX | WS_CHILD | WS_VISIBLE | WS_GROUP
CHECKBOX "&QuickEdit Mode", IDC_CHECK_QUICK_EDIT, 140, 97, 102, 15, WS_CHILD | WS_VISIBLE | WS_TABSTOP
CHECKBOX "&Insert Mode", IDC_CHECK_INSERT_MODE, 140, 113, 76, 15, WS_CHILD | WS_VISIBLE | WS_TABSTOP
GROUPBOX "Code Page", -1, 7, 170, 238, 31
COMBOBOX IDL_CODEPAGE, 13, 181, 224, 58, CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
END
IDD_PROPPAGEFONT DIALOGEX 0, 0, 253, 220

View file

@ -29,6 +29,8 @@ BEGIN
GROUPBOX "Modifiko Opsione", -1, 133, 85, 112, 77, BS_GROUPBOX | WS_CHILD | WS_VISIBLE | WS_GROUP
CHECKBOX "Mënyra e shpejt Modifikimi", IDC_CHECK_QUICK_EDIT, 140, 97, 102, 15, WS_CHILD | WS_VISIBLE | WS_TABSTOP
CHECKBOX "Mënyr Futje", IDC_CHECK_INSERT_MODE, 140, 113, 76, 15, WS_CHILD | WS_VISIBLE | WS_TABSTOP
GROUPBOX "Code Page", -1, 7, 170, 238, 31
COMBOBOX IDL_CODEPAGE, 13, 181, 224, 58, CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
END
IDD_PROPPAGEFONT DIALOGEX 0, 0, 253, 220

View file

@ -27,6 +27,8 @@ BEGIN
GROUPBOX "Düzenleme Seçenekleri", -1, 133, 85, 112, 77, BS_GROUPBOX | WS_CHILD | WS_VISIBLE | WS_GROUP
CHECKBOX "&Hızlı Düzenleme Kipi", IDC_CHECK_QUICK_EDIT, 140, 97, 102, 15, WS_CHILD | WS_VISIBLE | WS_TABSTOP
CHECKBOX "Ek&leme Kipi", IDC_CHECK_INSERT_MODE, 140, 113, 76, 15, WS_CHILD | WS_VISIBLE | WS_TABSTOP
GROUPBOX "Code Page", -1, 7, 170, 238, 31
COMBOBOX IDL_CODEPAGE, 13, 181, 224, 58, CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
END
IDD_PROPPAGEFONT DIALOGEX 0, 0, 253, 220

View file

@ -27,6 +27,8 @@ BEGIN
GROUPBOX "Параметри редагування", -1, 133, 85, 112, 77, BS_GROUPBOX | WS_CHILD | WS_VISIBLE | WS_GROUP
CHECKBOX "&Швидке редагування", IDC_CHECK_QUICK_EDIT, 140, 97, 102, 15, WS_CHILD | WS_VISIBLE | WS_TABSTOP
CHECKBOX "&Режим вставлення", IDC_CHECK_INSERT_MODE, 140, 113, 76, 15, WS_CHILD | WS_VISIBLE | WS_TABSTOP
GROUPBOX "Code Page", -1, 7, 170, 238, 31
COMBOBOX IDL_CODEPAGE, 13, 181, 224, 58, CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
END
IDD_PROPPAGEFONT DIALOGEX 0, 0, 253, 220

View file

@ -27,6 +27,8 @@ BEGIN
GROUPBOX "编辑选项", -1, 133, 85, 112, 77, BS_GROUPBOX | WS_CHILD | WS_VISIBLE | WS_GROUP
CHECKBOX "快速编辑模式(&Q)", IDC_CHECK_QUICK_EDIT, 140, 97, 102, 15, WS_CHILD | WS_VISIBLE | WS_TABSTOP
CHECKBOX "插入模式(&I)", IDC_CHECK_INSERT_MODE, 140, 113, 76, 15, WS_CHILD | WS_VISIBLE | WS_TABSTOP
GROUPBOX "Code Page", -1, 7, 170, 238, 31
COMBOBOX IDL_CODEPAGE, 13, 181, 224, 58, CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
END
IDD_PROPPAGEFONT DIALOGEX 0, 0, 253, 220

View file

@ -27,6 +27,8 @@ BEGIN
GROUPBOX "編輯選項", -1, 133, 85, 112, 77, BS_GROUPBOX | WS_CHILD | WS_VISIBLE | WS_GROUP
CHECKBOX "快速編輯模式(&Q)", IDC_CHECK_QUICK_EDIT, 140, 97, 102, 15, WS_CHILD | WS_VISIBLE | WS_TABSTOP
CHECKBOX "插入模式(&I)", IDC_CHECK_INSERT_MODE, 140, 113, 76, 15, WS_CHILD | WS_VISIBLE | WS_TABSTOP
GROUPBOX "Code Page", -1, 7, 170, 238, 31
COMBOBOX IDL_CODEPAGE, 13, 181, 224, 58, CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
END
IDD_PROPPAGEFONT DIALOGEX 0, 0, 253, 220

View file

@ -4,6 +4,7 @@
* 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"
@ -11,6 +12,231 @@
#define NDEBUG
#include <debug.h>
#define MAX_VALUE_NAME 16383
/*
* A function that locates the insertion point (index) for a given value 'Value'
* in a list 'List' to maintain its sorted order by increasing values.
*
* - When 'BisectRightOrLeft' == TRUE, the bisection is performed to the right,
* i.e. the returned insertion point comes after (to the right of) any existing
* entries of 'Value' in 'List'.
* The returned insertion point 'i' partitions the list 'List' into two halves
* such that:
* all(val <= Value for val in List[start:i[) for the left side, and
* all(val > Value for val in List[i:end+1[) for the right side.
*
* - When 'BisectRightOrLeft' == FALSE, the bisection is performed to the left,
* i.e. the returned insertion point comes before (to the left of) any existing
* entries of 'Value' in 'List'.
* The returned insertion point 'i' partitions the list 'List' into two halves
* such that:
* all(val < Value for val in List[start:i[) for the left side, and
* all(val >= Value for val in List[i:end+1[) for the right side.
*
* The exact value of List[i] may, or may not, be equal to Value, depending on
* whether or not 'Value' is actually present on the list.
*/
static UINT
BisectListSortedByValueEx(
IN HWND hWndList,
IN ULONG_PTR Value,
IN UINT itemStart,
IN UINT itemEnd,
OUT PUINT pValueItem OPTIONAL,
IN BOOL BisectRightOrLeft)
{
UINT iItemStart, iItemEnd, iItem;
ULONG_PTR itemData;
/* Sanity checks */
if (itemStart > itemEnd)
return CB_ERR; // Fail
/* Initialize */
iItemStart = itemStart;
iItemEnd = itemEnd;
iItem = iItemStart;
if (pValueItem)
*pValueItem = CB_ERR;
while (iItemStart <= iItemEnd)
{
/*
* Bisect. Note the following:
* - if iItemEnd == iItemStart + 1, then iItem == iItemStart;
* - if iItemStart == iItemEnd, then iItemStart == iItem == iItemEnd.
* In all but the last case, iItemStart <= iItem < iItemEnd.
*/
iItem = (iItemStart + iItemEnd) / 2;
itemData = (ULONG_PTR)SendMessageW(hWndList, CB_GETITEMDATA, (WPARAM)iItem, 0);
if (itemData == CB_ERR)
return CB_ERR; // Fail
if (Value == itemData)
{
/* Found a candidate */
if (pValueItem)
*pValueItem = iItem;
/*
* Try to find the last element (if BisectRightOrLeft == TRUE)
* or the first element (if BisectRightOrLeft == FALSE).
*/
if (BisectRightOrLeft)
{
iItemStart = iItem + 1; // iItemStart may be > iItemEnd
}
else
{
if (iItem <= itemStart) break;
iItemEnd = iItem - 1; // iItemEnd may be < iItemStart, i.e. iItemStart may be > iItemEnd
}
}
else if (Value < itemData)
{
if (iItem <= itemStart) break;
/* The value should be before iItem */
iItemEnd = iItem - 1; // iItemEnd may be < iItemStart, i.e. iItemStart may be > iItemEnd, if iItem == iItemStart.
}
else // if (itemData < Value)
{
/* The value should be after iItem */
iItemStart = iItem + 1; // iItemStart may be > iItemEnd, if iItem == iItemEnd.
}
/* Here, iItemStart may be == iItemEnd */
}
return iItemStart;
}
static UINT
BisectListSortedByValue(
IN HWND hWndList,
IN ULONG_PTR Value,
OUT PUINT pValueItem OPTIONAL,
IN BOOL BisectRightOrLeft)
{
INT iItemEnd = (INT)SendMessageW(hWndList, CB_GETCOUNT, 0, 0);
if (iItemEnd == CB_ERR || iItemEnd <= 0)
return CB_ERR; // Fail
return BisectListSortedByValueEx(hWndList, Value,
0, (UINT)(iItemEnd - 1),
pValueItem,
BisectRightOrLeft);
}
static VOID
AddCodePage(
IN HWND hWndList,
IN UINT CodePage)
{
UINT iItem, iDupItem;
CPINFOEXW CPInfo;
/*
* 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))
{
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);
_snwprintf(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(hWndList, CodePage, &iDupItem, TRUE);
if (iItem == CB_ERR)
iItem = 0;
if (iDupItem != CB_ERR)
return;
iItem = (INT)SendMessageW(hWndList, CB_INSERTSTRING, iItem, (LPARAM)CPInfo.CodePageName);
if (iItem != CB_ERR && iItem != CB_ERRSPACE)
iItem = SendMessageW(hWndList, CB_SETITEMDATA, iItem, CodePage);
}
static VOID
BuildCodePageList(IN HWND hDlg)
{
HWND hWndList;
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;
}
hWndList = GetDlgItem(hDlg, IDL_CODEPAGE);
/* 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
{
/* Ignore these parameters, prepare for next iteration */
dwSize = ARRAYSIZE(szValueName);
++dwIndex;
/* Check the value type validity */
if (dwType != REG_SZ)
continue;
/*
* 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(hWndList, CodePage);
}
RegCloseKey(hKey);
/* Add the special UTF-7 (CP_UTF7 65000) and UTF-8 (CP_UTF8 65001) code pages */
AddCodePage(hWndList, CP_UTF7);
AddCodePage(hWndList, CP_UTF8);
/* Find and select the current code page in the sorted list */
if (BisectListSortedByValue(hWndList, ConInfo->CodePage, &CodePage, FALSE) == CB_ERR ||
CodePage == CB_ERR)
{
/* Not found, select the first element */
CodePage = 0;
}
SendMessageW(hWndList, CB_SETCURSEL, (WPARAM)CodePage, 0);
}
static VOID
UpdateDialogElements(HWND hwndDlg, PCONSOLE_STATE_INFO pConInfo)
{
@ -21,42 +247,42 @@ UpdateDialogElements(HWND hwndDlg, PCONSOLE_STATE_INFO pConInfo)
{
/* Small cursor */
hDlgCtrl = GetDlgItem(hwndDlg, IDC_RADIO_SMALL_CURSOR);
SendMessage(hDlgCtrl, BM_SETCHECK, (WPARAM)BST_CHECKED, 0);
SendMessageW(hDlgCtrl, BM_SETCHECK, (WPARAM)BST_CHECKED, 0);
hDlgCtrl = GetDlgItem(hwndDlg, IDC_RADIO_MEDIUM_CURSOR);
SendMessage(hDlgCtrl, BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0);
SendMessageW(hDlgCtrl, BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0);
hDlgCtrl = GetDlgItem(hwndDlg, IDC_RADIO_LARGE_CURSOR);
SendMessage(hDlgCtrl, BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0);
SendMessageW(hDlgCtrl, BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0);
}
else if (pConInfo->CursorSize <= 50)
{
hDlgCtrl = GetDlgItem(hwndDlg, IDC_RADIO_MEDIUM_CURSOR);
SendMessage(hDlgCtrl, BM_SETCHECK, (WPARAM)BST_CHECKED, 0);
SendMessageW(hDlgCtrl, BM_SETCHECK, (WPARAM)BST_CHECKED, 0);
hDlgCtrl = GetDlgItem(hwndDlg, IDC_RADIO_SMALL_CURSOR);
SendMessage(hDlgCtrl, BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0);
SendMessageW(hDlgCtrl, BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0);
hDlgCtrl = GetDlgItem(hwndDlg, IDC_RADIO_LARGE_CURSOR);
SendMessage(hDlgCtrl, BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0);
SendMessageW(hDlgCtrl, BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0);
}
else /* if (pConInfo->CursorSize <= 100) */
{
hDlgCtrl = GetDlgItem(hwndDlg, IDC_RADIO_LARGE_CURSOR);
SendMessage(hDlgCtrl, BM_SETCHECK, (WPARAM)BST_CHECKED, 0);
SendMessageW(hDlgCtrl, BM_SETCHECK, (WPARAM)BST_CHECKED, 0);
hDlgCtrl = GetDlgItem(hwndDlg, IDC_RADIO_SMALL_CURSOR);
SendMessage(hDlgCtrl, BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0);
SendMessageW(hDlgCtrl, BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0);
hDlgCtrl = GetDlgItem(hwndDlg, IDC_RADIO_MEDIUM_CURSOR);
SendMessage(hDlgCtrl, BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0);
SendMessageW(hDlgCtrl, BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0);
}
/* Update num buffers */
hDlgCtrl = GetDlgItem(hwndDlg, IDC_UPDOWN_NUM_BUFFER);
SendMessage(hDlgCtrl, UDM_SETRANGE, 0, MAKELONG(999, 1));
SendMessageW(hDlgCtrl, UDM_SETRANGE, 0, MAKELONG(999, 1));
SetDlgItemInt(hwndDlg, 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));
SendMessageW(hDlgCtrl, UDM_SETRANGE, 0, MAKELONG(999, 1));
SetDlgItemInt(hwndDlg, IDC_EDIT_BUFFER_SIZE, pConInfo->HistoryBufferSize, FALSE);
/* Update discard duplicates */
@ -67,18 +293,18 @@ UpdateDialogElements(HWND hwndDlg, PCONSOLE_STATE_INFO pConInfo)
if (pConInfo->FullScreen)
{
hDlgCtrl = GetDlgItem(hwndDlg, IDC_RADIO_DISPLAY_FULL);
SendMessage(hDlgCtrl, BM_SETCHECK, (WPARAM)BST_CHECKED, 0);
SendMessageW(hDlgCtrl, BM_SETCHECK, (WPARAM)BST_CHECKED, 0);
hDlgCtrl = GetDlgItem(hwndDlg, IDC_RADIO_DISPLAY_WINDOW);
SendMessage(hDlgCtrl, BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0);
SendMessageW(hDlgCtrl, BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0);
}
else
{
hDlgCtrl = GetDlgItem(hwndDlg, IDC_RADIO_DISPLAY_WINDOW);
SendMessage(hDlgCtrl, BM_SETCHECK, (WPARAM)BST_CHECKED, 0);
SendMessageW(hDlgCtrl, BM_SETCHECK, (WPARAM)BST_CHECKED, 0);
hDlgCtrl = GetDlgItem(hwndDlg, IDC_RADIO_DISPLAY_FULL);
SendMessage(hDlgCtrl, BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0);
SendMessageW(hDlgCtrl, BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0);
}
/* Update quick edit */
@ -101,6 +327,7 @@ OptionsProc(HWND hwndDlg,
{
case WM_INITDIALOG:
{
BuildCodePageList(hwndDlg);
UpdateDialogElements(hwndDlg, ConInfo);
return TRUE;
}
@ -172,48 +399,48 @@ OptionsProc(HWND hwndDlg,
}
case IDC_CHECK_QUICK_EDIT:
{
lResult = SendMessage((HWND)lParam, BM_GETCHECK, 0, 0);
lResult = SendMessageW((HWND)lParam, BM_GETCHECK, 0, 0);
if (lResult == BST_CHECKED)
{
ConInfo->QuickEdit = FALSE;
SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0);
SendMessageW((HWND)lParam, BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0);
}
else if (lResult == BST_UNCHECKED)
{
ConInfo->QuickEdit = TRUE;
SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_CHECKED, 0);
SendMessageW((HWND)lParam, BM_SETCHECK, (WPARAM)BST_CHECKED, 0);
}
PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
break;
}
case IDC_CHECK_INSERT_MODE:
{
lResult = SendMessage((HWND)lParam, BM_GETCHECK, 0, 0);
lResult = SendMessageW((HWND)lParam, BM_GETCHECK, 0, 0);
if (lResult == BST_CHECKED)
{
ConInfo->InsertMode = FALSE;
SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0);
SendMessageW((HWND)lParam, BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0);
}
else if (lResult == BST_UNCHECKED)
{
ConInfo->InsertMode = TRUE;
SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_CHECKED, 0);
SendMessageW((HWND)lParam, BM_SETCHECK, (WPARAM)BST_CHECKED, 0);
}
PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
break;
}
case IDC_CHECK_DISCARD_DUPLICATES:
{
lResult = SendMessage((HWND)lParam, BM_GETCHECK, 0, 0);
lResult = SendMessageW((HWND)lParam, BM_GETCHECK, 0, 0);
if (lResult == BST_CHECKED)
{
ConInfo->HistoryNoDup = FALSE;
SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0);
SendMessageW((HWND)lParam, BM_SETCHECK, (WPARAM)BST_UNCHECKED, 0);
}
else if (lResult == BST_UNCHECKED)
{
ConInfo->HistoryNoDup = TRUE;
SendMessage((HWND)lParam, BM_SETCHECK, (WPARAM)BST_CHECKED, 0);
SendMessageW((HWND)lParam, BM_SETCHECK, (WPARAM)BST_CHECKED, 0);
}
PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
break;
@ -246,6 +473,26 @@ OptionsProc(HWND hwndDlg,
}
break;
}
case IDL_CODEPAGE:
{
if (HIWORD(wParam) == CBN_SELENDOK)
{
INT iItem;
UINT CodePage;
iItem = (INT)SendMessageW((HWND)lParam, CB_GETCURSEL, 0, 0);
if (iItem != CB_ERR)
{
CodePage = (UINT)SendMessageW((HWND)lParam, CB_GETITEMDATA, iItem, 0);
if (CodePage != CB_ERR)
{
ConInfo->CodePage = CodePage;
PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
}
}
}
break;
}
default:
break;
}

View file

@ -21,9 +21,10 @@
#define IDC_UPDOWN_NUM_BUFFER 206
#define IDC_RADIO_SMALL_CURSOR 207
#define IDC_RADIO_MEDIUM_CURSOR 208
#define IDC_RADIO_LARGE_CURSOR 209
#define IDC_RADIO_DISPLAY_WINDOW 210
#define IDC_RADIO_LARGE_CURSOR 209
#define IDC_RADIO_DISPLAY_WINDOW 210
#define IDC_RADIO_DISPLAY_FULL 211
#define IDL_CODEPAGE 212
/* Apply dialog */
#define IDC_RADIO_APPLY_ALL 300

View file

@ -217,7 +217,8 @@ ConDrvInitConsole(OUT PCONSOLE* NewConsole,
}
/* Set-up the code page */
Console->InputCodePage = Console->OutputCodePage = ConsoleInfo->CodePage;
if (IsValidCodePage(ConsoleInfo->CodePage))
Console->InputCodePage = Console->OutputCodePage = ConsoleInfo->CodePage;
/* Initialize a new text-mode screen buffer with default settings */
ScreenBufferInfo.ScreenBufferSize = ConsoleInfo->ScreenBufferSize;

View file

@ -156,7 +156,9 @@ GuiConsoleShowConsoleProperties(PGUI_CONSOLE_DATA GuiData,
pSharedInfo->ScreenAttributes = DEFAULT_SCREEN_ATTRIB;
pSharedInfo->PopupAttributes = DEFAULT_POPUP_ATTRIB ;
}
/// pSharedInfo->CodePage;
/* We display the output code page only */
pSharedInfo->CodePage = Console->OutputCodePage;
/* GUI Information */
wcsncpy(pSharedInfo->FaceName, GuiData->GuiInfo.FaceName, LF_FACESIZE);
@ -317,7 +319,7 @@ GuiApplyUserSettings(PGUI_CONSOLE_DATA GuiData,
ConInfo.HistoryBufferSize = pConInfo->HistoryBufferSize;
ConInfo.NumberOfHistoryBuffers = pConInfo->NumberOfHistoryBuffers;
ConInfo.HistoryNoDup = !!pConInfo->HistoryNoDup;
ConInfo.CodePage = pConInfo->CodePage;
ConInfo.CodePage = pConInfo->CodePage; // Done in ConSrvApplyUserSettings
#endif
/*

View file

@ -52,6 +52,15 @@ ConSrvApplyUserSettings(IN PCONSOLE Console,
ActiveBuffer->CursorInfo.bVisible = (ConsoleInfo->CursorSize != 0);
ActiveBuffer->CursorInfo.dwSize = min(max(ConsoleInfo->CursorSize, 0), 100);
/* Update the code page */
if ((Console->OutputCodePage != ConsoleInfo->CodePage) &&
IsValidCodePage(ConsoleInfo->CodePage))
{
Console->InputCodePage = Console->OutputCodePage = ConsoleInfo->CodePage;
// ConDrvSetConsoleCP(Console, ConsoleInfo->CodePage, TRUE); // Output
// ConDrvSetConsoleCP(Console, ConsoleInfo->CodePage, FALSE); // Input
}
// FIXME: Check ConsoleInfo->WindowSize with respect to
// TermGetLargestConsoleWindowSize(...).