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

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

unix.superglobalmegacorp.com

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