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