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