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 L"123456789" 33 34 #define NUM_SHEETS 4 35 36 #define MAX_FIELD_DIG_SAMPLES 3 37 38 39 HWND hList; 40 HWND hLocaleList, hGeoList; 41 BOOL bSpain = FALSE; 42 43 GROUPINGDATA 44 GroupingFormats[MAX_GROUPINGFORMATS] = 45 { 46 {0, L"0;0"}, 47 {3, L"3;0"}, 48 {32, L"3;2;0"} 49 }; 50 51 static BOOL CALLBACK 52 LocalesEnumProc(LPTSTR lpLocale) 53 { 54 LCID lcid; 55 WCHAR lang[255]; 56 INT index; 57 BOOL bNoShow = FALSE; 58 59 lcid = wcstoul(lpLocale, NULL, 16); 60 61 /* Display only languages with installed support */ 62 if (!IsValidLocale(lcid, LCID_INSTALLED)) 63 return TRUE; 64 65 if (lcid == MAKELCID(MAKELANGID(LANG_SPANISH, SUBLANG_SPANISH), SORT_DEFAULT) || 66 lcid == MAKELCID(MAKELANGID(LANG_SPANISH, SUBLANG_SPANISH_MODERN), SORT_DEFAULT)) 67 { 68 if (bSpain == FALSE) 69 { 70 LoadStringW(hApplet, IDS_SPAIN, lang, 255); 71 bSpain = TRUE; 72 } 73 else 74 { 75 bNoShow = TRUE; 76 } 77 } 78 else 79 { 80 GetLocaleInfoW(lcid, LOCALE_SLANGUAGE, lang, sizeof(lang)/sizeof(WCHAR)); 81 } 82 83 if (bNoShow == FALSE) 84 { 85 index = SendMessageW(hList, 86 CB_ADDSTRING, 87 0, 88 (LPARAM)lang); 89 90 SendMessageW(hList, 91 CB_SETITEMDATA, 92 index, 93 (LPARAM)lcid); 94 } 95 96 return TRUE; 97 } 98 99 100 /* Update all locale samples */ 101 static 102 VOID 103 UpdateLocaleSample( 104 HWND hwndDlg, 105 PGLOBALDATA pGlobalData) 106 { 107 WCHAR OutBuffer[MAX_SAMPLES_STR_SIZE]; 108 NUMBERFMT NumberFormat; 109 CURRENCYFMTW CurrencyFormat; 110 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; 117 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; 126 127 /* Get number format sample */ 128 GetNumberFormatW(pGlobalData->UserLCID, 0, SAMPLE_NUMBER, 129 &NumberFormat, 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)); 134 135 /* Get monetary format sample */ 136 GetCurrencyFormatW(pGlobalData->UserLCID, 0, SAMPLE_NUMBER, 137 &CurrencyFormat, 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)); 142 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)); 150 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); 157 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); 164 } 165 166 static VOID 167 CreateLanguagesList(HWND hwnd) 168 { 169 WCHAR langSel[255]; 170 171 hList = hwnd; 172 bSpain = FALSE; 173 EnumSystemLocalesW(LocalesEnumProc, LCID_SUPPORTED); 174 175 /* Select current locale */ 176 /* or should it be System and not user? */ 177 GetLocaleInfoW(GetUserDefaultLCID(), LOCALE_SLANGUAGE, langSel, sizeof(langSel)/sizeof(WCHAR)); 178 179 SendMessageW(hList, 180 CB_SELECTSTRING, 181 -1, 182 (LPARAM)langSel); 183 } 184 185 186 BOOL 187 LoadCurrentLocale( 188 PGLOBALDATA pGlobalData) 189 { 190 WCHAR szBuffer[16]; 191 PWSTR ptr; 192 HKEY hLocaleKey; 193 DWORD ret; 194 DWORD dwSize; 195 196 ret = RegOpenKeyExW(HKEY_CURRENT_USER, 197 L"Control Panel\\International", 198 0, 199 KEY_READ, 200 &hLocaleKey); 201 if (ret != ERROR_SUCCESS) 202 { 203 PrintErrorMsgBox(IDS_ERROR_INT_KEY_REG); 204 return FALSE; 205 } 206 207 dwSize = 9 * sizeof(WCHAR); 208 RegQueryValueExW(hLocaleKey, 209 L"Locale", 210 NULL, 211 NULL, 212 (PBYTE)szBuffer, 213 &dwSize); 214 pGlobalData->UserLCID = (LCID)wcstoul(szBuffer, &ptr, 16); 215 216 /* Number */ 217 dwSize = MAX_NUMDECIMALSEP * sizeof(WCHAR); 218 RegQueryValueExW(hLocaleKey, 219 L"sDecimal", 220 NULL, 221 NULL, 222 (PBYTE)pGlobalData->szNumDecimalSep, 223 &dwSize); 224 225 dwSize = MAX_NUMTHOUSANDSEP * sizeof(WCHAR); 226 RegQueryValueExW(hLocaleKey, 227 L"sThousand", 228 NULL, 229 NULL, 230 (PBYTE)pGlobalData->szNumThousandSep, 231 &dwSize); 232 233 dwSize = MAX_NUMNEGATIVESIGN * sizeof(WCHAR); 234 RegQueryValueExW(hLocaleKey, 235 L"sNegativeSign", 236 NULL, 237 NULL, 238 (PBYTE)pGlobalData->szNumNegativeSign, 239 &dwSize); 240 241 dwSize = MAX_NUMPOSITIVESIGN * sizeof(WCHAR); 242 RegQueryValueExW(hLocaleKey, 243 L"sPositiveSign", 244 NULL, 245 NULL, 246 (PBYTE)pGlobalData->szNumPositiveSign, 247 &dwSize); 248 249 dwSize = MAX_NUMLISTSEP * sizeof(WCHAR); 250 RegQueryValueExW(hLocaleKey, 251 L"sList", 252 NULL, 253 NULL, 254 (PBYTE)pGlobalData->szNumListSep, 255 &dwSize); 256 257 dwSize = MAX_NUMNATIVEDIGITS * sizeof(WCHAR); 258 RegQueryValueExW(hLocaleKey, 259 L"sNativeDigits", 260 NULL, 261 NULL, 262 (PBYTE)pGlobalData->szNumNativeDigits, 263 &dwSize); 264 265 pGlobalData->nNumNegFormat = 0; 266 dwSize = 16 * sizeof(WCHAR); 267 if (RegQueryValueExW(hLocaleKey, 268 L"iNegNumber", 269 NULL, 270 NULL, 271 (PBYTE)szBuffer, 272 &dwSize) == ERROR_SUCCESS) 273 pGlobalData->nNumNegFormat = _wtoi(szBuffer); 274 275 pGlobalData->nNumDigits = 0; 276 dwSize = 16 * sizeof(WCHAR); 277 if (RegQueryValueExW(hLocaleKey, 278 L"iDigits", 279 NULL, 280 NULL, 281 (PBYTE)szBuffer, 282 &dwSize) == ERROR_SUCCESS) 283 pGlobalData->nNumDigits = _wtoi(szBuffer); 284 285 pGlobalData->nNumLeadingZero = 0; 286 dwSize = 16 * sizeof(WCHAR); 287 if (RegQueryValueExW(hLocaleKey, 288 L"iLZero", 289 NULL, 290 NULL, 291 (PBYTE)szBuffer, 292 &dwSize) == ERROR_SUCCESS) 293 pGlobalData->nNumLeadingZero = _wtoi(szBuffer); 294 295 pGlobalData->nNumMeasure = 0; 296 dwSize = 16 * sizeof(WCHAR); 297 if (RegQueryValueExW(hLocaleKey, 298 L"iMeasure", 299 NULL, 300 NULL, 301 (PBYTE)szBuffer, 302 &dwSize) == ERROR_SUCCESS) 303 pGlobalData->nNumMeasure = _wtoi(szBuffer); 304 305 pGlobalData->nNumShape = 0; 306 dwSize = 16 * sizeof(WCHAR); 307 if (RegQueryValueExW(hLocaleKey, 308 L"NumShape", 309 NULL, 310 NULL, 311 (PBYTE)szBuffer, 312 &dwSize) == ERROR_SUCCESS) 313 pGlobalData->nNumShape = _wtoi(szBuffer); 314 315 pGlobalData->nNumGrouping = 0; 316 dwSize = 16 * sizeof(WCHAR); 317 if (RegQueryValueExW(hLocaleKey, 318 L"sGrouping", 319 NULL, 320 NULL, 321 (PBYTE)szBuffer, 322 &dwSize) == ERROR_SUCCESS) 323 { 324 pGlobalData->nNumGrouping = 0; 325 if (szBuffer[0] == L'3') 326 { 327 if ((szBuffer[1] == L';') && 328 (szBuffer[2] == L'2')) 329 pGlobalData->nNumGrouping = 2; 330 else 331 pGlobalData->nNumGrouping = 1; 332 } 333 } 334 335 /* Currency */ 336 dwSize = MAX_CURRSYMBOL * sizeof(WCHAR); 337 RegQueryValueExW(hLocaleKey, 338 L"sCurrency", 339 NULL, 340 NULL, 341 (PBYTE)pGlobalData->szCurrSymbol, 342 &dwSize); 343 344 dwSize = MAX_CURRDECIMALSEP * sizeof(WCHAR); 345 RegQueryValueExW(hLocaleKey, 346 L"sMonDecimalSep", 347 NULL, 348 NULL, 349 (PBYTE)pGlobalData->szCurrDecimalSep, 350 &dwSize); 351 352 dwSize = MAX_CURRTHOUSANDSEP * sizeof(WCHAR); 353 RegQueryValueExW(hLocaleKey, 354 L"sMonThousandSep", 355 NULL, 356 NULL, 357 (PBYTE)pGlobalData->szCurrThousandSep, 358 &dwSize); 359 360 pGlobalData->nCurrGrouping = 0; 361 dwSize = 16 * sizeof(WCHAR); 362 if (RegQueryValueExW(hLocaleKey, 363 L"sMonGrouping", 364 NULL, 365 NULL, 366 (PBYTE)szBuffer, 367 &dwSize) == ERROR_SUCCESS) 368 { 369 pGlobalData->nCurrGrouping = 0; 370 if (szBuffer[0] == L'3') 371 { 372 if ((szBuffer[1] == L';') && 373 (szBuffer[2] == L'2')) 374 pGlobalData->nCurrGrouping = 2; 375 else 376 pGlobalData->nCurrGrouping = 1; 377 } 378 } 379 380 pGlobalData->nCurrPosFormat = 0; 381 dwSize = 16 * sizeof(WCHAR); 382 if (RegQueryValueExW(hLocaleKey, 383 L"iCurrency", 384 NULL, 385 NULL, 386 (PBYTE)szBuffer, 387 &dwSize) == ERROR_SUCCESS) 388 pGlobalData->nCurrPosFormat = _wtoi(szBuffer); 389 390 pGlobalData->nCurrNegFormat = 0; 391 dwSize = 16 * sizeof(WCHAR); 392 if (RegQueryValueExW(hLocaleKey, 393 L"iNegCurr", 394 NULL, 395 NULL, 396 (PBYTE)szBuffer, 397 &dwSize) == ERROR_SUCCESS) 398 pGlobalData->nCurrNegFormat = _wtoi(szBuffer); 399 400 pGlobalData->nCurrDigits = 0; 401 dwSize = 16 * sizeof(WCHAR); 402 if (RegQueryValueExW(hLocaleKey, 403 L"iCurrDigits", 404 NULL, 405 NULL, 406 (PBYTE)szBuffer, 407 &dwSize) == ERROR_SUCCESS) 408 pGlobalData->nCurrDigits = _wtoi(szBuffer); 409 410 /* Time */ 411 dwSize = MAX_TIMEFORMAT * sizeof(WCHAR); 412 RegQueryValueExW(hLocaleKey, 413 L"sTimeFormat", 414 NULL, 415 NULL, 416 (PBYTE)pGlobalData->szTimeFormat, 417 &dwSize); 418 419 dwSize = MAX_TIMESEPARATOR * sizeof(WCHAR); 420 RegQueryValueExW(hLocaleKey, 421 L"sTime", 422 NULL, 423 NULL, 424 (PBYTE)pGlobalData->szTimeSep, 425 &dwSize); 426 427 dwSize = MAX_TIMEAMSYMBOL * sizeof(WCHAR); 428 RegQueryValueExW(hLocaleKey, 429 L"s1159", 430 NULL, 431 NULL, 432 (PBYTE)pGlobalData->szTimeAM, 433 &dwSize); 434 435 dwSize = MAX_TIMEPMSYMBOL * sizeof(WCHAR); 436 RegQueryValueExW(hLocaleKey, 437 L"s2359", 438 NULL, 439 NULL, 440 (PBYTE)pGlobalData->szTimePM, 441 &dwSize); 442 443 pGlobalData->nTime = 0; 444 dwSize = 16 * sizeof(WCHAR); 445 if (RegQueryValueExW(hLocaleKey, 446 L"iTime", 447 NULL, 448 NULL, 449 (PBYTE)szBuffer, 450 &dwSize) == ERROR_SUCCESS) 451 pGlobalData->nTime = _wtoi(szBuffer); 452 453 pGlobalData->nTimePrefix = 0; 454 dwSize = 16 * sizeof(WCHAR); 455 if (RegQueryValueExW(hLocaleKey, 456 L"iTimePrefix", 457 NULL, 458 NULL, 459 (PBYTE)szBuffer, 460 &dwSize) == ERROR_SUCCESS) 461 pGlobalData->nTimePrefix = _wtoi(szBuffer); 462 463 pGlobalData->nTimeLeadingZero = 0; 464 dwSize = 16 * sizeof(WCHAR); 465 if (RegQueryValueExW(hLocaleKey, 466 L"iTLZero", 467 NULL, 468 NULL, 469 (PBYTE)szBuffer, 470 &dwSize) == ERROR_SUCCESS) 471 pGlobalData->nTimeLeadingZero = _wtoi(szBuffer); 472 473 /* Date */ 474 dwSize = MAX_LONGDATEFORMAT * sizeof(WCHAR); 475 RegQueryValueExW(hLocaleKey, 476 L"sLongDate", 477 NULL, 478 NULL, 479 (PBYTE)pGlobalData->szLongDateFormat, 480 &dwSize); 481 482 dwSize = MAX_SHORTDATEFORMAT * sizeof(WCHAR); 483 RegQueryValueExW(hLocaleKey, 484 L"sShortDate", 485 NULL, 486 NULL, 487 (PBYTE)pGlobalData->szShortDateFormat, 488 &dwSize); 489 490 dwSize = MAX_DATESEPARATOR * sizeof(WCHAR); 491 RegQueryValueExW(hLocaleKey, 492 L"sDate", 493 NULL, 494 NULL, 495 (PBYTE)pGlobalData->szDateSep, 496 &dwSize); 497 498 pGlobalData->nFirstDayOfWeek = 0; 499 dwSize = 16 * sizeof(WCHAR); 500 if (RegQueryValueExW(hLocaleKey, 501 L"iFirstDayOfWeek", 502 NULL, 503 NULL, 504 (PBYTE)szBuffer, 505 &dwSize) == ERROR_SUCCESS) 506 pGlobalData->nFirstDayOfWeek = _wtoi(szBuffer); 507 508 pGlobalData->nFirstWeekOfYear = 0; 509 dwSize = 16 * sizeof(WCHAR); 510 if (RegQueryValueExW(hLocaleKey, 511 L"iFirstWeekOfYear", 512 NULL, 513 NULL, 514 (PBYTE)szBuffer, 515 &dwSize) == ERROR_SUCCESS) 516 pGlobalData->nFirstWeekOfYear = _wtoi(szBuffer); 517 518 pGlobalData->nDate = 0; 519 dwSize = 16 * sizeof(WCHAR); 520 if (RegQueryValueExW(hLocaleKey, 521 L"iDate", 522 NULL, 523 NULL, 524 (PBYTE)szBuffer, 525 &dwSize) == ERROR_SUCCESS) 526 pGlobalData->nDate = _wtoi(szBuffer); 527 528 pGlobalData->nCalendarType = 0; 529 dwSize = 16 * sizeof(WCHAR); 530 if (RegQueryValueExW(hLocaleKey, 531 L"iCalendarType", 532 NULL, 533 NULL, 534 (PBYTE)szBuffer, 535 &dwSize) == ERROR_SUCCESS) 536 pGlobalData->nCalendarType = _wtoi(szBuffer); 537 538 /* Misc */ 539 dwSize = MAX_MISCCOUNTRY * sizeof(WCHAR); 540 RegQueryValueExW(hLocaleKey, 541 L"sCountry", 542 NULL, 543 NULL, 544 (PBYTE)pGlobalData->szMiscCountry, 545 &dwSize); 546 547 dwSize = MAX_MISCLANGUAGE * sizeof(WCHAR); 548 RegQueryValueExW(hLocaleKey, 549 L"sLanguage", 550 NULL, 551 NULL, 552 (PBYTE)pGlobalData->szMiscLanguage, 553 &dwSize); 554 555 pGlobalData->nMiscCountry = 0; 556 dwSize = 16 * sizeof(WCHAR); 557 if (RegQueryValueExW(hLocaleKey, 558 L"iCountry", 559 NULL, 560 NULL, 561 (PBYTE)szBuffer, 562 &dwSize) == ERROR_SUCCESS) 563 pGlobalData->nMiscCountry = _wtoi(szBuffer); 564 565 RegCloseKey(hLocaleKey); 566 567 return TRUE; 568 } 569 570 571 VOID 572 SetNewLocale( 573 PGLOBALDATA pGlobalData, 574 LCID lcid) 575 { 576 WCHAR szBuffer[16]; 577 578 pGlobalData->UserLCID = lcid; 579 580 /* Number */ 581 GetLocaleInfo(lcid, 582 LOCALE_SDECIMAL | LOCALE_NOUSEROVERRIDE, 583 pGlobalData->szNumDecimalSep, 584 MAX_NUMDECIMALSEP); 585 586 GetLocaleInfo(lcid, 587 LOCALE_STHOUSAND | LOCALE_NOUSEROVERRIDE, 588 pGlobalData->szNumThousandSep, 589 MAX_NUMTHOUSANDSEP); 590 591 GetLocaleInfo(lcid, 592 LOCALE_SNEGATIVESIGN | LOCALE_NOUSEROVERRIDE, 593 pGlobalData->szNumNegativeSign, 594 MAX_NUMNEGATIVESIGN); 595 596 GetLocaleInfo(lcid, 597 LOCALE_SPOSITIVESIGN | LOCALE_NOUSEROVERRIDE, 598 pGlobalData->szNumPositiveSign, 599 MAX_NUMPOSITIVESIGN); 600 601 GetLocaleInfo(lcid, 602 LOCALE_SLIST | LOCALE_NOUSEROVERRIDE, 603 pGlobalData->szNumListSep, 604 MAX_NUMLISTSEP); 605 606 GetLocaleInfo(lcid, 607 LOCALE_SNATIVEDIGITS | LOCALE_NOUSEROVERRIDE, 608 pGlobalData->szNumNativeDigits, 609 MAX_NUMNATIVEDIGITS); 610 611 GetLocaleInfo(lcid, 612 LOCALE_INEGNUMBER | LOCALE_NOUSEROVERRIDE, 613 szBuffer, 614 sizeof(szBuffer) / sizeof(WCHAR)); 615 pGlobalData->nNumNegFormat = _wtoi(szBuffer); 616 617 GetLocaleInfo(lcid, 618 LOCALE_IDIGITS | LOCALE_NOUSEROVERRIDE, 619 szBuffer, 620 sizeof(szBuffer) / sizeof(WCHAR)); 621 pGlobalData->nNumDigits = _wtoi(szBuffer); 622 623 GetLocaleInfo(lcid, 624 LOCALE_ILZERO | LOCALE_NOUSEROVERRIDE, 625 szBuffer, 626 sizeof(szBuffer) / sizeof(WCHAR)); 627 pGlobalData->nNumLeadingZero = _wtoi(szBuffer); 628 629 GetLocaleInfo(lcid, 630 LOCALE_IMEASURE | LOCALE_NOUSEROVERRIDE, 631 szBuffer, 632 sizeof(szBuffer) / sizeof(WCHAR)); 633 pGlobalData->nNumMeasure = _wtoi(szBuffer); 634 635 GetLocaleInfo(lcid, 636 LOCALE_IDIGITSUBSTITUTION | LOCALE_NOUSEROVERRIDE, 637 szBuffer, 638 sizeof(szBuffer) / sizeof(WCHAR)); 639 pGlobalData->nNumShape = _wtoi(szBuffer); 640 641 GetLocaleInfo(lcid, 642 LOCALE_SGROUPING | LOCALE_NOUSEROVERRIDE, 643 szBuffer, 644 sizeof(szBuffer) / sizeof(WCHAR)); 645 pGlobalData->nNumGrouping = 0; 646 if (szBuffer[0] == L'3') 647 { 648 if ((szBuffer[1] == L';') && 649 (szBuffer[2] == L'2')) 650 pGlobalData->nNumGrouping = 2; 651 else 652 pGlobalData->nNumGrouping = 1; 653 } 654 655 /* Currency */ 656 GetLocaleInfo(lcid, 657 LOCALE_SCURRENCY | LOCALE_NOUSEROVERRIDE, 658 pGlobalData->szCurrSymbol, 659 MAX_CURRSYMBOL); 660 661 GetLocaleInfo(lcid, 662 LOCALE_SMONDECIMALSEP | LOCALE_NOUSEROVERRIDE, 663 pGlobalData->szCurrDecimalSep, 664 MAX_CURRDECIMALSEP); 665 666 GetLocaleInfo(lcid, 667 LOCALE_SMONTHOUSANDSEP | LOCALE_NOUSEROVERRIDE, 668 pGlobalData->szCurrThousandSep, 669 MAX_CURRTHOUSANDSEP); 670 671 GetLocaleInfo(lcid, 672 LOCALE_SMONGROUPING | LOCALE_NOUSEROVERRIDE, 673 szBuffer, 674 sizeof(szBuffer) / sizeof(WCHAR)); 675 pGlobalData->nCurrGrouping = 0; 676 if (szBuffer[0] == L'3') 677 { 678 if ((szBuffer[1] == L';') && 679 (szBuffer[2] == L'2')) 680 pGlobalData->nCurrGrouping = 2; 681 else 682 pGlobalData->nCurrGrouping = 1; 683 } 684 685 GetLocaleInfo(lcid, 686 LOCALE_ICURRENCY | LOCALE_NOUSEROVERRIDE, 687 szBuffer, 688 sizeof(szBuffer) / sizeof(WCHAR)); 689 pGlobalData->nCurrPosFormat = _wtoi(szBuffer); 690 691 GetLocaleInfo(lcid, 692 LOCALE_INEGCURR | LOCALE_NOUSEROVERRIDE, 693 szBuffer, 694 sizeof(szBuffer) / sizeof(WCHAR)); 695 pGlobalData->nCurrNegFormat = _wtoi(szBuffer); 696 697 GetLocaleInfo(lcid, 698 LOCALE_ICURRDIGITS | LOCALE_NOUSEROVERRIDE, 699 szBuffer, 700 sizeof(szBuffer) / sizeof(WCHAR)); 701 pGlobalData->nCurrDigits = _wtoi(szBuffer); 702 703 /* Time */ 704 GetLocaleInfo(lcid, 705 LOCALE_STIMEFORMAT | LOCALE_NOUSEROVERRIDE, 706 pGlobalData->szTimeFormat, 707 MAX_TIMEFORMAT); 708 709 GetLocaleInfo(lcid, 710 LOCALE_STIME | LOCALE_NOUSEROVERRIDE, 711 pGlobalData->szTimeSep, 712 MAX_TIMESEPARATOR); 713 714 GetLocaleInfo(lcid, 715 LOCALE_S1159 | LOCALE_NOUSEROVERRIDE, 716 pGlobalData->szTimeAM, 717 MAX_TIMEAMSYMBOL); 718 719 GetLocaleInfo(lcid, 720 LOCALE_S2359 | LOCALE_NOUSEROVERRIDE, 721 pGlobalData->szTimePM, 722 MAX_TIMEPMSYMBOL); 723 724 GetLocaleInfo(lcid, 725 LOCALE_ITIME | LOCALE_NOUSEROVERRIDE, 726 szBuffer, 727 sizeof(szBuffer) / sizeof(WCHAR)); 728 pGlobalData->nTime = _wtoi(szBuffer); 729 730 GetLocaleInfo(lcid, 731 LOCALE_ITIMEMARKPOSN | LOCALE_NOUSEROVERRIDE, 732 szBuffer, 733 sizeof(szBuffer) / sizeof(WCHAR)); 734 pGlobalData->nTimePrefix = _wtoi(szBuffer); 735 736 GetLocaleInfo(lcid, 737 LOCALE_ITLZERO | LOCALE_NOUSEROVERRIDE, 738 szBuffer, 739 sizeof(szBuffer) / sizeof(WCHAR)); 740 pGlobalData->nTimeLeadingZero = _wtoi(szBuffer); 741 742 /* Date */ 743 GetLocaleInfo(lcid, 744 LOCALE_SLONGDATE | LOCALE_NOUSEROVERRIDE, 745 pGlobalData->szLongDateFormat, 746 MAX_LONGDATEFORMAT); 747 748 GetLocaleInfo(lcid, 749 LOCALE_SSHORTDATE | LOCALE_NOUSEROVERRIDE, 750 pGlobalData->szShortDateFormat, 751 MAX_SHORTDATEFORMAT); 752 753 GetLocaleInfo(lcid, 754 LOCALE_SDATE | LOCALE_NOUSEROVERRIDE, 755 pGlobalData->szDateSep, 756 MAX_DATESEPARATOR); 757 758 GetLocaleInfo(lcid, 759 LOCALE_IFIRSTDAYOFWEEK | LOCALE_NOUSEROVERRIDE, 760 szBuffer, 761 sizeof(szBuffer) / sizeof(WCHAR)); 762 pGlobalData->nFirstDayOfWeek = _wtoi(szBuffer); 763 764 GetLocaleInfo(lcid, 765 LOCALE_IFIRSTWEEKOFYEAR | LOCALE_NOUSEROVERRIDE, 766 szBuffer, 767 sizeof(szBuffer) / sizeof(WCHAR)); 768 pGlobalData->nFirstWeekOfYear = _wtoi(szBuffer); 769 770 GetLocaleInfo(lcid, 771 LOCALE_IDATE | LOCALE_NOUSEROVERRIDE, 772 szBuffer, 773 sizeof(szBuffer) / sizeof(WCHAR)); 774 pGlobalData->nDate = _wtoi(szBuffer); 775 776 GetLocaleInfo(lcid, 777 LOCALE_ICALENDARTYPE | LOCALE_NOUSEROVERRIDE, 778 szBuffer, 779 sizeof(szBuffer) / sizeof(WCHAR)); 780 pGlobalData->nCalendarType = _wtoi(szBuffer); 781 782 /* Misc */ 783 GetLocaleInfo(lcid, 784 LOCALE_SCOUNTRY | LOCALE_NOUSEROVERRIDE, 785 pGlobalData->szMiscCountry, 786 MAX_MISCCOUNTRY); 787 788 GetLocaleInfo(lcid, 789 LOCALE_SLANGUAGE | LOCALE_NOUSEROVERRIDE, 790 pGlobalData->szMiscLanguage, 791 MAX_MISCLANGUAGE); 792 793 GetLocaleInfo(lcid, 794 LOCALE_ICOUNTRY | LOCALE_NOUSEROVERRIDE, 795 szBuffer, 796 sizeof(szBuffer) / sizeof(WCHAR)); 797 pGlobalData->nMiscCountry = _wtoi(szBuffer); 798 } 799 800 801 static 802 VOID 803 SaveUserLocale( 804 PGLOBALDATA pGlobalData, 805 HKEY hLocaleKey) 806 { 807 WCHAR szBuffer[16]; 808 809 wsprintf(szBuffer, L"%08lx", (DWORD)pGlobalData->UserLCID); 810 RegSetValueExW(hLocaleKey, 811 L"Locale", 812 0, 813 REG_SZ, 814 (PBYTE)szBuffer, 815 (wcslen(szBuffer) + 1) * sizeof(WCHAR)); 816 817 /* Number */ 818 RegSetValueExW(hLocaleKey, 819 L"sDecimal", 820 0, 821 REG_SZ, 822 (PBYTE)pGlobalData->szNumDecimalSep, 823 (wcslen(pGlobalData->szNumDecimalSep) + 1) * sizeof(WCHAR)); 824 825 RegSetValueExW(hLocaleKey, 826 L"sThousand", 827 0, 828 REG_SZ, 829 (PBYTE)pGlobalData->szNumThousandSep, 830 (wcslen(pGlobalData->szNumThousandSep) + 1) * sizeof(WCHAR)); 831 832 RegSetValueExW(hLocaleKey, 833 L"sNegativeSign", 834 0, 835 REG_SZ, 836 (PBYTE)pGlobalData->szNumNegativeSign, 837 (wcslen(pGlobalData->szNumNegativeSign) + 1) * sizeof(WCHAR)); 838 839 RegSetValueExW(hLocaleKey, 840 L"sPositiveSign", 841 0, 842 REG_SZ, 843 (PBYTE)pGlobalData->szNumPositiveSign, 844 (wcslen(pGlobalData->szNumPositiveSign) + 1) * sizeof(WCHAR)); 845 846 RegSetValueExW(hLocaleKey, 847 L"sGrouping", 848 0, 849 REG_SZ, 850 (PBYTE)GroupingFormats[pGlobalData->nNumGrouping].pszString, 851 (wcslen(GroupingFormats[pGlobalData->nNumGrouping].pszString) + 1) * sizeof(WCHAR)); 852 853 RegSetValueExW(hLocaleKey, 854 L"sList", 855 0, 856 REG_SZ, 857 (PBYTE)pGlobalData->szNumListSep, 858 (wcslen(pGlobalData->szNumListSep) + 1) * sizeof(WCHAR)); 859 860 RegSetValueExW(hLocaleKey, 861 L"sNativeDigits", 862 0, 863 REG_SZ, 864 (PBYTE)pGlobalData->szNumNativeDigits, 865 (wcslen(pGlobalData->szNumNativeDigits) + 1) * sizeof(WCHAR)); 866 867 _itow(pGlobalData->nNumNegFormat, 868 szBuffer, DECIMAL_RADIX); 869 RegSetValueExW(hLocaleKey, 870 L"iNegNumber", 871 0, 872 REG_SZ, 873 (PBYTE)szBuffer, 874 (wcslen(szBuffer) + 1) * sizeof(WCHAR)); 875 876 _itow(pGlobalData->nNumDigits, 877 szBuffer, DECIMAL_RADIX); 878 RegSetValueExW(hLocaleKey, 879 L"iDigits", 880 0, 881 REG_SZ, 882 (PBYTE)szBuffer, 883 (wcslen(szBuffer) + 1) * sizeof(WCHAR)); 884 885 _itow(pGlobalData->nNumLeadingZero, 886 szBuffer, DECIMAL_RADIX); 887 RegSetValueExW(hLocaleKey, 888 L"iLZero", 889 0, 890 REG_SZ, 891 (PBYTE)szBuffer, 892 (wcslen(szBuffer) + 1) * sizeof(WCHAR)); 893 894 _itow(pGlobalData->nNumMeasure, 895 szBuffer, DECIMAL_RADIX); 896 RegSetValueExW(hLocaleKey, 897 L"iMeasure", 898 0, 899 REG_SZ, 900 (PBYTE)szBuffer, 901 (wcslen(szBuffer) + 1) * sizeof(WCHAR)); 902 903 _itow(pGlobalData->nNumShape, 904 szBuffer, DECIMAL_RADIX); 905 RegSetValueExW(hLocaleKey, 906 L"NumShape", 907 0, 908 REG_SZ, 909 (PBYTE)szBuffer, 910 (wcslen(szBuffer) + 1) * sizeof(WCHAR)); 911 912 /* Currency */ 913 RegSetValueExW(hLocaleKey, 914 L"sCurrency", 915 0, 916 REG_SZ, 917 (PBYTE)pGlobalData->szCurrSymbol, 918 (wcslen(pGlobalData->szCurrSymbol) + 1) * sizeof(WCHAR)); 919 920 RegSetValueExW(hLocaleKey, 921 L"sMonDecimalSep", 922 0, 923 REG_SZ, 924 (PBYTE)pGlobalData->szCurrDecimalSep, 925 (wcslen(pGlobalData->szCurrDecimalSep) + 1) * sizeof(WCHAR)); 926 927 RegSetValueExW(hLocaleKey, 928 L"sMonThousandSep", 929 0, 930 REG_SZ, 931 (PBYTE)pGlobalData->szCurrThousandSep, 932 (wcslen(pGlobalData->szCurrThousandSep) + 1) * sizeof(WCHAR)); 933 934 RegSetValueExW(hLocaleKey, 935 L"sMonGrouping", 936 0, 937 REG_SZ, 938 (PBYTE)GroupingFormats[pGlobalData->nCurrGrouping].pszString, 939 (wcslen(GroupingFormats[pGlobalData->nCurrGrouping].pszString) + 1) * sizeof(WCHAR)); 940 941 _itow(pGlobalData->nCurrPosFormat, 942 szBuffer, DECIMAL_RADIX); 943 RegSetValueExW(hLocaleKey, 944 L"iCurrency", 945 0, 946 REG_SZ, 947 (PBYTE)szBuffer, 948 (wcslen(szBuffer) + 1) * sizeof(WCHAR)); 949 950 _itow(pGlobalData->nCurrNegFormat, 951 szBuffer, DECIMAL_RADIX); 952 RegSetValueExW(hLocaleKey, 953 L"iNegCurr", 954 0, 955 REG_SZ, 956 (PBYTE)szBuffer, 957 (wcslen(szBuffer) + 1) * sizeof(WCHAR)); 958 959 _itow(pGlobalData->nCurrDigits, 960 szBuffer, DECIMAL_RADIX); 961 RegSetValueExW(hLocaleKey, 962 L"iCurrDigits", 963 0, 964 REG_SZ, 965 (PBYTE)szBuffer, 966 (wcslen(szBuffer) + 1) * sizeof(WCHAR)); 967 968 /* Time */ 969 RegSetValueExW(hLocaleKey, 970 L"sTimeFormat", 971 0, 972 REG_SZ, 973 (PBYTE)pGlobalData->szTimeFormat, 974 (wcslen(pGlobalData->szTimeFormat) + 1) * sizeof(WCHAR)); 975 976 RegSetValueExW(hLocaleKey, 977 L"sTime", 978 0, 979 REG_SZ, 980 (PBYTE)pGlobalData->szTimeSep, 981 (wcslen(pGlobalData->szTimeSep) + 1) * sizeof(WCHAR)); 982 983 RegSetValueExW(hLocaleKey, 984 L"s1159", 985 0, 986 REG_SZ, 987 (PBYTE)pGlobalData->szTimeAM, 988 (wcslen(pGlobalData->szTimeAM) + 1) * sizeof(WCHAR)); 989 990 RegSetValueExW(hLocaleKey, 991 L"s2359", 992 0, 993 REG_SZ, 994 (PBYTE)pGlobalData->szTimePM, 995 (wcslen(pGlobalData->szTimePM) + 1) * sizeof(WCHAR)); 996 997 _itow(pGlobalData->nTime, 998 szBuffer, DECIMAL_RADIX); 999 RegSetValueExW(hLocaleKey, 1000 L"iTime", 1001 0, 1002 REG_SZ, 1003 (PBYTE)szBuffer, 1004 (wcslen(szBuffer) + 1) * sizeof(WCHAR)); 1005 1006 _itow(pGlobalData->nTimePrefix, 1007 szBuffer, DECIMAL_RADIX); 1008 RegSetValueExW(hLocaleKey, 1009 L"iTimePrefix", 1010 0, 1011 REG_SZ, 1012 (PBYTE)szBuffer, 1013 (wcslen(szBuffer) + 1) * sizeof(WCHAR)); 1014 1015 _itow(pGlobalData->nTimeLeadingZero, 1016 szBuffer, DECIMAL_RADIX); 1017 RegSetValueExW(hLocaleKey, 1018 L"iTLZero", 1019 0, 1020 REG_SZ, 1021 (PBYTE)szBuffer, 1022 (wcslen(szBuffer) + 1) * sizeof(WCHAR)); 1023 1024 /* Date */ 1025 RegSetValueExW(hLocaleKey, 1026 L"sLongDate", 1027 0, 1028 REG_SZ, 1029 (PBYTE)pGlobalData->szLongDateFormat, 1030 (wcslen(pGlobalData->szLongDateFormat) + 1) * sizeof(WCHAR)); 1031 1032 RegSetValueExW(hLocaleKey, 1033 L"sShortDate", 1034 0, 1035 REG_SZ, 1036 (PBYTE)pGlobalData->szShortDateFormat, 1037 (wcslen(pGlobalData->szShortDateFormat) + 1) * sizeof(WCHAR)); 1038 1039 RegSetValueExW(hLocaleKey, 1040 L"sDate", 1041 0, 1042 REG_SZ, 1043 (PBYTE)pGlobalData->szDateSep, 1044 (wcslen(pGlobalData->szDateSep) + 1) * sizeof(WCHAR)); 1045 1046 _itow(pGlobalData->nFirstDayOfWeek, 1047 szBuffer, DECIMAL_RADIX); 1048 RegSetValueExW(hLocaleKey, 1049 L"iFirstDayOfWeek", 1050 0, 1051 REG_SZ, 1052 (PBYTE)szBuffer, 1053 (wcslen(szBuffer) + 1) * sizeof(WCHAR)); 1054 1055 _itow(pGlobalData->nFirstWeekOfYear, 1056 szBuffer, DECIMAL_RADIX); 1057 RegSetValueExW(hLocaleKey, 1058 L"iFirstWeekOfYear", 1059 0, 1060 REG_SZ, 1061 (PBYTE)szBuffer, 1062 (wcslen(szBuffer) + 1) * sizeof(WCHAR)); 1063 1064 _itow(pGlobalData->nDate, 1065 szBuffer, DECIMAL_RADIX); 1066 RegSetValueExW(hLocaleKey, 1067 L"iDate", 1068 0, 1069 REG_SZ, 1070 (PBYTE)szBuffer, 1071 (wcslen(szBuffer) + 1) * sizeof(WCHAR)); 1072 1073 _itow(pGlobalData->nCalendarType, 1074 szBuffer, DECIMAL_RADIX); 1075 RegSetValueExW(hLocaleKey, 1076 L"iCalendarType", 1077 0, 1078 REG_SZ, 1079 (PBYTE)szBuffer, 1080 (wcslen(szBuffer) + 1) * sizeof(WCHAR)); 1081 1082 /* Misc */ 1083 RegSetValueExW(hLocaleKey, 1084 L"sCountry", 1085 0, 1086 REG_SZ, 1087 (PBYTE)pGlobalData->szMiscCountry, 1088 (wcslen(pGlobalData->szMiscCountry) + 1) * sizeof(WCHAR)); 1089 1090 RegSetValueExW(hLocaleKey, 1091 L"sLanguage", 1092 0, 1093 REG_SZ, 1094 (PBYTE)pGlobalData->szMiscLanguage, 1095 (wcslen(pGlobalData->szMiscLanguage) + 1) * sizeof(WCHAR)); 1096 1097 _itow(pGlobalData->nMiscCountry, 1098 szBuffer, DECIMAL_RADIX); 1099 RegSetValueExW(hLocaleKey, 1100 L"iCountry", 1101 0, 1102 REG_SZ, 1103 (PBYTE)szBuffer, 1104 (wcslen(szBuffer) + 1) * sizeof(WCHAR)); 1105 } 1106 1107 1108 /* Sets new locale */ 1109 VOID 1110 SaveCurrentLocale( 1111 PGLOBALDATA pGlobalData) 1112 { 1113 HKEY hLocaleKey; 1114 DWORD ret; 1115 1116 if (pGlobalData->bApplyToDefaultUser) 1117 { 1118 ret = RegOpenKeyExW(HKEY_USERS, 1119 L".DEFAULT\\Control Panel\\International", 1120 0, 1121 KEY_WRITE, 1122 &hLocaleKey); 1123 if (ret != ERROR_SUCCESS) 1124 { 1125 PrintErrorMsgBox(IDS_ERROR_DEF_INT_KEY_REG); 1126 return; 1127 } 1128 1129 SaveUserLocale(pGlobalData, hLocaleKey); 1130 1131 /* Flush and close the locale key */ 1132 RegFlushKey(hLocaleKey); 1133 RegCloseKey(hLocaleKey); 1134 } 1135 1136 ret = RegOpenKeyExW(HKEY_CURRENT_USER, 1137 L"Control Panel\\International", 1138 0, 1139 KEY_WRITE, 1140 &hLocaleKey); 1141 if (ret != ERROR_SUCCESS) 1142 { 1143 PrintErrorMsgBox(IDS_ERROR_INT_KEY_REG); 1144 return; 1145 } 1146 1147 SaveUserLocale(pGlobalData, hLocaleKey); 1148 1149 /* Flush and close the locale key */ 1150 RegFlushKey(hLocaleKey); 1151 RegCloseKey(hLocaleKey); 1152 1153 /* Set the new locale for the current process */ 1154 NtSetDefaultLocale(TRUE, pGlobalData->UserLCID); 1155 } 1156 1157 /* Location enumerate procedure */ 1158 BOOL 1159 CALLBACK 1160 LocationsEnumProc(GEOID gId) 1161 { 1162 WCHAR loc[MAX_STR_SIZE]; 1163 INT index; 1164 1165 if (GetGeoInfoW(gId, GEO_FRIENDLYNAME, loc, MAX_STR_SIZE, LANG_SYSTEM_DEFAULT) == 0) 1166 return TRUE; 1167 1168 index = (INT)SendMessageW(hGeoList, 1169 CB_ADDSTRING, 1170 0, 1171 (LPARAM)loc); 1172 1173 SendMessageW(hGeoList, 1174 CB_SETITEMDATA, 1175 index, 1176 (LPARAM)gId); 1177 1178 return TRUE; 1179 } 1180 1181 /* Enumerate all system locations identifiers */ 1182 static 1183 GEOID 1184 CreateLocationsList(HWND hWnd) 1185 { 1186 GEOID userGeoID; 1187 WCHAR loc[MAX_STR_SIZE]; 1188 1189 hGeoList = hWnd; 1190 1191 EnumSystemGeoID(GEOCLASS_NATION, 0, LocationsEnumProc); 1192 1193 /* Select current location */ 1194 userGeoID = GetUserGeoID(GEOCLASS_NATION); 1195 GetGeoInfoW(userGeoID, 1196 GEO_FRIENDLYNAME, 1197 loc, 1198 MAX_STR_SIZE, 1199 LANG_SYSTEM_DEFAULT); 1200 1201 SendMessageW(hGeoList, 1202 CB_SELECTSTRING, 1203 (WPARAM) -1, 1204 (LPARAM)loc); 1205 1206 return userGeoID; 1207 } 1208 1209 VOID 1210 SaveGeoID( 1211 PGLOBALDATA pGlobalData) 1212 { 1213 HKEY hGeoKey; 1214 WCHAR value[15]; 1215 DWORD valuesize; 1216 DWORD ret; 1217 1218 wsprintf(value, L"%lu", (DWORD)pGlobalData->geoid); 1219 valuesize = (wcslen(value) + 1) * sizeof(WCHAR); 1220 1221 if (pGlobalData->bApplyToDefaultUser) 1222 { 1223 ret = RegOpenKeyExW(HKEY_USERS, 1224 L".DEFAULT\\Control Panel\\International\\Geo", 1225 0, 1226 KEY_WRITE, 1227 &hGeoKey); 1228 if (ret != ERROR_SUCCESS) 1229 { 1230 PrintErrorMsgBox(IDS_ERROR_DEF_INT_KEY_REG); 1231 return; 1232 } 1233 1234 ret = RegSetValueExW(hGeoKey, 1235 L"Nation", 1236 0, 1237 REG_SZ, 1238 (PBYTE)value, 1239 valuesize); 1240 1241 RegFlushKey(hGeoKey); 1242 RegCloseKey(hGeoKey); 1243 1244 if (ret != ERROR_SUCCESS) 1245 { 1246 PrintErrorMsgBox(IDS_ERROR_INT_KEY_REG); 1247 return; 1248 } 1249 } 1250 1251 ret = RegOpenKeyExW(HKEY_CURRENT_USER, 1252 L"Control Panel\\International\\Geo", 1253 0, 1254 KEY_WRITE, 1255 &hGeoKey); 1256 if (ret != ERROR_SUCCESS) 1257 { 1258 PrintErrorMsgBox(IDS_ERROR_INT_KEY_REG); 1259 return; 1260 } 1261 1262 ret = RegSetValueExW(hGeoKey, 1263 L"Nation", 1264 0, 1265 REG_SZ, 1266 (PBYTE)value, 1267 valuesize); 1268 1269 RegFlushKey(hGeoKey); 1270 RegCloseKey(hGeoKey); 1271 1272 if (ret != ERROR_SUCCESS) 1273 { 1274 PrintErrorMsgBox(IDS_ERROR_INT_KEY_REG); 1275 return; 1276 } 1277 } 1278 1279 DWORD 1280 VerifyUnattendLCID(HWND hwndDlg) 1281 { 1282 LRESULT lCount, lIndex, lResult; 1283 1284 lCount = SendMessage(hList, CB_GETCOUNT, (WPARAM)0, (LPARAM)0); 1285 if (lCount == CB_ERR) 1286 { 1287 return 0; 1288 } 1289 1290 for (lIndex = 0; lIndex < lCount; lIndex++) 1291 { 1292 lResult = SendMessage(hList, CB_GETITEMDATA, (WPARAM)lIndex, (LPARAM)0); 1293 if (lResult == CB_ERR) 1294 { 1295 continue; 1296 } 1297 1298 if (lResult == (LRESULT)UnattendLCID) 1299 { 1300 SendMessage(hList, CB_SETCURSEL, (WPARAM)lIndex, (LPARAM)0); 1301 PropSheet_Changed(GetParent(hwndDlg), hwndDlg); 1302 return 1; 1303 } 1304 } 1305 1306 return 0; 1307 } 1308 1309 1310 static 1311 VOID 1312 InitPropSheetPage( 1313 PROPSHEETPAGEW *psp, 1314 WORD idDlg, 1315 DLGPROC DlgProc, 1316 PGLOBALDATA pGlobalData) 1317 { 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; 1325 } 1326 1327 1328 INT_PTR 1329 APIENTRY 1330 CustomizeLocalePropertySheet( 1331 HWND hwndDlg, 1332 PGLOBALDATA pGlobalData) 1333 { 1334 PROPSHEETPAGEW PsPage[NUM_SHEETS + 1]; 1335 PROPSHEETHEADERW psh; 1336 WCHAR Caption[MAX_STR_SIZE]; 1337 1338 LoadStringW(hApplet, IDS_CUSTOMIZE_TITLE, Caption, sizeof(Caption) / sizeof(TCHAR)); 1339 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; 1348 psh.nStartPage = 0; 1349 psh.ppsp = PsPage; 1350 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); 1355 1356 if (IsSortPageNeeded(pGlobalData->UserLCID)) 1357 { 1358 psh.nPages++; 1359 InitPropSheetPage(&PsPage[4], IDD_SORTPAGE, SortPageProc, pGlobalData); 1360 } 1361 1362 return PropertySheetW(&psh); 1363 } 1364 1365 1366 /* Property page dialog callback */ 1367 INT_PTR CALLBACK 1368 GeneralPageProc(HWND hwndDlg, 1369 UINT uMsg, 1370 WPARAM wParam, 1371 LPARAM lParam) 1372 { 1373 PGLOBALDATA pGlobalData; 1374 1375 pGlobalData = (PGLOBALDATA)GetWindowLongPtr(hwndDlg, DWLP_USER); 1376 1377 switch (uMsg) 1378 { 1379 case WM_INITDIALOG: 1380 pGlobalData = (PGLOBALDATA)((LPPROPSHEETPAGE)lParam)->lParam; 1381 SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pGlobalData); 1382 1383 if (pGlobalData) 1384 { 1385 LoadCurrentLocale(pGlobalData); 1386 1387 CreateLanguagesList(GetDlgItem(hwndDlg, IDC_LANGUAGELIST)); 1388 UpdateLocaleSample(hwndDlg, pGlobalData); 1389 pGlobalData->geoid = CreateLocationsList(GetDlgItem(hwndDlg, IDC_LOCATION_COMBO)); 1390 if (IsUnattendedSetupEnabled) 1391 { 1392 if (VerifyUnattendLCID(hwndDlg)) 1393 { 1394 SetNewLocale(pGlobalData, UnattendLCID); 1395 SaveCurrentLocale(pGlobalData); 1396 PostQuitMessage(0); 1397 } 1398 else 1399 { 1400 DPRINT1("VerifyUnattendLCID failed\n"); 1401 } 1402 return TRUE; 1403 } 1404 } 1405 break; 1406 1407 case WM_COMMAND: 1408 switch (LOWORD(wParam)) 1409 { 1410 case IDC_LANGUAGELIST: 1411 if (HIWORD(wParam) == CBN_SELCHANGE) 1412 { 1413 LCID NewLcid; 1414 INT iCurSel; 1415 1416 iCurSel = SendMessage(hList, 1417 CB_GETCURSEL, 1418 0, 1419 0); 1420 if (iCurSel == CB_ERR) 1421 break; 1422 1423 NewLcid = SendMessage(hList, 1424 CB_GETITEMDATA, 1425 iCurSel, 1426 0); 1427 if (NewLcid == (LCID)CB_ERR) 1428 break; 1429 1430 SetNewLocale(pGlobalData, NewLcid); 1431 UpdateLocaleSample(hwndDlg, pGlobalData); 1432 pGlobalData->bUserLocaleChanged = TRUE; 1433 1434 PropSheet_Changed(GetParent(hwndDlg), hwndDlg); 1435 } 1436 break; 1437 1438 case IDC_LOCATION_COMBO: 1439 if (HIWORD(wParam) == CBN_SELCHANGE) 1440 { 1441 GEOID NewGeoID; 1442 INT iCurSel; 1443 1444 iCurSel = SendMessage(GetDlgItem(hwndDlg, IDC_LOCATION_COMBO), 1445 CB_GETCURSEL, 1446 0, 1447 0); 1448 if (iCurSel == CB_ERR) 1449 break; 1450 1451 NewGeoID = SendMessage(GetDlgItem(hwndDlg, IDC_LOCATION_COMBO), 1452 CB_GETITEMDATA, 1453 iCurSel, 1454 0); 1455 if (NewGeoID == (GEOID)CB_ERR) 1456 break; 1457 1458 pGlobalData->geoid = NewGeoID; 1459 pGlobalData->bGeoIdChanged = TRUE; 1460 1461 PropSheet_Changed(GetParent(hwndDlg), hwndDlg); 1462 } 1463 break; 1464 1465 case IDC_SETUP_BUTTON: 1466 if (CustomizeLocalePropertySheet(GetParent(hwndDlg), pGlobalData) > 0) 1467 { 1468 UpdateLocaleSample(hwndDlg, pGlobalData); 1469 pGlobalData->bUserLocaleChanged = TRUE; 1470 PropSheet_Changed(GetParent(hwndDlg), hwndDlg); 1471 } 1472 break; 1473 } 1474 break; 1475 1476 case WM_NOTIFY: 1477 if (((LPNMHDR)lParam)->code == (UINT)PSN_APPLY) 1478 { 1479 /* Apply changes */ 1480 PropSheet_UnChanged(GetParent(hwndDlg), hwndDlg); 1481 1482 /* Set new locale */ 1483 if (pGlobalData->bUserLocaleChanged == TRUE) 1484 { 1485 SaveCurrentLocale(pGlobalData); 1486 pGlobalData->bUserLocaleChanged = FALSE; 1487 } 1488 1489 /* Set new GEO ID */ 1490 if (pGlobalData->bGeoIdChanged == TRUE) 1491 { 1492 SaveGeoID(pGlobalData); 1493 pGlobalData->bGeoIdChanged = FALSE; 1494 } 1495 1496 AddNewKbLayoutsByLcid(pGlobalData->UserLCID); 1497 1498 /* Post WM_WININICHANGE messages to system */ 1499 PostMessageW(HWND_BROADCAST, WM_WININICHANGE, 0, (LPARAM)L"intl"); 1500 } 1501 break; 1502 } 1503 1504 return FALSE; 1505 } 1506 1507 /* EOF */ 1508