Annotation of q_a/samples/timers/timers.c, revision 1.1.1.2

1.1.1.2 ! root        1: /******************************************************************************\
1.1       root        2: *
                      3: *  PROGRAM:     TIMERS.C
                      4: *
                      5: *  PURPOSE:     To demonstrate the use of APIs SetTimer() and KillTimer().
                      6: *
1.1.1.2 ! root        7: *  FUNCTIONS:   WinMain               - standard WinMain()
        !             8: *               MainWndProc           - main window procedure
        !             9: *               TimerFunc             - handles timer messages
        !            10: *               SetButtonPositions    - sizes buttons to client area
        !            11: *               SetFlashRectPositions - sizes flashing rectangles to
1.1       root       12: *                                         client area
                     13: *               DrawStuff()             - draws separator, headers,
                     14: *                                         rectangles
                     15: *
                     16: *  COMMENTS:    When a timer is started it's corresponding rectangle (in
                     17: *               the client area) is inverted each time a WM_TIMER is
                     18: *               received or each timer the TimerFunc() is called.
                     19: *
1.1.1.2 ! root       20: *
        !            21: *                           Microsoft Developer Support
        !            22: *                     Copyright (c) 1992 Microsoft Corporation
        !            23: *
        !            24: \******************************************************************************/
1.1       root       25: 
                     26: #include <windows.h>
                     27: #include <string.h>
                     28: #include "timers.h"
                     29: 
                     30: 
                     31: 
1.1.1.2 ! root       32: /******************************************************************************\
1.1       root       33: *
                     34: *  FUNCTION:    WinMain (standard WinMain INPUTS/RETURNS)
                     35: *
1.1.1.2 ! root       36: *  GLOBAL VARS: ghInst - handle of program instance
1.1       root       37: *
                     38: *  LOCAL VARS:  hwnd - handle of the main standard window
                     39: *               msg  - msg to get/dispatch
                     40: *
1.1.1.2 ! root       41: \******************************************************************************/
1.1       root       42: 
1.1.1.2 ! root       43: int WINAPI WinMain (HANDLE hInstance,HANDLE hPrevInstance,
        !            44:                     LPSTR lpCmdLine, int nCmdShow) {
1.1       root       45:   HWND hwnd;
                     46:   MSG msg;
                     47: 
                     48:   if (!hPrevInstance)
                     49:   {
                     50:     WNDCLASS wc;
                     51: 
                     52:     wc.style         = CS_HREDRAW | CS_VREDRAW;
                     53:     wc.lpfnWndProc   = (WNDPROC)MainWndProc;
                     54:     wc.cbClsExtra    = 0;
                     55:     wc.cbWndExtra    = 0;
                     56:     wc.hInstance     = hInstance;
                     57:     wc.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
                     58:     wc.hCursor       = LoadCursor (NULL, IDC_ARROW);
                     59:     wc.hbrBackground = GetStockObject (WHITE_BRUSH);
1.1.1.2 ! root       60:     wc.lpszMenuName  = (LPCTSTR) NULL;
        !            61:     wc.lpszClassName = (LPCTSTR) "TIMERS";
1.1       root       62: 
                     63:     if (!RegisterClass (&wc))
1.1.1.2 ! root       64:     {
        !            65:       MessageBox (NULL, (LPCTSTR) "WinMain(): RegisterClass() failed",
        !            66:                   (LPCTSTR) "Err! - TIMERS", MB_OK | MB_ICONEXCLAMATION);
1.1       root       67:       return(FALSE);
                     68:     }
                     69:   }
                     70: 
1.1.1.2 ! root       71:   ghInst = hInstance;
1.1       root       72:   if (!(hwnd = CreateWindow ("TIMERS", "TIMERS Sample Application",
                     73:                              WS_OVERLAPPEDWINDOW,
                     74:                              CW_USEDEFAULT, CW_USEDEFAULT,
                     75:                              CW_USEDEFAULT, CW_USEDEFAULT,
1.1.1.2 ! root       76:                              NULL, NULL, ghInst, NULL)))
1.1       root       77:     return (NULL);
                     78: 
1.1.1.2 ! root       79:   ShowWindow (hwnd, nCmdShow);
1.1       root       80: 
1.1.1.2 ! root       81:   while (GetMessage (&msg, NULL, NULL, NULL))
        !            82:   {
        !            83:     TranslateMessage (&msg);
        !            84:     DispatchMessage  (&msg);
1.1       root       85:   }
                     86:   return (msg.wParam);
                     87:   UNREFERENCED_PARAMETER(lpCmdLine);
                     88: }
                     89: 
                     90: 
                     91: 
