75476f11c5396df8d33fb81ec3a361d473aec27f
[reactos.git] / reactos / dll / cpl / intl / generalp.c
1 /*
2 * ReactOS
3 * Copyright (C) 2004, 2005 ReactOS Team
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19 /* $Id$
20 *
21 * PROJECT: ReactOS International Control Panel
22 * FILE: lib/cpl/intl/generalp.c
23 * PURPOSE: General property page
24 * PROGRAMMER: Eric Kohl
25 * Klemens Friedl
26 * Aleksey Bragin
27 */
28
29 #include <windows.h>
30 #include <commctrl.h>
31 #include <cpl.h>
32 #include <tchar.h>
33 #include <stdio.h>
34
35 #include "intl.h"
36 #include "resource.h"
37
38 #define SAMPLE_NUMBER _T("123456789")
39 #define NO_FLAG 0
40
41 HWND hList;
42 HWND hLocaleList, hGeoList;
43 BOOL bSpain = FALSE;
44
45 static BOOL CALLBACK
46 LocalesEnumProc(LPTSTR lpLocale)
47 {
48 LCID lcid;
49 TCHAR lang[255];
50 INT index;
51 BOOL bNoShow = FALSE;
52
53 lcid = _tcstoul(lpLocale, NULL, 16);
54
55 if (lcid == MAKELCID(MAKELANGID(LANG_SPANISH, SUBLANG_SPANISH), SORT_DEFAULT) ||
56 lcid == MAKELCID(MAKELANGID(LANG_SPANISH, SUBLANG_SPANISH_MODERN), SORT_DEFAULT))
57 {
58 if (bSpain == FALSE)
59 {
60 LoadString(hApplet, IDS_SPAIN, lang, 255);
61 bSpain = TRUE;
62 }
63 else
64 {
65 bNoShow = TRUE;
66 }
67 }
68 else
69 {
70 GetLocaleInfo(lcid, LOCALE_SLANGUAGE, lang, sizeof(lang));
71 }
72
73 if (bNoShow == FALSE)
74 {
75 index = SendMessage(hList,
76 CB_ADDSTRING,
77 0,
78 (LPARAM)lang);
79
80 SendMessage(hList,
81 CB_SETITEMDATA,
82 index,
83 (LPARAM)lcid);
84 }
85
86 return TRUE;
87 }
88
89 /* Update all locale samples */
90 static VOID
91 UpdateLocaleSample(HWND hwndDlg, LCID lcidLocale)
92 {
93 TCHAR OutBuffer[MAX_FMT_SIZE];
94
95 /* Get number format sample */
96 GetNumberFormat(lcidLocale, NO_FLAG, SAMPLE_NUMBER, NULL, OutBuffer,
97 MAX_FMT_SIZE);
98 SendMessage(GetDlgItem(hwndDlg, IDC_NUMSAMPLE_EDIT),
99 WM_SETTEXT, 0, (LPARAM)OutBuffer);
100
101 /* Get monetary format sample */
102 GetCurrencyFormat(lcidLocale, LOCALE_USE_CP_ACP, SAMPLE_NUMBER, NULL,
103 OutBuffer, MAX_FMT_SIZE);
104 SendMessage(GetDlgItem(hwndDlg, IDC_MONEYSAMPLE_EDIT),
105 WM_SETTEXT, 0, (LPARAM)OutBuffer);
106
107 /* Get time format sample */
108 GetTimeFormat(lcidLocale, NO_FLAG, NULL, NULL, OutBuffer, MAX_FMT_SIZE);
109 SendMessage(GetDlgItem(hwndDlg, IDC_TIMESAMPLE_EDIT),
110 WM_SETTEXT,
111 0,
112 (LPARAM)OutBuffer);
113
114 /* Get short date format sample */
115 GetDateFormat(lcidLocale, DATE_SHORTDATE, NULL, NULL, OutBuffer,
116 MAX_FMT_SIZE);
117 SendMessage(GetDlgItem(hwndDlg, IDC_SHORTTIMESAMPLE_EDIT), WM_SETTEXT,
118 0, (LPARAM)OutBuffer);
119
120 /* Get long date sample */
121 GetDateFormat(lcidLocale, DATE_LONGDATE, NULL, NULL, OutBuffer,
122 MAX_FMT_SIZE);
123 SendMessage(GetDlgItem(hwndDlg, IDC_FULLTIMESAMPLE_EDIT),
124 WM_SETTEXT, 0, (LPARAM)OutBuffer);
125 }
126
127 static VOID
128 CreateLanguagesList(HWND hwnd)
129 {
130 TCHAR langSel[255];
131
132 hList = hwnd;
133 bSpain = FALSE;
134 EnumSystemLocales(LocalesEnumProc, LCID_SUPPORTED);
135
136 /* Select current locale */
137 /* or should it be System and not user? */
138 GetLocaleInfo(GetUserDefaultLCID(), LOCALE_SLANGUAGE, langSel, sizeof(langSel));
139
140 SendMessage(hList,
141 CB_SELECTSTRING,
142 -1,
143 (LPARAM)langSel);
144 }
145
146 /* Sets new locale */
147 VOID
148 SetNewLocale(LCID lcid)
149 {
150 // HKCU\\Control Panel\\International\\Locale = 0409 (type=0)
151 // HKLM,"SYSTEM\CurrentControlSet\Control\NLS\Language","Default",0x00000000,"0409" (type=0)
152 // HKLM,"SYSTEM\CurrentControlSet\Control\NLS\Language","InstallLanguage",0x00000000,"0409" (type=0)
153
154 // Set locale
155 HKEY localeKey;
156 HKEY langKey;
157 DWORD ret;
158 TCHAR value[9];
159 DWORD valuesize;
160 TCHAR ACPPage[9];
161 TCHAR OEMPage[9];
162
163 ret = GetLocaleInfo(MAKELCID(lcid, SORT_DEFAULT), LOCALE_IDEFAULTCODEPAGE, (WORD*)OEMPage, sizeof(OEMPage));
164 if (ret == 0)
165 {
166 MessageBox(NULL, _T("Problem reading OEM code page"), _T("Big Problem"), MB_OK);
167 return;
168 }
169
170 GetLocaleInfo(MAKELCID(lcid, SORT_DEFAULT), LOCALE_IDEFAULTANSICODEPAGE, (WORD*)ACPPage, sizeof(ACPPage));
171 if (ret == 0)
172 {
173 MessageBox(NULL, _T("Problem reading ANSI code page"), _T("Big Problem"), MB_OK);
174 return;
175 }
176
177 ret = RegOpenKey(HKEY_CURRENT_USER, _T("Control Panel\\International"), &localeKey);
178 if (ret != ERROR_SUCCESS)
179 {
180 // some serious error
181 MessageBox(NULL, _T("Problem opening HKCU\\Control Panel\\International key"),
182 _T("Big Problem"), MB_OK);
183 return;
184 }
185
186 wsprintf(value, _T("%04X"), (DWORD)lcid);
187 valuesize = (_tcslen(value) + 1) * sizeof(TCHAR);
188
189 RegSetValueEx(localeKey, _T("Locale"), 0, REG_SZ, (LPBYTE)value, valuesize);
190 RegCloseKey(localeKey);
191
192 ret = RegOpenKey(HKEY_USERS, _T(".DEFAULT\\Control Panel\\International"), &localeKey);
193 if (ret != ERROR_SUCCESS)
194 {
195 // some serious error
196 MessageBox(NULL, _T("Problem opening HKU\\.DEFAULT\\Control Panel\\International key"),
197 _T("Big Problem"), MB_OK);
198 return;
199 }
200
201 wsprintf(value, _T("%04X"), (DWORD)lcid);
202 valuesize = (_tcslen(value) + 1) * sizeof(TCHAR);
203
204 RegSetValueEx(localeKey, _T("Locale"), 0, REG_SZ, (BYTE *)value, valuesize);
205 RegCloseKey(localeKey);
206
207 // Set language
208 ret = RegOpenKey(HKEY_LOCAL_MACHINE, _T("SYSTEM\\CurrentControlSet\\Control\\NLS\\Language"), &langKey);
209 if (ret != ERROR_SUCCESS)
210 {
211 MessageBoxW(NULL, _T("Problem opening HKLM\\SYSTEM\\CurrentControlSet\\Control\\NLS\\Language key"),
212 _T("Big Problem"), MB_OK);
213 return;
214 }
215
216 RegSetValueEx(langKey, _T("Default"), 0, REG_SZ, (BYTE *)value, valuesize );
217 RegSetValueEx(langKey, _T("InstallLanguage"), 0, REG_SZ, (BYTE *)value, valuesize );
218
219 RegCloseKey(langKey);
220
221
222 /* Set language */
223 ret = RegOpenKey(HKEY_LOCAL_MACHINE, _T("SYSTEM\\CurrentControlSet\\Control\\NLS\\CodePage"), &langKey);
224 if (ret != ERROR_SUCCESS)
225 {
226 MessageBox(NULL, _T("Problem opening HKLM\\SYSTEM\\CurrentControlSet\\Control\\NLS\\CodePage key"),
227 _T("Big Problem"), MB_OK);
228 return;
229 }
230
231 RegSetValueExW(langKey, _T("OEMCP"), 0, REG_SZ, (BYTE *)OEMPage, (_tcslen(OEMPage) +1 ) * sizeof(TCHAR));
232 RegSetValueExW(langKey, _T("ACP"), 0, REG_SZ, (BYTE *)ACPPage, (_tcslen(ACPPage) +1 ) * sizeof(TCHAR));
233
234 RegCloseKey(langKey);
235 }
236
237 /* Location enumerate procedure */
238 BOOL
239 CALLBACK
240 LocationsEnumProc(GEOID gId)
241 {
242 TCHAR loc[MAX_STR_SIZE];
243 INT index;
244
245 GetGeoInfo(gId, GEO_FRIENDLYNAME, loc, MAX_FMT_SIZE, LANG_SYSTEM_DEFAULT);
246 index = (INT)SendMessage(hGeoList,
247 CB_ADDSTRING,
248 0,
249 (LPARAM)loc);
250
251 SendMessage(hGeoList,
252 CB_SETITEMDATA,
253 index,
254 (LPARAM)gId);
255
256 return TRUE;
257 }
258
259 /* Enumerate all system locations identifiers */
260 static
261 VOID
262 CreateLocationsList(HWND hWnd)
263 {
264 GEOID userGeoID;
265 TCHAR loc[MAX_STR_SIZE];
266
267 hGeoList = hWnd;
268
269 EnumSystemGeoID(GEOCLASS_NATION, 0, LocationsEnumProc);
270
271 /* Select current location */
272 userGeoID = GetUserGeoID(GEOCLASS_NATION);
273 GetGeoInfo(userGeoID,
274 GEO_FRIENDLYNAME,
275 loc,
276 MAX_FMT_SIZE,
277 LANG_SYSTEM_DEFAULT);
278
279 SendMessage(hGeoList,
280 CB_SELECTSTRING,
281 (WPARAM) -1,
282 (LPARAM)loc);
283 }
284
285 DWORD
286 VerifyUnattendLCID(HWND hwndDlg)
287 {
288 LRESULT lCount, lIndex, lResult;
289
290 lCount = SendMessage(hList, CB_GETCOUNT, (WPARAM)0, (LPARAM)0);
291 if (lCount == CB_ERR)
292 {
293 return 0;
294 }
295
296 for (lIndex = 0; lIndex < lCount; lIndex++)
297 {
298 lResult = SendMessage(hList, CB_GETITEMDATA, (WPARAM)lIndex, (LPARAM)0);
299 if (lResult == CB_ERR)
300 {
301 continue;
302 }
303
304 if (lResult == (LCID)UnattendLCID)
305 {
306 SendMessage(hList, CB_SETCURSEL, (WPARAM)lIndex, (LPARAM)0);
307 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
308 return 1;
309 }
310 }
311
312 return 0;
313 }
314
315
316 /* Property page dialog callback */
317 INT_PTR CALLBACK
318 GeneralPageProc(HWND hwndDlg,
319 UINT uMsg,
320 WPARAM wParam,
321 LPARAM lParam)
322 {
323 switch(uMsg)
324 {
325 case WM_INITDIALOG:
326 CreateLanguagesList(GetDlgItem(hwndDlg, IDC_LANGUAGELIST));
327 UpdateLocaleSample(hwndDlg, LOCALE_USER_DEFAULT);
328 CreateLocationsList(GetDlgItem(hwndDlg, IDC_LOCATION_COMBO));
329 if (IsUnattendedSetupEnabled)
330 {
331 if (VerifyUnattendLCID(hwndDlg))
332 {
333 SetNewLocale(UnattendLCID);
334 PostQuitMessage(0);
335 }
336 return TRUE;
337 }
338 break;
339
340 case WM_COMMAND:
341 switch (LOWORD(wParam))
342 {
343 case IDC_LANGUAGELIST:
344 if (HIWORD(wParam) == CBN_SELCHANGE)
345 {
346 LCID NewLcid;
347 INT iCurSel;
348
349 iCurSel = SendMessage(hList,
350 CB_GETCURSEL,
351 0,
352 0);
353 if (iCurSel == CB_ERR)
354 break;
355
356 NewLcid = SendMessage(hList,
357 CB_GETITEMDATA,
358 iCurSel,
359 0);
360 if (NewLcid == (LCID)CB_ERR)
361 break;
362
363 UpdateLocaleSample(hwndDlg, NewLcid);
364
365 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
366 }
367 break;
368
369 case IDC_SETUP_BUTTON:
370 {
371 LCID NewLcid;
372 INT iCurSel;
373
374 iCurSel = SendMessage(hList,
375 CB_GETCURSEL,
376 0,
377 0);
378 if (iCurSel == CB_ERR)
379 break;
380
381 NewLcid = SendMessage(hList,
382 CB_GETITEMDATA,
383 iCurSel,
384 0);
385 if (NewLcid == (LCID)CB_ERR)
386 break;
387
388 SetupApplet(NewLcid);
389 }
390 break;
391 }
392 break;
393
394 case WM_NOTIFY:
395 {
396 LPNMHDR lpnm = (LPNMHDR)lParam;
397
398 if (lpnm->code == (UINT)PSN_APPLY)
399 {
400 /* Apply changes */
401 LCID NewLcid;
402 INT iCurSel;
403
404 /* Acquire new value */
405 iCurSel = SendMessage(hList,
406 CB_GETCURSEL,
407 0,
408 0);
409 if (iCurSel == CB_ERR)
410 break;
411
412 NewLcid = SendMessage(hList,
413 CB_GETITEMDATA,
414 iCurSel,
415 0);
416 if (NewLcid == (LCID)CB_ERR)
417 break;
418
419 /* Set new locale */
420 SetNewLocale(NewLcid);
421 }
422 }
423 break;
424 }
425
426 return FALSE;
427 }
428
429
430 /* EOF */