|
|
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.