Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1327 lines
44 KiB

  1. /*++
  2. Copyright (c) 1994-2000, Microsoft Corporation All rights reserved.
  3. Module Name:
  4. numdlg.c
  5. Abstract:
  6. This module implements the number property sheet for the Regional
  7. Options applet.
  8. Revision History:
  9. --*/
  10. //
  11. // Include Files.
  12. //
  13. #include "intl.h"
  14. #include <windowsx.h>
  15. #include <tchar.h>
  16. #include "intlhlp.h"
  17. #include "maxvals.h"
  18. #define STRSAFE_LIB
  19. #include <strsafe.h>
  20. //
  21. // Constant Declarations.
  22. //
  23. #define MAX_DIGIT_SUBST 2
  24. #define CHAR_MAX_DIGIT_SUBST TEXT('2')
  25. #define EUROPEAN_DIGITS TEXT("0123456789")
  26. #define LPK_EUROPEAN_DIGITS TEXT("\x206f\x0030\x0031\x0032\x0033\x0034\x0035\x0036\x0037\x0038\x0039")
  27. #define LANGUAGE_GROUPS_KEY TEXT("System\\CurrentControlSet\\Control\\Nls\\Language Groups")
  28. //
  29. // Global Variables.
  30. //
  31. static TCHAR sz_iNegNumber[MAX_INEGNUMBER + 1];
  32. static TCHAR sz_iMeasure[MAX_IMEASURE + 1];
  33. static TCHAR sz_NumShape[MAX_IDIGITSUBSTITUTION + 1];
  34. static TCHAR sz_sDecimal[MAX_SDECIMAL + 1];
  35. static TCHAR sz_sGrouping[MAX_SGROUPING + 1];
  36. static TCHAR sz_sList[MAX_SLIST + 1];
  37. static TCHAR sz_sNativeDigits[MAX_FORMAT + 1];
  38. static TCHAR sz_sNegativeSign[MAX_SNEGSIGN + 1];
  39. static TCHAR sz_sPositiveSign[MAX_SPOSSIGN + 1];
  40. static TCHAR sz_sThousand[MAX_STHOUSAND + 1];
  41. static TCHAR sz_iDigits[MAX_IDIGITS + 1];
  42. static TCHAR sz_iLZero[MAX_ILZERO + 1];
  43. //
  44. // Native Digits tables.
  45. //
  46. #define MAX_LANG_GROUPS 16
  47. #define MAX_DIGITS_PER_LG 2
  48. static const int c_szDigitsPerLangGroup[MAX_LANG_GROUPS][MAX_DIGITS_PER_LG] =
  49. {
  50. 0, 0, // 0 = (invalid)
  51. 0, 0, // 1 = Western Europe (added by code, see Number_SetValues(..))
  52. 0, 0, // 2 = Central Europe
  53. 0, 0, // 3 = Baltic
  54. 0, 0, // 4 = Greek
  55. 0, 0, // 5 = Cyrillic
  56. 0, 0, // 6 = Turkish
  57. 0, 0, // 7 = Japanese
  58. 0, 0, // 8 = Korean
  59. 0, 0, // 9 = Traditional Chinese
  60. 0, 0, // 10 = Simplified Chinese
  61. 12, 0, // 11 = Thai
  62. 0, 0, // 12 = Hebrew
  63. 1, 2, // 13 = Arabic
  64. 0, 0, // 14 = Vietnamese
  65. 3, 8 // 15 = Indian (NT5 supports only Devenagari and Tamil (i.e. fonts and kbd))
  66. };
  67. static const LPTSTR c_szNativeDigits[15] =
  68. {
  69. TEXT("0123456789"), // European
  70. TEXT("\x0660\x0661\x0662\x0663\x0664\x0665\x0666\x0667\x0668\x0669"), // Arabic-Indic
  71. TEXT("\x06f0\x06f1\x06f2\x06f3\x06f4\x06f5\x06f6\x06f7\x06f8\x06f9"), // Extended Arabic-Indic
  72. TEXT("\x0966\x0967\x0968\x0969\x096a\x096b\x096c\x096d\x096e\x096f"), // Devanagari
  73. TEXT("\x09e6\x09e7\x09e8\x09e9\x09ea\x09eb\x09ec\x09ed\x09ee\x09ef"), // Bengali
  74. TEXT("\x0a66\x0a67\x0a68\x0a69\x0a6a\x0a6b\x0a6c\x0a6d\x0a6e\x0a6f"), // Gurmukhi
  75. TEXT("\x0ae6\x0ae7\x0ae8\x0ae9\x0aea\x0aeb\x0aec\x0aed\x0aee\x0aef"), // Gujarati
  76. TEXT("\x0b66\x0b67\x0b68\x0b69\x0b6a\x0b6b\x0b6c\x0b6d\x0b6e\x0b6f"), // Oriya
  77. TEXT("\x0030\x0be7\x0be8\x0be9\x0bea\x0beb\x0bec\x0bed\x0bee\x0bef"), // Tamil
  78. TEXT("\x0c66\x0c67\x0c68\x0c69\x0c6a\x0c6b\x0c6c\x0c6d\x0c6e\x0c6f"), // Telugu
  79. TEXT("\x0ce6\x0ce7\x0ce8\x0ce9\x0cea\x0ceb\x0cec\x0ced\x0cee\x0cef"), // Kannada
  80. TEXT("\x0d66\x0d67\x0d68\x0d69\x0d6a\x0d6b\x0d6c\x0d6d\x0d6e\x0d6f"), // Malayalam
  81. TEXT("\x0e50\x0e51\x0e52\x0e53\x0e54\x0e55\x0e56\x0e57\x0e58\x0e59"), // Thai
  82. TEXT("\x0ed0\x0ed1\x0ed2\x0ed3\x0ed4\x0ed5\x0ed6\x0ed7\x0ed8\x0ed9"), // Lao
  83. TEXT("\x0f20\x0f21\x0f22\x0f23\x0f24\x0f25\x0f26\x0f27\x0f28\x0f29") // Tibetan
  84. };
  85. //
  86. // Context Help Ids.
  87. //
  88. static int aNumberHelpIds[] =
  89. {
  90. IDC_SAMPLELBL3, IDH_COMM_GROUPBOX,
  91. IDC_SAMPLELBL1, IDH_INTL_NUM_POSVALUE,
  92. IDC_SAMPLE1, IDH_INTL_NUM_POSVALUE,
  93. IDC_SAMPLELBL2, IDH_INTL_NUM_NEGVALUE,
  94. IDC_SAMPLE2, IDH_INTL_NUM_NEGVALUE,
  95. IDC_SAMPLELBL1A, IDH_INTL_NUM_POSVALUE_ARABIC,
  96. IDC_SAMPLE1A, IDH_INTL_NUM_POSVALUE_ARABIC,
  97. IDC_SAMPLELBL2A, IDH_INTL_NUM_NEGVALUE_ARABIC,
  98. IDC_SAMPLE2A, IDH_INTL_NUM_NEGVALUE_ARABIC,
  99. IDC_DECIMAL_SYMBOL, IDH_INTL_NUM_DECSYMBOL,
  100. IDC_NUM_DECIMAL_DIGITS, IDH_INTL_NUM_DIGITSAFTRDEC,
  101. IDC_DIGIT_GROUP_SYMBOL, IDH_INTL_NUM_DIGITGRPSYMBOL,
  102. IDC_NUM_DIGITS_GROUP, IDH_INTL_NUM_DIGITSINGRP,
  103. IDC_NEG_SIGN, IDH_INTL_NUM_NEGSIGNSYMBOL,
  104. IDC_NEG_NUM_FORMAT, IDH_INTL_NUM_NEGNUMFORMAT,
  105. IDC_SEPARATOR, IDH_INTL_NUM_LISTSEPARATOR,
  106. IDC_DISPLAY_LEAD_0, IDH_INTL_NUM_DISPLEADZEROS,
  107. IDC_MEASURE_SYS, IDH_INTL_NUM_MEASUREMNTSYS,
  108. IDC_NATIVE_DIGITS_TEXT, IDH_INTL_NUM_NATIVE_DIGITS,
  109. IDC_NATIVE_DIGITS, IDH_INTL_NUM_NATIVE_DIGITS,
  110. IDC_DIGIT_SUBST_TEXT, IDH_INTL_NUM_DIGIT_SUBST,
  111. IDC_DIGIT_SUBST, IDH_INTL_NUM_DIGIT_SUBST,
  112. 0, 0
  113. };
  114. ////////////////////////////////////////////////////////////////////////////
  115. //
  116. // Number_IsEuropeanDigits
  117. //
  118. ////////////////////////////////////////////////////////////////////////////
  119. BOOL Number_IsEuropeanDigits(
  120. TCHAR *pNum)
  121. {
  122. int Ctr;
  123. int Length = lstrlen(pNum);
  124. for (Ctr = 0; Ctr < Length; Ctr++)
  125. {
  126. if (!((pNum[Ctr] >= TEXT('0')) && (pNum[Ctr] <= TEXT('9'))))
  127. {
  128. return (FALSE);
  129. }
  130. }
  131. //
  132. // Return success.
  133. //
  134. return (TRUE);
  135. }
  136. ////////////////////////////////////////////////////////////////////////////
  137. //
  138. // Number_GetDigitSubstitution
  139. //
  140. ////////////////////////////////////////////////////////////////////////////
  141. int Number_GetDigitSubstitution()
  142. {
  143. TCHAR szBuf[10];
  144. int cch;
  145. //
  146. // Get the digit substitution.
  147. //
  148. if ((cch = GetLocaleInfo(UserLocaleID, LOCALE_IDIGITSUBSTITUTION, szBuf, 10)) &&
  149. (cch == 2) &&
  150. ((szBuf[0] >= CHAR_ZERO) && (szBuf[0] <= CHAR_MAX_DIGIT_SUBST)))
  151. {
  152. return (szBuf[0] - CHAR_ZERO);
  153. }
  154. return (0);
  155. }
  156. ////////////////////////////////////////////////////////////////////////////
  157. //
  158. // Number_DisplaySample
  159. //
  160. // Update the Number sample. Format the number based on the user's
  161. // current locale settings. Display either a positive value or a
  162. // negative value based on the Positive/Negative radio buttons.
  163. //
  164. ////////////////////////////////////////////////////////////////////////////
  165. void Number_DisplaySample(
  166. HWND hDlg)
  167. {
  168. TCHAR szBuf[MAX_SAMPLE_SIZE];
  169. int nCharCount;
  170. //
  171. // Show or hide the Arabic info based on the current user locale id.
  172. //
  173. ShowWindow(GetDlgItem(hDlg, IDC_SAMPLELBL1A), bShowArabic ? SW_SHOW : SW_HIDE);
  174. ShowWindow(GetDlgItem(hDlg, IDC_SAMPLE1A), bShowArabic ? SW_SHOW : SW_HIDE);
  175. ShowWindow(GetDlgItem(hDlg, IDC_SAMPLELBL2A), bShowArabic ? SW_SHOW : SW_HIDE);
  176. ShowWindow(GetDlgItem(hDlg, IDC_SAMPLE2A), bShowArabic ? SW_SHOW : SW_HIDE);
  177. //
  178. // Get the string representing the number format for the positive sample
  179. // number and, if the the value is valid, display it. Perform the same
  180. // operations for the negative sample.
  181. //
  182. nCharCount = GetNumberFormat( UserLocaleID,
  183. 0,
  184. szSample_Number,
  185. NULL,
  186. szBuf,
  187. MAX_SAMPLE_SIZE );
  188. if (nCharCount)
  189. {
  190. SetDlgItemText(hDlg, IDC_SAMPLE1, szBuf);
  191. if (bShowArabic)
  192. {
  193. SetDlgItemText(hDlg, IDC_SAMPLE1A, szBuf);
  194. SetDlgItemRTL(hDlg, IDC_SAMPLE1A);
  195. }
  196. }
  197. else
  198. {
  199. MessageBox(hDlg, szLocaleGetError, NULL, MB_OK | MB_ICONINFORMATION);
  200. }
  201. nCharCount = GetNumberFormat( UserLocaleID,
  202. 0,
  203. szNegSample_Number,
  204. NULL,
  205. szBuf,
  206. MAX_SAMPLE_SIZE );
  207. if (nCharCount)
  208. {
  209. SetDlgItemText(hDlg, IDC_SAMPLE2, szBuf);
  210. if (bShowArabic)
  211. {
  212. SetDlgItemText(hDlg, IDC_SAMPLE2A, szBuf);
  213. SetDlgItemRTL(hDlg, IDC_SAMPLE2A);
  214. }
  215. }
  216. else
  217. {
  218. MessageBox(hDlg, szLocaleGetError, NULL, MB_OK | MB_ICONINFORMATION);
  219. }
  220. }
  221. ////////////////////////////////////////////////////////////////////////////
  222. //
  223. // Number_SaveValues
  224. //
  225. // Save values in the case that we need to restore them.
  226. //
  227. ////////////////////////////////////////////////////////////////////////////
  228. void Number_SaveValues()
  229. {
  230. //
  231. // Save registry values.
  232. //
  233. if (!GetLocaleInfo( UserLocaleID,
  234. LOCALE_INEGNUMBER,
  235. sz_iNegNumber,
  236. MAX_INEGNUMBER + 1 ))
  237. {
  238. //_tcscpy(sz_iNegNumber, TEXT("1"));
  239. if(FAILED(StringCchCopy(sz_iNegNumber, MAX_INEGNUMBER+1, TEXT("1"))))
  240. {
  241. // This should be impossible, but we need to avoid PREfast complaints.
  242. }
  243. }
  244. if (!GetLocaleInfo( UserLocaleID,
  245. LOCALE_IMEASURE,
  246. sz_iMeasure,
  247. MAX_IMEASURE + 1 ))
  248. {
  249. //_tcscpy(sz_iMeasure, TEXT("1"));
  250. if(FAILED(StringCchCopy(sz_iMeasure, MAX_IMEASURE+1, TEXT("1"))))
  251. {
  252. // This should be impossible, but we need to avoid PREfast complaints.
  253. }
  254. }
  255. if (!GetLocaleInfo( UserLocaleID,
  256. LOCALE_IDIGITSUBSTITUTION,
  257. sz_NumShape,
  258. MAX_IDIGITSUBSTITUTION + 1 ))
  259. {
  260. //_tcscpy(sz_NumShape, TEXT("1"));
  261. if(FAILED(StringCchCopy(sz_NumShape, MAX_IDIGITSUBSTITUTION+1, TEXT("1"))))
  262. {
  263. // This should be impossible, but we need to avoid PREfast complaints.
  264. }
  265. }
  266. if (!GetLocaleInfo( UserLocaleID,
  267. LOCALE_SDECIMAL,
  268. sz_sDecimal,
  269. MAX_SDECIMAL + 1 ))
  270. {
  271. //_tcscpy(sz_sDecimal, TEXT("."));
  272. if(FAILED(StringCchCopy(sz_sDecimal, MAX_SDECIMAL+1, TEXT("."))))
  273. {
  274. // This should be impossible, but we need to avoid PREfast complaints.
  275. }
  276. }
  277. if (!GetLocaleInfo( UserLocaleID,
  278. LOCALE_SGROUPING,
  279. sz_sGrouping,
  280. MAX_SGROUPING + 1 ))
  281. {
  282. //_tcscpy(sz_sGrouping, TEXT("3;0"));
  283. if(FAILED(StringCchCopy(sz_sGrouping, MAX_SGROUPING+1, TEXT("3;0"))))
  284. {
  285. // This should be impossible, but we need to avoid PREfast complaints.
  286. }
  287. }
  288. if (!GetLocaleInfo( UserLocaleID,
  289. LOCALE_SLIST,
  290. sz_sList,
  291. MAX_SLIST + 1 ))
  292. {
  293. //_tcscpy(sz_sList, TEXT(","));
  294. if(FAILED(StringCchCopy(sz_sList, MAX_SLIST+1, TEXT(","))))
  295. {
  296. // This should be impossible, but we need to avoid PREfast complaints.
  297. }
  298. }
  299. if (!GetLocaleInfo( UserLocaleID,
  300. LOCALE_SNATIVEDIGITS,
  301. sz_sNativeDigits,
  302. MAX_FORMAT + 1 ))
  303. {
  304. //_tcscpy(sz_sNativeDigits, TEXT("0123456789"));
  305. if(FAILED(StringCchCopy(sz_sNativeDigits, MAX_FORMAT+1, TEXT("0123456789"))))
  306. {
  307. // This should be impossible, but we need to avoid PREfast complaints.
  308. }
  309. }
  310. if (!GetLocaleInfo( UserLocaleID,
  311. LOCALE_SNEGATIVESIGN,
  312. sz_sNegativeSign,
  313. MAX_SNEGSIGN + 1 ))
  314. {
  315. //_tcscpy(sz_sNegativeSign, TEXT("-"));
  316. if(FAILED(StringCchCopy(sz_sNegativeSign, MAX_SNEGSIGN+1, TEXT("-"))))
  317. {
  318. // This should be impossible, but we need to avoid PREfast complaints.
  319. }
  320. }
  321. if (!GetLocaleInfo( UserLocaleID,
  322. LOCALE_SPOSITIVESIGN,
  323. sz_sPositiveSign,
  324. MAX_SPOSSIGN + 1 ))
  325. {
  326. //_tcscpy(sz_sPositiveSign, TEXT(""));
  327. if(FAILED(StringCchCopy(sz_sPositiveSign, MAX_SPOSSIGN+1, TEXT(""))))
  328. {
  329. // This should be impossible, but we need to avoid PREfast complaints.
  330. }
  331. }
  332. if (!GetLocaleInfo( UserLocaleID,
  333. LOCALE_STHOUSAND,
  334. sz_sThousand,
  335. MAX_STHOUSAND + 1 ))
  336. {
  337. //_tcscpy(sz_sThousand, TEXT(","));
  338. if(FAILED(StringCchCopy(sz_sThousand, MAX_STHOUSAND+1, TEXT(","))))
  339. {
  340. // This should be impossible, but we need to avoid PREfast complaints.
  341. }
  342. }
  343. if (!GetLocaleInfo( UserLocaleID,
  344. LOCALE_IDIGITS,
  345. sz_iDigits,
  346. MAX_IDIGITS + 1 ))
  347. {
  348. //_tcscpy(sz_iDigits, TEXT("2"));
  349. if(FAILED(StringCchCopy(sz_iDigits, MAX_IDIGITS+1, TEXT("2"))))
  350. {
  351. // This should be impossible, but we need to avoid PREfast complaints.
  352. }
  353. }
  354. if (!GetLocaleInfo( UserLocaleID,
  355. LOCALE_ILZERO,
  356. sz_iLZero,
  357. MAX_ILZERO + 1 ))
  358. {
  359. //_tcscpy(sz_iLZero, TEXT("2"));
  360. if(FAILED(StringCchCopy(sz_iLZero, MAX_ILZERO+1, TEXT("2"))))
  361. {
  362. // This should be impossible, but we need to avoid PREfast complaints.
  363. }
  364. }
  365. }
  366. ////////////////////////////////////////////////////////////////////////////
  367. //
  368. // Number_RestoreValues
  369. //
  370. ////////////////////////////////////////////////////////////////////////////
  371. void Number_RestoreValues()
  372. {
  373. if (g_dwCustChange & Process_Num)
  374. {
  375. SetLocaleInfo(UserLocaleID, LOCALE_INEGNUMBER, sz_iNegNumber);
  376. SetLocaleInfo(UserLocaleID, LOCALE_IMEASURE, sz_iMeasure);
  377. SetLocaleInfo(UserLocaleID, LOCALE_IDIGITSUBSTITUTION, sz_NumShape);
  378. SetLocaleInfo(UserLocaleID, LOCALE_SDECIMAL, sz_sDecimal);
  379. SetLocaleInfo(UserLocaleID, LOCALE_SGROUPING, sz_sGrouping);
  380. SetLocaleInfo(UserLocaleID, LOCALE_SLIST, sz_sList);
  381. SetLocaleInfo(UserLocaleID, LOCALE_SNATIVEDIGITS, sz_sNativeDigits);
  382. SetLocaleInfo(UserLocaleID, LOCALE_SNEGATIVESIGN, sz_sNegativeSign);
  383. SetLocaleInfo(UserLocaleID, LOCALE_SPOSITIVESIGN, sz_sPositiveSign);
  384. SetLocaleInfo(UserLocaleID, LOCALE_STHOUSAND, sz_sThousand);
  385. SetLocaleInfo(UserLocaleID, LOCALE_IDIGITS, sz_iDigits);
  386. SetLocaleInfo(UserLocaleID, LOCALE_ILZERO, sz_iLZero);
  387. }
  388. }
  389. ////////////////////////////////////////////////////////////////////////////
  390. //
  391. // Number_ClearValues
  392. //
  393. // Reset each of the list boxes in the number property sheet page.
  394. //
  395. ////////////////////////////////////////////////////////////////////////////
  396. void Number_ClearValues(
  397. HWND hDlg)
  398. {
  399. ComboBox_ResetContent(GetDlgItem(hDlg, IDC_DECIMAL_SYMBOL));
  400. ComboBox_ResetContent(GetDlgItem(hDlg, IDC_NEG_SIGN));
  401. ComboBox_ResetContent(GetDlgItem(hDlg, IDC_SEPARATOR));
  402. ComboBox_ResetContent(GetDlgItem(hDlg, IDC_DIGIT_GROUP_SYMBOL));
  403. ComboBox_ResetContent(GetDlgItem(hDlg, IDC_NUM_DECIMAL_DIGITS));
  404. ComboBox_ResetContent(GetDlgItem(hDlg, IDC_NUM_DIGITS_GROUP));
  405. ComboBox_ResetContent(GetDlgItem(hDlg, IDC_DISPLAY_LEAD_0));
  406. ComboBox_ResetContent(GetDlgItem(hDlg, IDC_NEG_NUM_FORMAT));
  407. ComboBox_ResetContent(GetDlgItem(hDlg, IDC_MEASURE_SYS));
  408. ComboBox_ResetContent(GetDlgItem(hDlg, IDC_NATIVE_DIGITS));
  409. ComboBox_ResetContent(GetDlgItem(hDlg, IDC_DIGIT_SUBST));
  410. }
  411. ////////////////////////////////////////////////////////////////////////////
  412. //
  413. // Number_SetValues
  414. //
  415. // Initialize all of the controls in the number property sheet page.
  416. //
  417. ////////////////////////////////////////////////////////////////////////////
  418. void Number_SetValues(
  419. HWND hDlg)
  420. {
  421. HWND hCtrl1, hCtrl2;
  422. HKEY hKey;
  423. int Index, Ctr1, Ctr2;
  424. DWORD cbData;
  425. TCHAR szBuf[SIZE_128];
  426. const nMax_Array_Fill = (cInt_Str >= 10 ? 10 : cInt_Str);
  427. NUMBERFMT nfmt;
  428. TCHAR szThousandSep[SIZE_128];
  429. TCHAR szEmpty[] = TEXT("");
  430. TCHAR szSample[] = TEXT("123456789");
  431. BOOL bShow;
  432. //
  433. // ----------------------------------------------------------------------
  434. // Initialize the dropdown box for the current locale setting for:
  435. // Decimal Symbol
  436. // Positive Sign
  437. // Negative Sign
  438. // List Separator
  439. // Grouping Symbol
  440. // ----------------------------------------------------------------------
  441. //
  442. DropDown_Use_Locale_Values(hDlg, LOCALE_SDECIMAL, IDC_DECIMAL_SYMBOL);
  443. DropDown_Use_Locale_Values(hDlg, LOCALE_SNEGATIVESIGN, IDC_NEG_SIGN);
  444. DropDown_Use_Locale_Values(hDlg, LOCALE_SLIST, IDC_SEPARATOR);
  445. DropDown_Use_Locale_Values(hDlg, LOCALE_STHOUSAND, IDC_DIGIT_GROUP_SYMBOL);
  446. //
  447. // ----------------------------------------------------------------------
  448. // Fill in the Number of Digits after Decimal Symbol drop down list
  449. // with the values of 0 through 10. Get the user locale value and
  450. // make it the current selection. If GetLocaleInfo fails, simply
  451. // select the first item in the list.
  452. // ----------------------------------------------------------------------
  453. //
  454. hCtrl1 = GetDlgItem(hDlg, IDC_NUM_DECIMAL_DIGITS);
  455. hCtrl2 = GetDlgItem(hDlg, IDC_NUM_DIGITS_GROUP);
  456. for (Index = 0; Index < nMax_Array_Fill; Index++)
  457. {
  458. ComboBox_InsertString(hCtrl1, -1, aInt_Str[Index]);
  459. }
  460. if (GetLocaleInfo(UserLocaleID, LOCALE_IDIGITS, szBuf, SIZE_128))
  461. {
  462. ComboBox_SelectString(hCtrl1, -1, szBuf);
  463. }
  464. else
  465. {
  466. ComboBox_SetCurSel(hCtrl1, 0);
  467. }
  468. //
  469. // ----------------------------------------------------------------------
  470. // Fill in the Number of Digits in "Thousands" Grouping's drop down
  471. // list with the appropriate options. Get the user locale value and
  472. // make it the current selection. If GetLocaleInfo fails, simply
  473. // select the first item in the list.
  474. // ----------------------------------------------------------------------
  475. //
  476. nfmt.NumDigits = 0; // no decimal in sample string
  477. nfmt.LeadingZero = 0; // no decimal in sample string
  478. nfmt.lpDecimalSep = szEmpty; // no decimal in sample string
  479. nfmt.NegativeOrder = 0; // not a negative value
  480. nfmt.lpThousandSep = szThousandSep;
  481. GetLocaleInfo(UserLocaleID, LOCALE_STHOUSAND, szThousandSep, SIZE_128);
  482. nfmt.Grouping = 0;
  483. GetNumberFormat(UserLocaleID, 0, szSample, &nfmt, szBuf, SIZE_128);
  484. ComboBox_InsertString(hCtrl2, -1, szBuf);
  485. nfmt.Grouping = 3;
  486. GetNumberFormat(UserLocaleID, 0, szSample, &nfmt, szBuf, SIZE_128);
  487. ComboBox_InsertString(hCtrl2, -1, szBuf);
  488. nfmt.Grouping = 32;
  489. GetNumberFormat(UserLocaleID, 0, szSample, &nfmt, szBuf, SIZE_128);
  490. ComboBox_InsertString(hCtrl2, -1, szBuf);
  491. if (GetLocaleInfo(UserLocaleID, LOCALE_SGROUPING, szBuf, SIZE_128) &&
  492. (szBuf[0]))
  493. {
  494. //
  495. // Since only the values 0, 3;0, and 3;2;0 are allowed, simply
  496. // ignore the ";#"s for subsequent groupings.
  497. //
  498. Index = 0;
  499. if (szBuf[0] == TEXT('3'))
  500. {
  501. if ((szBuf[1] == CHAR_SEMICOLON) && (szBuf[2] == TEXT('2')))
  502. {
  503. Index = 2;
  504. }
  505. else
  506. {
  507. Index = 1;
  508. }
  509. }
  510. else
  511. {
  512. //
  513. // We used to allow the user to set #;0, where # is a value from
  514. // 0 - 9. If it's 0, then fall through so that Index is 0.
  515. //
  516. if ((szBuf[0] > CHAR_ZERO) && (szBuf[0] <= CHAR_NINE) &&
  517. ((szBuf[1] == 0) || (lstrcmp(szBuf + 1, TEXT(";0")) == 0)))
  518. {
  519. nfmt.Grouping = szBuf[0] - CHAR_ZERO;
  520. if (GetNumberFormat(UserLocaleID, 0, szSample, &nfmt, szBuf, SIZE_128))
  521. {
  522. Index = ComboBox_InsertString(hCtrl2, -1, szBuf);
  523. if (Index >= 0)
  524. {
  525. ComboBox_SetItemData( hCtrl2,
  526. Index,
  527. (LPARAM)((DWORD)nfmt.Grouping) );
  528. }
  529. else
  530. {
  531. Index = 0;
  532. }
  533. }
  534. }
  535. }
  536. ComboBox_SetCurSel(hCtrl2, Index);
  537. }
  538. else
  539. {
  540. ComboBox_SetCurSel(hCtrl2, 0);
  541. }
  542. //
  543. // ----------------------------------------------------------------------
  544. // Initialize and Lock function. If it succeeds, call enum function to
  545. // enumerate all possible values for the list box via a call to EnumProc.
  546. // EnumProc will call Set_List_Values for each of the string values it
  547. // receives. When the enumeration of values is complete, call
  548. // Set_List_Values to clear the dialog item specific data and to clear
  549. // the lock on the function. Perform this set of operations for:
  550. // Display Leading Zeros, Negative Number Format, and Measurement Systems.
  551. // ----------------------------------------------------------------------
  552. //
  553. if (Set_List_Values(hDlg, IDC_DISPLAY_LEAD_0, 0))
  554. {
  555. EnumLeadingZeros(EnumProcEx, UserLocaleID, 0);
  556. Set_List_Values(0, IDC_DISPLAY_LEAD_0, 0);
  557. if (GetLocaleInfo(UserLocaleID, LOCALE_ILZERO, szBuf, SIZE_128))
  558. {
  559. ComboBox_SetCurSel( GetDlgItem(hDlg, IDC_DISPLAY_LEAD_0),
  560. Intl_StrToLong(szBuf) );
  561. }
  562. else
  563. {
  564. MessageBox(hDlg, szLocaleGetError, NULL, MB_OK | MB_ICONINFORMATION);
  565. }
  566. }
  567. if (Set_List_Values(hDlg, IDC_NEG_NUM_FORMAT, 0))
  568. {
  569. EnumNegNumFmt(EnumProcEx, UserLocaleID, 0);
  570. Set_List_Values(0, IDC_NEG_NUM_FORMAT, 0);
  571. if (GetLocaleInfo(UserLocaleID, LOCALE_INEGNUMBER, szBuf, SIZE_128))
  572. {
  573. ComboBox_SetCurSel( GetDlgItem(hDlg, IDC_NEG_NUM_FORMAT),
  574. Intl_StrToLong(szBuf) );
  575. }
  576. else
  577. {
  578. MessageBox(hDlg, szLocaleGetError, NULL, MB_OK | MB_ICONINFORMATION);
  579. }
  580. }
  581. if (Set_List_Values(hDlg, IDC_MEASURE_SYS, 0))
  582. {
  583. EnumMeasureSystem(EnumProc, UserLocaleID, 0);
  584. Set_List_Values(0, IDC_MEASURE_SYS, 0);
  585. if (GetLocaleInfo(UserLocaleID, LOCALE_IMEASURE, szBuf, SIZE_128))
  586. {
  587. ComboBox_SetCurSel( GetDlgItem(hDlg, IDC_MEASURE_SYS),
  588. Intl_StrToLong(szBuf) );
  589. }
  590. else
  591. {
  592. MessageBox(hDlg, szLocaleGetError, NULL, MB_OK | MB_ICONINFORMATION);
  593. }
  594. }
  595. //
  596. // ----------------------------------------------------------------------
  597. // Fill in the "Native Digits" dropdown and set the current selection.
  598. // Only show this combo box if there is more than one entry in the list.
  599. // ----------------------------------------------------------------------
  600. //
  601. hCtrl1 = GetDlgItem(hDlg, IDC_NATIVE_DIGITS);
  602. ComboBox_AddString( hCtrl1,
  603. bLPKInstalled
  604. ? LPK_EUROPEAN_DIGITS
  605. : EUROPEAN_DIGITS );
  606. ComboBox_SetCurSel(hCtrl1, 0);
  607. //
  608. // Go through the language groups to see which ones have extra native
  609. // digits options.
  610. //
  611. // Entry 0 in c_szNativeDigits is the European option. If any entries
  612. // in c_szDigitsPerLangGroup are 0 (European), then ignore them as the
  613. // European option is always enabled.
  614. //
  615. if (RegOpenKeyEx( HKEY_LOCAL_MACHINE,
  616. LANGUAGE_GROUPS_KEY,
  617. 0L,
  618. KEY_READ,
  619. &hKey ) == ERROR_SUCCESS)
  620. {
  621. for (Ctr1 = 1; Ctr1 < MAX_LANG_GROUPS; Ctr1++)
  622. {
  623. //
  624. // This assumes that if the first entry of
  625. // c_szDigitsPerLangGroup is 0, then all other entries are 0.
  626. //
  627. if (c_szDigitsPerLangGroup[Ctr1][0] != 0)
  628. {
  629. //
  630. // See if the language group is installed.
  631. //
  632. cbData = 0;
  633. //wsprintf(szBuf, TEXT("%x"), Ctr1);
  634. if(SUCCEEDED(StringCchPrintf(szBuf, ARRAYSIZE(szBuf), TEXT("%x"), Ctr1)))
  635. {
  636. RegQueryValueEx(hKey, szBuf, NULL, NULL, NULL, &cbData);
  637. if (cbData > sizeof(TCHAR))
  638. {
  639. //
  640. // Installed, so add the native digit options to
  641. // the combo box.
  642. //
  643. for (Ctr2 = 0; Ctr2 < MAX_DIGITS_PER_LG; Ctr2++)
  644. {
  645. if ((Index = c_szDigitsPerLangGroup[Ctr1][Ctr2]) != 0)
  646. {
  647. if (ComboBox_FindStringExact(
  648. hCtrl1,
  649. -1,
  650. c_szNativeDigits[Index] ) == CB_ERR)
  651. {
  652. ComboBox_AddString( hCtrl1,
  653. c_szNativeDigits[Index] );
  654. }
  655. }
  656. }
  657. }
  658. }
  659. }
  660. }
  661. RegCloseKey(hKey);
  662. }
  663. //
  664. // Add the current user's Native Digits option if it's not already
  665. // in the combo box.
  666. //
  667. if (GetLocaleInfo( UserLocaleID,
  668. LOCALE_SNATIVEDIGITS,
  669. szBuf,
  670. SIZE_128 ) &&
  671. (!Number_IsEuropeanDigits(szBuf)))
  672. {
  673. if ((Index = ComboBox_FindStringExact(hCtrl1, -1, szBuf)) == CB_ERR)
  674. {
  675. Index = ComboBox_AddString(hCtrl1, szBuf);
  676. }
  677. if (Index != CB_ERR)
  678. {
  679. ComboBox_SetCurSel(hCtrl1, Index);
  680. }
  681. }
  682. //
  683. // Add the default Native Digits option for the user's chosen locale
  684. // if it's not already in the combo box.
  685. //
  686. if (GetLocaleInfo( UserLocaleID,
  687. LOCALE_SNATIVEDIGITS | LOCALE_NOUSEROVERRIDE,
  688. szBuf,
  689. SIZE_128 ) &&
  690. (!Number_IsEuropeanDigits(szBuf)))
  691. {
  692. if (ComboBox_FindStringExact(hCtrl1, -1, szBuf) == CB_ERR)
  693. {
  694. ComboBox_AddString(hCtrl1, szBuf);
  695. }
  696. }
  697. //
  698. // Disable the control if there is only 1 entry in the list.
  699. //
  700. bShow = ComboBox_GetCount(hCtrl1) > 1;
  701. EnableWindow(GetDlgItem(hDlg, IDC_NATIVE_DIGITS_TEXT), bShow);
  702. EnableWindow(GetDlgItem(hDlg, IDC_NATIVE_DIGITS), bShow);
  703. ShowWindow(GetDlgItem(hDlg, IDC_NATIVE_DIGITS_TEXT), bShow ? SW_SHOW : SW_HIDE);
  704. ShowWindow(GetDlgItem(hDlg, IDC_NATIVE_DIGITS), bShow ? SW_SHOW : SW_HIDE);
  705. //
  706. // ----------------------------------------------------------------------
  707. // Fill in the "Digit Substitution" dropdown and set the current
  708. // selection. Only show this combo box if a language pack is installed.
  709. // ----------------------------------------------------------------------
  710. //
  711. hCtrl1 = GetDlgItem(hDlg, IDC_DIGIT_SUBST);
  712. for (Index = 0; Index <= MAX_DIGIT_SUBST; Index++)
  713. {
  714. LoadString(hInstance, IDS_DIGIT_SUBST_CONTEXT + Index, szBuf, SIZE_128);
  715. ComboBox_InsertString(hCtrl1, Index, szBuf);
  716. }
  717. ComboBox_SetCurSel( hCtrl1,
  718. Number_GetDigitSubstitution() );
  719. EnableWindow(GetDlgItem(hDlg, IDC_DIGIT_SUBST_TEXT), bLPKInstalled);
  720. EnableWindow(hCtrl1, bLPKInstalled);
  721. ShowWindow(GetDlgItem(hDlg, IDC_DIGIT_SUBST_TEXT), bLPKInstalled ? SW_SHOW : SW_HIDE);
  722. ShowWindow(hCtrl1, bLPKInstalled ? SW_SHOW : SW_HIDE);
  723. //
  724. // ----------------------------------------------------------------------
  725. // Display the current sample that represents all of the locale settings.
  726. // ----------------------------------------------------------------------
  727. //
  728. Number_DisplaySample(hDlg);
  729. }
  730. ////////////////////////////////////////////////////////////////////////////
  731. //
  732. // Number_ApplySettings
  733. //
  734. // For every control that has changed (that affects the Locale settings),
  735. // call Set_Locale_Values to update the user locale information.
  736. // Notify the parent of changes and reset the change flag stored in the
  737. // property sheet page structure appropriately. Redisplay the number
  738. // sample if bRedisplay is TRUE.
  739. //
  740. ////////////////////////////////////////////////////////////////////////////
  741. BOOL Number_ApplySettings(
  742. HWND hDlg,
  743. BOOL bRedisplay)
  744. {
  745. LPPROPSHEETPAGE lpPropSheet = (LPPROPSHEETPAGE)(GetWindowLongPtr(hDlg, DWLP_USER));
  746. LPARAM Changes = lpPropSheet->lParam;
  747. if (Changes & NC_DSymbol)
  748. {
  749. if (!Set_Locale_Values( hDlg,
  750. LOCALE_SDECIMAL,
  751. IDC_DECIMAL_SYMBOL,
  752. TEXT("sDecimal"),
  753. FALSE,
  754. 0,
  755. 0,
  756. NULL ))
  757. {
  758. return (FALSE);
  759. }
  760. }
  761. if (Changes & NC_NSign)
  762. {
  763. if (!Set_Locale_Values( hDlg,
  764. LOCALE_SNEGATIVESIGN,
  765. IDC_NEG_SIGN,
  766. 0,
  767. FALSE,
  768. 0,
  769. 0,
  770. NULL ))
  771. {
  772. return (FALSE);
  773. }
  774. }
  775. if (Changes & NC_SList)
  776. {
  777. if (!Set_Locale_Values( hDlg,
  778. LOCALE_SLIST,
  779. IDC_SEPARATOR,
  780. TEXT("sList"),
  781. FALSE,
  782. 0,
  783. 0,
  784. NULL ))
  785. {
  786. return (FALSE);
  787. }
  788. }
  789. if (Changes & NC_SThousand)
  790. {
  791. if (!Set_Locale_Values( hDlg,
  792. LOCALE_STHOUSAND,
  793. IDC_DIGIT_GROUP_SYMBOL,
  794. TEXT("sThousand"),
  795. FALSE,
  796. 0,
  797. 0,
  798. NULL ))
  799. {
  800. return (FALSE);
  801. }
  802. }
  803. if (Changes & NC_IDigits)
  804. {
  805. if (!Set_Locale_Values( hDlg,
  806. LOCALE_IDIGITS,
  807. IDC_NUM_DECIMAL_DIGITS,
  808. TEXT("iDigits"),
  809. TRUE,
  810. 0,
  811. 0,
  812. NULL ))
  813. {
  814. return (FALSE);
  815. }
  816. }
  817. if (Changes & NC_DGroup)
  818. {
  819. if (!Set_Locale_Values( hDlg,
  820. LOCALE_SGROUPING,
  821. IDC_NUM_DIGITS_GROUP,
  822. 0,
  823. TRUE,
  824. 0,
  825. TEXT(";0"),
  826. NULL ))
  827. {
  828. return (FALSE);
  829. }
  830. }
  831. if (Changes & NC_LZero)
  832. {
  833. if (!Set_Locale_Values( hDlg,
  834. LOCALE_ILZERO,
  835. IDC_DISPLAY_LEAD_0,
  836. TEXT("iLzero"),
  837. TRUE,
  838. 0,
  839. 0,
  840. NULL ))
  841. {
  842. return (FALSE);
  843. }
  844. }
  845. if (Changes & NC_NegFmt)
  846. {
  847. if (!Set_Locale_Values( hDlg,
  848. LOCALE_INEGNUMBER,
  849. IDC_NEG_NUM_FORMAT,
  850. 0,
  851. TRUE,
  852. 0,
  853. 0,
  854. NULL ))
  855. {
  856. return (FALSE);
  857. }
  858. }
  859. if (Changes & NC_Measure)
  860. {
  861. if (!Set_Locale_Values( hDlg,
  862. LOCALE_IMEASURE,
  863. IDC_MEASURE_SYS,
  864. TEXT("iMeasure"),
  865. TRUE,
  866. 0,
  867. 0,
  868. NULL ))
  869. {
  870. return (FALSE);
  871. }
  872. }
  873. if (Changes & NC_NativeDigits)
  874. {
  875. if (!Set_Locale_Values( hDlg,
  876. LOCALE_SNATIVEDIGITS,
  877. IDC_NATIVE_DIGITS,
  878. TEXT("sNativeDigits"),
  879. FALSE,
  880. 0,
  881. 0,
  882. NULL ))
  883. {
  884. return (FALSE);
  885. }
  886. }
  887. if (Changes & NC_DigitSubst)
  888. {
  889. if (!Set_Locale_Values( hDlg,
  890. LOCALE_IDIGITSUBSTITUTION,
  891. IDC_DIGIT_SUBST,
  892. TEXT("NumShape"),
  893. TRUE,
  894. 0,
  895. 0,
  896. NULL ))
  897. {
  898. return (FALSE);
  899. }
  900. }
  901. PropSheet_UnChanged(GetParent(hDlg), hDlg);
  902. lpPropSheet->lParam = NC_EverChg;
  903. //
  904. // Display the current sample that represents all of the locale settings.
  905. //
  906. if (bRedisplay)
  907. {
  908. Number_ClearValues(hDlg);
  909. Number_SetValues(hDlg);
  910. }
  911. //
  912. // Changes made in the second level.
  913. //
  914. if (Changes)
  915. {
  916. g_dwCustChange |= Process_Num;
  917. }
  918. //
  919. // Return success.
  920. //
  921. return (TRUE);
  922. }
  923. ////////////////////////////////////////////////////////////////////////////
  924. //
  925. // Number_ValidatePPS
  926. //
  927. // Validate each of the combo boxes whose values are constrained.
  928. // If any of the input fails, notify the user and then return FALSE
  929. // to indicate validation failure.
  930. //
  931. ////////////////////////////////////////////////////////////////////////////
  932. BOOL Number_ValidatePPS(
  933. HWND hDlg,
  934. LPARAM Changes)
  935. {
  936. //
  937. // If nothing has changed, return TRUE immediately.
  938. //
  939. if (Changes <= NC_EverChg)
  940. {
  941. return (TRUE);
  942. }
  943. //
  944. // If the decimal symbol has changed, ensure that there are no digits
  945. // contained in the new symbol.
  946. //
  947. if (Changes & NC_DSymbol &&
  948. Item_Has_Digits(hDlg, IDC_DECIMAL_SYMBOL, FALSE))
  949. {
  950. No_Numerals_Error(hDlg, IDC_DECIMAL_SYMBOL, IDS_LOCALE_DECIMAL_SYM);
  951. return (FALSE);
  952. }
  953. //
  954. // If the negative sign symbol has changed, ensure that there are no
  955. // digits contained in the new symbol.
  956. //
  957. if (Changes & NC_NSign &&
  958. Item_Has_Digits(hDlg, IDC_NEG_SIGN, TRUE))
  959. {
  960. No_Numerals_Error(hDlg, IDC_NEG_SIGN, IDS_LOCALE_NEG_SIGN);
  961. return (FALSE);
  962. }
  963. //
  964. // If the thousands grouping symbol has changed, ensure that there
  965. // are no digits contained in the new symbol.
  966. //
  967. if (Changes & NC_SThousand &&
  968. Item_Has_Digits(hDlg, IDC_DIGIT_GROUP_SYMBOL, FALSE))
  969. {
  970. No_Numerals_Error(hDlg, IDC_DIGIT_GROUP_SYMBOL, IDS_LOCALE_GROUP_SYM);
  971. return (FALSE);
  972. }
  973. //
  974. // Return success.
  975. //
  976. return (TRUE);
  977. }
  978. ////////////////////////////////////////////////////////////////////////////
  979. //
  980. // Number_InitPropSheet
  981. //
  982. // The extra long value for the property sheet page is used as a set of
  983. // state or change flags for each of the list boxes in the property sheet.
  984. // Initialize this value to 0. Call Number_SetValues with the property
  985. // sheet handle to initialize all of the property sheet controls.
  986. // Constrain the size of certain ComboBox text sizes.
  987. //
  988. ////////////////////////////////////////////////////////////////////////////
  989. void Number_InitPropSheet(
  990. HWND hDlg,
  991. LPARAM lParam)
  992. {
  993. //
  994. // The lParam holds a pointer to the property sheet page, save it for
  995. // later reference.
  996. //
  997. SetWindowLongPtr(hDlg, DWLP_USER, lParam);
  998. Number_SetValues(hDlg);
  999. ComboBox_LimitText(GetDlgItem(hDlg, IDC_NEG_SIGN), MAX_SNEGSIGN);
  1000. ComboBox_LimitText(GetDlgItem(hDlg, IDC_DECIMAL_SYMBOL), MAX_SDECIMAL);
  1001. ComboBox_LimitText(GetDlgItem(hDlg, IDC_DIGIT_GROUP_SYMBOL), MAX_STHOUSAND);
  1002. ComboBox_LimitText(GetDlgItem(hDlg, IDC_SEPARATOR), MAX_SLIST);
  1003. }
  1004. ////////////////////////////////////////////////////////////////////////////
  1005. //
  1006. // NumberDlgProc
  1007. //
  1008. //
  1009. ////////////////////////////////////////////////////////////////////////////
  1010. INT_PTR CALLBACK NumberDlgProc(
  1011. HWND hDlg,
  1012. UINT message,
  1013. WPARAM wParam,
  1014. LPARAM lParam)
  1015. {
  1016. NMHDR *lpnm;
  1017. LPPROPSHEETPAGE lpPropSheet = (LPPROPSHEETPAGE)(GetWindowLongPtr(hDlg, DWLP_USER));
  1018. switch (message)
  1019. {
  1020. case ( WM_NOTIFY ) :
  1021. {
  1022. lpnm = (NMHDR *)lParam;
  1023. switch (lpnm->code)
  1024. {
  1025. case ( PSN_SETACTIVE ) :
  1026. {
  1027. //
  1028. // If there has been a change in the regional Locale
  1029. // setting, clear all of the current info in the
  1030. // property sheet, get the new values, and update the
  1031. // appropriate registry values.
  1032. //
  1033. if (Verified_Regional_Chg & Process_Num)
  1034. {
  1035. Verified_Regional_Chg &= ~Process_Num;
  1036. Number_ClearValues(hDlg);
  1037. Number_SetValues(hDlg);
  1038. lpPropSheet->lParam = 0;
  1039. }
  1040. break;
  1041. }
  1042. case ( PSN_KILLACTIVE ) :
  1043. {
  1044. //
  1045. // Validate the entries on the property page.
  1046. //
  1047. SetWindowLongPtr( hDlg,
  1048. DWLP_MSGRESULT,
  1049. !Number_ValidatePPS( hDlg,
  1050. lpPropSheet->lParam ) );
  1051. break;
  1052. }
  1053. case ( PSN_APPLY ) :
  1054. {
  1055. //
  1056. // Apply the settings.
  1057. //
  1058. if (Number_ApplySettings(hDlg, TRUE))
  1059. {
  1060. SetWindowLongPtr(hDlg, DWLP_MSGRESULT, PSNRET_NOERROR);
  1061. //
  1062. // Zero out the NC_EverChg bit.
  1063. //
  1064. lpPropSheet->lParam = 0;
  1065. }
  1066. else
  1067. {
  1068. SetWindowLongPtr( hDlg,
  1069. DWLP_MSGRESULT,
  1070. PSNRET_INVALID_NOCHANGEPAGE );
  1071. }
  1072. break;
  1073. }
  1074. default :
  1075. {
  1076. return (FALSE);
  1077. }
  1078. }
  1079. break;
  1080. }
  1081. case ( WM_INITDIALOG ) :
  1082. {
  1083. Number_InitPropSheet(hDlg, lParam);
  1084. Number_SaveValues();
  1085. break;
  1086. }
  1087. case ( WM_DESTROY ) :
  1088. {
  1089. break;
  1090. }
  1091. case ( WM_HELP ) :
  1092. {
  1093. WinHelp( (HWND)((LPHELPINFO)lParam)->hItemHandle,
  1094. szHelpFile,
  1095. HELP_WM_HELP,
  1096. (DWORD_PTR)(LPTSTR)aNumberHelpIds );
  1097. break;
  1098. }
  1099. case ( WM_CONTEXTMENU ) : // right mouse click
  1100. {
  1101. WinHelp( (HWND)wParam,
  1102. szHelpFile,
  1103. HELP_CONTEXTMENU,
  1104. (DWORD_PTR)(LPTSTR)aNumberHelpIds );
  1105. break;
  1106. }
  1107. case ( WM_COMMAND ) :
  1108. {
  1109. switch (LOWORD(wParam))
  1110. {
  1111. case ( IDC_DECIMAL_SYMBOL ) :
  1112. {
  1113. if (HIWORD(wParam) == CBN_SELCHANGE ||
  1114. HIWORD(wParam) == CBN_EDITCHANGE)
  1115. {
  1116. lpPropSheet->lParam |= NC_DSymbol;
  1117. }
  1118. break;
  1119. }
  1120. case ( IDC_NEG_SIGN ) :
  1121. {
  1122. if (HIWORD(wParam) == CBN_SELCHANGE ||
  1123. HIWORD(wParam) == CBN_EDITCHANGE)
  1124. {
  1125. lpPropSheet->lParam |= NC_NSign;
  1126. }
  1127. break;
  1128. }
  1129. case ( IDC_SEPARATOR ) :
  1130. {
  1131. if (HIWORD(wParam) == CBN_SELCHANGE ||
  1132. HIWORD(wParam) == CBN_EDITCHANGE)
  1133. {
  1134. lpPropSheet->lParam |= NC_SList;
  1135. }
  1136. break;
  1137. }
  1138. case ( IDC_DIGIT_GROUP_SYMBOL ) :
  1139. {
  1140. if (HIWORD(wParam) == CBN_SELCHANGE ||
  1141. HIWORD(wParam) == CBN_EDITCHANGE)
  1142. {
  1143. lpPropSheet->lParam |= NC_SThousand;
  1144. }
  1145. break;
  1146. }
  1147. case ( IDC_NUM_DECIMAL_DIGITS ) :
  1148. {
  1149. if (HIWORD(wParam) == CBN_SELCHANGE)
  1150. {
  1151. lpPropSheet->lParam |= NC_IDigits;
  1152. }
  1153. break;
  1154. }
  1155. case ( IDC_NUM_DIGITS_GROUP ) :
  1156. {
  1157. if (HIWORD(wParam) == CBN_SELCHANGE)
  1158. {
  1159. lpPropSheet->lParam |= NC_DGroup;
  1160. }
  1161. break;
  1162. }
  1163. case ( IDC_DISPLAY_LEAD_0 ) :
  1164. {
  1165. if (HIWORD(wParam) == CBN_SELCHANGE)
  1166. {
  1167. lpPropSheet->lParam |= NC_LZero;
  1168. }
  1169. break;
  1170. }
  1171. case ( IDC_NEG_NUM_FORMAT ) :
  1172. {
  1173. if (HIWORD(wParam) == CBN_SELCHANGE)
  1174. {
  1175. lpPropSheet->lParam |= NC_NegFmt;
  1176. }
  1177. break;
  1178. }
  1179. case ( IDC_MEASURE_SYS ) :
  1180. {
  1181. if (HIWORD(wParam) == CBN_SELCHANGE)
  1182. {
  1183. lpPropSheet->lParam |= NC_Measure;
  1184. }
  1185. break;
  1186. }
  1187. case ( IDC_NATIVE_DIGITS ) :
  1188. {
  1189. if (HIWORD(wParam) == CBN_SELCHANGE)
  1190. {
  1191. lpPropSheet->lParam |= NC_NativeDigits;
  1192. }
  1193. break;
  1194. }
  1195. case ( IDC_DIGIT_SUBST ) :
  1196. {
  1197. if (HIWORD(wParam) == CBN_SELCHANGE)
  1198. {
  1199. lpPropSheet->lParam |= NC_DigitSubst;
  1200. }
  1201. break;
  1202. }
  1203. }
  1204. //
  1205. // Turn on ApplyNow button.
  1206. //
  1207. if (lpPropSheet->lParam > NC_EverChg)
  1208. {
  1209. PropSheet_Changed(GetParent(hDlg), hDlg);
  1210. }
  1211. break;
  1212. }
  1213. default :
  1214. {
  1215. return (FALSE);
  1216. }
  1217. }
  1218. //
  1219. // Return success.
  1220. //
  1221. return (TRUE);
  1222. }