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.

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