xref: /reactos/dll/cpl/intl/generalp.c (revision c0fa4859)
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)/sizeof(TCHAR));
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)/sizeof(TCHAR));
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, OEMPage, sizeof(OEMPage)/sizeof(TCHAR));
164     if (ret == 0)
165     {
166         MessageBox(NULL, _T("Problem reading OEM code page"), _T("Big Problem"), MB_OK);
167         return;
168     }
169 
170     ret = GetLocaleInfo(MAKELCID(lcid, SORT_DEFAULT), LOCALE_IDEFAULTANSICODEPAGE, ACPPage, sizeof(ACPPage)/sizeof(TCHAR));
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 == (LRESULT)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_LOCATION_COMBO:
370                     if (HIWORD(wParam) == CBN_SELCHANGE)
371                     {
372                         PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
373                     }
374                     break;
375                 case IDC_SETUP_BUTTON:
376                     {
377                         LCID NewLcid;
378                         INT iCurSel;
379 
380                         iCurSel = SendMessage(hList,
381                                               CB_GETCURSEL,
382                                               0,
383                                               0);
384                         if (iCurSel == CB_ERR)
385                             break;
386 
387                         NewLcid = SendMessage(hList,
388                                               CB_GETITEMDATA,
389                                               iCurSel,
390                                               0);
391                         if (NewLcid == (LCID)CB_ERR)
392                             break;
393 
394                          SetupApplet(NewLcid);
395                     }
396                     break;
397             }
398             break;
399 
400         case WM_NOTIFY:
401             {
402                 LPNMHDR lpnm = (LPNMHDR)lParam;
403 
404                 if (lpnm->code == (UINT)PSN_APPLY)
405                 {
406                     /* Apply changes */
407                     LCID NewLcid;
408                     GEOID NewGeoID;
409                     INT iCurSel;
410 
411                     PropSheet_UnChanged(GetParent(hwndDlg), hwndDlg);
412 
413                     /* Acquire new value */
414                     iCurSel = SendMessage(hList,
415                                           CB_GETCURSEL,
416                                           0,
417                                           0);
418                     if (iCurSel == CB_ERR)
419                         break;
420 
421                     NewLcid = SendMessage(hList,
422                                           CB_GETITEMDATA,
423                                           iCurSel,
424                                           0);
425                     if (NewLcid == (LCID)CB_ERR)
426                         break;
427 
428                     iCurSel = SendMessage(GetDlgItem(hwndDlg, IDC_LOCATION_COMBO),
429                                           CB_GETCURSEL,
430                                           0,
431                                           0);
432                     if (iCurSel == CB_ERR)
433                         break;
434 
435                     NewGeoID = SendMessage(GetDlgItem(hwndDlg, IDC_LOCATION_COMBO),
436                                            CB_GETITEMDATA,
437                                            iCurSel,
438                                            0);
439                     if (NewGeoID == (GEOID)CB_ERR)
440                         break;
441 
442                     /* Set new locale */
443                     SetNewLocale(NewLcid);
444                     SetUserGeoID(NewGeoID);
445                     SetNonUnicodeLang(hwndDlg, NewLcid);
446                 }
447             }
448             break;
449     }
450 
451     return FALSE;
452 }
453 
454 
455 /* EOF */
456