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

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

unix.superglobalmegacorp.com

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