Source code of Windows XP (NT5)
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.

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