579 lines
12 KiB
C
579 lines
12 KiB
C
/*++
|
||
|
||
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 <commctrl.h>
|
||
#include <windowsx.h>
|
||
|
||
//
|
||
// 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;
|
||
}
|
||
|