alarm.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,041 行 · 第 1/2 页
C
1,041 行
#include <stdio.h>
#include <windows.h>
#include <time.h>
#include "alarm.h"
HINSTANCE MyInstance;
char AlarmClass[32]="AlarmClass";
digit_index NumberOfDigits = DIGITS_WITH_SECONDS;
digit_index DigitsToDraw;
unsigned ScreenWidthInMM;
unsigned ScreenHeightInMM;
/* following variables have units in Pixels */
pixels ScreenWidth;
pixels ScreenHeight;
pixels WidthOfClock;
pixels HeightOfClock;
pixels WidthOfWindow;
pixels HeightOfWindow;
pixels InterSegmentGap;
pixels SegmentHeight;
pixels SegmentWidth;
char Buffer[BUFLEN];
digit ClockDigits[DIGITS_WITH_SECONDS];
unsigned AlarmDigits[DIGITS_WITH_SECONDS];
colon Colons[NUMBER_OF_COLONS];
BOOL AlarmPM = FALSE;
HPEN Pens[NUMBER_OF_PENS];
BOOL FirstAlarmSetting = TRUE;
BOOL TwelveHour = TRUE;
BOOL Setting;
unsigned Tick;
static BOOL AlarmIsRinging;
static BOOL FirstInstance( HINSTANCE this_inst );
static BOOL AnyInstance( HINSTANCE this_inst, int cmdshow );
int PASCAL WinMain( HINSTANCE this_inst, HINSTANCE prev_inst,
LPSTR cmdline, int cmdshow )
/***********************************************
Initialization, message loop.
*/
{
MSG msg;
cmdline = cmdline;
MyInstance = this_inst;
#ifdef __WINDOWS_386__
sprintf( AlarmClass,"AlarmClass%d", this_inst );
prev_inst = 0;
#endif
if( !prev_inst ) {
if( !FirstInstance( this_inst ) ) return( FALSE );
}
if( !AnyInstance( this_inst, cmdshow ) ) return( FALSE );
while( GetMessage( &msg, NULL, NULL, NULL ) ) {
TranslateMessage( &msg );
DispatchMessage( &msg );
}
return( msg.wParam );
}
long _EXPORT FAR PASCAL WindowProc( HWND, unsigned, UINT, LONG );
static BOOL FirstInstance( HINSTANCE this_inst )
/********************************************
Register window class for the application,
and do any other application initialization.
*/
{
WNDCLASS wc;
BOOL rc;
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = (LPVOID) WindowProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = this_inst;
wc.hIcon = NULL;
wc.hCursor = LoadCursor( NULL, IDC_ARROW );
wc.hbrBackground = GetStockObject( WHITE_BRUSH );
wc.lpszMenuName = "AlarmMenu";
wc.lpszClassName = AlarmClass;
rc = RegisterClass( &wc );
return( rc );
}
static BOOL AnyInstance( HINSTANCE this_inst, int cmdshow )
/*******************************************************
Do work required for every instance of the application:
create the window, initialize data.
*/
{
HDC dc;
HWND win_handle;
/*
* create main window
*/
dc = GetDC(NULL);
ScreenHeight = GetDeviceCaps( dc, VERTRES );
ScreenWidth = GetDeviceCaps( dc, HORZRES );
ScreenHeightInMM = GetDeviceCaps( dc, VERTSIZE );
ScreenWidthInMM = GetDeviceCaps( dc, HORZSIZE );
ReleaseDC( NULL, dc );
CreateSupplies();
win_handle = CreateWindow(
AlarmClass, /* class */
"Alarm Clock", /* caption */
WS_OVERLAPPEDWINDOW, /* style */
CW_USEDEFAULT, /* init. x pos */
CW_USEDEFAULT, /* init. y pos */
CW_USEDEFAULT, /* init. x size */
CW_USEDEFAULT, /* init. y size */
NULL, /* parent window */
NULL, /* menu handle */
this_inst, /* program handle */
NULL /* create parms */
);
if( !win_handle ) return( FALSE );
/*
* display window
*/
ShowWindow( win_handle, cmdshow );
UpdateWindow( win_handle );
if( !SetTimer( win_handle, TIMER_ID, ONE_SECOND/4, 0L ) ) {
MessageBox( NULL, "Too many timers in use", Buffer,
MB_ICONHAND+MB_OK+MB_SYSTEMMODAL );
return( FALSE );
}
return( TRUE );
}
BOOL _EXPORT FAR PASCAL About( HWND win_handle, unsigned msg,
WORD wparam, LONG lparam )
/*********************************************************
Process messages for the about dialog.
*/
{
lparam = lparam; /* turn off warning */
win_handle = win_handle;
switch( msg ) {
case WM_INITDIALOG:
return( TRUE );
case WM_COMMAND:
if( wparam == IDOK ) {
EndDialog( win_handle, TRUE );
return( TRUE );
}
break;
}
return( FALSE );
}
static void TransferClockToAlarm( void )
/***************************************
Transfer the digits from the Clock array to the Alarm array.
*/
{
digit_index i;
for( i = 0; i < DIGITS_WITH_SECONDS; ++i ) {
AlarmDigits[i] = ClockDigits[i].value;
}
}
static void TransferAlarmToClock( void )
/***************************************
Transfer digits from the Alarm array to the Clock array
*/
{
digit_index i;
for( i = 0; i < DIGITS_WITH_SECONDS; ++i ) {
ClockDigits[i].value = AlarmDigits[i];
}
}
static void RePaintTheClock( HWND win_handle )
/*********************************************
Re-paint the entire clock, since it has been invalidated.
*/
{
PAINTSTRUCT ps;
InvalidateRect( win_handle, NULL, TRUE );
BeginPaint( win_handle, &ps );
InitializeTheClock();
PaintClock( ps.hdc );
EndPaint( win_handle, &ps );
}
static void CheckAlarm( void )
/*****************************
See if the alarm has gone off, and pop up a message box if it has.
*/
{
digit_index i;
if( AlarmIsRinging ) return;
for( i = 0; i < DIGITS_WITH_SECONDS; ++i ) {
if( AlarmDigits[i] != ClockDigits[i].value ) return;
}
AlarmIsRinging = TRUE;
MessageBox( NULL, "The alarm clock is ringing!", Buffer,
MB_ICONEXCLAMATION | MB_OK | MB_TASKMODAL );
AlarmIsRinging = FALSE;
}
static void UpdateTheClock( HWND win_handle )
/********************************************
Incrementally update the clock display.
*/
{
HDC dc;
dc = GetDC( win_handle );
PaintClock( dc );
ReleaseDC( win_handle, dc );
}
static void SetNumberOfDigits( digit_index num )
/***********************************************
Set the number of digits to be displayed (4 or 6)
*/
{
NumberOfDigits = num;
DigitsToDraw = num;
}
static void SetAlarm( void )
/***************************
Put the clock into alarm setting mode.
*/
{
if( Setting ) return;
Setting = TRUE;
if( FirstAlarmSetting ) {
TransferClockToAlarm();
if( NumberOfDigits == DIGITS_WITHOUT_SECONDS ) {
AlarmDigits[SEC_TENS] = 0;
AlarmDigits[SEC_ONES] = 0;
}
FirstAlarmSetting = FALSE;
}
TransferAlarmToClock();
}
static void RunTheClock( void )
/******************************
Put the clock into running mode.
*/
{
if( !Setting ) return;
Setting = FALSE;
TransferClockToAlarm();
}
static void Set12HourClock( HWND win_handle )
/********************************************
Put the clock into 12 hour mode.
*/
{
int i;
if( TwelveHour ) return;
TwelveHour = TRUE;
i = AlarmDigits[HOUR_TENS]*10 + AlarmDigits[HOUR_ONES];
if( i > 12 ) {
i -= 12;
AlarmPM = TRUE;
}
AlarmDigits[HOUR_TENS] = i / 10;
AlarmDigits[HOUR_ONES] = i % 10;
if( Setting ) TransferAlarmToClock();
UpdateTheClock( win_handle );
}
static void Set24HourClock( HWND win_handle )
/********************************************
Put the clock into 24 hour mode
*/
{
int i;
if( !TwelveHour ) return;
TwelveHour = FALSE;
i = AlarmDigits[HOUR_TENS]*10 + AlarmDigits[HOUR_ONES];
if( i <= 12 && AlarmPM ) {
i += 12;
AlarmPM = FALSE;
}
AlarmDigits[HOUR_TENS] = i / 10;
AlarmDigits[HOUR_ONES] = i % 10;
if( Setting ) TransferAlarmToClock();
UpdateTheClock( win_handle );
}
static void DisplayAboutBox( HWND win_handle )
/*********************************************
Display the "About ..." box
*/
{
FARPROC proc;
proc = MakeProcInstance( (FARPROC)About, MyInstance );
DialogBox( MyInstance, "AboutBox", win_handle, (DLGPROC)proc );
FreeProcInstance( proc );
}
static void MenuItem( HWND win_handle, WORD wparam )
/***************************************************
Handle a menu item which has been selected by the user.
*/
{
switch( wparam ) {
case MENU_ABOUT:
DisplayAboutBox( win_handle );
break;
case MENU_DISPLAY_SECONDS:
SetNumberOfDigits( DIGITS_WITH_SECONDS );
break;
case MENU_SUPRESS_SECONDS:
SetNumberOfDigits( DIGITS_WITHOUT_SECONDS );
break;
case MENU_SET_ALARM:
SetAlarm();
break;
case MENU_RUN_CLOCK:
RunTheClock();
break;
case MENU_12_HOUR_CLOCK:
Set12HourClock( win_handle );
break;
case MENU_24_HOUR_CLOCK:
Set24HourClock( win_handle );
break;
}
InvalidateRect( win_handle, NULL, TRUE );
}
static int Check[] = { MF_UNCHECKED, MF_CHECKED };
static void InitMenu( HMENU mh )
/*******************************
Initialize the menu display. Disable any items which are not applicable.
*/
{
BOOL on;
CheckMenuItem( mh, MENU_SET_ALARM, Check[ Setting ] );
CheckMenuItem( mh, MENU_RUN_CLOCK, Check[ !Setting ] );
on = ( NumberOfDigits == DIGITS_WITHOUT_SECONDS );
CheckMenuItem( mh, MENU_SUPRESS_SECONDS, Check[ on ] );
CheckMenuItem( mh, MENU_DISPLAY_SECONDS, Check[ !on ] );
CheckMenuItem( mh, MENU_24_HOUR_CLOCK, Check[ !TwelveHour ] );
CheckMenuItem( mh, MENU_12_HOUR_CLOCK, Check[ TwelveHour ] );
}
static unsigned MaximumNumber[] = { 0, 0, 5, 9, 5, 9 };
static void MouseClick( pixels x, pixels y, unsigned msg )
/*********************************************************
Handle a mouse click at position x,y.
*/
{
digit_index i;
TransferAlarmToClock();
if( TwelveHour ) {
MaximumNumber[HOUR_TENS] = 1;
if( ClockDigits[HOUR_TENS].value == 1 ) {
MaximumNumber[HOUR_ONES] = 2;
} else {
MaximumNumber[HOUR_ONES] = 9;
}
} else {
MaximumNumber[HOUR_TENS] = 2;
if( ClockDigits[HOUR_TENS].value == 2 ) {
MaximumNumber[HOUR_ONES] = 4;
} else {
MaximumNumber[HOUR_ONES] = 9;
}
}
for( i = 0; i < NumberOfDigits; ++i ) {
if( x < ClockDigits[i].segment[SEGMENT_0].position.start.x ) continue;
if( x > ClockDigits[i].segment[SEGMENT_6].position.end.x ) continue;
if( y < ClockDigits[i].segment[SEGMENT_0].position.start.y ) continue;
if( y > ClockDigits[i].segment[SEGMENT_6].position.end.y ) continue;
if( msg == WM_LBUTTONDOWN ) {
ClockDigits[i].value++;
} else if( msg == WM_RBUTTONDOWN ) {
ClockDigits[i].value--;
}
if( ClockDigits[i].value > MaximumNumber[ i ] ) {
ClockDigits[i].value = 0;
} else if( ClockDigits[i].value < 0 ) {
ClockDigits[i].value = MaximumNumber[i];
}
}
if( TwelveHour ) {
if( x < ClockDigits[HOUR_TENS].segment[SEGMENT_0].position.start.x &&
y > ClockDigits[HOUR_TENS].segment[SEGMENT_0].position.start.y &&
y < ClockDigits[HOUR_TENS].segment[SEGMENT_6].position.end.y ) {
AlarmPM = !AlarmPM;
}
if( ClockDigits[HOUR_TENS].value == 1 && ClockDigits[HOUR_ONES].value > 2 ) {
ClockDigits[HOUR_ONES].value = 2;
}
if( ClockDigits[HOUR_TENS].value == 0 &&
ClockDigits[HOUR_ONES].value == 0 ) {
ClockDigits[HOUR_ONES].value = 1;
}
} else {
if( ClockDigits[HOUR_TENS].value == 2 &&
ClockDigits[HOUR_ONES].value > 4 ) {
ClockDigits[HOUR_ONES].value = 4;
}
}
TransferClockToAlarm();
}
LONG _EXPORT FAR PASCAL WindowProc( HWND win_handle, unsigned msg,
UINT wparam, LONG lparam )
/**************************************************************
Handle messages for the main application window.
*/
{
switch( msg ) {
case WM_INITMENU:
InitMenu( (HMENU)wparam );
break;
case WM_COMMAND:
MenuItem( win_handle, LOWORD(wparam) );
break;
case WM_SYSCOLORCHANGE:
DeleteSupplies();
CreateSupplies();
break;
case WM_PAINT:
RePaintTheClock( win_handle );
break;
case WM_TIMER:
case WM_TIMECHANGE:
if( Setting ) break;
Tick++;
CheckAlarm();
UpdateTheClock( win_handle );
break;
case WM_SIZE:
ReSize( LOWORD( lparam ), HIWORD( lparam ), wparam );
break;
case WM_DESTROY:
DeleteSupplies();
KillTimer( win_handle, TIMER_ID );
PostQuitMessage( 0 );
break;
case WM_LBUTTONDOWN:
case WM_RBUTTONDOWN:
if( !Setting ) break;
MouseClick( LOWORD( lparam ), HIWORD( lparam ), msg );
UpdateTheClock( win_handle );
break;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?