3 * Copyright (C) 2004, 2005 ReactOS Team
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.
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.
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.
20 * PROJECT: ReactOS International Control Panel
21 * FILE: dll/cpl/intl/generalp.c
22 * PURPOSE: General property page
23 * PROGRAMMER: Eric Kohl
32 #define SAMPLE_NUMBER L"123456789"
36 #define MAX_FIELD_DIG_SAMPLES 3
40 HWND hLocaleList
, hGeoList
;
44 GroupingFormats
[MAX_GROUPINGFORMATS
] =
52 GeneralPropertyPageLocalesEnumProc(LPTSTR lpLocale
)
59 lcid
= wcstoul(lpLocale
, NULL
, 16);
61 /* Display only languages with installed support */
62 if (!IsValidLocale(lcid
, LCID_INSTALLED
))
65 if (lcid
== MAKELCID(MAKELANGID(LANG_SPANISH
, SUBLANG_SPANISH
), SORT_DEFAULT
) ||
66 lcid
== MAKELCID(MAKELANGID(LANG_SPANISH
, SUBLANG_SPANISH_MODERN
), SORT_DEFAULT
))
70 LoadStringW(hApplet
, IDS_SPAIN
, lang
, 255);
80 GetLocaleInfoW(lcid
, LOCALE_SLANGUAGE
, lang
, sizeof(lang
)/sizeof(WCHAR
));
85 index
= SendMessageW(hList
,
100 /* Update all locale samples */
105 PGLOBALDATA pGlobalData
)
107 WCHAR OutBuffer
[MAX_SAMPLES_STR_SIZE
];
108 NUMBERFMT NumberFormat
;
109 CURRENCYFMTW CurrencyFormat
;
111 NumberFormat
.NumDigits
= pGlobalData
->nNumDigits
;
112 NumberFormat
.LeadingZero
= pGlobalData
->nNumLeadingZero
;
113 NumberFormat
.Grouping
= GroupingFormats
[pGlobalData
->nNumGrouping
].nInteger
;
114 NumberFormat
.lpDecimalSep
= pGlobalData
->szNumDecimalSep
;
115 NumberFormat
.lpThousandSep
= pGlobalData
->szNumThousandSep
;
116 NumberFormat
.NegativeOrder
= pGlobalData
->nNumNegFormat
;
118 CurrencyFormat
.NumDigits
= pGlobalData
->nCurrDigits
;
119 CurrencyFormat
.LeadingZero
= pGlobalData
->nNumLeadingZero
;
120 CurrencyFormat
.Grouping
= GroupingFormats
[pGlobalData
->nCurrGrouping
].nInteger
;
121 CurrencyFormat
.lpDecimalSep
= pGlobalData
->szCurrDecimalSep
;
122 CurrencyFormat
.lpThousandSep
= pGlobalData
->szCurrThousandSep
;
123 CurrencyFormat
.NegativeOrder
= pGlobalData
->nCurrNegFormat
;
124 CurrencyFormat
.PositiveOrder
= pGlobalData
->nCurrPosFormat
;
125 CurrencyFormat
.lpCurrencySymbol
= pGlobalData
->szCurrSymbol
;
127 /* Get number format sample */
128 GetNumberFormatW(pGlobalData
->UserLCID
, 0, SAMPLE_NUMBER
,
130 OutBuffer
, MAX_SAMPLES_STR_SIZE
);
131 SendDlgItemMessageW(hwndDlg
, IDC_NUMSAMPLE_EDIT
,
132 WM_SETTEXT
, 0, (LPARAM
)OutBuffer
);
133 ZeroMemory(OutBuffer
, MAX_SAMPLES_STR_SIZE
* sizeof(WCHAR
));
135 /* Get monetary format sample */
136 GetCurrencyFormatW(pGlobalData
->UserLCID
, 0, SAMPLE_NUMBER
,
138 OutBuffer
, MAX_SAMPLES_STR_SIZE
);
139 SendDlgItemMessageW(hwndDlg
, IDC_MONEYSAMPLE_EDIT
,
140 WM_SETTEXT
, 0, (LPARAM
)OutBuffer
);
141 ZeroMemory(OutBuffer
, MAX_SAMPLES_STR_SIZE
* sizeof(WCHAR
));
143 /* Get time format sample */
144 GetTimeFormatW(pGlobalData
->UserLCID
, 0, NULL
,
145 pGlobalData
->szTimeFormat
,
146 OutBuffer
, MAX_SAMPLES_STR_SIZE
);
147 SendDlgItemMessageW(hwndDlg
, IDC_TIMESAMPLE_EDIT
,
148 WM_SETTEXT
, 0, (LPARAM
)OutBuffer
);
149 ZeroMemory(OutBuffer
, MAX_SAMPLES_STR_SIZE
* sizeof(WCHAR
));
151 /* Get short date format sample */
152 GetDateFormatW(pGlobalData
->UserLCID
, 0, NULL
,
153 pGlobalData
->szShortDateFormat
,
154 OutBuffer
, MAX_SAMPLES_STR_SIZE
);
155 SendDlgItemMessageW(hwndDlg
, IDC_SHORTTIMESAMPLE_EDIT
,
156 WM_SETTEXT
, 0, (LPARAM
)OutBuffer
);
158 /* Get long date sample */
159 GetDateFormatW(pGlobalData
->UserLCID
, 0, NULL
,
160 pGlobalData
->szLongDateFormat
,
161 OutBuffer
, MAX_SAMPLES_STR_SIZE
);
162 SendDlgItemMessageW(hwndDlg
, IDC_FULLTIMESAMPLE_EDIT
,
163 WM_SETTEXT
, 0, (LPARAM
)OutBuffer
);
167 CreateLanguagesList(HWND hwnd
)
173 EnumSystemLocalesW(GeneralPropertyPageLocalesEnumProc
, LCID_SUPPORTED
);
175 /* Select current locale */
176 /* or should it be System and not user? */
177 GetLocaleInfoW(GetUserDefaultLCID(), LOCALE_SLANGUAGE
, langSel
, sizeof(langSel
)/sizeof(WCHAR
));
188 PGLOBALDATA pGlobalData
)
196 ret
= RegOpenKeyExW(HKEY_CURRENT_USER
,
197 L
"Control Panel\\International",
201 if (ret
!= ERROR_SUCCESS
)
203 PrintErrorMsgBox(IDS_ERROR_INT_KEY_REG
);
207 dwSize
= 9 * sizeof(WCHAR
);
208 RegQueryValueExW(hLocaleKey
,
214 pGlobalData
->UserLCID
= (LCID
)wcstoul(szBuffer
, &ptr
, 16);
217 dwSize
= MAX_NUMDECIMALSEP
* sizeof(WCHAR
);
218 RegQueryValueExW(hLocaleKey
,
222 (PBYTE
)pGlobalData
->szNumDecimalSep
,
225 dwSize
= MAX_NUMTHOUSANDSEP
* sizeof(WCHAR
);
226 RegQueryValueExW(hLocaleKey
,
230 (PBYTE
)pGlobalData
->szNumThousandSep
,
233 dwSize
= MAX_NUMNEGATIVESIGN
* sizeof(WCHAR
);
234 RegQueryValueExW(hLocaleKey
,
238 (PBYTE
)pGlobalData
->szNumNegativeSign
,
241 dwSize
= MAX_NUMPOSITIVESIGN
* sizeof(WCHAR
);
242 RegQueryValueExW(hLocaleKey
,
246 (PBYTE
)pGlobalData
->szNumPositiveSign
,
249 dwSize
= MAX_NUMLISTSEP
* sizeof(WCHAR
);
250 RegQueryValueExW(hLocaleKey
,
254 (PBYTE
)pGlobalData
->szNumListSep
,
257 dwSize
= MAX_NUMNATIVEDIGITS
* sizeof(WCHAR
);
258 RegQueryValueExW(hLocaleKey
,
262 (PBYTE
)pGlobalData
->szNumNativeDigits
,
265 pGlobalData
->nNumNegFormat
= 0;
266 dwSize
= 16 * sizeof(WCHAR
);
267 if (RegQueryValueExW(hLocaleKey
,
272 &dwSize
) == ERROR_SUCCESS
)
273 pGlobalData
->nNumNegFormat
= _wtoi(szBuffer
);
275 pGlobalData
->nNumDigits
= 0;
276 dwSize
= 16 * sizeof(WCHAR
);
277 if (RegQueryValueExW(hLocaleKey
,
282 &dwSize
) == ERROR_SUCCESS
)
283 pGlobalData
->nNumDigits
= _wtoi(szBuffer
);
285 pGlobalData
->nNumLeadingZero
= 0;
286 dwSize
= 16 * sizeof(WCHAR
);
287 if (RegQueryValueExW(hLocaleKey
,
292 &dwSize
) == ERROR_SUCCESS
)
293 pGlobalData
->nNumLeadingZero
= _wtoi(szBuffer
);
295 pGlobalData
->nNumMeasure
= 0;
296 dwSize
= 16 * sizeof(WCHAR
);
297 if (RegQueryValueExW(hLocaleKey
,
302 &dwSize
) == ERROR_SUCCESS
)
303 pGlobalData
->nNumMeasure
= _wtoi(szBuffer
);
305 pGlobalData
->nNumShape
= 0;
306 dwSize
= 16 * sizeof(WCHAR
);
307 if (RegQueryValueExW(hLocaleKey
,
312 &dwSize
) == ERROR_SUCCESS
)
313 pGlobalData
->nNumShape
= _wtoi(szBuffer
);
315 pGlobalData
->nNumGrouping
= 0;
316 dwSize
= 16 * sizeof(WCHAR
);
317 if (RegQueryValueExW(hLocaleKey
,
322 &dwSize
) == ERROR_SUCCESS
)
324 pGlobalData
->nNumGrouping
= 0;
325 if (szBuffer
[0] == L
'3')
327 if ((szBuffer
[1] == L
';') &&
328 (szBuffer
[2] == L
'2'))
329 pGlobalData
->nNumGrouping
= 2;
331 pGlobalData
->nNumGrouping
= 1;
336 dwSize
= MAX_CURRSYMBOL
* sizeof(WCHAR
);
337 RegQueryValueExW(hLocaleKey
,
341 (PBYTE
)pGlobalData
->szCurrSymbol
,
344 dwSize
= MAX_CURRDECIMALSEP
* sizeof(WCHAR
);
345 RegQueryValueExW(hLocaleKey
,
349 (PBYTE
)pGlobalData
->szCurrDecimalSep
,
352 dwSize
= MAX_CURRTHOUSANDSEP
* sizeof(WCHAR
);
353 RegQueryValueExW(hLocaleKey
,
357 (PBYTE
)pGlobalData
->szCurrThousandSep
,
360 pGlobalData
->nCurrGrouping
= 0;
361 dwSize
= 16 * sizeof(WCHAR
);
362 if (RegQueryValueExW(hLocaleKey
,
367 &dwSize
) == ERROR_SUCCESS
)
369 pGlobalData
->nCurrGrouping
= 0;
370 if (szBuffer
[0] == L
'3')
372 if ((szBuffer
[1] == L
';') &&
373 (szBuffer
[2] == L
'2'))
374 pGlobalData
->nCurrGrouping
= 2;
376 pGlobalData
->nCurrGrouping
= 1;
380 pGlobalData
->nCurrPosFormat
= 0;
381 dwSize
= 16 * sizeof(WCHAR
);
382 if (RegQueryValueExW(hLocaleKey
,
387 &dwSize
) == ERROR_SUCCESS
)
388 pGlobalData
->nCurrPosFormat
= _wtoi(szBuffer
);
390 pGlobalData
->nCurrNegFormat
= 0;
391 dwSize
= 16 * sizeof(WCHAR
);
392 if (RegQueryValueExW(hLocaleKey
,
397 &dwSize
) == ERROR_SUCCESS
)
398 pGlobalData
->nCurrNegFormat
= _wtoi(szBuffer
);
400 pGlobalData
->nCurrDigits
= 0;
401 dwSize
= 16 * sizeof(WCHAR
);
402 if (RegQueryValueExW(hLocaleKey
,
407 &dwSize
) == ERROR_SUCCESS
)
408 pGlobalData
->nCurrDigits
= _wtoi(szBuffer
);
411 dwSize
= MAX_TIMEFORMAT
* sizeof(WCHAR
);
412 RegQueryValueExW(hLocaleKey
,
416 (PBYTE
)pGlobalData
->szTimeFormat
,
419 dwSize
= MAX_TIMESEPARATOR
* sizeof(WCHAR
);
420 RegQueryValueExW(hLocaleKey
,
424 (PBYTE
)pGlobalData
->szTimeSep
,
427 dwSize
= MAX_TIMEAMSYMBOL
* sizeof(WCHAR
);
428 RegQueryValueExW(hLocaleKey
,
432 (PBYTE
)pGlobalData
->szTimeAM
,
435 dwSize
= MAX_TIMEPMSYMBOL
* sizeof(WCHAR
);
436 RegQueryValueExW(hLocaleKey
,
440 (PBYTE
)pGlobalData
->szTimePM
,
443 pGlobalData
->nTime
= 0;
444 dwSize
= 16 * sizeof(WCHAR
);
445 if (RegQueryValueExW(hLocaleKey
,
450 &dwSize
) == ERROR_SUCCESS
)
451 pGlobalData
->nTime
= _wtoi(szBuffer
);
453 pGlobalData
->nTimePrefix
= 0;
454 dwSize
= 16 * sizeof(WCHAR
);
455 if (RegQueryValueExW(hLocaleKey
,
460 &dwSize
) == ERROR_SUCCESS
)
461 pGlobalData
->nTimePrefix
= _wtoi(szBuffer
);
463 pGlobalData
->nTimeLeadingZero
= 0;
464 dwSize
= 16 * sizeof(WCHAR
);
465 if (RegQueryValueExW(hLocaleKey
,
470 &dwSize
) == ERROR_SUCCESS
)
471 pGlobalData
->nTimeLeadingZero
= _wtoi(szBuffer
);
474 dwSize
= MAX_LONGDATEFORMAT
* sizeof(WCHAR
);
475 RegQueryValueExW(hLocaleKey
,
479 (PBYTE
)pGlobalData
->szLongDateFormat
,
482 dwSize
= MAX_SHORTDATEFORMAT
* sizeof(WCHAR
);
483 RegQueryValueExW(hLocaleKey
,
487 (PBYTE
)pGlobalData
->szShortDateFormat
,
490 dwSize
= MAX_DATESEPARATOR
* sizeof(WCHAR
);
491 RegQueryValueExW(hLocaleKey
,
495 (PBYTE
)pGlobalData
->szDateSep
,
498 pGlobalData
->nFirstDayOfWeek
= 0;
499 dwSize
= 16 * sizeof(WCHAR
);
500 if (RegQueryValueExW(hLocaleKey
,
505 &dwSize
) == ERROR_SUCCESS
)
506 pGlobalData
->nFirstDayOfWeek
= _wtoi(szBuffer
);
508 pGlobalData
->nFirstWeekOfYear
= 0;
509 dwSize
= 16 * sizeof(WCHAR
);
510 if (RegQueryValueExW(hLocaleKey
,
515 &dwSize
) == ERROR_SUCCESS
)
516 pGlobalData
->nFirstWeekOfYear
= _wtoi(szBuffer
);
518 pGlobalData
->nDate
= 0;
519 dwSize
= 16 * sizeof(WCHAR
);
520 if (RegQueryValueExW(hLocaleKey
,
525 &dwSize
) == ERROR_SUCCESS
)
526 pGlobalData
->nDate
= _wtoi(szBuffer
);
528 pGlobalData
->nCalendarType
= 0;
529 dwSize
= 16 * sizeof(WCHAR
);
530 if (RegQueryValueExW(hLocaleKey
,
535 &dwSize
) == ERROR_SUCCESS
)
536 pGlobalData
->nCalendarType
= _wtoi(szBuffer
);
539 dwSize
= MAX_MISCCOUNTRY
* sizeof(WCHAR
);
540 RegQueryValueExW(hLocaleKey
,
544 (PBYTE
)pGlobalData
->szMiscCountry
,
547 dwSize
= MAX_MISCLANGUAGE
* sizeof(WCHAR
);
548 RegQueryValueExW(hLocaleKey
,
552 (PBYTE
)pGlobalData
->szMiscLanguage
,
555 pGlobalData
->nMiscCountry
= 0;
556 dwSize
= 16 * sizeof(WCHAR
);
557 if (RegQueryValueExW(hLocaleKey
,
562 &dwSize
) == ERROR_SUCCESS
)
563 pGlobalData
->nMiscCountry
= _wtoi(szBuffer
);
565 RegCloseKey(hLocaleKey
);
573 PGLOBALDATA pGlobalData
,
578 pGlobalData
->UserLCID
= lcid
;
582 LOCALE_SDECIMAL
| LOCALE_NOUSEROVERRIDE
,
583 pGlobalData
->szNumDecimalSep
,
587 LOCALE_STHOUSAND
| LOCALE_NOUSEROVERRIDE
,
588 pGlobalData
->szNumThousandSep
,
592 LOCALE_SNEGATIVESIGN
| LOCALE_NOUSEROVERRIDE
,
593 pGlobalData
->szNumNegativeSign
,
594 MAX_NUMNEGATIVESIGN
);
597 LOCALE_SPOSITIVESIGN
| LOCALE_NOUSEROVERRIDE
,
598 pGlobalData
->szNumPositiveSign
,
599 MAX_NUMPOSITIVESIGN
);
602 LOCALE_SLIST
| LOCALE_NOUSEROVERRIDE
,
603 pGlobalData
->szNumListSep
,
607 LOCALE_SNATIVEDIGITS
| LOCALE_NOUSEROVERRIDE
,
608 pGlobalData
->szNumNativeDigits
,
609 MAX_NUMNATIVEDIGITS
);
612 LOCALE_INEGNUMBER
| LOCALE_NOUSEROVERRIDE
,
614 sizeof(szBuffer
) / sizeof(WCHAR
));
615 pGlobalData
->nNumNegFormat
= _wtoi(szBuffer
);
618 LOCALE_IDIGITS
| LOCALE_NOUSEROVERRIDE
,
620 sizeof(szBuffer
) / sizeof(WCHAR
));
621 pGlobalData
->nNumDigits
= _wtoi(szBuffer
);
624 LOCALE_ILZERO
| LOCALE_NOUSEROVERRIDE
,
626 sizeof(szBuffer
) / sizeof(WCHAR
));
627 pGlobalData
->nNumLeadingZero
= _wtoi(szBuffer
);
630 LOCALE_IMEASURE
| LOCALE_NOUSEROVERRIDE
,
632 sizeof(szBuffer
) / sizeof(WCHAR
));
633 pGlobalData
->nNumMeasure
= _wtoi(szBuffer
);
636 LOCALE_IDIGITSUBSTITUTION
| LOCALE_NOUSEROVERRIDE
,
638 sizeof(szBuffer
) / sizeof(WCHAR
));
639 pGlobalData
->nNumShape
= _wtoi(szBuffer
);
642 LOCALE_SGROUPING
| LOCALE_NOUSEROVERRIDE
,
644 sizeof(szBuffer
) / sizeof(WCHAR
));
645 pGlobalData
->nNumGrouping
= 0;
646 if (szBuffer
[0] == L
'3')
648 if ((szBuffer
[1] == L
';') &&
649 (szBuffer
[2] == L
'2'))
650 pGlobalData
->nNumGrouping
= 2;
652 pGlobalData
->nNumGrouping
= 1;
657 LOCALE_SCURRENCY
| LOCALE_NOUSEROVERRIDE
,
658 pGlobalData
->szCurrSymbol
,
662 LOCALE_SMONDECIMALSEP
| LOCALE_NOUSEROVERRIDE
,
663 pGlobalData
->szCurrDecimalSep
,
667 LOCALE_SMONTHOUSANDSEP
| LOCALE_NOUSEROVERRIDE
,
668 pGlobalData
->szCurrThousandSep
,
669 MAX_CURRTHOUSANDSEP
);
672 LOCALE_SMONGROUPING
| LOCALE_NOUSEROVERRIDE
,
674 sizeof(szBuffer
) / sizeof(WCHAR
));
675 pGlobalData
->nCurrGrouping
= 0;
676 if (szBuffer
[0] == L
'3')
678 if ((szBuffer
[1] == L
';') &&
679 (szBuffer
[2] == L
'2'))
680 pGlobalData
->nCurrGrouping
= 2;
682 pGlobalData
->nCurrGrouping
= 1;
686 LOCALE_ICURRENCY
| LOCALE_NOUSEROVERRIDE
,
688 sizeof(szBuffer
) / sizeof(WCHAR
));
689 pGlobalData
->nCurrPosFormat
= _wtoi(szBuffer
);
692 LOCALE_INEGCURR
| LOCALE_NOUSEROVERRIDE
,
694 sizeof(szBuffer
) / sizeof(WCHAR
));
695 pGlobalData
->nCurrNegFormat
= _wtoi(szBuffer
);
698 LOCALE_ICURRDIGITS
| LOCALE_NOUSEROVERRIDE
,
700 sizeof(szBuffer
) / sizeof(WCHAR
));
701 pGlobalData
->nCurrDigits
= _wtoi(szBuffer
);
705 LOCALE_STIMEFORMAT
| LOCALE_NOUSEROVERRIDE
,
706 pGlobalData
->szTimeFormat
,
710 LOCALE_STIME
| LOCALE_NOUSEROVERRIDE
,
711 pGlobalData
->szTimeSep
,
715 LOCALE_S1159
| LOCALE_NOUSEROVERRIDE
,
716 pGlobalData
->szTimeAM
,
720 LOCALE_S2359
| LOCALE_NOUSEROVERRIDE
,
721 pGlobalData
->szTimePM
,
725 LOCALE_ITIME
| LOCALE_NOUSEROVERRIDE
,
727 sizeof(szBuffer
) / sizeof(WCHAR
));
728 pGlobalData
->nTime
= _wtoi(szBuffer
);
731 LOCALE_ITIMEMARKPOSN
| LOCALE_NOUSEROVERRIDE
,
733 sizeof(szBuffer
) / sizeof(WCHAR
));
734 pGlobalData
->nTimePrefix
= _wtoi(szBuffer
);
737 LOCALE_ITLZERO
| LOCALE_NOUSEROVERRIDE
,
739 sizeof(szBuffer
) / sizeof(WCHAR
));
740 pGlobalData
->nTimeLeadingZero
= _wtoi(szBuffer
);
744 LOCALE_SLONGDATE
| LOCALE_NOUSEROVERRIDE
,
745 pGlobalData
->szLongDateFormat
,
749 LOCALE_SSHORTDATE
| LOCALE_NOUSEROVERRIDE
,
750 pGlobalData
->szShortDateFormat
,
751 MAX_SHORTDATEFORMAT
);
754 LOCALE_SDATE
| LOCALE_NOUSEROVERRIDE
,
755 pGlobalData
->szDateSep
,
759 LOCALE_IFIRSTDAYOFWEEK
| LOCALE_NOUSEROVERRIDE
,
761 sizeof(szBuffer
) / sizeof(WCHAR
));
762 pGlobalData
->nFirstDayOfWeek
= _wtoi(szBuffer
);
765 LOCALE_IFIRSTWEEKOFYEAR
| LOCALE_NOUSEROVERRIDE
,
767 sizeof(szBuffer
) / sizeof(WCHAR
));
768 pGlobalData
->nFirstWeekOfYear
= _wtoi(szBuffer
);
771 LOCALE_IDATE
| LOCALE_NOUSEROVERRIDE
,
773 sizeof(szBuffer
) / sizeof(WCHAR
));
774 pGlobalData
->nDate
= _wtoi(szBuffer
);
777 LOCALE_ICALENDARTYPE
| LOCALE_NOUSEROVERRIDE
,
779 sizeof(szBuffer
) / sizeof(WCHAR
));
780 pGlobalData
->nCalendarType
= _wtoi(szBuffer
);
784 LOCALE_SCOUNTRY
| LOCALE_NOUSEROVERRIDE
,
785 pGlobalData
->szMiscCountry
,
789 LOCALE_SLANGUAGE
| LOCALE_NOUSEROVERRIDE
,
790 pGlobalData
->szMiscLanguage
,
794 LOCALE_ICOUNTRY
| LOCALE_NOUSEROVERRIDE
,
796 sizeof(szBuffer
) / sizeof(WCHAR
));
797 pGlobalData
->nMiscCountry
= _wtoi(szBuffer
);
804 PGLOBALDATA pGlobalData
,
809 wsprintf(szBuffer
, L
"%08lx", (DWORD
)pGlobalData
->UserLCID
);
810 RegSetValueExW(hLocaleKey
,
815 (wcslen(szBuffer
) + 1) * sizeof(WCHAR
));
818 RegSetValueExW(hLocaleKey
,
822 (PBYTE
)pGlobalData
->szNumDecimalSep
,
823 (wcslen(pGlobalData
->szNumDecimalSep
) + 1) * sizeof(WCHAR
));
825 RegSetValueExW(hLocaleKey
,
829 (PBYTE
)pGlobalData
->szNumThousandSep
,
830 (wcslen(pGlobalData
->szNumThousandSep
) + 1) * sizeof(WCHAR
));
832 RegSetValueExW(hLocaleKey
,
836 (PBYTE
)pGlobalData
->szNumNegativeSign
,
837 (wcslen(pGlobalData
->szNumNegativeSign
) + 1) * sizeof(WCHAR
));
839 RegSetValueExW(hLocaleKey
,
843 (PBYTE
)pGlobalData
->szNumPositiveSign
,
844 (wcslen(pGlobalData
->szNumPositiveSign
) + 1) * sizeof(WCHAR
));
846 RegSetValueExW(hLocaleKey
,
850 (PBYTE
)GroupingFormats
[pGlobalData
->nNumGrouping
].pszString
,
851 (wcslen(GroupingFormats
[pGlobalData
->nNumGrouping
].pszString
) + 1) * sizeof(WCHAR
));
853 RegSetValueExW(hLocaleKey
,
857 (PBYTE
)pGlobalData
->szNumListSep
,
858 (wcslen(pGlobalData
->szNumListSep
) + 1) * sizeof(WCHAR
));
860 RegSetValueExW(hLocaleKey
,
864 (PBYTE
)pGlobalData
->szNumNativeDigits
,
865 (wcslen(pGlobalData
->szNumNativeDigits
) + 1) * sizeof(WCHAR
));
867 _itow(pGlobalData
->nNumNegFormat
,
868 szBuffer
, DECIMAL_RADIX
);
869 RegSetValueExW(hLocaleKey
,
874 (wcslen(szBuffer
) + 1) * sizeof(WCHAR
));
876 _itow(pGlobalData
->nNumDigits
,
877 szBuffer
, DECIMAL_RADIX
);
878 RegSetValueExW(hLocaleKey
,
883 (wcslen(szBuffer
) + 1) * sizeof(WCHAR
));
885 _itow(pGlobalData
->nNumLeadingZero
,
886 szBuffer
, DECIMAL_RADIX
);
887 RegSetValueExW(hLocaleKey
,
892 (wcslen(szBuffer
) + 1) * sizeof(WCHAR
));
894 _itow(pGlobalData
->nNumMeasure
,
895 szBuffer
, DECIMAL_RADIX
);
896 RegSetValueExW(hLocaleKey
,
901 (wcslen(szBuffer
) + 1) * sizeof(WCHAR
));
903 _itow(pGlobalData
->nNumShape
,
904 szBuffer
, DECIMAL_RADIX
);
905 RegSetValueExW(hLocaleKey
,
910 (wcslen(szBuffer
) + 1) * sizeof(WCHAR
));
913 RegSetValueExW(hLocaleKey
,
917 (PBYTE
)pGlobalData
->szCurrSymbol
,
918 (wcslen(pGlobalData
->szCurrSymbol
) + 1) * sizeof(WCHAR
));
920 RegSetValueExW(hLocaleKey
,
924 (PBYTE
)pGlobalData
->szCurrDecimalSep
,
925 (wcslen(pGlobalData
->szCurrDecimalSep
) + 1) * sizeof(WCHAR
));
927 RegSetValueExW(hLocaleKey
,
931 (PBYTE
)pGlobalData
->szCurrThousandSep
,
932 (wcslen(pGlobalData
->szCurrThousandSep
) + 1) * sizeof(WCHAR
));
934 RegSetValueExW(hLocaleKey
,
938 (PBYTE
)GroupingFormats
[pGlobalData
->nCurrGrouping
].pszString
,
939 (wcslen(GroupingFormats
[pGlobalData
->nCurrGrouping
].pszString
) + 1) * sizeof(WCHAR
));
941 _itow(pGlobalData
->nCurrPosFormat
,
942 szBuffer
, DECIMAL_RADIX
);
943 RegSetValueExW(hLocaleKey
,
948 (wcslen(szBuffer
) + 1) * sizeof(WCHAR
));
950 _itow(pGlobalData
->nCurrNegFormat
,
951 szBuffer
, DECIMAL_RADIX
);
952 RegSetValueExW(hLocaleKey
,
957 (wcslen(szBuffer
) + 1) * sizeof(WCHAR
));
959 _itow(pGlobalData
->nCurrDigits
,
960 szBuffer
, DECIMAL_RADIX
);
961 RegSetValueExW(hLocaleKey
,
966 (wcslen(szBuffer
) + 1) * sizeof(WCHAR
));
969 RegSetValueExW(hLocaleKey
,
973 (PBYTE
)pGlobalData
->szTimeFormat
,
974 (wcslen(pGlobalData
->szTimeFormat
) + 1) * sizeof(WCHAR
));
976 RegSetValueExW(hLocaleKey
,
980 (PBYTE
)pGlobalData
->szTimeSep
,
981 (wcslen(pGlobalData
->szTimeSep
) + 1) * sizeof(WCHAR
));
983 RegSetValueExW(hLocaleKey
,
987 (PBYTE
)pGlobalData
->szTimeAM
,
988 (wcslen(pGlobalData
->szTimeAM
) + 1) * sizeof(WCHAR
));
990 RegSetValueExW(hLocaleKey
,
994 (PBYTE
)pGlobalData
->szTimePM
,
995 (wcslen(pGlobalData
->szTimePM
) + 1) * sizeof(WCHAR
));
997 _itow(pGlobalData
->nTime
,
998 szBuffer
, DECIMAL_RADIX
);
999 RegSetValueExW(hLocaleKey
,
1004 (wcslen(szBuffer
) + 1) * sizeof(WCHAR
));
1006 _itow(pGlobalData
->nTimePrefix
,
1007 szBuffer
, DECIMAL_RADIX
);
1008 RegSetValueExW(hLocaleKey
,
1013 (wcslen(szBuffer
) + 1) * sizeof(WCHAR
));
1015 _itow(pGlobalData
->nTimeLeadingZero
,
1016 szBuffer
, DECIMAL_RADIX
);
1017 RegSetValueExW(hLocaleKey
,
1022 (wcslen(szBuffer
) + 1) * sizeof(WCHAR
));
1025 RegSetValueExW(hLocaleKey
,
1029 (PBYTE
)pGlobalData
->szLongDateFormat
,
1030 (wcslen(pGlobalData
->szLongDateFormat
) + 1) * sizeof(WCHAR
));
1032 RegSetValueExW(hLocaleKey
,
1036 (PBYTE
)pGlobalData
->szShortDateFormat
,
1037 (wcslen(pGlobalData
->szShortDateFormat
) + 1) * sizeof(WCHAR
));
1039 RegSetValueExW(hLocaleKey
,
1043 (PBYTE
)pGlobalData
->szDateSep
,
1044 (wcslen(pGlobalData
->szDateSep
) + 1) * sizeof(WCHAR
));
1046 _itow(pGlobalData
->nFirstDayOfWeek
,
1047 szBuffer
, DECIMAL_RADIX
);
1048 RegSetValueExW(hLocaleKey
,
1053 (wcslen(szBuffer
) + 1) * sizeof(WCHAR
));
1055 _itow(pGlobalData
->nFirstWeekOfYear
,
1056 szBuffer
, DECIMAL_RADIX
);
1057 RegSetValueExW(hLocaleKey
,
1058 L
"iFirstWeekOfYear",
1062 (wcslen(szBuffer
) + 1) * sizeof(WCHAR
));
1064 _itow(pGlobalData
->nDate
,
1065 szBuffer
, DECIMAL_RADIX
);
1066 RegSetValueExW(hLocaleKey
,
1071 (wcslen(szBuffer
) + 1) * sizeof(WCHAR
));
1073 _itow(pGlobalData
->nCalendarType
,
1074 szBuffer
, DECIMAL_RADIX
);
1075 RegSetValueExW(hLocaleKey
,
1080 (wcslen(szBuffer
) + 1) * sizeof(WCHAR
));
1083 RegSetValueExW(hLocaleKey
,
1087 (PBYTE
)pGlobalData
->szMiscCountry
,
1088 (wcslen(pGlobalData
->szMiscCountry
) + 1) * sizeof(WCHAR
));
1090 RegSetValueExW(hLocaleKey
,
1094 (PBYTE
)pGlobalData
->szMiscLanguage
,
1095 (wcslen(pGlobalData
->szMiscLanguage
) + 1) * sizeof(WCHAR
));
1097 _itow(pGlobalData
->nMiscCountry
,
1098 szBuffer
, DECIMAL_RADIX
);
1099 RegSetValueExW(hLocaleKey
,
1104 (wcslen(szBuffer
) + 1) * sizeof(WCHAR
));
1108 /* Sets new locale */
1111 PGLOBALDATA pGlobalData
)
1116 if (pGlobalData
->bApplyToDefaultUser
)
1118 ret
= RegOpenKeyExW(HKEY_USERS
,
1119 L
".DEFAULT\\Control Panel\\International",
1123 if (ret
!= ERROR_SUCCESS
)
1125 PrintErrorMsgBox(IDS_ERROR_DEF_INT_KEY_REG
);
1129 SaveUserLocale(pGlobalData
, hLocaleKey
);
1131 /* Flush and close the locale key */
1132 RegFlushKey(hLocaleKey
);
1133 RegCloseKey(hLocaleKey
);
1136 ret
= RegOpenKeyExW(HKEY_CURRENT_USER
,
1137 L
"Control Panel\\International",
1141 if (ret
!= ERROR_SUCCESS
)
1143 PrintErrorMsgBox(IDS_ERROR_INT_KEY_REG
);
1147 SaveUserLocale(pGlobalData
, hLocaleKey
);
1149 /* Flush and close the locale key */
1150 RegFlushKey(hLocaleKey
);
1151 RegCloseKey(hLocaleKey
);
1153 /* Set the new locale for the current process */
1154 NtSetDefaultLocale(TRUE
, pGlobalData
->UserLCID
);
1157 /* Location enumerate procedure */
1160 LocationsEnumProc(GEOID gId
)
1162 WCHAR loc
[MAX_STR_SIZE
];
1165 if (GetGeoInfoW(gId
, GEO_FRIENDLYNAME
, loc
, MAX_STR_SIZE
, LANG_SYSTEM_DEFAULT
) == 0)
1168 index
= (INT
)SendMessageW(hGeoList
,
1173 SendMessageW(hGeoList
,
1181 /* Enumerate all system locations identifiers */
1184 CreateLocationsList(HWND hWnd
)
1187 WCHAR loc
[MAX_STR_SIZE
];
1191 EnumSystemGeoID(GEOCLASS_NATION
, 0, LocationsEnumProc
);
1193 /* Select current location */
1194 userGeoID
= GetUserGeoID(GEOCLASS_NATION
);
1195 GetGeoInfoW(userGeoID
,
1199 LANG_SYSTEM_DEFAULT
);
1201 SendMessageW(hGeoList
,
1211 PGLOBALDATA pGlobalData
)
1218 wsprintf(value
, L
"%lu", (DWORD
)pGlobalData
->geoid
);
1219 valuesize
= (wcslen(value
) + 1) * sizeof(WCHAR
);
1221 if (pGlobalData
->bApplyToDefaultUser
)
1223 ret
= RegOpenKeyExW(HKEY_USERS
,
1224 L
".DEFAULT\\Control Panel\\International\\Geo",
1228 if (ret
!= ERROR_SUCCESS
)
1230 PrintErrorMsgBox(IDS_ERROR_DEF_INT_KEY_REG
);
1234 ret
= RegSetValueExW(hGeoKey
,
1241 RegFlushKey(hGeoKey
);
1242 RegCloseKey(hGeoKey
);
1244 if (ret
!= ERROR_SUCCESS
)
1246 PrintErrorMsgBox(IDS_ERROR_INT_KEY_REG
);
1251 ret
= RegOpenKeyExW(HKEY_CURRENT_USER
,
1252 L
"Control Panel\\International\\Geo",
1256 if (ret
!= ERROR_SUCCESS
)
1258 PrintErrorMsgBox(IDS_ERROR_INT_KEY_REG
);
1262 ret
= RegSetValueExW(hGeoKey
,
1269 RegFlushKey(hGeoKey
);
1270 RegCloseKey(hGeoKey
);
1272 if (ret
!= ERROR_SUCCESS
)
1274 PrintErrorMsgBox(IDS_ERROR_INT_KEY_REG
);
1280 VerifyUnattendLCID(HWND hwndDlg
)
1282 LRESULT lCount
, lIndex
, lResult
;
1284 lCount
= SendMessage(hList
, CB_GETCOUNT
, (WPARAM
)0, (LPARAM
)0);
1285 if (lCount
== CB_ERR
)
1290 for (lIndex
= 0; lIndex
< lCount
; lIndex
++)
1292 lResult
= SendMessage(hList
, CB_GETITEMDATA
, (WPARAM
)lIndex
, (LPARAM
)0);
1293 if (lResult
== CB_ERR
)
1298 if (lResult
== (LRESULT
)UnattendLCID
)
1300 SendMessage(hList
, CB_SETCURSEL
, (WPARAM
)lIndex
, (LPARAM
)0);
1301 PropSheet_Changed(GetParent(hwndDlg
), hwndDlg
);
1313 PROPSHEETPAGEW
*psp
,
1316 PGLOBALDATA pGlobalData
)
1318 ZeroMemory(psp
, sizeof(PROPSHEETPAGEW
));
1319 psp
->dwSize
= sizeof(PROPSHEETPAGEW
);
1320 psp
->dwFlags
= PSP_DEFAULT
;
1321 psp
->hInstance
= hApplet
;
1322 psp
->pszTemplate
= MAKEINTRESOURCE(idDlg
);
1323 psp
->pfnDlgProc
= DlgProc
;
1324 psp
->lParam
= (LPARAM
)pGlobalData
;
1330 CustomizeLocalePropertySheet(
1332 PGLOBALDATA pGlobalData
)
1334 PROPSHEETPAGEW PsPage
[NUM_SHEETS
+ 1];
1335 PROPSHEETHEADERW psh
;
1336 WCHAR Caption
[MAX_STR_SIZE
];
1338 LoadStringW(hApplet
, IDS_CUSTOMIZE_TITLE
, Caption
, sizeof(Caption
) / sizeof(TCHAR
));
1340 ZeroMemory(&psh
, sizeof(PROPSHEETHEADER
));
1341 psh
.dwSize
= sizeof(PROPSHEETHEADER
);
1342 psh
.dwFlags
= PSH_PROPSHEETPAGE
| PSH_USECALLBACK
;
1343 psh
.hwndParent
= hwndDlg
;
1344 psh
.hInstance
= hApplet
;
1345 psh
.hIcon
= LoadIcon(hApplet
, MAKEINTRESOURCE(IDC_CPLICON
));
1346 psh
.pszCaption
= Caption
;
1347 psh
.nPages
= (sizeof(PsPage
) / sizeof(PROPSHEETPAGE
)) - 1;
1351 InitPropSheetPage(&PsPage
[0], IDD_NUMBERSPAGE
, NumbersPageProc
, pGlobalData
);
1352 InitPropSheetPage(&PsPage
[1], IDD_CURRENCYPAGE
, CurrencyPageProc
, pGlobalData
);
1353 InitPropSheetPage(&PsPage
[2], IDD_TIMEPAGE
, TimePageProc
, pGlobalData
);
1354 InitPropSheetPage(&PsPage
[3], IDD_DATEPAGE
, DatePageProc
, pGlobalData
);
1356 if (IsSortPageNeeded(pGlobalData
->UserLCID
))
1359 InitPropSheetPage(&PsPage
[4], IDD_SORTPAGE
, SortPageProc
, pGlobalData
);
1362 return PropertySheetW(&psh
);
1366 /* Property page dialog callback */
1368 GeneralPageProc(HWND hwndDlg
,
1373 PGLOBALDATA pGlobalData
;
1375 pGlobalData
= (PGLOBALDATA
)GetWindowLongPtr(hwndDlg
, DWLP_USER
);
1380 pGlobalData
= (PGLOBALDATA
)((LPPROPSHEETPAGE
)lParam
)->lParam
;
1381 SetWindowLongPtr(hwndDlg
, DWLP_USER
, (LONG_PTR
)pGlobalData
);
1385 LoadCurrentLocale(pGlobalData
);
1387 CreateLanguagesList(GetDlgItem(hwndDlg
, IDC_LANGUAGELIST
));
1388 UpdateLocaleSample(hwndDlg
, pGlobalData
);
1389 pGlobalData
->geoid
= CreateLocationsList(GetDlgItem(hwndDlg
, IDC_LOCATION_COMBO
));
1390 if (IsUnattendedSetupEnabled
)
1392 if (VerifyUnattendLCID(hwndDlg
))
1394 SetNewLocale(pGlobalData
, UnattendLCID
);
1395 SaveCurrentLocale(pGlobalData
);
1400 DPRINT1("VerifyUnattendLCID failed\n");
1408 switch (LOWORD(wParam
))
1410 case IDC_LANGUAGELIST
:
1411 if (HIWORD(wParam
) == CBN_SELCHANGE
)
1416 iCurSel
= SendMessage(hList
,
1420 if (iCurSel
== CB_ERR
)
1423 NewLcid
= SendMessage(hList
,
1427 if (NewLcid
== (LCID
)CB_ERR
)
1430 SetNewLocale(pGlobalData
, NewLcid
);
1431 UpdateLocaleSample(hwndDlg
, pGlobalData
);
1432 pGlobalData
->bUserLocaleChanged
= TRUE
;
1434 PropSheet_Changed(GetParent(hwndDlg
), hwndDlg
);
1438 case IDC_LOCATION_COMBO
:
1439 if (HIWORD(wParam
) == CBN_SELCHANGE
)
1444 iCurSel
= SendMessage(GetDlgItem(hwndDlg
, IDC_LOCATION_COMBO
),
1448 if (iCurSel
== CB_ERR
)
1451 NewGeoID
= SendMessage(GetDlgItem(hwndDlg
, IDC_LOCATION_COMBO
),
1455 if (NewGeoID
== (GEOID
)CB_ERR
)
1458 pGlobalData
->geoid
= NewGeoID
;
1459 pGlobalData
->bGeoIdChanged
= TRUE
;
1461 PropSheet_Changed(GetParent(hwndDlg
), hwndDlg
);
1465 case IDC_SETUP_BUTTON
:
1466 if (CustomizeLocalePropertySheet(GetParent(hwndDlg
), pGlobalData
) > 0)
1468 UpdateLocaleSample(hwndDlg
, pGlobalData
);
1469 pGlobalData
->bUserLocaleChanged
= TRUE
;
1470 PropSheet_Changed(GetParent(hwndDlg
), hwndDlg
);
1477 if (((LPNMHDR
)lParam
)->code
== (UINT
)PSN_APPLY
)
1480 PropSheet_UnChanged(GetParent(hwndDlg
), hwndDlg
);
1482 /* Set new locale */
1483 if (pGlobalData
->bUserLocaleChanged
== TRUE
)
1485 SaveCurrentLocale(pGlobalData
);
1486 pGlobalData
->bUserLocaleChanged
= FALSE
;
1489 /* Set new GEO ID */
1490 if (pGlobalData
->bGeoIdChanged
== TRUE
)
1492 SaveGeoID(pGlobalData
);
1493 pGlobalData
->bGeoIdChanged
= FALSE
;
1496 AddNewKbLayoutsByLcid(pGlobalData
->UserLCID
);
1498 /* Post WM_WININICHANGE messages to system */
1499 PostMessageW(HWND_BROADCAST
, WM_WININICHANGE
, 0, (LPARAM
)L
"intl");