/*++ Copyright (c) 1996 Microsoft Corporation Module Name: timectrl.c Abstract: For implementing a dialog control for setting time values Environment: Fax driver user interface Revision History: 01/16/96 -davidx- Created it. mm/dd/yy -author- description --*/ #include "faxlib.h" #include "timectrl.h" #include #include // // Static time format information // static BOOL timeCtrlInitialized = FALSE; static UINT use24Hour; static UINT hourLeadingZero; static TCHAR timeSep[8]; static TCHAR amSuffix[8]; static TCHAR pmSuffix[8]; static TCHAR intlApplet[] = TEXT("Intl"); static TCHAR use24HourKey[] = TEXT("iTime"); static TCHAR hourLeadingZeroKey[] = TEXT("iTLZero"); static TCHAR timeSepKey[] = TEXT("sTime"); static TCHAR amSuffixKey[] = TEXT("s1159"); static TCHAR pmSuffixKey[] = TEXT("s2359"); static TCHAR timeSepDefault[] = TEXT(":"); static TCHAR amSuffixDefault[] = TEXT("AM"); static TCHAR pmSuffixDefault[] = TEXT("PM"); VOID InitStaticValues( VOID ) /*++ Routine Description: One time initialization of the time control module Arguments: NONE Return Value: NONE --*/ { if (! timeCtrlInitialized) { // // We only need to perform the initialization once. // Make sure to modify the global data inside a critical section. // use24Hour = GetProfileInt(intlApplet, use24HourKey, FALSE); hourLeadingZero = GetProfileInt(intlApplet, hourLeadingZeroKey, TRUE); GetProfileString(intlApplet, timeSepKey, timeSepDefault, timeSep, sizeof(timeSep) / sizeof(TCHAR)); GetProfileString(intlApplet, amSuffixKey, amSuffixDefault, amSuffix, sizeof(amSuffix) / sizeof(TCHAR)); GetProfileString(intlApplet, pmSuffixKey, pmSuffixDefault, pmSuffix, sizeof(pmSuffix) / sizeof(TCHAR)); timeCtrlInitialized = TRUE; Verbose(("Use 24-hour format: %d\n", use24Hour)); Verbose(("Hour leading zero: %d\n", hourLeadingZero)); Verbose(("Time separator: %ws\n", timeSep)); Verbose(("AM suffix: %ws\n", amSuffix)); Verbose(("PM suffix: %ws\n", pmSuffix)); } } VOID EnableTimeControl( HWND hDlg, INT id, BOOL enabled ) /*++ Routine Description: Enable or disable a time control Arguments: hDlg - Specifies the dialog window containing the time control id - Identifies the time control enabled - Whether to enable or disable the time control Return Value: NONE --*/ { // EnableWindow(GetDlgItem(hDlg, IDC_SENDTIME), enabled); EnableWindow(GetDlgItem(hDlg, id+TC_HOUR), enabled); InvalidateRect(GetDlgItem(hDlg, id+TC_TIME_SEP), NULL, FALSE); EnableWindow(GetDlgItem(hDlg, id+TC_MINUTE), enabled); EnableWindow(GetDlgItem(hDlg, id+TC_AMPM), enabled); EnableWindow(GetDlgItem(hDlg, id+TC_ARROW), enabled); } VOID SetHourMinuteValue( HWND hDlg, INT id, INT part, INT value ) /*++ Routine Description: Set the hour or minute value Arguments: hDlg - Specifies the dialog window containing the time control id - Identifies the time control part - Whether we're setting hour or minute value value - Specifies the new hour or minute value Return Value: NONE --*/ { TCHAR buffer[4]; if (value < 0 || value > ((part == TC_MINUTE) ? 59 : 23)) value = 0; if (part == TC_HOUR && !use24Hour) { SendDlgItemMessage(hDlg, id+TC_AMPM, LB_SETTOPINDEX, value / 12, 0); if ((value %= 12) == 0) value = 12; } wsprintf(buffer, (part == TC_MINUTE || hourLeadingZero) ? TEXT("%02d") : TEXT("%d"), value); SetDlgItemText(hDlg, id+part, buffer); } VOID InitTimeControl( HWND hDlg, INT id, PFAX_TIME pTimeVal ) /*++ Routine Description: Setting the current value of a time control Arguments: hDlg - Specifies the dialog window containing the time control id - Identifies the time control pTimeVal - Specifies the new value for the time control Return Value: NONE --*/ { HWND hwnd, hwndArrow; // // Make sure the static global information is initialized // InitStaticValues(); // // Display the time separator // SetDlgItemText(hDlg, id+TC_TIME_SEP, timeSep); // // Display the AM/PM suffix if necessary // if (hwnd = GetDlgItem(hDlg, id+TC_AMPM)) { if (! use24Hour) { SendMessage(hwnd, LB_INSERTSTRING, 0, (LPARAM) &amSuffix[0]); SendMessage(hwnd, LB_INSERTSTRING, 1, (LPARAM) &pmSuffix[0]); } else EnableWindow(hwnd, FALSE); } // // Display hour and minute values // SetHourMinuteValue(hDlg, id, TC_HOUR, pTimeVal->Hour); SetHourMinuteValue(hDlg, id, TC_MINUTE, pTimeVal->Minute); // // Connect the updown arrow to the minute field by default // if ((hwnd = GetDlgItem(hDlg, id+TC_MINUTE)) && (hwndArrow = GetDlgItem(hDlg, id+TC_ARROW))) { UDACCEL udAccel[2]; udAccel[0].nSec = 0; udAccel[0].nInc = 1; udAccel[1].nSec = 2; udAccel[1].nInc = 5; SendMessage(hwndArrow, UDM_SETRANGE, 0, MAKELPARAM(59, 0)); SendMessage(hwndArrow, UDM_SETACCEL, 2, (LPARAM) &udAccel[0]); SendMessage(hwndArrow, UDM_SETBUDDY, (WPARAM) hwnd, 0); } } BOOL GetHourMinuteValue( HWND hDlg, INT id, INT part, PWORD pValue ) /*++ Routine Description: Retrieve the current hour or minute value Arguments: hDlg - Specifies the dialog window containing the time control id - Identifies the time control part - Whether we're interest in hour or minute value pValue - Buffer for storing the current hour value Return Value: TRUE if successful, FALSE otherwise --*/ { INT value, minVal, maxVal; BOOL success; // // Read the text field as an integer value // value = GetDlgItemInt(hDlg, id+part, &success, FALSE); // // Make sure the input value is valid // if (! success) value = 0; else { if (part == TC_MINUTE) minVal = 0, maxVal = 59; else if (use24Hour) minVal = 0, maxVal = 23; else minVal = 1, maxVal = 12; success = FALSE; if (value < minVal) value = minVal; else if (value > maxVal) value = maxVal; else success = TRUE; } // // Convert AM/PM hours to absolute number between 0-23 // if (part == TC_HOUR && !use24Hour) { if (SendDlgItemMessage(hDlg, id+TC_AMPM, LB_GETTOPINDEX, 0, 0)) { // PM if (value != 12) value += 12; } else { // AM if (value == 12) value = 0; } } *pValue = (WORD) value; return success; } VOID GetTimeControlValue( HWND hDlg, INT id, PFAX_TIME pTimeVal ) /*++ Routine Description: Retrieve the current value of a time control Arguments: hDlg - Specifies the dialog window containing the time control id - Identifies the time control pTimeVal - Buffer for storing the current time value Return Value: NONE --*/ { GetHourMinuteValue(hDlg, id, TC_HOUR, &pTimeVal->Hour); GetHourMinuteValue(hDlg, id, TC_MINUTE, &pTimeVal->Minute); } BOOL HandleTimeControl( HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam, INT id, INT part ) /*++ Routine Description: Handle dialog messages intended for a time control Arguments: hDlg - Specifies the dialog window containing the time control message, wParam, lParam - Parameters passed to the dialog procedure id - Identifies the time control part - Identifies what part of the time control in question Return Value: TRUE if the message is handled, FALSE otherwise --*/ { HWND hwnd, hwndArrow; UDACCEL udAccel[2]; WORD wMax, wMin; switch (message) { case WM_COMMAND: // // Make sure the control is indeed ours // hwnd = GetDlgItem(hDlg, id+part); hwndArrow = GetDlgItem(hDlg, id+TC_ARROW); if (hwnd != GET_WM_COMMAND_HWND(wParam, lParam)) { Warning(("Bad window handle\n")); return FALSE; } switch (GET_WM_COMMAND_CMD(wParam, lParam)) { case LBN_SETFOCUS: // // AM/PM list box is coming into focus // Assert(part == TC_AMPM); udAccel[0].nSec = 0; udAccel[0].nInc = 1; SendMessage(hwnd, LB_SETCURSEL, SendMessage(hwnd, LB_GETTOPINDEX, 0, 0), 0); SendMessage(hwndArrow, UDM_SETRANGE, 0, MAKELPARAM(1, 0)); SendMessage(hwndArrow, UDM_SETACCEL, 1, (LPARAM) &udAccel[0]); SendMessage(hwndArrow, UDM_SETBUDDY, (WPARAM) hwnd, 0); break; case LBN_KILLFOCUS: // // Leaving AM/PM listbox // Assert(part == TC_AMPM); SendMessage(hwnd, LB_SETCURSEL, (WPARAM) -1, 0); SendMessage(hwndArrow, UDM_SETBUDDY, 0, 0); break; case EN_SETFOCUS: // // Entering hour or minute text field // Assert(part == TC_HOUR || part == TC_MINUTE); udAccel[0].nSec = 0; udAccel[0].nInc = 1; udAccel[1].nSec = 2; if (part == TC_MINUTE) { wMin = 0, wMax = 59; udAccel[1].nInc = 5; } else { udAccel[1].nInc = 1; if (use24Hour) wMin = 0, wMax = 23; else wMin = 1, wMax = 12; } SendMessage(hwndArrow, UDM_SETRANGE, 0, MAKELPARAM(wMax, wMin)); SendMessage(hwndArrow, UDM_SETACCEL, 2, (LPARAM) &udAccel[0]); SendMessage(hwndArrow, UDM_SETBUDDY, (WPARAM) hwnd, 0); SendMessage(hwnd, EM_SETSEL, 0, -1); break; case EN_CHANGE: // // Changing hour or minute field // Assert(part == TC_HOUR || part == TC_MINUTE); if (!GetHourMinuteValue(hDlg, id, part, &wMax) && GetWindowTextLength(hwnd)) { MessageBeep(MB_ICONASTERISK); SendMessage(hwnd, EM_UNDO, 0, 0); } break; case EN_KILLFOCUS: // // Leaving hour or minute text field // Assert(part == TC_HOUR || part == TC_MINUTE); GetHourMinuteValue(hDlg, id, part, &wMax); SetHourMinuteValue(hDlg, id, part, wMax); SendMessage(hwndArrow, UDM_SETBUDDY, 0, 0); break; } return TRUE; case WM_CTLCOLORLISTBOX: case WM_CTLCOLORSTATIC: case WM_CTLCOLOREDIT: case WM_CTLCOLOR: // // Set the background color of the time control to the color of editable text // or static text depending on whether the control is disabled or enabled // hwnd = GET_WM_CTLCOLOR_HWND(wParam, lParam, message); if (hwnd == GetDlgItem(hDlg, id + TC_HOUR) || hwnd == GetDlgItem(hDlg, id + TC_MINUTE) || hwnd == GetDlgItem(hDlg, id + TC_TIME_SEP) || hwnd == GetDlgItem(hDlg, id + TC_AMPM)) { message = part ? WM_CTLCOLOREDIT : WM_CTLCOLORSTATIC; return (BOOL)DefWindowProc(hDlg, message, wParam, lParam); } break; } return FALSE; }