8c4692f621c5c8834233970c34456d833da9070d
[reactos.git] / reactos / lib / cpl / intl / locale.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/locale.c
23 * PURPOSE: Locale property page
24 * PROGRAMMER: Eric Kohl
25 * Klemens Friedl
26 * Aleksey Bragin
27 */
28
29 #define WINVER 0x0501
30
31 #include <windows.h>
32 #include <commctrl.h>
33 #include <cpl.h>
34
35 #include <stdio.h>
36
37 #include "intl.h"
38 #include "resource.h"
39
40 HWND hList;
41
42 BOOL CALLBACK LocalesEnumProc(
43 LPTSTR lpLocale // locale id
44 )
45 {
46 LCID lcid;
47 TCHAR lang[255];
48 int index;
49
50 //swscanf(lpLocale, L"%lx", &lcid); // maybe use wcstoul?
51 lcid = wcstoul(lpLocale, NULL, 16);
52
53 GetLocaleInfo(lcid, LOCALE_SLANGUAGE, lang, sizeof(lang));
54
55 index = SendMessageW(hList,
56 CB_ADDSTRING,
57 0,
58 (LPARAM)lang);
59
60 SendMessageW(hList,
61 CB_SETITEMDATA,
62 index,
63 (LPARAM)lcid);
64
65 return TRUE;
66 }
67
68
69 static VOID
70 CreateLanguagesList(HWND hwnd)
71 {
72 TCHAR langSel[255];
73
74 hList = hwnd;
75 EnumSystemLocalesW(LocalesEnumProc, LCID_SUPPORTED);
76
77 // Select current locale
78 GetLocaleInfo(GetUserDefaultLCID(), LOCALE_SLANGUAGE, langSel, sizeof(langSel)); // or should it be System and not user?
79
80 SendMessageW(hList,
81 CB_SELECTSTRING,
82 -1,
83 (LPARAM)langSel);
84 }
85
86 // Sets new locale
87 void SetNewLocale(LCID lcid)
88 {
89 // HKCU\\Control Panel\\International\\Locale = 0409 (type=0)
90 // HKLM,"SYSTEM\CurrentControlSet\Control\NLS\Language","Default",0x00000000,"0409" (type=0)
91 // HKLM,"SYSTEM\CurrentControlSet\Control\NLS\Language","InstallLanguage",0x00000000,"0409" (type=0)
92
93 // Set locale
94 HKEY localeKey;
95 HKEY langKey;
96 DWORD ret;
97 TCHAR value[9];
98 DWORD valuesize;
99 WCHAR ACPPage[9];
100 WCHAR OEMPage[9];
101
102 ret = GetLocaleInfoW(MAKELCID(lcid, SORT_DEFAULT), LOCALE_IDEFAULTCODEPAGE, (WORD*)OEMPage, sizeof(OEMPage));
103 if (ret == 0)
104 {
105 MessageBoxW(NULL, L"Problem reading OEM code page", L"Big Problem", MB_OK);
106 return;
107 }
108
109 GetLocaleInfoW(MAKELCID(lcid, SORT_DEFAULT), LOCALE_IDEFAULTANSICODEPAGE, (WORD*)ACPPage, sizeof(ACPPage));
110 if (ret == 0)
111 {
112 MessageBoxW(NULL, L"Problem reading ANSI code page", L"Big Problem", MB_OK);
113 return;
114 }
115
116 ret = RegOpenKeyW(HKEY_CURRENT_USER, L"Control Panel\\International", &localeKey);
117
118 if (ret != ERROR_SUCCESS)
119 {
120 // some serious error
121 MessageBoxW(NULL, L"Problem opening HKCU\\Control Panel\\International key", L"Big Problem", MB_OK);
122 return;
123 }
124
125 wsprintf(value, L"%04X", (DWORD)lcid);
126 valuesize = (wcslen(value) + 1) * sizeof(WCHAR);
127
128 RegSetValueExW(localeKey, L"Locale", 0, REG_SZ, (BYTE *)value, valuesize);
129 RegCloseKey(localeKey);
130
131 ret = RegOpenKeyW(HKEY_USERS, L".DEFAULT\\Control Panel\\International", &localeKey);
132
133 if (ret != ERROR_SUCCESS)
134 {
135 // some serious error
136 MessageBoxW(NULL, L"Problem opening HKU\\.DEFAULT\\Control Panel\\International key", L"Big Problem", MB_OK);
137 return;
138 }
139
140 wsprintf(value, L"%04X", (DWORD)lcid);
141 valuesize = (wcslen(value) + 1) * sizeof(WCHAR);
142
143 RegSetValueExW(localeKey, L"Locale", 0, REG_SZ, (BYTE *)value, valuesize);
144 RegCloseKey(localeKey);
145
146 // Set language
147 ret = RegOpenKeyW(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Control\\NLS\\Language", &langKey);
148
149 if (ret != ERROR_SUCCESS)
150 {
151 MessageBoxW(NULL, L"Problem opening HKLM\\SYSTEM\\CurrentControlSet\\Control\\NLS\\Language key", L"Big Problem", MB_OK);
152 return;
153 }
154
155 RegSetValueExW(langKey, L"Default", 0, REG_SZ, (BYTE *)value, valuesize );
156 RegSetValueExW(langKey, L"InstallLanguage", 0, REG_SZ, (BYTE *)value, valuesize );
157
158 RegCloseKey(langKey);
159
160
161 // Set language
162 ret = RegOpenKeyW(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Control\\NLS\\CodePage", &langKey);
163
164 if (ret != ERROR_SUCCESS)
165 {
166 MessageBoxW(NULL, L"Problem opening HKLM\\SYSTEM\\CurrentControlSet\\Control\\NLS\\CodePage key", L"Big Problem", MB_OK);
167 return;
168 }
169
170 RegSetValueExW(langKey, L"OEMCP", 0, REG_SZ, (BYTE *)OEMPage, (wcslen(OEMPage) +1 ) * sizeof(WCHAR) );
171 RegSetValueExW(langKey, L"ACP", 0, REG_SZ, (BYTE *)ACPPage, (wcslen(ACPPage) +1 ) * sizeof(WCHAR) );
172
173 RegCloseKey(langKey);
174
175 }
176
177 /* Property page dialog callback */
178 INT_PTR CALLBACK
179 LocalePageProc(HWND hwndDlg,
180 UINT uMsg,
181 WPARAM wParam,
182 LPARAM lParam)
183 {
184 switch(uMsg)
185 {
186 case WM_INITDIALOG:
187 CreateLanguagesList(GetDlgItem(hwndDlg, IDC_LANGUAGELIST));
188 break;
189 case WM_COMMAND:
190 switch (LOWORD(wParam))
191 {
192 case IDC_LANGUAGELIST:
193 if (HIWORD(wParam) == CBN_SELCHANGE)
194 {
195 PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
196 }
197 break;
198 }
199 break;
200
201 case WM_NOTIFY:
202 {
203 LPNMHDR lpnm = (LPNMHDR)lParam;
204 if (lpnm->code == (UINT)PSN_APPLY)
205 {
206 // Apply changes
207 LCID NewLcid;
208 int iCurSel;
209
210 // Acquire new value
211 iCurSel = SendMessageW(hList,
212 CB_GETCURSEL,
213 0,
214 0);
215 if (iCurSel == CB_ERR)
216 break;
217
218 NewLcid = SendMessageW(hList,
219 CB_GETITEMDATA,
220 iCurSel,
221 0);
222
223 if (NewLcid == (LCID)CB_ERR)
224 break;
225
226
227 // Actually set new locale
228 SetNewLocale(NewLcid);
229 }
230 }
231 break;
232 }
233 return FALSE;
234 }
235
236
237 /* EOF */