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.

1530 lines
45 KiB

  1. /*++
  2. Copyright (c) 1994-2000, Microsoft Corporation All rights reserved.
  3. Module Name:
  4. datedlg.c
  5. Abstract:
  6. This module implements the date 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 <commctrl.h>
  17. #include "intlhlp.h"
  18. #include "maxvals.h"
  19. #include "winnlsp.h"
  20. //
  21. // Context Help Ids.
  22. //
  23. static int aDateHelpIds[] =
  24. {
  25. IDC_GROUPBOX1, IDH_COMM_GROUPBOX,
  26. IDC_GROUPBOX2, IDH_COMM_GROUPBOX,
  27. IDC_GROUPBOX3, IDH_COMM_GROUPBOX,
  28. IDC_SAMPLE1, IDH_INTL_DATE_SHORTSAMPLE,
  29. IDC_SAMPLELBL1, IDH_INTL_DATE_SHORTSAMPLE,
  30. IDC_SAMPLE1A, IDH_INTL_DATE_SHORTSAMPLE_ARABIC,
  31. IDC_SAMPLELBL1A, IDH_INTL_DATE_SHORTSAMPLE_ARABIC,
  32. IDC_SHORT_DATE_STYLE, IDH_INTL_DATE_SHORTSTYLE,
  33. IDC_SEPARATOR, IDH_INTL_DATE_SEPARATOR,
  34. IDC_SAMPLE2, IDH_INTL_DATE_LONGSAMPLE,
  35. IDC_SAMPLELBL2, IDH_INTL_DATE_LONGSAMPLE,
  36. IDC_SAMPLE2A, IDH_INTL_DATE_LONGSAMPLE_ARABIC,
  37. IDC_SAMPLELBL2A, IDH_INTL_DATE_LONGSAMPLE_ARABIC,
  38. IDC_LONG_DATE_STYLE, IDH_INTL_DATE_LONGSTYLE,
  39. IDC_CALENDAR_TYPE_TEXT, IDH_INTL_DATE_CALENDARTYPE,
  40. IDC_CALENDAR_TYPE, IDH_INTL_DATE_CALENDARTYPE,
  41. IDC_TWO_DIGIT_YEAR_LOW, IDH_INTL_DATE_TWO_DIGIT_YEAR,
  42. IDC_TWO_DIGIT_YEAR_HIGH, IDH_INTL_DATE_TWO_DIGIT_YEAR,
  43. IDC_TWO_DIGIT_YEAR_ARROW, IDH_INTL_DATE_TWO_DIGIT_YEAR,
  44. IDC_ADD_HIJRI_DATE, IDH_INTL_DATE_ADD_HIJRI_DATE,
  45. IDC_ADD_HIJRI_DATE_TEXT, IDH_INTL_DATE_ADD_HIJRI_DATE,
  46. 0, 0
  47. };
  48. //
  49. // Global Variables.
  50. //
  51. TCHAR szNLS_LongDate[SIZE_128];
  52. TCHAR szNLS_ShortDate[SIZE_128];
  53. static TCHAR sz_iCalendarType[MAX_ICALTYPE + 1];
  54. static TCHAR sz_sDate[MAX_SDATE + 1];
  55. static TCHAR sz_sLongDate[MAX_SLONGDATE + 1];
  56. static TCHAR sz_sShortDate[MAX_FORMAT + 1];
  57. static const TCHAR c_szInternational[] = TEXT("Control Panel\\International");
  58. static const TCHAR c_szAddHijriDate[] = TEXT("AddHijriDate");
  59. static const TCHAR c_szAddHijriDateTemp[] = TEXT("AddHijriDateTemp");
  60. static const PTSTR c_szAddHijriDateValues[] =
  61. {
  62. TEXT("AddHijriDate-2"),
  63. TEXT("AddHijriDate"),
  64. TEXT(""),
  65. TEXT("AddHijriDate+1"),
  66. TEXT("AddHijriDate+2")
  67. };
  68. static const TCHAR c_szTwoDigitYearKey[] = TEXT("Software\\Policies\\Microsoft\\Control Panel\\International\\Calendars\\TwoDigitYearMax");
  69. //
  70. // Function Prototypes.
  71. //
  72. void Date_InitializeHijriDateComboBox(
  73. HWND hDlg);
  74. ////////////////////////////////////////////////////////////////////////////
  75. //
  76. // Date_EnumerateDates
  77. //
  78. // Enumerates the appropriate dates for the chosen calendar.
  79. //
  80. ////////////////////////////////////////////////////////////////////////////
  81. void Date_EnumerateDates(
  82. HWND hDlg,
  83. DWORD dwDateFlag)
  84. {
  85. DWORD dwLocaleFlag;
  86. int nItemId;
  87. DWORD dwIndex;
  88. DWORD dwCalNum = 0;
  89. TCHAR szBuf[SIZE_128];
  90. HWND hCtrlDate;
  91. HWND hCtrlCal = GetDlgItem(hDlg, IDC_CALENDAR_TYPE);
  92. //
  93. // Initialize variables according to the dwDateFlag parameter.
  94. //
  95. if (dwDateFlag == CAL_SSHORTDATE)
  96. {
  97. dwLocaleFlag = LOCALE_SSHORTDATE;
  98. nItemId = IDC_SHORT_DATE_STYLE;
  99. }
  100. else // CAL_SLONGDATE
  101. {
  102. dwLocaleFlag = LOCALE_SLONGDATE;
  103. nItemId = IDC_LONG_DATE_STYLE;
  104. }
  105. hCtrlDate = GetDlgItem(hDlg, nItemId);
  106. //
  107. // Initialize to reset the contents for the appropriate combo box.
  108. //
  109. if (!Set_List_Values(hDlg, nItemId, 0))
  110. {
  111. return;
  112. }
  113. //
  114. // Reset the contents of the combo box.
  115. //
  116. ComboBox_ResetContent(hCtrlDate);
  117. //
  118. // Get the currently selected calendar id.
  119. //
  120. dwIndex = ComboBox_GetCurSel(hCtrlCal);
  121. if (dwIndex != CB_ERR)
  122. {
  123. dwCalNum = (DWORD)ComboBox_GetItemData(hCtrlCal, dwIndex);
  124. }
  125. //
  126. // Enumerate the dates for the currently selected calendar.
  127. //
  128. EnumCalendarInfo(EnumProc, UserLocaleID, dwCalNum, dwDateFlag);
  129. dwIndex = ComboBox_GetCount(hCtrlCal);
  130. if ((dwIndex == 0) || (dwIndex == CB_ERR))
  131. {
  132. EnumCalendarInfo(EnumProc, UserLocaleID, CAL_GREGORIAN, dwDateFlag);
  133. }
  134. //
  135. // Add (if necesary) and select the current user setting in the
  136. // combo box.
  137. //
  138. dwIndex = 0;
  139. if (GetLocaleInfo(UserLocaleID, dwLocaleFlag, szBuf, SIZE_128))
  140. {
  141. if ((dwIndex = ComboBox_FindStringExact(hCtrlDate, -1, szBuf)) == CB_ERR)
  142. {
  143. //
  144. // Need to add this entry to the combo box.
  145. //
  146. Set_List_Values(0, 0, szBuf);
  147. if ((dwIndex = ComboBox_FindStringExact(hCtrlDate, -1, szBuf)) == CB_ERR)
  148. {
  149. dwIndex = 0;
  150. }
  151. }
  152. }
  153. else
  154. {
  155. MessageBox(hDlg, szLocaleGetError, NULL, MB_OK | MB_ICONINFORMATION);
  156. }
  157. Set_List_Values(0, nItemId, 0);
  158. Localize_Combobox_Styles(hDlg, nItemId, dwLocaleFlag);
  159. ComboBox_SetCurSel(hCtrlDate, dwIndex);
  160. }
  161. ////////////////////////////////////////////////////////////////////////////
  162. //
  163. // Date_GetTwoDigitYearRangeFromPolicy
  164. //
  165. // Read the two digit year from the Policy registry.
  166. //
  167. ////////////////////////////////////////////////////////////////////////////
  168. BOOL Date_GetTwoDigitYearRangeFromPolicy(
  169. CALID CalId)
  170. {
  171. HKEY hKey;
  172. BYTE buf[MAX_PATH];
  173. TCHAR szCalId[MAX_PATH];
  174. DWORD dwResultLen = sizeof(buf), dwType;
  175. BOOL bRet = FALSE;
  176. //
  177. // Convert CalendarId to a string.
  178. //
  179. wsprintf(szCalId, TEXT("%d"), CalId);
  180. if (RegOpenKey( HKEY_CURRENT_USER,
  181. c_szTwoDigitYearKey,
  182. &hKey ) == ERROR_SUCCESS)
  183. {
  184. if ((RegQueryValueEx( hKey,
  185. szCalId,
  186. NULL,
  187. &dwType,
  188. &buf[0],
  189. &dwResultLen ) == ERROR_SUCCESS) &&
  190. (dwType == REG_SZ) &&
  191. (dwResultLen > 2))
  192. {
  193. bRet = TRUE;
  194. }
  195. RegCloseKey(hKey);
  196. }
  197. //
  198. // Return the result.
  199. //
  200. return (bRet);
  201. }
  202. ////////////////////////////////////////////////////////////////////////////
  203. //
  204. // Date_GetTwoDigitYearRange
  205. //
  206. // Fills in the two digit year range controls.
  207. //
  208. ////////////////////////////////////////////////////////////////////////////
  209. void Date_GetTwoDigitYearRange(
  210. HWND hDlg,
  211. CALID CalId)
  212. {
  213. HWND hwndYearHigh = GetDlgItem(hDlg, IDC_TWO_DIGIT_YEAR_HIGH);
  214. HWND hwndScroll = GetDlgItem(hDlg, IDC_TWO_DIGIT_YEAR_ARROW);
  215. DWORD YearHigh, YearHighDefault;
  216. //
  217. // Enable the high range control.
  218. //
  219. EnableWindow(hwndYearHigh, TRUE);
  220. EnableWindow(hwndScroll, TRUE);
  221. //
  222. // Get the default two digit year upper boundary.
  223. //
  224. if (!GetCalendarInfo( LOCALE_USER_DEFAULT,
  225. CalId,
  226. CAL_ITWODIGITYEARMAX | CAL_RETURN_NUMBER |
  227. CAL_NOUSEROVERRIDE,
  228. NULL,
  229. 0,
  230. &YearHighDefault ))
  231. {
  232. YearHighDefault = 0;
  233. }
  234. //
  235. // Disable the two digit year upper boundary control if it is
  236. // enforced by a policy or if the default value is 99 or less.
  237. //
  238. if ((Date_GetTwoDigitYearRangeFromPolicy(CalId)) ||
  239. (YearHighDefault <= 99))
  240. {
  241. //
  242. // Disable the two digit year max controls.
  243. //
  244. EnableWindow(hwndScroll, FALSE);
  245. EnableWindow(hwndYearHigh, FALSE);
  246. }
  247. //
  248. // Get the two digit year upper boundary. If the default is less
  249. // than or equal to 99, then use the default value and ignore the
  250. // registry. This is done for calendars like the Japanese Era
  251. // calendar where it doesn't make sense to have a sliding window.
  252. //
  253. if (YearHighDefault <= 99)
  254. {
  255. YearHigh = YearHighDefault;
  256. }
  257. else if (!GetCalendarInfo( LOCALE_USER_DEFAULT,
  258. CalId,
  259. CAL_ITWODIGITYEARMAX | CAL_RETURN_NUMBER,
  260. NULL,
  261. 0,
  262. &YearHigh ) ||
  263. (YearHigh < 99) || (YearHigh > 9999))
  264. {
  265. YearHigh = (YearHighDefault >= 99) ? YearHighDefault : 2029;
  266. }
  267. //
  268. // Set the range on the controls.
  269. //
  270. SendMessage(hwndScroll, UDM_SETRANGE, 0, MAKELPARAM(9999, 99));
  271. SendMessage(hwndScroll, UDM_SETBUDDY, (WPARAM)hwndYearHigh, 0L);
  272. //
  273. // Set the values of the controls.
  274. //
  275. SetDlgItemInt(hDlg, IDC_TWO_DIGIT_YEAR_LOW, (UINT)(YearHigh - 99), FALSE);
  276. SendMessage(hwndScroll, UDM_SETPOS, 0, MAKELONG((short)YearHigh, 0));
  277. }
  278. ////////////////////////////////////////////////////////////////////////////
  279. //
  280. // Date_SetTwoDigitYearMax
  281. //
  282. // Sets the two digit year max value in the registry.
  283. //
  284. ////////////////////////////////////////////////////////////////////////////
  285. BOOL Date_SetTwoDigitYearMax(
  286. HWND hDlg,
  287. CALID CalId)
  288. {
  289. TCHAR szYear[SIZE_64];
  290. //
  291. // Get the max year.
  292. //
  293. szYear[0] = 0;
  294. if (GetWindowText( GetDlgItem(hDlg, IDC_TWO_DIGIT_YEAR_HIGH),
  295. szYear,
  296. SIZE_64 ) != 0)
  297. {
  298. //
  299. // Set the two digit year upper boundary.
  300. //
  301. return (SetCalendarInfo( LOCALE_USER_DEFAULT,
  302. CalId,
  303. CAL_ITWODIGITYEARMAX,
  304. szYear ));
  305. }
  306. //
  307. // Return success.
  308. //
  309. return (TRUE);
  310. }
  311. ////////////////////////////////////////////////////////////////////////////
  312. //
  313. // Date_ChangeYear
  314. //
  315. // Changes the lower bound based on the upper bound value.
  316. //
  317. ////////////////////////////////////////////////////////////////////////////
  318. void Date_ChangeYear(
  319. HWND hDlg)
  320. {
  321. DWORD YearHigh;
  322. BOOL bSuccess;
  323. //
  324. // Get the two digit year upper boundary.
  325. //
  326. YearHigh = GetDlgItemInt(hDlg, IDC_TWO_DIGIT_YEAR_HIGH, &bSuccess, FALSE);
  327. if ((!bSuccess) || (YearHigh < 99) || (YearHigh > 9999))
  328. {
  329. //
  330. // Invalid value, so set the lower control to 0.
  331. //
  332. SetDlgItemInt(hDlg, IDC_TWO_DIGIT_YEAR_LOW, 0, FALSE);
  333. }
  334. else
  335. {
  336. //
  337. // Set the value of the lower control.
  338. //
  339. SetDlgItemInt(hDlg, IDC_TWO_DIGIT_YEAR_LOW, (UINT)(YearHigh - 99), FALSE);
  340. }
  341. }
  342. ////////////////////////////////////////////////////////////////////////////
  343. //
  344. // Date_DisplaySample
  345. //
  346. // Updates the date samples. It formats the date based on the user's
  347. // current locale settings.
  348. //
  349. ////////////////////////////////////////////////////////////////////////////
  350. void Date_DisplaySample(
  351. HWND hDlg)
  352. {
  353. TCHAR szBuf[MAX_SAMPLE_SIZE];
  354. BOOL bNoError = TRUE;
  355. if (!bShowArabic) {
  356. // If user locale is not Arabic, make sure that the control for date samples are:
  357. // * LTR reading orders for non-Hebrew locales
  358. // * RTL reading orders for Hebrew locales.
  359. SetControlReadingOrder(bHebrewUI, GetDlgItem(hDlg, IDC_SAMPLE1));
  360. SetControlReadingOrder(bHebrewUI, GetDlgItem(hDlg, IDC_SAMPLE2));
  361. }
  362. // In Hebrew locale, we want to format the short date for left-to-right reading order.
  363. // If we make it right-to-left reading order, the Gregorian short date will display
  364. // in a complete different display order.
  365. // The left-to-right reading order won't affect the Hebrew short date display.
  366. if (GetDateFormat( UserLocaleID,
  367. (bHebrewUI ? DATE_LTRREADING :
  368. (bShowRtL ? DATE_LTRREADING : 0)) | DATE_SHORTDATE,
  369. NULL,
  370. NULL,
  371. szBuf,
  372. MAX_SAMPLE_SIZE ))
  373. {
  374. SetDlgItemText(hDlg, IDC_SAMPLE1, szBuf);
  375. }
  376. else
  377. {
  378. MessageBox(hDlg, szLocaleGetError, NULL, MB_OK | MB_ICONINFORMATION);
  379. bNoError = FALSE;
  380. }
  381. //
  382. // Show or hide the Arabic info based on the current user locale id.
  383. //
  384. ShowWindow(GetDlgItem(hDlg, IDC_SAMPLELBL1A), bShowArabic ? SW_SHOW : SW_HIDE);
  385. ShowWindow(GetDlgItem(hDlg, IDC_SAMPLE1A), bShowArabic ? SW_SHOW : SW_HIDE);
  386. if (bShowArabic)
  387. {
  388. if (GetDateFormat( UserLocaleID,
  389. DATE_RTLREADING | DATE_SHORTDATE,
  390. NULL,
  391. NULL,
  392. szBuf,
  393. MAX_SAMPLE_SIZE ))
  394. {
  395. SetDlgItemText(hDlg, IDC_SAMPLE1A, szBuf);
  396. SetDlgItemRTL(hDlg, IDC_SAMPLE1A);
  397. }
  398. else
  399. {
  400. MessageBox(hDlg, szLocaleGetError, NULL, MB_OK | MB_ICONINFORMATION);
  401. bNoError = FALSE;
  402. }
  403. }
  404. if (GetDateFormat( UserLocaleID,
  405. (bHebrewUI ? DATE_RTLREADING :
  406. (bShowRtL ? DATE_LTRREADING : 0)) | DATE_LONGDATE,
  407. NULL,
  408. NULL,
  409. szBuf,
  410. MAX_SAMPLE_SIZE ))
  411. {
  412. SetDlgItemText(hDlg, IDC_SAMPLE2, szBuf);
  413. }
  414. else if (bNoError)
  415. {
  416. MessageBox(hDlg, szLocaleGetError, NULL, MB_OK | MB_ICONINFORMATION);
  417. }
  418. //
  419. // Show or hide the Right to left info based on the current user locale id.
  420. //
  421. ShowWindow(GetDlgItem(hDlg, IDC_SAMPLELBL2A), bShowArabic ? SW_SHOW : SW_HIDE);
  422. ShowWindow(GetDlgItem(hDlg, IDC_SAMPLE2A), bShowArabic ? SW_SHOW : SW_HIDE);
  423. if (bShowArabic)
  424. {
  425. if (GetDateFormat( UserLocaleID,
  426. DATE_RTLREADING | DATE_LONGDATE,
  427. NULL,
  428. NULL,
  429. szBuf,
  430. MAX_SAMPLE_SIZE ))
  431. {
  432. SetDlgItemText(hDlg, IDC_SAMPLE2A, szBuf);
  433. SetDlgItemRTL(hDlg, IDC_SAMPLE2A);
  434. }
  435. else if (bNoError)
  436. {
  437. MessageBox(hDlg, szLocaleGetError, NULL, MB_OK | MB_ICONINFORMATION);
  438. }
  439. }
  440. }
  441. ////////////////////////////////////////////////////////////////////////////
  442. //
  443. // Date_ClearValues
  444. //
  445. // Reset each of the list boxes in the date property sheet page.
  446. //
  447. ////////////////////////////////////////////////////////////////////////////
  448. void Date_ClearValues(
  449. HWND hDlg)
  450. {
  451. ComboBox_ResetContent(GetDlgItem(hDlg, IDC_SHORT_DATE_STYLE));
  452. ComboBox_ResetContent(GetDlgItem(hDlg, IDC_LONG_DATE_STYLE));
  453. ComboBox_ResetContent(GetDlgItem(hDlg, IDC_SEPARATOR));
  454. ComboBox_ResetContent(GetDlgItem(hDlg, IDC_CALENDAR_TYPE));
  455. ComboBox_ResetContent(GetDlgItem(hDlg, IDC_TWO_DIGIT_YEAR_LOW));
  456. ComboBox_ResetContent(GetDlgItem(hDlg, IDC_TWO_DIGIT_YEAR_HIGH));
  457. }
  458. ////////////////////////////////////////////////////////////////////////////
  459. //
  460. // Date_EnableHijriComboBox
  461. //
  462. // Enables/Disables Show/Hides the Hijri date advance combo where necessary
  463. //
  464. ////////////////////////////////////////////////////////////////////////////
  465. void Date_EnableHijriComboBox(
  466. HWND hDlg,
  467. BOOL Status)
  468. {
  469. HWND hAddHijriDateCB = GetDlgItem(hDlg, IDC_ADD_HIJRI_DATE);
  470. HWND hAddHijriDateText = GetDlgItem(hDlg, IDC_ADD_HIJRI_DATE_TEXT);
  471. INT iCount;
  472. //
  473. // If the combo box is empty, then disable it.
  474. //
  475. iCount = (INT)SendMessage(hAddHijriDateCB, CB_GETCOUNT, 0L, 0L);
  476. if ((iCount == CB_ERR) || (iCount <= 0L))
  477. {
  478. Status = FALSE;
  479. }
  480. EnableWindow(hAddHijriDateCB, Status);
  481. ShowWindow(hAddHijriDateCB, Status ? SW_SHOW : SW_HIDE );
  482. EnableWindow(hAddHijriDateText, Status);
  483. ShowWindow(hAddHijriDateText, Status ? SW_SHOW : SW_HIDE);
  484. }
  485. ////////////////////////////////////////////////////////////////////////////
  486. //
  487. // Date_SaveValues
  488. //
  489. // Save values in the case that we need to restore them.
  490. //
  491. ////////////////////////////////////////////////////////////////////////////
  492. void Date_SaveValues()
  493. {
  494. //
  495. // Save registry values.
  496. //
  497. if (!GetLocaleInfo( UserLocaleID,
  498. LOCALE_ICALENDARTYPE,
  499. sz_iCalendarType,
  500. MAX_ICALTYPE + 1 ))
  501. {
  502. _tcscpy(sz_iCalendarType, TEXT("1"));
  503. }
  504. if (!GetLocaleInfo( UserLocaleID,
  505. LOCALE_SDATE,
  506. sz_sDate,
  507. MAX_SDATE + 1 ))
  508. {
  509. _tcscpy(sz_sDate, TEXT("/"));
  510. }
  511. if (!GetLocaleInfo( UserLocaleID,
  512. LOCALE_SLONGDATE,
  513. sz_sLongDate,
  514. MAX_SLONGDATE + 1 ))
  515. {
  516. _tcscpy(sz_sLongDate, TEXT("dddd, MMMM dd, yyyy"));
  517. }
  518. if (!GetLocaleInfo( UserLocaleID,
  519. LOCALE_SSHORTDATE,
  520. sz_sShortDate,
  521. MAX_SSHORTDATE + 1 ))
  522. {
  523. _tcscpy(sz_sShortDate, TEXT("M/d/yyyy"));
  524. }
  525. }
  526. ////////////////////////////////////////////////////////////////////////////
  527. //
  528. // Date_RestoreValues
  529. //
  530. ////////////////////////////////////////////////////////////////////////////
  531. void Date_RestoreValues()
  532. {
  533. if (g_dwCustChange & Process_Date)
  534. {
  535. SetLocaleInfo(UserLocaleID, LOCALE_ICALENDARTYPE, sz_iCalendarType);
  536. SetLocaleInfo(UserLocaleID, LOCALE_SDATE, sz_sDate);
  537. SetLocaleInfo(UserLocaleID, LOCALE_SLONGDATE, sz_sLongDate);
  538. SetLocaleInfo(UserLocaleID, LOCALE_SSHORTDATE, sz_sShortDate);
  539. }
  540. }
  541. ////////////////////////////////////////////////////////////////////////////
  542. //
  543. // Date_SetValues
  544. //
  545. // Initialize all of the controls in the date property sheet page.
  546. //
  547. ////////////////////////////////////////////////////////////////////////////
  548. void Date_SetValues(
  549. HWND hDlg)
  550. {
  551. TCHAR szBuf[SIZE_128];
  552. int i, nItem;
  553. HWND hCtrl;
  554. LONG CalId;
  555. //
  556. // Initialize the dropdown box for the current locale setting for the
  557. // date separator.
  558. //
  559. DropDown_Use_Locale_Values(hDlg, LOCALE_SDATE, IDC_SEPARATOR);
  560. //
  561. // Initialize and Lock function. If it succeeds, call enum function to
  562. // enumerate all possible values for the list box via a call to EnumProc.
  563. // EnumProc will call Set_List_Values for each of the string values it
  564. // receives. When the enumeration of values is complete, call
  565. // Set_List_Values to clear the dialog item specific data and to clear
  566. // the lock on the function. Perform this set of operations for:
  567. // Calendar Type, Short Date Sytle, and Long Date Style.
  568. //
  569. if (Set_List_Values(hDlg, IDC_CALENDAR_TYPE, 0))
  570. {
  571. hCtrl = GetDlgItem(hDlg, IDC_CALENDAR_TYPE);
  572. EnumCalendarInfo(EnumProc, UserLocaleID, ENUM_ALL_CALENDARS, CAL_SCALNAME);
  573. Set_List_Values(0, IDC_CALENDAR_TYPE, 0);
  574. EnumCalendarInfo(EnumProc, UserLocaleID, ENUM_ALL_CALENDARS, CAL_ICALINTVALUE);
  575. Set_List_Values(0, IDC_CALENDAR_TYPE, 0);
  576. if (GetLocaleInfo(UserLocaleID, LOCALE_ICALENDARTYPE, szBuf, SIZE_128))
  577. {
  578. TCHAR szBufTmp[SIZE_128] = {0};
  579. int iTmp = 0;
  580. LONG CalIdTmp;
  581. if( GetLocaleInfo( UserLocaleID,
  582. LOCALE_ICALENDARTYPE | LOCALE_NOUSEROVERRIDE,
  583. szBufTmp,
  584. SIZE_128))
  585. {
  586. //
  587. // Convert the id to a number.
  588. //
  589. CalId = Intl_StrToLong(szBuf);
  590. CalIdTmp = Intl_StrToLong(szBufTmp);
  591. //
  592. // Search for calendars
  593. //
  594. nItem = ComboBox_GetCount(hCtrl);
  595. for (i = 0; i < nItem; i++)
  596. {
  597. if (ComboBox_GetItemData(hCtrl, i) == CalId)
  598. {
  599. break;
  600. }
  601. if (ComboBox_GetItemData(hCtrl, i) == CalIdTmp)
  602. {
  603. iTmp = i;
  604. }
  605. }
  606. //
  607. // Look if we find something.
  608. //
  609. if (i < nItem)
  610. {
  611. ComboBox_SetCurSel(hCtrl, i);
  612. }
  613. else
  614. {
  615. CalId = CalIdTmp;
  616. ComboBox_SetCurSel(hCtrl, iTmp); // Zero or something else.
  617. }
  618. //
  619. // Enable/disable the Add Hijri date check box.
  620. //
  621. Date_InitializeHijriDateComboBox(hDlg);
  622. Date_EnableHijriComboBox(hDlg, (CalId == CAL_HIJRI));
  623. //
  624. // Set the two digit year range.
  625. //
  626. Date_GetTwoDigitYearRange(hDlg, (CALID)CalId);
  627. //
  628. // Subtract 1 from calendar value because calendars are one
  629. // based, not zero based like all other locale values.
  630. //
  631. }
  632. }
  633. else
  634. {
  635. MessageBox(hDlg, szLocaleGetError, NULL, MB_OK | MB_ICONINFORMATION);
  636. }
  637. //
  638. // If more than one selection, enable dropdown box.
  639. // Otherwise, disable it.
  640. //
  641. if (ComboBox_GetCount(hCtrl) > 1)
  642. {
  643. EnableWindow(GetDlgItem(hDlg, IDC_CALENDAR_TYPE_TEXT), TRUE);
  644. EnableWindow(GetDlgItem(hDlg, IDC_CALENDAR_TYPE), TRUE);
  645. ShowWindow(GetDlgItem(hDlg, IDC_CALENDAR_TYPE_TEXT), SW_SHOW);
  646. ShowWindow(GetDlgItem(hDlg, IDC_CALENDAR_TYPE), SW_SHOW);
  647. }
  648. else
  649. {
  650. EnableWindow(GetDlgItem(hDlg, IDC_CALENDAR_TYPE_TEXT), FALSE);
  651. EnableWindow(GetDlgItem(hDlg, IDC_CALENDAR_TYPE), FALSE);
  652. ShowWindow(GetDlgItem(hDlg, IDC_CALENDAR_TYPE_TEXT), SW_HIDE);
  653. ShowWindow(GetDlgItem(hDlg, IDC_CALENDAR_TYPE), SW_HIDE);
  654. }
  655. }
  656. Date_EnumerateDates(hDlg, CAL_SSHORTDATE);
  657. Date_EnumerateDates(hDlg, CAL_SLONGDATE);
  658. //
  659. // Display the current sample that represents all of the locale settings.
  660. //
  661. Date_DisplaySample(hDlg);
  662. }
  663. ////////////////////////////////////////////////////////////////////////////
  664. //
  665. // Date_SetHijriDate
  666. //
  667. // Saves the Hijri date advance amount to the registry.
  668. //
  669. ////////////////////////////////////////////////////////////////////////////
  670. void Date_SetHijriDate(
  671. HWND hHijriComboBox)
  672. {
  673. HKEY hKey;
  674. INT iIndex;
  675. //
  676. // Get the string index to set.
  677. //
  678. iIndex = (INT)SendMessage(hHijriComboBox, CB_GETCURSEL, 0L, 0L);
  679. if (iIndex == CB_ERR)
  680. {
  681. return;
  682. }
  683. iIndex = (INT)SendMessage(hHijriComboBox, CB_GETITEMDATA, (WPARAM)iIndex, 0L);
  684. if (iIndex != CB_ERR)
  685. {
  686. if (RegOpenKeyEx( HKEY_CURRENT_USER,
  687. c_szInternational,
  688. 0,
  689. KEY_READ | KEY_WRITE,
  690. &hKey ) == ERROR_SUCCESS)
  691. {
  692. RegSetValueEx( hKey,
  693. c_szAddHijriDate,
  694. 0,
  695. REG_SZ,
  696. (LPBYTE)c_szAddHijriDateValues[iIndex],
  697. (lstrlen(c_szAddHijriDateValues[iIndex]) + 1) * sizeof(TCHAR) );
  698. RegCloseKey(hKey);
  699. }
  700. }
  701. }
  702. ////////////////////////////////////////////////////////////////////////////
  703. //
  704. // Date_ApplySettings
  705. //
  706. // For every control that has changed (that affects the Locale settings),
  707. // call Set_Locale_Values to update the user locale information. Notify
  708. // the parent of changes and reset the change flag stored in the property
  709. // sheet page structure appropriately. Redisplay the date sample if
  710. // bRedisplay is TRUE.
  711. //
  712. ////////////////////////////////////////////////////////////////////////////
  713. BOOL Date_ApplySettings(
  714. HWND hDlg,
  715. BOOL bRedisplay)
  716. {
  717. TCHAR szBuf[SIZE_128];
  718. CALID CalId = 0;
  719. LPPROPSHEETPAGE lpPropSheet = (LPPROPSHEETPAGE)(GetWindowLongPtr(hDlg, DWLP_USER));
  720. LPARAM Changes = lpPropSheet->lParam;
  721. HWND hwndYearHigh = GetDlgItem(hDlg, IDC_TWO_DIGIT_YEAR_HIGH);
  722. if (Changes & DC_ShortFmt)
  723. {
  724. //
  725. // szNLS_ShortDate is set in Date_ValidatePPS.
  726. //
  727. if (!Set_Locale_Values( hDlg,
  728. LOCALE_SSHORTDATE,
  729. IDC_SHORT_DATE_STYLE,
  730. TEXT("sShortDate"),
  731. FALSE,
  732. 0,
  733. 0,
  734. szNLS_ShortDate ))
  735. {
  736. return (FALSE);
  737. }
  738. //
  739. // If the date separator field has also been changed by the user,
  740. // then don't update now. It will be updated below.
  741. //
  742. if (!(Changes & DC_SDate))
  743. {
  744. //
  745. // Since the short date style changed, reset date separator
  746. // list box.
  747. //
  748. ComboBox_ResetContent(GetDlgItem(hDlg, IDC_SEPARATOR));
  749. DropDown_Use_Locale_Values(hDlg, LOCALE_SDATE, IDC_SEPARATOR);
  750. if (!Set_Locale_Values( hDlg,
  751. LOCALE_SDATE,
  752. IDC_SEPARATOR,
  753. TEXT("sDate"),
  754. FALSE,
  755. 0,
  756. 0,
  757. NULL ))
  758. {
  759. return (FALSE);
  760. }
  761. }
  762. }
  763. if (Changes & DC_LongFmt)
  764. {
  765. //
  766. // szNLS_LongDate is set in Date_ValidatePPS.
  767. //
  768. if (!Set_Locale_Values( hDlg,
  769. LOCALE_SLONGDATE,
  770. IDC_LONG_DATE_STYLE,
  771. TEXT("sLongDate"),
  772. FALSE,
  773. 0,
  774. 0,
  775. szNLS_LongDate ))
  776. {
  777. return (FALSE);
  778. }
  779. }
  780. if (Changes & DC_SDate)
  781. {
  782. if (!Set_Locale_Values( hDlg,
  783. LOCALE_SDATE,
  784. IDC_SEPARATOR,
  785. TEXT("sDate"),
  786. FALSE,
  787. 0,
  788. 0,
  789. NULL ))
  790. {
  791. return (FALSE);
  792. }
  793. //
  794. // Since the date separator changed, reset the short date style
  795. // list box.
  796. //
  797. Date_EnumerateDates(hDlg, CAL_SSHORTDATE);
  798. }
  799. if (Changes & DC_Calendar)
  800. {
  801. if (!Set_Locale_Values( hDlg,
  802. LOCALE_ICALENDARTYPE,
  803. IDC_CALENDAR_TYPE,
  804. 0,
  805. TRUE,
  806. 1,
  807. 0,
  808. NULL ))
  809. {
  810. return (FALSE);
  811. }
  812. if (GetLocaleInfo(UserLocaleID, LOCALE_ICALENDARTYPE, szBuf, SIZE_128))
  813. {
  814. CalId = Intl_StrToLong(szBuf);
  815. Date_InitializeHijriDateComboBox(hDlg);
  816. Date_EnableHijriComboBox(hDlg, (CalId == CAL_HIJRI));
  817. }
  818. }
  819. if (Changes & DC_Arabic_Calendar)
  820. {
  821. Date_SetHijriDate( GetDlgItem(hDlg, IDC_ADD_HIJRI_DATE) );
  822. }
  823. if (Changes & DC_TwoDigitYearMax)
  824. {
  825. if (CalId == 0)
  826. {
  827. HWND hCtrl = GetDlgItem(hDlg, IDC_CALENDAR_TYPE);
  828. int index;
  829. if ((index = ComboBox_GetCurSel(hCtrl)) == CB_ERR)
  830. {
  831. if (GetLocaleInfo( UserLocaleID,
  832. LOCALE_ICALENDARTYPE | LOCALE_NOUSEROVERRIDE,
  833. szBuf,
  834. SIZE_128))
  835. {
  836. CalId = Intl_StrToLong(szBuf);
  837. }
  838. else
  839. {
  840. return (FALSE);
  841. }
  842. }
  843. else
  844. {
  845. CalId = (CALID)ComboBox_GetItemData(hCtrl, index);
  846. }
  847. }
  848. if (!Date_SetTwoDigitYearMax(hDlg, CalId))
  849. {
  850. //
  851. // Make sure that the API failed due to a reason other than
  852. // the upper year two digit max is <= 99. This can easily
  853. // be checked by seeing if the control is enabled or not.
  854. //
  855. if (IsWindowEnabled(hwndYearHigh))
  856. {
  857. return (FALSE);
  858. }
  859. }
  860. }
  861. PropSheet_UnChanged(GetParent(hDlg), hDlg);
  862. lpPropSheet->lParam = DC_EverChg;
  863. //
  864. // Display the current sample that represents all of the locale settings.
  865. //
  866. if (bRedisplay)
  867. {
  868. Date_DisplaySample(hDlg);
  869. }
  870. //
  871. // Changes made in the second level.
  872. //
  873. if (Changes)
  874. {
  875. g_dwCustChange |= Process_Date;
  876. }
  877. //
  878. // Return success.
  879. //
  880. return (TRUE);
  881. }
  882. ////////////////////////////////////////////////////////////////////////////
  883. //
  884. // Date_ValidatePPS
  885. //
  886. // Validate each of the combo boxes whose values are constrained.
  887. // If any of the input fails, notify the user and then return FALSE
  888. // to indicate validation failure.
  889. //
  890. ////////////////////////////////////////////////////////////////////////////
  891. BOOL Date_ValidatePPS(
  892. HWND hDlg,
  893. LPARAM Changes)
  894. {
  895. //
  896. // If nothing has changed, return TRUE immediately.
  897. //
  898. if (Changes <= DC_EverChg)
  899. {
  900. return (TRUE);
  901. }
  902. //
  903. // If the date separator has changed, ensure that there are no digits
  904. // and no invalid characters contained in the new separator.
  905. //
  906. if (Changes & DC_SDate &&
  907. Item_Has_Digits_Or_Invalid_Chars( hDlg,
  908. IDC_SEPARATOR,
  909. FALSE,
  910. szInvalidSDate ))
  911. {
  912. No_Numerals_Error(hDlg, IDC_SEPARATOR, IDS_LOCALE_DATE_SEP);
  913. return (FALSE);
  914. }
  915. //
  916. // If the short date style has changed, ensure that there are only
  917. // characters in this set " dHhMmsty,-./:;\", the separator string,
  918. // and text enclosed in single quotes.
  919. //
  920. if (Changes & DC_ShortFmt)
  921. {
  922. if (NLSize_Style( hDlg,
  923. IDC_SHORT_DATE_STYLE,
  924. szNLS_ShortDate,
  925. LOCALE_SSHORTDATE ) ||
  926. Item_Check_Invalid_Chars( hDlg,
  927. szNLS_ShortDate,
  928. szSDateChars,
  929. IDC_SEPARATOR,
  930. FALSE,
  931. szSDCaseSwap,
  932. IDC_SHORT_DATE_STYLE ))
  933. {
  934. Invalid_Chars_Error(hDlg, IDC_SHORT_DATE_STYLE, IDS_LOCALE_SDATE);
  935. return (FALSE);
  936. }
  937. }
  938. //
  939. // If the long date style has changed, ensure that there are only
  940. // characters in this set " dgHhMmsty,-./:;\", the separator string,
  941. // and text enclosed in single quotes.
  942. //
  943. if (Changes & DC_LongFmt)
  944. {
  945. if (NLSize_Style( hDlg,
  946. IDC_LONG_DATE_STYLE,
  947. szNLS_LongDate,
  948. LOCALE_SLONGDATE ) ||
  949. Item_Check_Invalid_Chars( hDlg,
  950. szNLS_LongDate,
  951. szLDateChars,
  952. IDC_SEPARATOR,
  953. FALSE,
  954. szLDCaseSwap,
  955. IDC_LONG_DATE_STYLE ))
  956. {
  957. Invalid_Chars_Error(hDlg, IDC_LONG_DATE_STYLE, IDS_LOCALE_LDATE);
  958. return (FALSE);
  959. }
  960. }
  961. //
  962. // If the two digit year has changed, make sure the value is between
  963. // 99 and 9999 (if the window is still enabled).
  964. //
  965. if (Changes & DC_TwoDigitYearMax)
  966. {
  967. DWORD YearHigh;
  968. BOOL bSuccess;
  969. if (IsWindowEnabled(GetDlgItem(hDlg, IDC_TWO_DIGIT_YEAR_HIGH)))
  970. {
  971. YearHigh = GetDlgItemInt( hDlg,
  972. IDC_TWO_DIGIT_YEAR_HIGH,
  973. &bSuccess,
  974. FALSE );
  975. if ((!bSuccess) || (YearHigh < 99) || (YearHigh > 9999))
  976. {
  977. TCHAR szBuf[SIZE_128];
  978. LoadString(hInstance, IDS_LOCALE_YEAR_ERROR, szBuf, SIZE_128);
  979. MessageBox(hDlg, szBuf, NULL, MB_OK | MB_ICONINFORMATION);
  980. SetFocus(GetDlgItem(hDlg, IDC_TWO_DIGIT_YEAR_HIGH));
  981. return (FALSE);
  982. }
  983. }
  984. }
  985. //
  986. // Return success.
  987. //
  988. return (TRUE);
  989. }
  990. ////////////////////////////////////////////////////////////////////////////
  991. //
  992. // Date_InitializeHijriDateComboBox
  993. //
  994. // Initialize the HijriDate advance combo box.
  995. //
  996. ////////////////////////////////////////////////////////////////////////////
  997. void Date_InitializeHijriDateComboBox(
  998. HWND hDlg)
  999. {
  1000. HWND hHijriDate = GetDlgItem(hDlg, IDC_ADD_HIJRI_DATE);
  1001. HKEY hKey;
  1002. TCHAR szBuf[128];
  1003. TCHAR szCurrentValue[16]; // Max size ever needed should be 15 characters including the NULL
  1004. INT iIndex;
  1005. DWORD dwCtr, dwNumEntries, DataLen;
  1006. //
  1007. // Clear contents.
  1008. //
  1009. SendMessage( hHijriDate,
  1010. CB_RESETCONTENT,
  1011. 0L,
  1012. 0L);
  1013. if (RegOpenKeyEx( HKEY_CURRENT_USER,
  1014. c_szInternational,
  1015. 0,
  1016. KEY_READ | KEY_WRITE,
  1017. &hKey ) == ERROR_SUCCESS)
  1018. {
  1019. //
  1020. // Read the default/current value.
  1021. //
  1022. // Use the byte count, the API expects that even for Unicode strings
  1023. DataLen = sizeof(szCurrentValue);
  1024. if (RegQueryValueEx( hKey,
  1025. c_szAddHijriDate,
  1026. NULL,
  1027. NULL,
  1028. (LPBYTE)szCurrentValue,
  1029. &DataLen ) != ERROR_SUCCESS)
  1030. {
  1031. szCurrentValue[0] = TEXT('\0');
  1032. }
  1033. dwNumEntries = (ARRAYSIZE(c_szAddHijriDateValues));
  1034. for (dwCtr = 0; dwCtr < dwNumEntries; dwCtr++)
  1035. {
  1036. //
  1037. // Fill the combo box.
  1038. //
  1039. if (RegSetValueEx( hKey,
  1040. c_szAddHijriDateTemp,
  1041. 0,
  1042. REG_SZ,
  1043. (LPBYTE)c_szAddHijriDateValues[dwCtr],
  1044. (lstrlen(c_szAddHijriDateValues[dwCtr]) + 1) * sizeof(TCHAR)) == ERROR_SUCCESS)
  1045. {
  1046. //
  1047. // 0x80000000 is a private flag to make GetDateFormat read
  1048. // the HijriDate setting from the temp reg value.
  1049. //
  1050. if (GetDateFormat( MAKELCID(MAKELANGID(LANG_ARABIC,
  1051. SUBLANG_DEFAULT),
  1052. SORT_DEFAULT),
  1053. DATE_ADDHIJRIDATETEMP | DATE_LONGDATE |
  1054. DATE_RTLREADING,
  1055. NULL,
  1056. NULL,
  1057. szBuf,
  1058. ARRAYSIZE(szBuf)))
  1059. {
  1060. iIndex = (INT)SendMessage(hHijriDate, CB_ADDSTRING, 0L, (LPARAM)szBuf);
  1061. if (iIndex != CB_ERR)
  1062. {
  1063. SendMessage(hHijriDate, CB_SETITEMDATA, iIndex, (LPARAM)dwCtr);
  1064. if (!lstrcmp(szCurrentValue, c_szAddHijriDateValues[dwCtr]))
  1065. {
  1066. SendMessage(hHijriDate, CB_SETCURSEL, iIndex, 0L);
  1067. }
  1068. }
  1069. }
  1070. }
  1071. }
  1072. //
  1073. // Delete the value after we're done.
  1074. //
  1075. RegDeleteValue(hKey, c_szAddHijriDateTemp);
  1076. RegCloseKey(hKey);
  1077. }
  1078. }
  1079. ////////////////////////////////////////////////////////////////////////////
  1080. //
  1081. // Date_InitPropSheet
  1082. //
  1083. // The extra long value for the property sheet page is used as a set of
  1084. // state or change flags for each of the list boxes in the property sheet.
  1085. // Initialize this value to 0. Call Date_SetValues with the property
  1086. // sheet handle and the value TRUE (to indicate that the Positive Value
  1087. // button should also be initialized) to initialize all of the property
  1088. // sheet controls.
  1089. //
  1090. ////////////////////////////////////////////////////////////////////////////
  1091. void Date_InitPropSheet(
  1092. HWND hDlg,
  1093. LPARAM lParam)
  1094. {
  1095. //
  1096. // The lParam holds a pointer to the property sheet page, save it
  1097. // for later reference.
  1098. //
  1099. SetWindowLongPtr(hDlg, DWLP_USER, lParam);
  1100. //
  1101. // Set the values.
  1102. //
  1103. Date_SetValues(hDlg);
  1104. szNLS_ShortDate[0] = szNLS_LongDate[0] = 0;
  1105. ComboBox_LimitText(GetDlgItem(hDlg, IDC_SEPARATOR), MAX_SDATE);
  1106. ComboBox_LimitText(GetDlgItem(hDlg, IDC_SHORT_DATE_STYLE), MAX_FORMAT);
  1107. ComboBox_LimitText(GetDlgItem(hDlg, IDC_LONG_DATE_STYLE), MAX_FORMAT);
  1108. Edit_LimitText(GetDlgItem(hDlg, IDC_TWO_DIGIT_YEAR_LOW), MAX_YEAR);
  1109. Edit_LimitText(GetDlgItem(hDlg, IDC_TWO_DIGIT_YEAR_HIGH), MAX_YEAR);
  1110. //
  1111. // Set the Add Hijri Date combo box appropriately.
  1112. //
  1113. if (bShowArabic)
  1114. {
  1115. Date_InitializeHijriDateComboBox(hDlg);
  1116. }
  1117. //
  1118. // Make sure the Apply button is off.
  1119. //
  1120. PropSheet_UnChanged(GetParent(hDlg), hDlg);
  1121. if (lParam)
  1122. {
  1123. ((LPPROPSHEETPAGE)lParam)->lParam = DC_EverChg;
  1124. }
  1125. }
  1126. ////////////////////////////////////////////////////////////////////////////
  1127. //
  1128. // DateDlgProc
  1129. //
  1130. ////////////////////////////////////////////////////////////////////////////
  1131. INT_PTR CALLBACK DateDlgProc(
  1132. HWND hDlg,
  1133. UINT message,
  1134. WPARAM wParam,
  1135. LPARAM lParam)
  1136. {
  1137. NMHDR *lpnm;
  1138. LPPROPSHEETPAGE lpPropSheet = (LPPROPSHEETPAGE)(GetWindowLongPtr(hDlg, DWLP_USER));
  1139. DWORD dwIndex;
  1140. HWND hCtrl;
  1141. switch (message)
  1142. {
  1143. case ( WM_INITDIALOG ) :
  1144. {
  1145. Date_InitPropSheet(hDlg, lParam);
  1146. Date_SaveValues();
  1147. break;
  1148. }
  1149. case ( WM_DESTROY ) :
  1150. {
  1151. break;
  1152. }
  1153. case ( WM_HELP ) :
  1154. {
  1155. WinHelp( (HWND)((LPHELPINFO)lParam)->hItemHandle,
  1156. szHelpFile,
  1157. HELP_WM_HELP,
  1158. (DWORD_PTR)(LPTSTR)aDateHelpIds );
  1159. break;
  1160. }
  1161. case ( WM_CONTEXTMENU ) : // right mouse click
  1162. {
  1163. WinHelp( (HWND)wParam,
  1164. szHelpFile,
  1165. HELP_CONTEXTMENU,
  1166. (DWORD_PTR)(LPTSTR)aDateHelpIds );
  1167. break;
  1168. }
  1169. case ( WM_COMMAND ) :
  1170. {
  1171. if (!lpPropSheet)
  1172. {
  1173. break;
  1174. }
  1175. switch ( LOWORD(wParam) )
  1176. {
  1177. case ( IDC_SHORT_DATE_STYLE ) :
  1178. {
  1179. if (HIWORD(wParam) == CBN_SELCHANGE ||
  1180. HIWORD(wParam) == CBN_EDITCHANGE)
  1181. {
  1182. lpPropSheet->lParam |= DC_ShortFmt;
  1183. }
  1184. break;
  1185. }
  1186. case ( IDC_LONG_DATE_STYLE ) :
  1187. {
  1188. if (HIWORD(wParam) == CBN_SELCHANGE ||
  1189. HIWORD(wParam) == CBN_EDITCHANGE)
  1190. {
  1191. lpPropSheet->lParam |= DC_LongFmt;
  1192. }
  1193. break;
  1194. }
  1195. case ( IDC_SEPARATOR ) :
  1196. {
  1197. if (HIWORD(wParam) == CBN_SELCHANGE ||
  1198. HIWORD(wParam) == CBN_EDITCHANGE)
  1199. {
  1200. lpPropSheet->lParam |= DC_SDate;
  1201. }
  1202. break;
  1203. }
  1204. case ( IDC_CALENDAR_TYPE ) :
  1205. {
  1206. if (HIWORD(wParam) == CBN_SELCHANGE)
  1207. {
  1208. lpPropSheet->lParam |= DC_Calendar;
  1209. hCtrl = GetDlgItem(hDlg, IDC_CALENDAR_TYPE);
  1210. dwIndex = ComboBox_GetCurSel(hCtrl);
  1211. if (dwIndex != CB_ERR)
  1212. {
  1213. dwIndex = (DWORD)ComboBox_GetItemData(hCtrl, dwIndex);
  1214. Date_InitializeHijriDateComboBox(hDlg);
  1215. Date_EnableHijriComboBox(hDlg, (dwIndex == CAL_HIJRI) );
  1216. Date_GetTwoDigitYearRange(hDlg, (CALID)dwIndex);
  1217. }
  1218. Date_EnumerateDates(hDlg, CAL_SSHORTDATE);
  1219. Date_EnumerateDates(hDlg, CAL_SLONGDATE);
  1220. }
  1221. break;
  1222. }
  1223. case ( IDC_ADD_HIJRI_DATE ) :
  1224. {
  1225. if (HIWORD(wParam) == CBN_SELCHANGE)
  1226. {
  1227. lpPropSheet->lParam |= DC_Arabic_Calendar;
  1228. }
  1229. break;
  1230. }
  1231. case ( IDC_TWO_DIGIT_YEAR_HIGH ) :
  1232. {
  1233. if (GET_WM_COMMAND_CMD(wParam, lParam) == EN_CHANGE)
  1234. {
  1235. Date_ChangeYear(hDlg);
  1236. lpPropSheet->lParam |= DC_TwoDigitYearMax;
  1237. }
  1238. break;
  1239. }
  1240. }
  1241. //
  1242. // Turn on ApplyNow button.
  1243. //
  1244. if (lpPropSheet->lParam > DC_EverChg)
  1245. {
  1246. PropSheet_Changed(GetParent(hDlg), hDlg);
  1247. }
  1248. break;
  1249. }
  1250. case ( WM_NOTIFY ) :
  1251. {
  1252. lpnm = (NMHDR *)lParam;
  1253. switch (lpnm->code)
  1254. {
  1255. case ( PSN_SETACTIVE ) :
  1256. {
  1257. //
  1258. // If there has been a change in the regional Locale
  1259. // setting, clear all of the current info in the
  1260. // property sheet, get the new values, and update the
  1261. // appropriate registry values.
  1262. //
  1263. if (Verified_Regional_Chg & Process_Date)
  1264. {
  1265. Verified_Regional_Chg &= ~Process_Date;
  1266. Date_ClearValues(hDlg);
  1267. Date_SetValues(hDlg);
  1268. lpPropSheet->lParam = 0;
  1269. }
  1270. break;
  1271. }
  1272. case ( PSN_KILLACTIVE ) :
  1273. {
  1274. //
  1275. // Validate the entries on the property page.
  1276. //
  1277. SetWindowLongPtr( hDlg,
  1278. DWLP_MSGRESULT,
  1279. !Date_ValidatePPS( hDlg,
  1280. lpPropSheet->lParam ) );
  1281. break;
  1282. }
  1283. case ( PSN_APPLY ) :
  1284. {
  1285. //
  1286. // Apply the settings.
  1287. //
  1288. if (Date_ApplySettings(hDlg, TRUE))
  1289. {
  1290. SetWindowLongPtr(hDlg, DWLP_MSGRESULT, PSNRET_NOERROR);
  1291. //
  1292. // Zero out the DC_EverChg bit.
  1293. //
  1294. lpPropSheet->lParam = 0;
  1295. }
  1296. else
  1297. {
  1298. SetWindowLongPtr( hDlg,
  1299. DWLP_MSGRESULT,
  1300. PSNRET_INVALID_NOCHANGEPAGE );
  1301. }
  1302. break;
  1303. }
  1304. default :
  1305. {
  1306. return (FALSE);
  1307. }
  1308. }
  1309. break;
  1310. }
  1311. case ( WM_VSCROLL ) :
  1312. {
  1313. if ((GET_WM_VSCROLL_CODE(wParam, lParam) == SB_ENDSCROLL) &&
  1314. ((HWND)SendMessage( GET_WM_VSCROLL_HWND(wParam, lParam),
  1315. UDM_GETBUDDY,
  1316. 0,
  1317. 0L ) == GetDlgItem(hDlg, IDC_TWO_DIGIT_YEAR_HIGH)))
  1318. {
  1319. DWORD YearHigh;
  1320. //
  1321. // Get the high year.
  1322. //
  1323. YearHigh = (DWORD)SendDlgItemMessage( hDlg,
  1324. IDC_TWO_DIGIT_YEAR_ARROW,
  1325. UDM_GETPOS,
  1326. 0,
  1327. 0L );
  1328. //
  1329. // Set the low year based on the high year.
  1330. //
  1331. SetDlgItemInt( hDlg,
  1332. IDC_TWO_DIGIT_YEAR_LOW,
  1333. (UINT)(YearHigh - 99),
  1334. FALSE );
  1335. //
  1336. // Mark it as changed.
  1337. //
  1338. lpPropSheet->lParam |= DC_TwoDigitYearMax;
  1339. //
  1340. // Turn on ApplyNow button.
  1341. //
  1342. PropSheet_Changed(GetParent(hDlg), hDlg);
  1343. }
  1344. break;
  1345. }
  1346. default :
  1347. {
  1348. return (FALSE);
  1349. }
  1350. }
  1351. //
  1352. // Return success.
  1353. //
  1354. return (TRUE);
  1355. }