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