|
|
/*++
Copyright (c) 1994-2000, Microsoft Corporation All rights reserved.
Module Name:
datedlg.c
Abstract:
This module implements the date property sheet for the Regional Options applet.
Revision History:
--*/
//
// Include Files.
//
#include "intl.h"
#include <windowsx.h>
#include <tchar.h>
#include <commctrl.h>
#include "intlhlp.h"
#include "maxvals.h"
#include "winnlsp.h"
#define STRSAFE_LIB
#include <strsafe.h>
//
// Context Help Ids.
//
static int aDateHelpIds[] = { IDC_GROUPBOX1, IDH_COMM_GROUPBOX, IDC_GROUPBOX2, IDH_COMM_GROUPBOX, IDC_GROUPBOX3, IDH_COMM_GROUPBOX, IDC_SAMPLE1, IDH_INTL_DATE_SHORTSAMPLE, IDC_SAMPLELBL1, IDH_INTL_DATE_SHORTSAMPLE, IDC_SAMPLE1A, IDH_INTL_DATE_SHORTSAMPLE_ARABIC, IDC_SAMPLELBL1A, IDH_INTL_DATE_SHORTSAMPLE_ARABIC, IDC_SHORT_DATE_STYLE, IDH_INTL_DATE_SHORTSTYLE, IDC_SEPARATOR, IDH_INTL_DATE_SEPARATOR, IDC_SAMPLE2, IDH_INTL_DATE_LONGSAMPLE, IDC_SAMPLELBL2, IDH_INTL_DATE_LONGSAMPLE, IDC_SAMPLE2A, IDH_INTL_DATE_LONGSAMPLE_ARABIC, IDC_SAMPLELBL2A, IDH_INTL_DATE_LONGSAMPLE_ARABIC, IDC_LONG_DATE_STYLE, IDH_INTL_DATE_LONGSTYLE, IDC_CALENDAR_TYPE_TEXT, IDH_INTL_DATE_CALENDARTYPE, IDC_CALENDAR_TYPE, IDH_INTL_DATE_CALENDARTYPE, IDC_TWO_DIGIT_YEAR_LOW, IDH_INTL_DATE_TWO_DIGIT_YEAR, IDC_TWO_DIGIT_YEAR_HIGH, IDH_INTL_DATE_TWO_DIGIT_YEAR, IDC_TWO_DIGIT_YEAR_ARROW, IDH_INTL_DATE_TWO_DIGIT_YEAR, IDC_ADD_HIJRI_DATE, IDH_INTL_DATE_ADD_HIJRI_DATE, IDC_ADD_HIJRI_DATE_TEXT, IDH_INTL_DATE_ADD_HIJRI_DATE,
0, 0 };
//
// Global Variables.
//
TCHAR szNLS_LongDate[SIZE_128]; TCHAR szNLS_ShortDate[SIZE_128];
static TCHAR sz_iCalendarType[MAX_ICALTYPE + 1]; static TCHAR sz_sDate[MAX_SDATE + 1]; static TCHAR sz_sLongDate[MAX_SLONGDATE + 1]; static TCHAR sz_sShortDate[MAX_FORMAT + 1];
static const TCHAR c_szInternational[] = TEXT("Control Panel\\International"); static const TCHAR c_szAddHijriDate[] = TEXT("AddHijriDate"); static const TCHAR c_szAddHijriDateTemp[] = TEXT("AddHijriDateTemp"); static const PTSTR c_szAddHijriDateValues[] = { TEXT("AddHijriDate-2"), TEXT("AddHijriDate"), TEXT(""), TEXT("AddHijriDate+1"), TEXT("AddHijriDate+2") };
static const TCHAR c_szTwoDigitYearKey[] = TEXT("Software\\Policies\\Microsoft\\Control Panel\\International\\Calendars\\TwoDigitYearMax");
//
// Function Prototypes.
//
void Date_InitializeHijriDateComboBox( HWND hDlg);
////////////////////////////////////////////////////////////////////////////
//
// Date_EnumerateDates
//
// Enumerates the appropriate dates for the chosen calendar.
//
////////////////////////////////////////////////////////////////////////////
void Date_EnumerateDates( HWND hDlg, DWORD dwDateFlag) { DWORD dwLocaleFlag; int nItemId; DWORD dwIndex; DWORD dwCalNum = 0; TCHAR szBuf[SIZE_128]; HWND hCtrlDate; HWND hCtrlCal = GetDlgItem(hDlg, IDC_CALENDAR_TYPE);
//
// Initialize variables according to the dwDateFlag parameter.
//
if (dwDateFlag == CAL_SSHORTDATE) { dwLocaleFlag = LOCALE_SSHORTDATE; nItemId = IDC_SHORT_DATE_STYLE; } else // CAL_SLONGDATE
{ dwLocaleFlag = LOCALE_SLONGDATE; nItemId = IDC_LONG_DATE_STYLE; } hCtrlDate = GetDlgItem(hDlg, nItemId);
//
// Initialize to reset the contents for the appropriate combo box.
//
if (!Set_List_Values(hDlg, nItemId, 0)) { return; }
//
// Reset the contents of the combo box.
//
ComboBox_ResetContent(hCtrlDate);
//
// Get the currently selected calendar id.
//
dwIndex = ComboBox_GetCurSel(hCtrlCal); if (dwIndex != CB_ERR) { dwCalNum = (DWORD)ComboBox_GetItemData(hCtrlCal, dwIndex); }
//
// Enumerate the dates for the currently selected calendar.
//
EnumCalendarInfo(EnumProc, UserLocaleID, dwCalNum, dwDateFlag); dwIndex = ComboBox_GetCount(hCtrlCal); if ((dwIndex == 0) || (dwIndex == CB_ERR)) { EnumCalendarInfo(EnumProc, UserLocaleID, CAL_GREGORIAN, dwDateFlag); }
//
// Add (if necesary) and select the current user setting in the
// combo box.
//
dwIndex = 0; if (GetLocaleInfo(UserLocaleID, dwLocaleFlag, szBuf, SIZE_128)) { if ((dwIndex = ComboBox_FindStringExact(hCtrlDate, -1, szBuf)) == CB_ERR) { //
// Need to add this entry to the combo box.
//
Set_List_Values(0, 0, szBuf); if ((dwIndex = ComboBox_FindStringExact(hCtrlDate, -1, szBuf)) == CB_ERR) { dwIndex = 0; } } } else { MessageBox(hDlg, szLocaleGetError, NULL, MB_OK | MB_ICONINFORMATION); } Set_List_Values(0, nItemId, 0);
Localize_Combobox_Styles(hDlg, nItemId, dwLocaleFlag); ComboBox_SetCurSel(hCtrlDate, dwIndex); }
////////////////////////////////////////////////////////////////////////////
//
// Date_GetTwoDigitYearRangeFromPolicy
//
// Read the two digit year from the Policy registry.
//
////////////////////////////////////////////////////////////////////////////
BOOL Date_GetTwoDigitYearRangeFromPolicy( CALID CalId) { HKEY hKey; BYTE buf[MAX_PATH]; TCHAR szCalId[MAX_PATH]; DWORD dwResultLen = sizeof(buf), dwType; BOOL bRet = FALSE;
//
// Convert CalendarId to a string.
//
//wsprintf(szCalId, TEXT("%d"), CalId);
if(FAILED(StringCchPrintf(szCalId, ARRAYSIZE(szCalId), TEXT("%d"), CalId))) { return(FALSE); }
if (RegOpenKey( HKEY_CURRENT_USER, c_szTwoDigitYearKey, &hKey ) == ERROR_SUCCESS) { if ((RegQueryValueEx( hKey, szCalId, NULL, &dwType, &buf[0], &dwResultLen ) == ERROR_SUCCESS) && (dwType == REG_SZ) && (dwResultLen > 2)) { bRet = TRUE; }
RegCloseKey(hKey); }
//
// Return the result.
//
return (bRet); }
////////////////////////////////////////////////////////////////////////////
//
// Date_GetTwoDigitYearRange
//
// Fills in the two digit year range controls.
//
////////////////////////////////////////////////////////////////////////////
void Date_GetTwoDigitYearRange( HWND hDlg, CALID CalId) { HWND hwndYearHigh = GetDlgItem(hDlg, IDC_TWO_DIGIT_YEAR_HIGH); HWND hwndScroll = GetDlgItem(hDlg, IDC_TWO_DIGIT_YEAR_ARROW); DWORD YearHigh, YearHighDefault;
//
// Enable the high range control.
//
EnableWindow(hwndYearHigh, TRUE); EnableWindow(hwndScroll, TRUE);
//
// Get the default two digit year upper boundary.
//
if (!GetCalendarInfo( LOCALE_USER_DEFAULT, CalId, CAL_ITWODIGITYEARMAX | CAL_RETURN_NUMBER | CAL_NOUSEROVERRIDE, NULL, 0, &YearHighDefault )) { YearHighDefault = 0; }
//
// Disable the two digit year upper boundary control if it is
// enforced by a policy or if the default value is 99 or less.
//
if ((Date_GetTwoDigitYearRangeFromPolicy(CalId)) || (YearHighDefault <= 99)) { //
// Disable the two digit year max controls.
//
EnableWindow(hwndScroll, FALSE); EnableWindow(hwndYearHigh, FALSE); }
//
// Get the two digit year upper boundary. If the default is less
// than or equal to 99, then use the default value and ignore the
// registry. This is done for calendars like the Japanese Era
// calendar where it doesn't make sense to have a sliding window.
//
if (YearHighDefault <= 99) { YearHigh = YearHighDefault; } else if (!GetCalendarInfo( LOCALE_USER_DEFAULT, CalId, CAL_ITWODIGITYEARMAX | CAL_RETURN_NUMBER, NULL, 0, &YearHigh ) || (YearHigh < 99) || (YearHigh > 9999)) { YearHigh = (YearHighDefault >= 99) ? YearHighDefault : 2029; }
//
// Set the range on the controls.
//
SendMessage(hwndScroll, UDM_SETRANGE, 0, MAKELPARAM(9999, 99)); SendMessage(hwndScroll, UDM_SETBUDDY, (WPARAM)hwndYearHigh, 0L);
//
// Set the values of the controls.
//
SetDlgItemInt(hDlg, IDC_TWO_DIGIT_YEAR_LOW, (UINT)(YearHigh - 99), FALSE); SendMessage(hwndScroll, UDM_SETPOS, 0, MAKELONG((short)YearHigh, 0)); }
////////////////////////////////////////////////////////////////////////////
//
// Date_SetTwoDigitYearMax
//
// Sets the two digit year max value in the registry.
//
////////////////////////////////////////////////////////////////////////////
BOOL Date_SetTwoDigitYearMax( HWND hDlg, CALID CalId) { TCHAR szYear[SIZE_64];
//
// Get the max year.
//
szYear[0] = 0; if (GetWindowText( GetDlgItem(hDlg, IDC_TWO_DIGIT_YEAR_HIGH), szYear, SIZE_64 ) != 0) { //
// Set the two digit year upper boundary.
//
return (SetCalendarInfo( LOCALE_USER_DEFAULT, CalId, CAL_ITWODIGITYEARMAX, szYear )); }
//
// Return success.
//
return (TRUE); }
////////////////////////////////////////////////////////////////////////////
//
// Date_ChangeYear
//
// Changes the lower bound based on the upper bound value.
//
////////////////////////////////////////////////////////////////////////////
void Date_ChangeYear( HWND hDlg) { DWORD YearHigh; BOOL bSuccess;
//
// Get the two digit year upper boundary.
//
YearHigh = GetDlgItemInt(hDlg, IDC_TWO_DIGIT_YEAR_HIGH, &bSuccess, FALSE);
if ((!bSuccess) || (YearHigh < 99) || (YearHigh > 9999)) { //
// Invalid value, so set the lower control to 0.
//
SetDlgItemInt(hDlg, IDC_TWO_DIGIT_YEAR_LOW, 0, FALSE); } else { //
// Set the value of the lower control.
//
SetDlgItemInt(hDlg, IDC_TWO_DIGIT_YEAR_LOW, (UINT)(YearHigh - 99), FALSE); } }
////////////////////////////////////////////////////////////////////////////
//
// Date_DisplaySample
//
// Updates the date samples. It formats the date based on the user's
// current locale settings.
//
////////////////////////////////////////////////////////////////////////////
void Date_DisplaySample( HWND hDlg) { TCHAR szBuf[MAX_SAMPLE_SIZE]; BOOL bNoError = TRUE;
if (!bShowArabic) { // If user locale is not Arabic, make sure that the control for date samples are:
// * LTR reading orders for non-Hebrew locales
// * RTL reading orders for Hebrew locales.
SetControlReadingOrder(bHebrewUI, GetDlgItem(hDlg, IDC_SAMPLE1)); SetControlReadingOrder(bHebrewUI, GetDlgItem(hDlg, IDC_SAMPLE2)); }
// In Hebrew locale, we want to format the short date for left-to-right reading order.
// If we make it right-to-left reading order, the Gregorian short date will display
// in a complete different display order.
// The left-to-right reading order won't affect the Hebrew short date display.
if (GetDateFormat( UserLocaleID, (bHebrewUI ? DATE_LTRREADING : (bShowRtL ? DATE_LTRREADING : 0)) | DATE_SHORTDATE, NULL, NULL, szBuf, MAX_SAMPLE_SIZE )) { SetDlgItemText(hDlg, IDC_SAMPLE1, szBuf); } else { MessageBox(hDlg, szLocaleGetError, NULL, MB_OK | MB_ICONINFORMATION); bNoError = FALSE; }
//
// Show or hide the Arabic info based on the current user locale id.
//
ShowWindow(GetDlgItem(hDlg, IDC_SAMPLELBL1A), bShowArabic ? SW_SHOW : SW_HIDE); ShowWindow(GetDlgItem(hDlg, IDC_SAMPLE1A), bShowArabic ? SW_SHOW : SW_HIDE); if (bShowArabic) { if (GetDateFormat( UserLocaleID, DATE_RTLREADING | DATE_SHORTDATE, NULL, NULL, szBuf, MAX_SAMPLE_SIZE )) { SetDlgItemText(hDlg, IDC_SAMPLE1A, szBuf); SetDlgItemRTL(hDlg, IDC_SAMPLE1A); } else { MessageBox(hDlg, szLocaleGetError, NULL, MB_OK | MB_ICONINFORMATION); bNoError = FALSE; } }
if (GetDateFormat( UserLocaleID, (bHebrewUI ? DATE_RTLREADING : (bShowRtL ? DATE_LTRREADING : 0)) | DATE_LONGDATE, NULL, NULL, szBuf, MAX_SAMPLE_SIZE )) { SetDlgItemText(hDlg, IDC_SAMPLE2, szBuf); } else if (bNoError) { MessageBox(hDlg, szLocaleGetError, NULL, MB_OK | MB_ICONINFORMATION); }
//
// Show or hide the Right to left info based on the current user locale id.
//
ShowWindow(GetDlgItem(hDlg, IDC_SAMPLELBL2A), bShowArabic ? SW_SHOW : SW_HIDE); ShowWindow(GetDlgItem(hDlg, IDC_SAMPLE2A), bShowArabic ? SW_SHOW : SW_HIDE); if (bShowArabic) { if (GetDateFormat( UserLocaleID, DATE_RTLREADING | DATE_LONGDATE, NULL, NULL, szBuf, MAX_SAMPLE_SIZE )) { SetDlgItemText(hDlg, IDC_SAMPLE2A, szBuf); SetDlgItemRTL(hDlg, IDC_SAMPLE2A); } else if (bNoError) { MessageBox(hDlg, szLocaleGetError, NULL, MB_OK | MB_ICONINFORMATION); } } }
////////////////////////////////////////////////////////////////////////////
//
// Date_ClearValues
//
// Reset each of the list boxes in the date property sheet page.
//
////////////////////////////////////////////////////////////////////////////
void Date_ClearValues( HWND hDlg) { ComboBox_ResetContent(GetDlgItem(hDlg, IDC_SHORT_DATE_STYLE)); ComboBox_ResetContent(GetDlgItem(hDlg, IDC_LONG_DATE_STYLE)); ComboBox_ResetContent(GetDlgItem(hDlg, IDC_SEPARATOR)); ComboBox_ResetContent(GetDlgItem(hDlg, IDC_CALENDAR_TYPE)); ComboBox_ResetContent(GetDlgItem(hDlg, IDC_TWO_DIGIT_YEAR_LOW)); ComboBox_ResetContent(GetDlgItem(hDlg, IDC_TWO_DIGIT_YEAR_HIGH)); }
////////////////////////////////////////////////////////////////////////////
//
// Date_EnableHijriComboBox
//
// Enables/Disables Show/Hides the Hijri date advance combo where necessary
//
////////////////////////////////////////////////////////////////////////////
void Date_EnableHijriComboBox( HWND hDlg, BOOL Status) { HWND hAddHijriDateCB = GetDlgItem(hDlg, IDC_ADD_HIJRI_DATE); HWND hAddHijriDateText = GetDlgItem(hDlg, IDC_ADD_HIJRI_DATE_TEXT); INT iCount;
//
// If the combo box is empty, then disable it.
//
iCount = (INT)SendMessage(hAddHijriDateCB, CB_GETCOUNT, 0L, 0L); if ((iCount == CB_ERR) || (iCount <= 0L)) { Status = FALSE; }
EnableWindow(hAddHijriDateCB, Status); ShowWindow(hAddHijriDateCB, Status ? SW_SHOW : SW_HIDE );
EnableWindow(hAddHijriDateText, Status); ShowWindow(hAddHijriDateText, Status ? SW_SHOW : SW_HIDE); }
////////////////////////////////////////////////////////////////////////////
//
// Date_SaveValues
//
// Save values in the case that we need to restore them.
//
////////////////////////////////////////////////////////////////////////////
void Date_SaveValues() { //
// Save registry values.
//
if (!GetLocaleInfo( UserLocaleID, LOCALE_ICALENDARTYPE, sz_iCalendarType, MAX_ICALTYPE + 1 )) { //_tcscpy(sz_iCalendarType, TEXT("1"));
if(FAILED(StringCchCopy(sz_iCalendarType, MAX_ICALTYPE+1, TEXT("1")))) { // This should be impossible, but we need to avoid PREfast complaints.
} } if (!GetLocaleInfo( UserLocaleID, LOCALE_SDATE, sz_sDate, MAX_SDATE + 1 )) { //_tcscpy(sz_sDate, TEXT("/"));
if(FAILED(StringCchCopy(sz_sDate, MAX_SDATE+1, TEXT("/")))) { // This should be impossible, but we need to avoid PREfast complaints.
} } if (!GetLocaleInfo( UserLocaleID, LOCALE_SLONGDATE, sz_sLongDate, MAX_SLONGDATE + 1 )) { //_tcscpy(sz_sLongDate, TEXT("dddd, MMMM dd, yyyy"));
if(FAILED(StringCchCopy(sz_sLongDate, MAX_SLONGDATE+1, TEXT("dddd, MMMM dd, yyyy")))) { // This should be impossible, but we need to avoid PREfast complaints.
} } if (!GetLocaleInfo( UserLocaleID, LOCALE_SSHORTDATE, sz_sShortDate, MAX_SSHORTDATE + 1 )) { //_tcscpy(sz_sShortDate, TEXT("M/d/yyyy"));
if(FAILED(StringCchCopy(sz_sShortDate, MAX_SSHORTDATE+1, TEXT("M/d/yyyy")))) { // This should be impossible, but we need to avoid PREfast complaints.
} } }
////////////////////////////////////////////////////////////////////////////
//
// Date_RestoreValues
//
////////////////////////////////////////////////////////////////////////////
void Date_RestoreValues() { if (g_dwCustChange & Process_Date) { SetLocaleInfo(UserLocaleID, LOCALE_ICALENDARTYPE, sz_iCalendarType); SetLocaleInfo(UserLocaleID, LOCALE_SDATE, sz_sDate); SetLocaleInfo(UserLocaleID, LOCALE_SLONGDATE, sz_sLongDate); SetLocaleInfo(UserLocaleID, LOCALE_SSHORTDATE, sz_sShortDate); } }
////////////////////////////////////////////////////////////////////////////
//
// Date_SetValues
//
// Initialize all of the controls in the date property sheet page.
//
////////////////////////////////////////////////////////////////////////////
void Date_SetValues( HWND hDlg) { TCHAR szBuf[SIZE_128]; int i, nItem; HWND hCtrl; LONG CalId;
//
// Initialize the dropdown box for the current locale setting for the
// date separator.
//
DropDown_Use_Locale_Values(hDlg, LOCALE_SDATE, IDC_SEPARATOR);
//
// Initialize and Lock function. If it succeeds, call enum function to
// enumerate all possible values for the list box via a call to EnumProc.
// EnumProc will call Set_List_Values for each of the string values it
// receives. When the enumeration of values is complete, call
// Set_List_Values to clear the dialog item specific data and to clear
// the lock on the function. Perform this set of operations for:
// Calendar Type, Short Date Sytle, and Long Date Style.
//
if (Set_List_Values(hDlg, IDC_CALENDAR_TYPE, 0)) { hCtrl = GetDlgItem(hDlg, IDC_CALENDAR_TYPE); EnumCalendarInfo(EnumProc, UserLocaleID, ENUM_ALL_CALENDARS, CAL_SCALNAME); Set_List_Values(0, IDC_CALENDAR_TYPE, 0); EnumCalendarInfo(EnumProc, UserLocaleID, ENUM_ALL_CALENDARS, CAL_ICALINTVALUE); Set_List_Values(0, IDC_CALENDAR_TYPE, 0); if (GetLocaleInfo(UserLocaleID, LOCALE_ICALENDARTYPE, szBuf, SIZE_128)) { TCHAR szBufTmp[SIZE_128] = {0}; int iTmp = 0; LONG CalIdTmp;
if( GetLocaleInfo( UserLocaleID, LOCALE_ICALENDARTYPE | LOCALE_NOUSEROVERRIDE, szBufTmp, SIZE_128)) { //
// Convert the id to a number.
//
CalId = Intl_StrToLong(szBuf); CalIdTmp = Intl_StrToLong(szBufTmp);
//
// Search for calendars
//
nItem = ComboBox_GetCount(hCtrl); for (i = 0; i < nItem; i++) { if (ComboBox_GetItemData(hCtrl, i) == CalId) { break; }
if (ComboBox_GetItemData(hCtrl, i) == CalIdTmp) { iTmp = i; } }
//
// Look if we find something.
//
if (i < nItem) { ComboBox_SetCurSel(hCtrl, i); } else { CalId = CalIdTmp; ComboBox_SetCurSel(hCtrl, iTmp); // Zero or something else.
}
//
// Enable/disable the Add Hijri date check box.
//
Date_InitializeHijriDateComboBox(hDlg); Date_EnableHijriComboBox(hDlg, (CalId == CAL_HIJRI));
//
// Set the two digit year range.
//
Date_GetTwoDigitYearRange(hDlg, (CALID)CalId);
//
// Subtract 1 from calendar value because calendars are one
// based, not zero based like all other locale values.
//
} } else { MessageBox(hDlg, szLocaleGetError, NULL, MB_OK | MB_ICONINFORMATION); }
//
// If more than one selection, enable dropdown box.
// Otherwise, disable it.
//
if (ComboBox_GetCount(hCtrl) > 1) { EnableWindow(GetDlgItem(hDlg, IDC_CALENDAR_TYPE_TEXT), TRUE); EnableWindow(GetDlgItem(hDlg, IDC_CALENDAR_TYPE), TRUE); ShowWindow(GetDlgItem(hDlg, IDC_CALENDAR_TYPE_TEXT), SW_SHOW); ShowWindow(GetDlgItem(hDlg, IDC_CALENDAR_TYPE), SW_SHOW); } else { EnableWindow(GetDlgItem(hDlg, IDC_CALENDAR_TYPE_TEXT), FALSE); EnableWindow(GetDlgItem(hDlg, IDC_CALENDAR_TYPE), FALSE); ShowWindow(GetDlgItem(hDlg, IDC_CALENDAR_TYPE_TEXT), SW_HIDE); ShowWindow(GetDlgItem(hDlg, IDC_CALENDAR_TYPE), SW_HIDE); } } Date_EnumerateDates(hDlg, CAL_SSHORTDATE); Date_EnumerateDates(hDlg, CAL_SLONGDATE);
//
// Display the current sample that represents all of the locale settings.
//
Date_DisplaySample(hDlg); }
////////////////////////////////////////////////////////////////////////////
//
// Date_SetHijriDate
//
// Saves the Hijri date advance amount to the registry.
//
////////////////////////////////////////////////////////////////////////////
void Date_SetHijriDate( HWND hHijriComboBox) { HKEY hKey; INT iIndex;
//
// Get the string index to set.
//
iIndex = (INT)SendMessage(hHijriComboBox, CB_GETCURSEL, 0L, 0L);
if (iIndex == CB_ERR) { return; }
iIndex = (INT)SendMessage(hHijriComboBox, CB_GETITEMDATA, (WPARAM)iIndex, 0L); if (iIndex != CB_ERR) { if (RegOpenKeyEx( HKEY_CURRENT_USER, c_szInternational, 0, KEY_READ | KEY_WRITE, &hKey ) == ERROR_SUCCESS) { RegSetValueEx( hKey, c_szAddHijriDate, 0, REG_SZ, (LPBYTE)c_szAddHijriDateValues[iIndex], (lstrlen(c_szAddHijriDateValues[iIndex]) + 1) * sizeof(TCHAR) );
RegCloseKey(hKey); } } }
////////////////////////////////////////////////////////////////////////////
//
// Date_ApplySettings
//
// For every control that has changed (that affects the Locale settings),
// call Set_Locale_Values to update the user locale information. Notify
// the parent of changes and reset the change flag stored in the property
// sheet page structure appropriately. Redisplay the date sample if
// bRedisplay is TRUE.
//
////////////////////////////////////////////////////////////////////////////
BOOL Date_ApplySettings( HWND hDlg, BOOL bRedisplay) { TCHAR szBuf[SIZE_128]; CALID CalId = 0; LPPROPSHEETPAGE lpPropSheet = (LPPROPSHEETPAGE)(GetWindowLongPtr(hDlg, DWLP_USER)); LPARAM Changes = lpPropSheet->lParam; HWND hwndYearHigh = GetDlgItem(hDlg, IDC_TWO_DIGIT_YEAR_HIGH);
if (Changes & DC_ShortFmt) { //
// szNLS_ShortDate is set in Date_ValidatePPS.
//
if (!Set_Locale_Values( hDlg, LOCALE_SSHORTDATE, IDC_SHORT_DATE_STYLE, TEXT("sShortDate"), FALSE, 0, 0, szNLS_ShortDate )) { return (FALSE); }
//
// If the date separator field has also been changed by the user,
// then don't update now. It will be updated below.
//
if (!(Changes & DC_SDate)) { //
// Since the short date style changed, reset date separator
// list box.
//
ComboBox_ResetContent(GetDlgItem(hDlg, IDC_SEPARATOR)); DropDown_Use_Locale_Values(hDlg, LOCALE_SDATE, IDC_SEPARATOR); if (!Set_Locale_Values( hDlg, LOCALE_SDATE, IDC_SEPARATOR, TEXT("sDate"), FALSE, 0, 0, NULL )) { return (FALSE); } } } if (Changes & DC_LongFmt) { //
// szNLS_LongDate is set in Date_ValidatePPS.
//
if (!Set_Locale_Values( hDlg, LOCALE_SLONGDATE, IDC_LONG_DATE_STYLE, TEXT("sLongDate"), FALSE, 0, 0, szNLS_LongDate )) { return (FALSE); } } if (Changes & DC_SDate) { if (!Set_Locale_Values( hDlg, LOCALE_SDATE, IDC_SEPARATOR, TEXT("sDate"), FALSE, 0, 0, NULL )) { return (FALSE); }
//
// Since the date separator changed, reset the short date style
// list box.
//
Date_EnumerateDates(hDlg, CAL_SSHORTDATE); } if (Changes & DC_Calendar) { if (!Set_Locale_Values( hDlg, LOCALE_ICALENDARTYPE, IDC_CALENDAR_TYPE, 0, TRUE, 1, 0, NULL )) { return (FALSE); }
if (GetLocaleInfo(UserLocaleID, LOCALE_ICALENDARTYPE, szBuf, SIZE_128)) { CalId = Intl_StrToLong(szBuf); Date_InitializeHijriDateComboBox(hDlg); Date_EnableHijriComboBox(hDlg, (CalId == CAL_HIJRI)); } }
if (Changes & DC_Arabic_Calendar) { Date_SetHijriDate( GetDlgItem(hDlg, IDC_ADD_HIJRI_DATE) ); }
if (Changes & DC_TwoDigitYearMax) { if (CalId == 0) { HWND hCtrl = GetDlgItem(hDlg, IDC_CALENDAR_TYPE); int index;
if ((index = ComboBox_GetCurSel(hCtrl)) == CB_ERR) { if (GetLocaleInfo( UserLocaleID, LOCALE_ICALENDARTYPE | LOCALE_NOUSEROVERRIDE, szBuf, SIZE_128)) { CalId = Intl_StrToLong(szBuf); } else { return (FALSE); } } else { CalId = (CALID)ComboBox_GetItemData(hCtrl, index); } } if (!Date_SetTwoDigitYearMax(hDlg, CalId)) { //
// Make sure that the API failed due to a reason other than
// the upper year two digit max is <= 99. This can easily
// be checked by seeing if the control is enabled or not.
//
if (IsWindowEnabled(hwndYearHigh)) { return (FALSE); } } }
PropSheet_UnChanged(GetParent(hDlg), hDlg); lpPropSheet->lParam = DC_EverChg;
//
// Display the current sample that represents all of the locale settings.
//
if (bRedisplay) { Date_DisplaySample(hDlg); }
//
// Changes made in the second level.
//
if (Changes) { g_dwCustChange |= Process_Date; }
//
// Return success.
//
return (TRUE); }
////////////////////////////////////////////////////////////////////////////
//
// Date_ValidatePPS
//
// Validate each of the combo boxes whose values are constrained.
// If any of the input fails, notify the user and then return FALSE
// to indicate validation failure.
//
////////////////////////////////////////////////////////////////////////////
BOOL Date_ValidatePPS( HWND hDlg, LPARAM Changes) { //
// If nothing has changed, return TRUE immediately.
//
if (Changes <= DC_EverChg) { return (TRUE); }
//
// If the date separator has changed, ensure that there are no digits
// and no invalid characters contained in the new separator.
//
if (Changes & DC_SDate && Item_Has_Digits_Or_Invalid_Chars( hDlg, IDC_SEPARATOR, FALSE, szInvalidSDate )) { No_Numerals_Error(hDlg, IDC_SEPARATOR, IDS_LOCALE_DATE_SEP); return (FALSE); }
//
// If the short date style has changed, ensure that there are only
// characters in this set " dHhMmsty,-./:;\", the separator string,
// and text enclosed in single quotes.
//
if (Changes & DC_ShortFmt) { if (NLSize_Style( hDlg, IDC_SHORT_DATE_STYLE, szNLS_ShortDate, LOCALE_SSHORTDATE ) || Item_Check_Invalid_Chars( hDlg, szNLS_ShortDate, szSDateChars, IDC_SEPARATOR, FALSE, szSDCaseSwap, IDC_SHORT_DATE_STYLE )) { Invalid_Chars_Error(hDlg, IDC_SHORT_DATE_STYLE, IDS_LOCALE_SDATE); return (FALSE); } }
//
// If the long date style has changed, ensure that there are only
// characters in this set " dgHhMmsty,-./:;\", the separator string,
// and text enclosed in single quotes.
//
if (Changes & DC_LongFmt) { if (NLSize_Style( hDlg, IDC_LONG_DATE_STYLE, szNLS_LongDate, LOCALE_SLONGDATE ) || Item_Check_Invalid_Chars( hDlg, szNLS_LongDate, szLDateChars, IDC_SEPARATOR, FALSE, szLDCaseSwap, IDC_LONG_DATE_STYLE )) { Invalid_Chars_Error(hDlg, IDC_LONG_DATE_STYLE, IDS_LOCALE_LDATE); return (FALSE); } }
//
// If the two digit year has changed, make sure the value is between
// 99 and 9999 (if the window is still enabled).
//
if (Changes & DC_TwoDigitYearMax) { DWORD YearHigh; BOOL bSuccess;
if (IsWindowEnabled(GetDlgItem(hDlg, IDC_TWO_DIGIT_YEAR_HIGH))) { YearHigh = GetDlgItemInt( hDlg, IDC_TWO_DIGIT_YEAR_HIGH, &bSuccess, FALSE );
if ((!bSuccess) || (YearHigh < 99) || (YearHigh > 9999)) { TCHAR szBuf[SIZE_128];
LoadString(hInstance, IDS_LOCALE_YEAR_ERROR, szBuf, SIZE_128); MessageBox(hDlg, szBuf, NULL, MB_OK | MB_ICONINFORMATION); SetFocus(GetDlgItem(hDlg, IDC_TWO_DIGIT_YEAR_HIGH)); return (FALSE); } } }
//
// Return success.
//
return (TRUE); }
////////////////////////////////////////////////////////////////////////////
//
// Date_InitializeHijriDateComboBox
//
// Initialize the HijriDate advance combo box.
//
////////////////////////////////////////////////////////////////////////////
void Date_InitializeHijriDateComboBox( HWND hDlg) { HWND hHijriDate = GetDlgItem(hDlg, IDC_ADD_HIJRI_DATE); HKEY hKey; TCHAR szBuf[128]; TCHAR szCurrentValue[16]; // Max size ever needed should be 15 characters including the NULL
INT iIndex; DWORD dwCtr, dwNumEntries, DataLen;
//
// Clear contents.
//
SendMessage( hHijriDate, CB_RESETCONTENT, 0L, 0L);
if (RegOpenKeyEx( HKEY_CURRENT_USER, c_szInternational, 0, KEY_READ | KEY_WRITE, &hKey ) == ERROR_SUCCESS) { //
// Read the default/current value.
//
// Use the byte count, the API expects that even for Unicode strings
DataLen = sizeof(szCurrentValue);
if (RegQueryValueEx( hKey, c_szAddHijriDate, NULL, NULL, (LPBYTE)szCurrentValue, &DataLen ) != ERROR_SUCCESS) { szCurrentValue[0] = TEXT('\0'); }
dwNumEntries = (ARRAYSIZE(c_szAddHijriDateValues)); for (dwCtr = 0; dwCtr < dwNumEntries; dwCtr++) { //
// Fill the combo box.
//
if (RegSetValueEx( hKey, c_szAddHijriDateTemp, 0, REG_SZ, (LPBYTE)c_szAddHijriDateValues[dwCtr], (lstrlen(c_szAddHijriDateValues[dwCtr]) + 1) * sizeof(TCHAR)) == ERROR_SUCCESS) { //
// 0x80000000 is a private flag to make GetDateFormat read
// the HijriDate setting from the temp reg value.
//
if (GetDateFormat( MAKELCID(MAKELANGID(LANG_ARABIC, SUBLANG_DEFAULT), SORT_DEFAULT), DATE_ADDHIJRIDATETEMP | DATE_LONGDATE | DATE_RTLREADING, NULL, NULL, szBuf, ARRAYSIZE(szBuf))) { iIndex = (INT)SendMessage(hHijriDate, CB_ADDSTRING, 0L, (LPARAM)szBuf); if (iIndex != CB_ERR) { SendMessage(hHijriDate, CB_SETITEMDATA, iIndex, (LPARAM)dwCtr);
if (!lstrcmp(szCurrentValue, c_szAddHijriDateValues[dwCtr])) { SendMessage(hHijriDate, CB_SETCURSEL, iIndex, 0L); } } } } }
//
// Delete the value after we're done.
//
RegDeleteValue(hKey, c_szAddHijriDateTemp);
RegCloseKey(hKey); } }
////////////////////////////////////////////////////////////////////////////
//
// Date_InitPropSheet
//
// The extra long value for the property sheet page is used as a set of
// state or change flags for each of the list boxes in the property sheet.
// Initialize this value to 0. Call Date_SetValues with the property
// sheet handle and the value TRUE (to indicate that the Positive Value
// button should also be initialized) to initialize all of the property
// sheet controls.
//
////////////////////////////////////////////////////////////////////////////
void Date_InitPropSheet( HWND hDlg, LPARAM lParam) { //
// The lParam holds a pointer to the property sheet page, save it
// for later reference.
//
SetWindowLongPtr(hDlg, DWLP_USER, lParam);
//
// Set the values.
//
Date_SetValues(hDlg); szNLS_ShortDate[0] = szNLS_LongDate[0] = 0;
ComboBox_LimitText(GetDlgItem(hDlg, IDC_SEPARATOR), MAX_SDATE); ComboBox_LimitText(GetDlgItem(hDlg, IDC_SHORT_DATE_STYLE), MAX_FORMAT); ComboBox_LimitText(GetDlgItem(hDlg, IDC_LONG_DATE_STYLE), MAX_FORMAT);
Edit_LimitText(GetDlgItem(hDlg, IDC_TWO_DIGIT_YEAR_LOW), MAX_YEAR); Edit_LimitText(GetDlgItem(hDlg, IDC_TWO_DIGIT_YEAR_HIGH), MAX_YEAR);
//
// Set the Add Hijri Date combo box appropriately.
//
if (bShowArabic) { Date_InitializeHijriDateComboBox(hDlg); }
//
// Make sure the Apply button is off.
//
PropSheet_UnChanged(GetParent(hDlg), hDlg); if (lParam) { ((LPPROPSHEETPAGE)lParam)->lParam = DC_EverChg; } }
////////////////////////////////////////////////////////////////////////////
//
// DateDlgProc
//
////////////////////////////////////////////////////////////////////////////
INT_PTR CALLBACK DateDlgProc( HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { NMHDR *lpnm; LPPROPSHEETPAGE lpPropSheet = (LPPROPSHEETPAGE)(GetWindowLongPtr(hDlg, DWLP_USER)); DWORD dwIndex; HWND hCtrl;
switch (message) { case ( WM_INITDIALOG ) : { Date_InitPropSheet(hDlg, lParam); Date_SaveValues(); break; } case ( WM_DESTROY ) : { break; } case ( WM_HELP ) : { WinHelp( (HWND)((LPHELPINFO)lParam)->hItemHandle, szHelpFile, HELP_WM_HELP, (DWORD_PTR)(LPTSTR)aDateHelpIds ); break; } case ( WM_CONTEXTMENU ) : // right mouse click
{ WinHelp( (HWND)wParam, szHelpFile, HELP_CONTEXTMENU, (DWORD_PTR)(LPTSTR)aDateHelpIds ); break; } case ( WM_COMMAND ) : { if (!lpPropSheet) { break; }
switch ( LOWORD(wParam) ) { case ( IDC_SHORT_DATE_STYLE ) : { if (HIWORD(wParam) == CBN_SELCHANGE || HIWORD(wParam) == CBN_EDITCHANGE) { lpPropSheet->lParam |= DC_ShortFmt; } break; } case ( IDC_LONG_DATE_STYLE ) : { if (HIWORD(wParam) == CBN_SELCHANGE || HIWORD(wParam) == CBN_EDITCHANGE) { lpPropSheet->lParam |= DC_LongFmt; } break; } case ( IDC_SEPARATOR ) : { if (HIWORD(wParam) == CBN_SELCHANGE || HIWORD(wParam) == CBN_EDITCHANGE) { lpPropSheet->lParam |= DC_SDate; } break; } case ( IDC_CALENDAR_TYPE ) : { if (HIWORD(wParam) == CBN_SELCHANGE) { lpPropSheet->lParam |= DC_Calendar;
hCtrl = GetDlgItem(hDlg, IDC_CALENDAR_TYPE); dwIndex = ComboBox_GetCurSel(hCtrl); if (dwIndex != CB_ERR) { dwIndex = (DWORD)ComboBox_GetItemData(hCtrl, dwIndex); Date_InitializeHijriDateComboBox(hDlg); Date_EnableHijriComboBox(hDlg, (dwIndex == CAL_HIJRI) ); Date_GetTwoDigitYearRange(hDlg, (CALID)dwIndex); }
Date_EnumerateDates(hDlg, CAL_SSHORTDATE); Date_EnumerateDates(hDlg, CAL_SLONGDATE); } break; } case ( IDC_ADD_HIJRI_DATE ) : { if (HIWORD(wParam) == CBN_SELCHANGE) { lpPropSheet->lParam |= DC_Arabic_Calendar; } break; } case ( IDC_TWO_DIGIT_YEAR_HIGH ) : { if (GET_WM_COMMAND_CMD(wParam, lParam) == EN_CHANGE) { Date_ChangeYear(hDlg); lpPropSheet->lParam |= DC_TwoDigitYearMax; } break; } }
//
// Turn on ApplyNow button.
//
if (lpPropSheet->lParam > DC_EverChg) { PropSheet_Changed(GetParent(hDlg), hDlg); }
break; } case ( WM_NOTIFY ) : { lpnm = (NMHDR *)lParam; switch (lpnm->code) { case ( PSN_SETACTIVE ) : { //
// If there has been a change in the regional Locale
// setting, clear all of the current info in the
// property sheet, get the new values, and update the
// appropriate registry values.
//
if (Verified_Regional_Chg & Process_Date) { Verified_Regional_Chg &= ~Process_Date; Date_ClearValues(hDlg); Date_SetValues(hDlg); lpPropSheet->lParam = 0; } break; } case ( PSN_KILLACTIVE ) : { //
// Validate the entries on the property page.
//
SetWindowLongPtr( hDlg, DWLP_MSGRESULT, !Date_ValidatePPS( hDlg, lpPropSheet->lParam ) ); break; } case ( PSN_APPLY ) : { //
// Apply the settings.
//
if (Date_ApplySettings(hDlg, TRUE)) { SetWindowLongPtr(hDlg, DWLP_MSGRESULT, PSNRET_NOERROR);
//
// Zero out the DC_EverChg bit.
//
lpPropSheet->lParam = 0; } else { SetWindowLongPtr( hDlg, DWLP_MSGRESULT, PSNRET_INVALID_NOCHANGEPAGE ); }
break; } default : { return (FALSE); } } break; } case ( WM_VSCROLL ) : { if ((GET_WM_VSCROLL_CODE(wParam, lParam) == SB_ENDSCROLL) && ((HWND)SendMessage( GET_WM_VSCROLL_HWND(wParam, lParam), UDM_GETBUDDY, 0, 0L ) == GetDlgItem(hDlg, IDC_TWO_DIGIT_YEAR_HIGH))) { DWORD YearHigh;
//
// Get the high year.
//
YearHigh = (DWORD)SendDlgItemMessage( hDlg, IDC_TWO_DIGIT_YEAR_ARROW, UDM_GETPOS, 0, 0L );
//
// Set the low year based on the high year.
//
SetDlgItemInt( hDlg, IDC_TWO_DIGIT_YEAR_LOW, (UINT)(YearHigh - 99), FALSE );
//
// Mark it as changed.
//
lpPropSheet->lParam |= DC_TwoDigitYearMax;
//
// Turn on ApplyNow button.
//
PropSheet_Changed(GetParent(hDlg), hDlg); }
break; } default : { return (FALSE); } }
//
// Return success.
//
return (TRUE); }
|