|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.