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;
|
|||
|
}
|
|||
|
|