alarm.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,037 行 · 第 1/2 页

C
1,037
字号
#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 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()
/*********************************

    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()
/*********************************

    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()
/***********************

    See if the alarm has gone off, and pop up a message box if it has.
*/
{
    digit_index         i;

    for( i = 0; i < DIGITS_WITH_SECONDS; ++i ) {
        if( AlarmDigits[i] != ClockDigits[i].value ) return;
    }
    MessageBox( NULL, "The alarm clock is ringing!", Buffer,
               MB_ICONHAND+MB_OK+MB_SYSTEMMODAL );
}


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()
/*********************

    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()
/************************

    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;

    default:

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?