1.1.1.2 ! root       92: /******************************************************************************\
1.1       root       93: *
                     94: *  FUNCTION:    MainWndProc (standard window procedure INPUTS/RETURNS)
                     95: *
1.1.1.2 ! root       96: *  GLOBAL VARS: ghInst       - handle of program instance
        !            97: *               gahwndButtons - array of button window handles
        !            98: *               gaFlashRects  - array of flashing rectangles coordinates
        !            99: *
        !           100: \******************************************************************************/
        !           101: 
        !           102: LRESULT CALLBACK MainWndProc (HWND hwnd, UINT message, WPARAM wParam,
        !           103:                               LPARAM lParam)
        !           104: {
        !           105:   switch (message)
        !           106:   {
        !           107:     case WM_CREATE:
        !           108:     {
        !           109:       LONG i;
        !           110: 
        !           111:       //
        !           112:       // Create the buttons to turn timer on/off
        !           113:       //
        !           114: 
1.1       root      115:       for (i= ID_TIMER1; i <= ID_TIMER4; i++)
1.1.1.2 ! root      116:       {
        !           117:         gahwndButtons[i] = CreateWindow ("button", "Start timer",
1.1       root      118:                                        WS_CHILD | BS_PUSHBUTTON,
                    119:                                        0, 0, 0, 0, hwnd, NULL,
1.1.1.2 ! root      120:                                        ghInst, NULL);
        !           121:         SetWindowLong (gahwndButtons[i], GWL_ID, i);
1.1       root      122:       }
                    123: 
1.1.1.2 ! root      124:       //
        !           125:       // Have TIMER1 started initially (giving the user a clue what to do)
        !           126:       //
        !           127: 
1.1       root      128:       PostMessage (hwnd, WM_COMMAND, (DWORD) ID_TIMER1,
1.1.1.2 ! root      129:                    (LONG) gahwndButtons[ID_TIMER1]);
1.1       root      130:       break;
                    131:     }
1.1.1.2 ! root      132: 
1.1       root      133:     case WM_COMMAND:
1.1.1.2 ! root      134:     {
        !           135:       char buf[BUFSIZE];
1.1       root      136:       WORD id;
                    137: 
                    138:       id = LOWORD (wParam);
                    139:       GetWindowText ((HWND) lParam, buf, BUFSIZE);
                    140:       if (!strcmp (buf, "Start timer"))
                    141:       {
1.1.1.2 ! root      142:         //
        !           143:         // Set button text to "Stop timer" and start the timer. For
        !           144:         //   timers 1&2 we'll specify a WNDPROC ("TimerFunc") which will
        !           145:         //   get called for each timer tick. For timers 3&4 we'll just
        !           146:         //   have WM_TIMER messages sent to this window procedure.
        !           147:         //
        !           148: 
1.1       root      149:         SetWindowText ((HWND) lParam, (LPTSTR) "Stop timer");
                    150:         if (id < ID_TIMER3)
1.1.1.2 ! root      151:         {
        !           152:           if (SetTimer (hwnd, (UINT) id, (UINT) (id * TIMERINTERVAL),
        !           153:                         (TIMERPROC) TimerFunc) == 0)
        !           154: 
        !           155:             MessageBox (NULL, (LPCTSTR) "MainWndProc(): SetTimer() failed",
        !           156:                         (LPCTSTR) "Err! - TIMERS", MB_OK | MB_ICONEXCLAMATION);
1.1       root      157:         }
                    158:         else
1.1.1.2 ! root      159:         {
        !           160:           if (SetTimer (hwnd, (UINT) id, (UINT) (id * TIMERINTERVAL),
1.1       root      161:                         NULL) == 0)
1.1.1.2 ! root      162: 
        !           163:             MessageBox (NULL, (LPCTSTR) "MainWndProc(): SetTimer() failed",
        !           164:                         (LPCTSTR) "Err! - TIMERS", MB_OK | MB_ICONEXCLAMATION);
1.1       root      165:         }
                    166:       }
                    167:       else
                    168:       {
                    169:         SetWindowText ((HWND) lParam, (LPTSTR) "Start timer");
                    170:         KillTimer (hwnd, (UINT) id);
                    171:       }
                    172:       break;
                    173:     }
1.1.1.2 ! root      174: 
1.1       root      175:     case WM_TIMER:
                    176:     {
1.1.1.2 ! root      177:       //
        !           178:       // Invert the gaFlashRect associated with this timer event
        !           179:       //
        !           180: 
1.1       root      181:       HDC hdc = GetDC (hwnd);
                    182: 
1.1.1.2 ! root      183:       InvertRect (hdc, &gaFlashRects[wParam]); // wParam = timerId
        !           184:       ReleaseDC  (hwnd, hdc);
1.1       root      185:       break;
                    186:     }
1.1.1.2 ! root      187: 
1.1       root      188:     case WM_SIZE:
1.1.1.2 ! root      189:     {
        !           190:       int width  = (int) LOWORD(lParam);
1.1       root      191:       int height = (int) HIWORD(lParam);
                    192: 
1.1.1.2 ! root      193:       //
        !           194:       // User resized the window, so reposition button & flashing rects
        !           195:       //
        !           196: 
1.1       root      197:       SetButtonPositions (width, height);
                    198:       SetFlashRectPositions (width, height);
                    199:       break;
                    200:     }
1.1.1.2 ! root      201: 
1.1       root      202:     case WM_PAINT:
1.1.1.2 ! root      203:     {
        !           204:       PAINTSTRUCT ps;
1.1       root      205: 
                    206:       BeginPaint (hwnd, &ps);
                    207:       DrawStuff (hwnd, ps.hdc);
                    208:       EndPaint (hwnd, &ps);
                    209:       break;
                    210:     }
1.1.1.2 ! root      211: 
1.1       root      212:     case WM_DESTROY:
1.1.1.2 ! root      213: 
1.1       root      214:       PostQuitMessage(NULL);
                    215:       break;
1.1.1.2 ! root      216: 
1.1       root      217:     default:
1.1.1.2 ! root      218: 
1.1       root      219:       return (DefWindowProc(hwnd, message, wParam, lParam));
                    220:   }
                    221:   return (NULL);
                    222: }
                    223: 
                    224: 
                    225: 
