ReactOS  0.4.15-dev-5496-g599ba9c
options.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS Console Configuration DLL
3  * LICENSE: GPL - See COPYING in the top level directory
4  * FILE: dll/cpl/console/options.c
5  * PURPOSE: Options dialog
6  * PROGRAMMERS: Johannes Anderwald (johannes.anderwald@reactos.org)
7  * Hermes Belusca-Maito (hermes.belusca@sfr.fr)
8  */
9 
10 #include "console.h"
11 
12 #define NDEBUG
13 #include <debug.h>
14 
15 #define MAX_VALUE_NAME 16383
16 
17 
18 static INT
20 {
21  return (INT)SendMessageW(ListCtl->hWndList, CB_GETCOUNT, 0, 0);
22 }
23 
24 static ULONG_PTR
26 {
27  return (ULONG_PTR)SendMessageW(ListCtl->hWndList, CB_GETITEMDATA, (WPARAM)Index, 0);
28 }
29 
30 static VOID
32  IN PLIST_CTL ListCtl,
33  IN UINT CodePage)
34 {
35  UINT iItem, iDupItem;
36  CPINFOEXW CPInfo;
37 
38  /*
39  * Add only valid code pages, that is:
40  * - If the CodePage is one of the reserved (alias) values:
41  * CP_ACP == 0 ; CP_OEMCP == 1 ; CP_MACCP == 2 ; CP_THREAD_ACP == 3 ;
42  * or the deprecated CP_SYMBOL == 42 (see http://archives.miloush.net/michkap/archive/2005/11/08/490495.html)
43  * it is considered invalid.
44  * - If IsValidCodePage() fails because the code page is listed but
45  * not installed on the system, it is also considered invalid.
46  */
47  if (CodePage == CP_ACP || CodePage == CP_OEMCP || CodePage == CP_MACCP ||
48  CodePage == CP_THREAD_ACP || CodePage == CP_SYMBOL || !IsValidCodePage(CodePage))
49  {
50  return;
51  }
52 
53  /* Retrieve the code page display name */
54  if (!GetCPInfoExW(CodePage, 0, &CPInfo))
55  {
56  /* We failed, just use the code page value as its name */
57  // _ultow(CodePage, CPInfo.CodePageName, 10);
58  StringCchPrintfW(CPInfo.CodePageName, ARRAYSIZE(CPInfo.CodePageName), L"%lu", CodePage);
59  }
60 
61  /* Add the code page into the list, sorted by code page value. Avoid any duplicates. */
62  iDupItem = CB_ERR;
63  iItem = BisectListSortedByValue(ListCtl, CodePage, &iDupItem, TRUE);
64  if (iItem == CB_ERR)
65  iItem = 0;
66  if (iDupItem != CB_ERR)
67  return;
68  iItem = (UINT)SendMessageW(ListCtl->hWndList, CB_INSERTSTRING, iItem, (LPARAM)CPInfo.CodePageName);
69  if (iItem != CB_ERR && iItem != CB_ERRSPACE)
70  iItem = SendMessageW(ListCtl->hWndList, CB_SETITEMDATA, iItem, CodePage);
71 }
72 
73 static VOID
75  IN HWND hDlg,
77 {
78  LIST_CTL ListCtl;
79  LRESULT lResult;
80  HKEY hKey;
81  DWORD dwIndex, dwType;
82  DWORD cchValueName;
83  UINT CodePage;
84 
85  /* Valid code page value names are string representations
86  * of their corresponding decimal values, that are not larger
87  * than MAXUSHORT == 65535. */
88  WCHAR szValueName[sizeof("65535")];
89 
90  /* Open the Nls\CodePage key */
91  // #define REGSTR_PATH_CODEPAGE TEXT("System\\CurrentControlSet\\Control\\Nls\\CodePage")
93  L"System\\CurrentControlSet\\Control\\Nls\\CodePage",
94  0,
96  &hKey) != ERROR_SUCCESS)
97  {
98  return;
99  }
100 
101  ListCtl.hWndList = GetDlgItem(hDlg, IDL_CODEPAGE);
102  ListCtl.GetCount = List_GetCount;
103  ListCtl.GetData = List_GetData;
104 
105  /* Enumerate all the available code pages on the system */
106  for (dwIndex = 0, cchValueName = ARRAYSIZE(szValueName);
107  (lResult = RegEnumValueW(hKey, dwIndex,
108  szValueName, &cchValueName,
109  NULL, &dwType,
111  ++dwIndex, cchValueName = ARRAYSIZE(szValueName))
112  {
113  /* Ignore if we failed for another reason, e.g. because
114  * the value name is too long (and thus, invalid). */
115  if (lResult != ERROR_SUCCESS)
116  continue;
117 
118  /* Validate the value name (exclude the unnamed value) */
119  if (!cchValueName || (*szValueName == UNICODE_NULL))
120  continue;
121  /* Too large value names have already been handled with ERROR_MORE_DATA */
122  ASSERT((cchValueName < ARRAYSIZE(szValueName)) &&
123  (szValueName[cchValueName] == UNICODE_NULL));
124 
125  /* Validate the value type */
126  if (dwType != REG_SZ)
127  continue;
128 
129  /*
130  * Add the code page into the list.
131  * If _wtol fails and returns 0, the code page is considered invalid
132  * (and indeed this value corresponds to the CP_ACP alias too).
133  */
134  CodePage = (UINT)_wtol(szValueName);
135  if (CodePage == 0) continue;
136  AddCodePage(&ListCtl, CodePage);
137  }
138 
139  RegCloseKey(hKey);
140 
141  /* Add the special UTF-7 (CP_UTF7 65000) and UTF-8 (CP_UTF8 65001) code pages */
142  AddCodePage(&ListCtl, CP_UTF7);
143  AddCodePage(&ListCtl, CP_UTF8);
144 
145  /* Find and select the current code page in the sorted list */
146  if (BisectListSortedByValue(&ListCtl, CurrentCodePage, &CodePage, FALSE) == CB_ERR ||
147  CodePage == CB_ERR)
148  {
149  /* Not found, select the first element */
150  CodePage = 0;
151  }
152  SendMessageW(ListCtl.hWndList, CB_SETCURSEL, (WPARAM)CodePage, 0);
153 }
154 
155 static VOID
157  IN HWND hDlg,
158  IN PCONSOLE_STATE_INFO pConInfo)
159 {
160  /* Update the cursor size */
161  if (pConInfo->CursorSize <= 25)
162  {
163  /* Small cursor */
165  // CheckDlgButton(hDlg, IDC_RADIO_SMALL_CURSOR , BST_CHECKED);
166  // CheckDlgButton(hDlg, IDC_RADIO_MEDIUM_CURSOR, BST_UNCHECKED);
167  // CheckDlgButton(hDlg, IDC_RADIO_LARGE_CURSOR , BST_UNCHECKED);
168  }
169  else if (pConInfo->CursorSize <= 50)
170  {
171  /* Medium cursor */
173  // CheckDlgButton(hDlg, IDC_RADIO_SMALL_CURSOR , BST_UNCHECKED);
174  // CheckDlgButton(hDlg, IDC_RADIO_MEDIUM_CURSOR, BST_CHECKED);
175  // CheckDlgButton(hDlg, IDC_RADIO_LARGE_CURSOR , BST_UNCHECKED);
176  }
177  else /* if (pConInfo->CursorSize <= 100) */
178  {
179  /* Large cursor */
181  // CheckDlgButton(hDlg, IDC_RADIO_SMALL_CURSOR , BST_UNCHECKED);
182  // CheckDlgButton(hDlg, IDC_RADIO_MEDIUM_CURSOR, BST_UNCHECKED);
183  // CheckDlgButton(hDlg, IDC_RADIO_LARGE_CURSOR , BST_CHECKED);
184  }
185 
186  /* Update the number of history buffers */
188  SetDlgItemInt(hDlg, IDC_EDIT_NUM_BUFFER, pConInfo->NumberOfHistoryBuffers, FALSE);
189 
190  /* Update the history buffer size */
192  SetDlgItemInt(hDlg, IDC_EDIT_BUFFER_SIZE, pConInfo->HistoryBufferSize, FALSE);
193 
194  /* Update discard duplicates */
196  pConInfo->HistoryNoDup ? BST_CHECKED : BST_UNCHECKED);
197 
198  /* Update full/window screen state */
199  if (pConInfo->FullScreen)
200  {
202  // CheckDlgButton(hDlg, IDC_RADIO_DISPLAY_WINDOW, BST_UNCHECKED);
203  // CheckDlgButton(hDlg, IDC_RADIO_DISPLAY_FULL , BST_CHECKED);
204  }
205  else
206  {
208  // CheckDlgButton(hDlg, IDC_RADIO_DISPLAY_WINDOW, BST_CHECKED);
209  // CheckDlgButton(hDlg, IDC_RADIO_DISPLAY_FULL , BST_UNCHECKED);
210  }
211 
212  /* Update "Quick-edit" state */
214  pConInfo->QuickEdit ? BST_CHECKED : BST_UNCHECKED);
215 
216  /* Update "Insert mode" state */
218  pConInfo->InsertMode ? BST_CHECKED : BST_UNCHECKED);
219 }
220 
221 INT_PTR
222 CALLBACK
224  UINT uMsg,
225  WPARAM wParam,
226  LPARAM lParam)
227 {
228  switch (uMsg)
229  {
230  case WM_INITDIALOG:
231  {
234  return TRUE;
235  }
236 
237  case WM_NOTIFY:
238  {
239  LPPSHNOTIFY lppsn = (LPPSHNOTIFY)lParam;
240 
241  if (lppsn->hdr.code == UDN_DELTAPOS)
242  {
243  LPNMUPDOWN lpnmud = (LPNMUPDOWN)lParam;
244 
245  if (lppsn->hdr.idFrom == IDC_UPDOWN_BUFFER_SIZE)
246  {
247  lpnmud->iPos = min(max(lpnmud->iPos + lpnmud->iDelta, 1), 999);
248  ConInfo->HistoryBufferSize = lpnmud->iPos;
249  PropSheet_Changed(GetParent(hDlg), hDlg);
250  }
251  else if (lppsn->hdr.idFrom == IDC_UPDOWN_NUM_BUFFER)
252  {
253  lpnmud->iPos = min(max(lpnmud->iPos + lpnmud->iDelta, 1), 999);
255  PropSheet_Changed(GetParent(hDlg), hDlg);
256  }
257  }
258  else if (lppsn->hdr.code == PSN_APPLY)
259  {
260  ApplyConsoleInfo(hDlg);
261  return TRUE;
262  }
263  break;
264  }
265 
266  case WM_COMMAND:
267  {
268  if (HIWORD(wParam) == BN_CLICKED)
269  {
270  switch (LOWORD(wParam))
271  {
273  {
274  ConInfo->CursorSize = 25;
275  PropSheet_Changed(GetParent(hDlg), hDlg);
276  break;
277  }
279  {
280  ConInfo->CursorSize = 50;
281  PropSheet_Changed(GetParent(hDlg), hDlg);
282  break;
283  }
285  {
286  ConInfo->CursorSize = 100;
287  PropSheet_Changed(GetParent(hDlg), hDlg);
288  break;
289  }
291  {
293  PropSheet_Changed(GetParent(hDlg), hDlg);
294  break;
295  }
297  {
299  PropSheet_Changed(GetParent(hDlg), hDlg);
300  break;
301  }
303  {
304  ConInfo->QuickEdit = (IsDlgButtonChecked(hDlg, IDC_CHECK_QUICK_EDIT) == BST_CHECKED); // BST_UNCHECKED or BST_INDETERMINATE => FALSE
305  PropSheet_Changed(GetParent(hDlg), hDlg);
306  break;
307  }
309  {
310  ConInfo->InsertMode = (IsDlgButtonChecked(hDlg, IDC_CHECK_INSERT_MODE) == BST_CHECKED); // BST_UNCHECKED or BST_INDETERMINATE => FALSE
311  PropSheet_Changed(GetParent(hDlg), hDlg);
312  break;
313  }
315  {
316  ConInfo->HistoryNoDup = (IsDlgButtonChecked(hDlg, IDC_CHECK_DISCARD_DUPLICATES) == BST_CHECKED); // BST_UNCHECKED or BST_INDETERMINATE => FALSE
317  PropSheet_Changed(GetParent(hDlg), hDlg);
318  break;
319  }
320  }
321  }
322  else
323  if (HIWORD(wParam) == EN_KILLFOCUS)
324  {
325  switch (LOWORD(wParam))
326  {
328  {
329  DWORD sizeBuff;
330 
331  sizeBuff = GetDlgItemInt(hDlg, IDC_EDIT_BUFFER_SIZE, NULL, FALSE);
332  sizeBuff = min(max(sizeBuff, 1), 999);
333 
334  ConInfo->HistoryBufferSize = sizeBuff;
335  PropSheet_Changed(GetParent(hDlg), hDlg);
336  break;
337  }
338  case IDC_EDIT_NUM_BUFFER:
339  {
340  DWORD numBuff;
341 
342  numBuff = GetDlgItemInt(hDlg, IDC_EDIT_NUM_BUFFER, NULL, FALSE);
343  numBuff = min(max(numBuff, 1), 999);
344 
345  ConInfo->NumberOfHistoryBuffers = numBuff;
346  PropSheet_Changed(GetParent(hDlg), hDlg);
347  break;
348  }
349  }
350  }
351  else
352  // (HIWORD(wParam) == CBN_KILLFOCUS)
354  (LOWORD(wParam) == IDL_CODEPAGE))
355  {
357  INT iItem;
358  UINT CodePage;
359 
360  iItem = (INT)SendMessageW(hWndList, CB_GETCURSEL, 0, 0);
361  if (iItem == CB_ERR)
362  break;
363 
364  CodePage = (UINT)SendMessageW(hWndList, CB_GETITEMDATA, iItem, 0);
365  if (CodePage == CB_ERR)
366  break;
367 
368  /* If the user has selected a different code page... */
369  if ((HIWORD(wParam) == CBN_SELENDOK) && (CodePage != ConInfo->CodePage))
370  {
371  /* ... update the code page and change the property sheet state */
372  ConInfo->CodePage = CodePage;
374  PropSheet_Changed(GetParent(hDlg), hDlg);
375  }
376  }
377 
378  break;
379  }
380 
381  default:
382  break;
383  }
384 
385  return FALSE;
386 }
#define CB_SETITEMDATA
Definition: winuser.h:1956
BOOL WINAPI CheckDlgButton(_In_ HWND, _In_ int, _In_ UINT)
#define IN
Definition: typedefs.h:39
#define max(a, b)
Definition: svc.c:63
#define IDC_CHECK_INSERT_MODE
Definition: resource.h:20
#define ERROR_SUCCESS
Definition: deptool.c:10
#define ERROR_NO_MORE_ITEMS
Definition: compat.h:105
#define IDC_RADIO_LARGE_CURSOR
Definition: resource.h:28
#define IDC_RADIO_SMALL_CURSOR
Definition: resource.h:26
struct _PSHNOTIFY * LPPSHNOTIFY
#define CP_UTF7
Definition: winnls.h:235
#define TRUE
Definition: types.h:120
WCHAR CodePageName[MAX_PATH]
Definition: winnls.h:599
#define CP_ACP
Definition: compat.h:109
#define CB_GETITEMDATA
Definition: winuser.h:1940
struct _NM_UPDOWN * LPNMUPDOWN
#define INT
Definition: polytest.cpp:20
#define CALLBACK
Definition: compat.h:35
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
UINT_PTR WPARAM
Definition: windef.h:207
#define PSN_APPLY
Definition: prsht.h:117
#define IDC_CHECK_DISCARD_DUPLICATES
Definition: resource.h:21
int32_t INT_PTR
Definition: typedefs.h:64
static HWND hWndList[5+1]
Definition: SetParent.c:10
#define CP_SYMBOL
Definition: winnls.h:234
int32_t INT
Definition: typedefs.h:58
#define CB_GETCURSEL
Definition: winuser.h:1933
WPARAM wParam
Definition: combotst.c:138
#define IDC_EDIT_BUFFER_SIZE
Definition: resource.h:22
HWND hWndList
Definition: console.h:93
uint32_t ULONG_PTR
Definition: typedefs.h:65
UINT code
Definition: winuser.h:3149
NMHDR hdr
Definition: prsht.h:330
#define L(x)
Definition: ntvdm.h:50
#define EN_KILLFOCUS
Definition: winuser.h:2015
#define IDC_CHECK_QUICK_EDIT
Definition: resource.h:19
#define FALSE
Definition: types.h:117
#define CP_UTF8
Definition: nls.h:20
#define UNICODE_NULL
#define CBN_SELENDOK
Definition: winuser.h:1971
UINT_PTR idFrom
Definition: winuser.h:3148
static UINT CurrentCodePage
Definition: font.c:48
#define IDC_RADIO_DISPLAY_FULL
Definition: resource.h:30
#define MAKELONG(a, b)
Definition: typedefs.h:249
#define CB_INSERTSTRING
Definition: winuser.h:1947
LONG WINAPI RegEnumValueW(_In_ HKEY hKey, _In_ DWORD index, _Out_ LPWSTR value, _Inout_ PDWORD val_count, _Reserved_ PDWORD reserved, _Out_opt_ PDWORD type, _Out_opt_ LPBYTE data, _Inout_opt_ PDWORD count)
Definition: reg.c:2853
UINT WINAPI GetDlgItemInt(_In_ HWND, _In_ int, _Out_opt_ PBOOL, _In_ BOOL)
static INT List_GetCount(IN PLIST_CTL ListCtl)
Definition: options.c:19
VOID ApplyConsoleInfo(HWND hwndDlg)
Definition: console.c:88
LONG_PTR LPARAM
Definition: windef.h:208
#define UDM_SETRANGE
Definition: commctrl.h:2141
UINT WINAPI IsDlgButtonChecked(_In_ HWND, _In_ int)
#define CB_ERR
Definition: winuser.h:2425
#define ASSERT(a)
Definition: mode.c:44
HWND WINAPI GetDlgItem(_In_opt_ HWND, _In_ int)
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define PropSheet_Changed(d, w)
Definition: prsht.h:344
_In_ WDFCOLLECTION _In_ ULONG Index
ULONG HistoryBufferSize
Definition: settings.h:50
#define BN_CLICKED
Definition: winuser.h:1915
unsigned long DWORD
Definition: ntddk_ex.h:95
LRESULT WINAPI SendDlgItemMessageW(_In_ HWND, _In_ int, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
PLIST_GETDATA GetData
Definition: console.h:95
static ULONG_PTR List_GetData(IN PLIST_CTL ListCtl, IN INT Index)
Definition: options.c:25
PLIST_GETCOUNT GetCount
Definition: console.h:94
BOOL WINAPI SetDlgItemInt(_In_ HWND, _In_ int, _In_ UINT, _In_ BOOL)
#define UDN_DELTAPOS
Definition: commctrl.h:2169
#define CB_ERRSPACE
Definition: winuser.h:2426
#define CB_SETCURSEL
Definition: winuser.h:1951
#define WM_COMMAND
Definition: winuser.h:1730
static VOID BuildCodePageList(IN HWND hDlg, IN UINT CurrentCodePage)
Definition: options.c:74
#define BST_UNCHECKED
Definition: winuser.h:199
#define IDL_CODEPAGE
Definition: resource.h:31
int iDelta
Definition: commctrl.h:2166
HWND WINAPI GetParent(_In_ HWND)
BOOL WINAPI IsValidCodePage(UINT CodePage)
Definition: nls.c:1604
ULONG NumberOfHistoryBuffers
Definition: settings.h:51
FxAutoRegKey hKey
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
static VOID UpdateDialogElements(IN HWND hDlg, IN PCONSOLE_STATE_INFO pConInfo)
Definition: options.c:156
LRESULT WINAPI SendMessageW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
STRSAFEAPI StringCchPrintfW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszFormat,...)
Definition: strsafe.h:530
FONT_PREVIEW FontPreview
Definition: font.c:21
PCONSOLE_STATE_INFO ConInfo
Definition: console.c:23
#define min(a, b)
Definition: monoChain.cc:55
unsigned int UINT
Definition: ndis.h:50
_Check_return_ _CRTIMP long __cdecl _wtol(_In_z_ const wchar_t *_Str)
#define NULL
Definition: types.h:112
#define IDC_RADIO_MEDIUM_CURSOR
Definition: resource.h:27
#define CBN_SELCHANGE
Definition: winuser.h:1969
#define ResetFontPreview(Preview)
Definition: console.h:65
#define BST_CHECKED
Definition: winuser.h:197
static VOID AddCodePage(IN PLIST_CTL ListCtl, IN UINT CodePage)
Definition: options.c:31
#define IDC_EDIT_NUM_BUFFER
Definition: resource.h:24
#define IDC_UPDOWN_BUFFER_SIZE
Definition: resource.h:23
#define IDC_RADIO_DISPLAY_WINDOW
Definition: resource.h:29
#define HIWORD(l)
Definition: typedefs.h:247
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3356
BOOL WINAPI GetCPInfoExW(UINT CodePage, DWORD dwFlags, LPCPINFOEXW lpCPInfoEx)
Definition: nls.c:2093
INT_PTR CALLBACK OptionsProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
Definition: options.c:223
#define IDC_UPDOWN_NUM_BUFFER
Definition: resource.h:25
BOOL WINAPI CheckRadioButton(_In_ HWND, _In_ int, _In_ int, _In_ int)
#define CB_GETCOUNT
Definition: winuser.h:1932
UINT BisectListSortedByValue(IN PLIST_CTL ListCtl, IN ULONG_PTR Value, OUT PUINT pValueItem OPTIONAL, IN BOOL BisectRightOrLeft)
Definition: utils.c:115
LONG_PTR LRESULT
Definition: windef.h:209
#define CP_THREAD_ACP
Definition: winnls.h:233
#define WM_INITDIALOG
Definition: winuser.h:1729
LPARAM lParam
Definition: combotst.c:139
#define LOWORD(l)
Definition: pedump.c:82
#define CP_OEMCP
Definition: winnls.h:231
#define RegCloseKey(hKey)
Definition: registry.h:47
#define WM_NOTIFY
Definition: richedit.h:61
#define CP_MACCP
Definition: winnls.h:232
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
#define REG_SZ
Definition: layer.c:22