1.1.1.2 ! root      226: /******************************************************************************\
1.1       root      227: *
                    228: *  FUNCTION:    TimerFunc
                    229: *
                    230: *  INPUTS:      hwnd     - window associated with timer
1.1.1.2 ! root      231: *               uMsg     - WM_TIMER message
        !           232: *               idEvent  - timer's ID
1.1       root      233: *               dwTime   - current system time
                    234: *
                    235: *  RETURNS:     0
                    236: *
1.1.1.2 ! root      237: *  GLOBAL VARS: gaFlashRects - array of flashing rectangles coordinates
1.1       root      238: *
                    239: *  LOCAL VARS:  hdc - device context of main window
                    240: *
1.1.1.2 ! root      241: *  COMMENTS:    Inverts the gaFlashRect corresponding to idEvent
1.1       root      242: *
1.1.1.2 ! root      243: \******************************************************************************/
1.1       root      244: 
1.1.1.2 ! root      245: void CALLBACK TimerFunc (HWND hwnd, UINT uMsg, UINT idEvent, DWORD dwTime)
        !           246: {
        !           247:   HDC hdc = GetDC (hwnd);
1.1       root      248: 
1.1.1.2 ! root      249:   InvertRect (hdc, &gaFlashRects[idEvent]);
        !           250:   ReleaseDC  (hwnd, hdc);
1.1       root      251: }
                    252: 
                    253: 
                    254: 
1.1.1.2 ! root      255: /******************************************************************************\
1.1       root      256: *
                    257: *  FUNCTION:    SetButtonPositions
                    258: *
                    259: *  INPUTS:      cx - new width of main window
                    260: *               cy - new height of main window
                    261: *
1.1.1.2 ! root      262: *  GLOBAL VARS: gahwndButtons - array of button HWNDs (unmodified)
1.1       root      263: *
                    264: *  COMMENTS:    Repositions buttons according to new window size (cx,cy)
                    265: *
1.1.1.2 ! root      266: \******************************************************************************/
1.1       root      267: 
                    268: void SetButtonPositions (int cx, int cy)
1.1.1.2 ! root      269: {
        !           270:   SetWindowPos (gahwndButtons[ID_TIMER1], NULL,     // upper-left button
1.1       root      271:                 BUTTONBORDER,
                    272:                 cy/2 - BUTTONBORDER - BUTTONHEIGHT,
                    273:                 cx/2 - 2*BUTTONBORDER,
                    274:                 BUTTONHEIGHT,
                    275:                 SWP_SHOWWINDOW);
                    276: 
1.1.1.2 ! root      277:   SetWindowPos (gahwndButtons[ID_TIMER2], NULL,     // upper-right button
1.1       root      278:                 cx/2 + BUTTONBORDER,
                    279:                 cy/2 - BUTTONBORDER - BUTTONHEIGHT,
                    280:                 cx/2 - 2*BUTTONBORDER,
                    281:                 BUTTONHEIGHT,
                    282:                 SWP_SHOWWINDOW);
                    283: 
1.1.1.2 ! root      284:   SetWindowPos (gahwndButtons[ID_TIMER3], NULL,     // lower-left button
1.1       root      285:                 BUTTONBORDER,
                    286:                 cy - BUTTONBORDER - BUTTONHEIGHT,
                    287:                 cx/2 - 2*BUTTONBORDER,
                    288:                 BUTTONHEIGHT,
                    289:                 SWP_SHOWWINDOW);
                    290: 
1.1.1.2 ! root      291:   SetWindowPos (gahwndButtons[ID_TIMER4], NULL,     // lower-right button
1.1       root      292:                 cx/2 + BUTTONBORDER,
                    293:                 cy - BUTTONBORDER - BUTTONHEIGHT,
                    294:                 cx/2 - 2*BUTTONBORDER,
                    295:                 BUTTONHEIGHT,
                    296:                 SWP_SHOWWINDOW);
                    297: }
                    298: 
                    299: 
                    300: 
1.1.1.2 ! root      301: /******************************************************************************\
1.1       root      302: *
1.1.1.2 ! root      303: *  FUNCTION:    SetgaFlashRectPositions
1.1       root      304: *
                    305: *  INPUTS:      cx - new width of main window
                    306: *               cy - new height of main window
                    307: *
1.1.1.2 ! root      308: *  GLOBAL VARS: gaFlashRects - array of flashing rectangles coordinates
1.1       root      309: *                            (modified)
                    310: *
                    311: *  COMMENTS:    Repositions flashing rectangles according to new window
                    312: *               size (cx,cy)
                    313: *
1.1.1.2 ! root      314: \******************************************************************************/
1.1       root      315: 
                    316: void SetFlashRectPositions (LONG cx, LONG cy)
                    317: {                                                 /* upper-left rect  */
1.1.1.2 ! root      318:   gaFlashRects[ID_TIMER1].left   = BUTTONBORDER;
        !           319:   gaFlashRects[ID_TIMER1].top    = 3*TEXTHEIGHT + BUTTONBORDER;
        !           320:   gaFlashRects[ID_TIMER1].right  = cx/2 - BUTTONBORDER;
        !           321:   gaFlashRects[ID_TIMER1].bottom = cy/2 - BUTTONHEIGHT - 2*BUTTONBORDER;
1.1       root      322: 
                    323:                                                   /* upper-right rect */
1.1.1.2 ! root      324:   gaFlashRects[ID_TIMER2].left   = cx/2 + BUTTONBORDER;
        !           325:   gaFlashRects[ID_TIMER2].top    = 3*TEXTHEIGHT + BUTTONBORDER;
        !           326:   gaFlashRects[ID_TIMER2].right  = cx - BUTTONBORDER;
        !           327:   gaFlashRects[ID_TIMER2].bottom = cy/2 - BUTTONHEIGHT - 2*BUTTONBORDER;
1.1       root      328: 
                    329:                                                   /* lower-left rect  */
1.1.1.2 ! root      330:   gaFlashRects[ID_TIMER3].left   = BUTTONBORDER;
        !           331:   gaFlashRects[ID_TIMER3].top    = cy/2 + 3*TEXTHEIGHT + BUTTONBORDER;
        !           332:   gaFlashRects[ID_TIMER3].right  = cx/2 - BUTTONBORDER;
        !           333:   gaFlashRects[ID_TIMER3].bottom = cy - BUTTONHEIGHT - 2*BUTTONBORDER;
1.1       root      334: 
                    335:                                                   /* lower-right rect */
1.1.1.2 ! root      336:   gaFlashRects[ID_TIMER4].left   = cx/2 + BUTTONBORDER;
        !           337:   gaFlashRects[ID_TIMER4].top    = cy/2 + 3*TEXTHEIGHT + BUTTONBORDER;
        !           338:   gaFlashRects[ID_TIMER4].right  = cx - BUTTONBORDER;
        !           339:   gaFlashRects[ID_TIMER4].bottom = cy - BUTTONHEIGHT - 2*BUTTONBORDER;
1.1       root      340: }
                    341: 
                    342: 
                    343: 
1.1.1.2 ! root      344: /******************************************************************************\
1.1       root      345: *
                    346: *  FUNCTION:    DrawStuff
                    347: *
                    348: *  INPUTS:      hwnd - main window handle
                    349: *               hdc  - DC for main window
                    350: *
1.1.1.2 ! root      351: *  GLOBAL VARS: gaFlashRects - array of flashing rectangles coordinates
1.1       root      352: *                            (not modified)
                    353: *
                    354: *  LOCAL VARS:  rect - client rectangle
                    355: *               hbr  - temporary brush handle
                    356: *
                    357: *  COMMENTS:    Draws separators, "Timer #" headers, & rectangles
                    358: *
1.1.1.2 ! root      359: \******************************************************************************/
1.1       root      360: 
                    361: void DrawStuff (HWND hwnd, HDC hdc)
1.1.1.2 ! root      362: {
        !           363:   RECT   rect;
1.1       root      364:   HBRUSH hbr;
                    365: 
1.1.1.2 ! root      366:   //
        !           367:   // Draw the separator lines between the timer info "windows"
        !           368:   //
        !           369: 
1.1       root      370:   GetClientRect (hwnd, &rect);
                    371:   MoveToEx (hdc, rect.right/2, 0, NULL);
                    372:   LineTo (hdc, rect.right/2, rect.bottom);
                    373: 
                    374:   MoveToEx (hdc, 0, rect.bottom/2, NULL);
                    375:   LineTo (hdc, rect.right, rect.bottom/2);
                    376: 
1.1.1.2 ! root      377:   //
        !           378:   // Draw the "Timer #" headers
        !           379:   //
        !           380: 
1.1       root      381:   TextOut (hdc, BUTTONBORDER, TEXTHEIGHT, "Timer 1:", 8);
                    382:   TextOut (hdc, rect.right/2 + BUTTONBORDER, TEXTHEIGHT, "Timer 2:", 8);
                    383:   TextOut (hdc, BUTTONBORDER, rect.bottom/2 + TEXTHEIGHT, "Timer 3:", 8);
                    384:   TextOut (hdc, rect.right/2 + BUTTONBORDER, rect.bottom/2 + TEXTHEIGHT,
                    385:            "Timer 4:", 8);
                    386: 
1.1.1.2 ! root      387:   //
        !           388:   // Draw the rectangles to flash on timer messages
        !           389:   //
        !           390: 
1.1       root      391:   hbr = CreateSolidBrush (0x0000ff);
1.1.1.2 ! root      392:   FillRect (hdc, &gaFlashRects[ID_TIMER1], hbr);
1.1       root      393:   DeleteObject (hbr);
                    394:   hbr = CreateSolidBrush (0x00ff00);
1.1.1.2 ! root      395:   FillRect (hdc, &gaFlashRects[ID_TIMER2], hbr);
1.1       root      396:   DeleteObject (hbr);
                    397:   hbr = CreateSolidBrush (0xff0000);
1.1.1.2 ! root      398:   FillRect (hdc, &gaFlashRects[ID_TIMER3], hbr);
1.1       root      399:   DeleteObject (hbr);
                    400:   hbr = CreateSolidBrush (0x2266aa);
1.1.1.2 ! root      401:   FillRect (hdc, &gaFlashRects[ID_TIMER4], hbr);
1.1       root      402:   DeleteObject (hbr);
                    403: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.