Moving the tests
[reactos.git] / rosapps / tests / winhello / winhello.c
1 /*
2 * ReactOS Winhello - Not So Simple Win32 Windowing test
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 */
18
19 /* What do we test with this app?
20 * - Windows and Class creation
21 * - A Simple Button
22 * - Some font rendering in the Window
23 * - Scrollbar support
24 * - Hotkeys
25 * - Messageboxes
26 * ????????
27 */
28
29 #include <windows.h>
30 #include <stdio.h>
31 #include <tchar.h>
32
33 HFONT tf;
34 LRESULT WINAPI MainWndProc(HWND, UINT, WPARAM, LPARAM);
35 BOOLEAN bolWM_CHAR;
36 BOOLEAN bolWM_KEYDOWN;
37
38 int WINAPI
39 WinMain(HINSTANCE hInstance,
40 HINSTANCE hPrevInstance,
41 LPSTR lpszCmdLine,
42 int nCmdShow)
43 {
44 WNDCLASS wc;
45 MSG msg;
46 HWND hWnd;
47 bolWM_CHAR = 0;
48 bolWM_KEYDOWN = 0;
49
50 wc.lpszClassName = "HelloClass";
51 wc.lpfnWndProc = MainWndProc;
52 wc.style = CS_VREDRAW | CS_HREDRAW;
53 wc.hInstance = hInstance;
54 wc.hIcon = LoadIcon(NULL, (LPCTSTR)IDI_APPLICATION);
55 wc.hCursor = LoadCursor(NULL, (LPCTSTR)IDC_ARROW);
56 wc.hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH);
57 wc.lpszMenuName = NULL;
58 wc.cbClsExtra = 0;
59 wc.cbWndExtra = 0;
60 if (RegisterClass(&wc) == 0)
61 {
62 fprintf(stderr, "RegisterClass failed (last error 0x%lX)\n",
63 GetLastError());
64 return(1);
65 }
66
67 hWnd = CreateWindow("HelloClass",
68 "Hello World",
69 WS_OVERLAPPEDWINDOW|WS_HSCROLL|WS_VSCROLL,
70 0, //Position; you can use CW_USEDEFAULT, too
71 0,
72 600, //height
73 400,
74 NULL,
75 NULL,
76 hInstance,
77 NULL);
78 if (hWnd == NULL)
79 {
80 fprintf(stderr, "CreateWindow failed (last error 0x%lX)\n",
81 GetLastError());
82 return(1);
83 }
84
85 tf = CreateFontA(14, 0, 0, TA_BASELINE, FW_NORMAL, FALSE, FALSE, FALSE,
86 ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
87 DEFAULT_QUALITY, FIXED_PITCH|FF_DONTCARE, "Timmons");
88
89 ShowWindow(hWnd, nCmdShow);
90
91 while(GetMessage(&msg, NULL, 0, 0))
92 {
93 TranslateMessage(&msg);
94 DispatchMessage(&msg);
95 }
96
97 DeleteObject(tf);
98
99 return msg.wParam;
100 }
101
102 #define CTRLC 1 /* Define our HotKeys */
103 #define ALTF1 2 /* Define our HotKeys */
104
105 LRESULT CALLBACK MainWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
106 {
107 PAINTSTRUCT ps; /* Also used during window drawing */
108 HDC hDC; /* A device context used for drawing */
109 RECT rc, clr, wir; /* A rectangle used during drawing */
110 char spr[100], sir[100];
111 static HBRUSH hbrWhite=NULL, hbrGray=NULL, hbrBlack=NULL, hbrRed=NULL, hbrBlue=NULL, hbrYellow=NULL;
112
113 /* The window handle for the "Click Me" button. */
114 static HWND hwndButton = 0;
115 static int cx, cy; /* Height and width of our button. */
116
117 switch(msg)
118 {
119
120 case WM_CHAR:
121 {
122
123 hDC = GetDC(hWnd);
124 TCHAR text[2];
125 text[0] = (TCHAR)wParam;
126 text[1] = _T('\0');
127
128 //Write in window
129 if( bolWM_KEYDOWN )
130 {
131 TextOut(hDC, 400, 10, "WM CHAR:", strlen("WM CHAR:"));
132 bolWM_KEYDOWN = 0;
133 }
134 else
135 {
136 TextOut(hDC, 400, 10, "WM_CHAR:", strlen("WM_CHAR:"));
137 bolWM_KEYDOWN = 1;
138 }
139 TextOut(hDC, 530, 10, text, strlen(text));
140
141 #if 0
142 // Make a line depending on the typed key
143 Rect.left = 10;
144 Rect.top = 75;
145 Rect.right = 610;
146 Rect.bottom = 85;
147 FillRect(hDC, &Rect, hbrWhite);
148
149 Rect.left=308;
150 Rect.right=312;
151 FillRect(hDC, &Rect, hbrRed);
152
153 Rect.left = 310;
154 Rect.top = 75;
155 Rect.right = 310 +text[0]*2;
156 Rect.bottom = 85;
157 HBRUSH hbrCustom = CreateSolidBrush ( RGB(text[0], text[0], text[0]));
158 FillRect(hDC, &Rect, hbrCustom);
159 DeleteObject ( hbrCustom );
160
161 #endif
162
163 ReleaseDC(hWnd, hDC);
164 return 0;
165 }
166
167 case WM_KEYDOWN:
168 {
169
170 hDC = GetDC(hWnd);
171 RECT Rect;
172 TCHAR text[2];
173 text[0] = (TCHAR)wParam;
174 text[1] = _T('\0');
175
176
177 /* Write in window */
178 Rect.left = 400;
179 Rect.top = 50;
180 Rect.right = 550;
181 Rect.bottom = 70;
182 FillRect(hDC, &Rect, hbrWhite);
183 if( bolWM_CHAR )
184 {
185 TextOut(hDC, 400, 30, "WM KEYDOWN:", strlen("WM KEYDOWN:"));
186 bolWM_CHAR = 0;
187 }
188 else
189 {
190 TextOut(hDC, 400, 30, "WM_KEYDOWN:", strlen("WM_KEYDOWN:"));
191 bolWM_CHAR = 1;
192 }
193 TextOut(hDC, 530, 30, text, strlen(text));
194 ReleaseDC(hWnd, hDC);
195 return 0;
196 }
197
198 case WM_KEYUP:
199 {
200
201 hDC = GetDC(hWnd);
202 RECT Rect;
203 TCHAR text[2];
204 text[0] = (TCHAR)wParam;
205 text[1] = _T('\0');
206
207
208 /* Write in window */
209 Rect.left = 400;
210 Rect.top = 10;
211 Rect.right = 550;
212 Rect.bottom = 70;
213 FillRect(hDC, &Rect, hbrWhite);
214 TextOut(hDC, 400, 50, "WM_KEYUP:", strlen("WM_KEYUP:"));
215 TextOut(hDC, 530, 50, text, strlen(text));
216 ReleaseDC(hWnd, hDC);
217 return 0;
218 }
219
220
221 case WM_LBUTTONDOWN:
222 {
223 ULONG x, y;
224 RECT Rect;
225 hDC = GetDC(hWnd);
226 x = LOWORD(lParam);
227 y = HIWORD(lParam);
228
229 Rect.left = x - 5;
230 Rect.top = y - 5;
231 Rect.right = x + 5;
232 Rect.bottom = y + 5;
233 FillRect(hDC, &Rect, hbrRed);
234
235 Rect.left = x - 3;
236 Rect.top = y - 3;
237 Rect.right = x + 3;
238 Rect.bottom = y + 3;
239 FillRect(hDC, &Rect, hbrBlack);
240
241 ReleaseDC(hWnd, hDC);
242 break;
243 }
244 case WM_LBUTTONUP:
245 {
246 ULONG x, y;
247 RECT Rect;
248 hDC = GetDC(hWnd);
249 x = LOWORD(lParam);
250 y = HIWORD(lParam);
251
252 Rect.left = x - 5;
253 Rect.top = y - 5;
254 Rect.right = x + 5;
255 Rect.bottom = y + 5;
256 FillRect(hDC, &Rect, hbrRed);
257
258 Rect.left = x - 3;
259 Rect.top = y - 3;
260 Rect.right = x + 3;
261 Rect.bottom = y + 3;
262 FillRect(hDC, &Rect, hbrGray);
263
264 ReleaseDC(hWnd, hDC);
265 break;
266 }
267 case WM_MBUTTONDOWN:
268 {
269 ULONG x, y;
270 RECT Rect;
271 hDC = GetDC(hWnd);
272 x = LOWORD(lParam);
273 y = HIWORD(lParam);
274
275 Rect.left = x - 5;
276 Rect.top = y - 5;
277 Rect.right = x + 5;
278 Rect.bottom = y + 5;
279 FillRect(hDC, &Rect, hbrBlue);
280
281 Rect.left = x - 3;
282 Rect.top = y - 3;
283 Rect.right = x + 3;
284 Rect.bottom = y + 3;
285 FillRect(hDC, &Rect, hbrBlack);
286
287 ReleaseDC(hWnd, hDC);
288 break;
289 }
290 case WM_MBUTTONUP:
291 {
292 ULONG x, y;
293 RECT Rect;
294 hDC = GetDC(hWnd);
295 x = LOWORD(lParam);
296 y = HIWORD(lParam);
297
298 Rect.left = x - 5;
299 Rect.top = y - 5;
300 Rect.right = x + 5;
301 Rect.bottom = y + 5;
302 FillRect(hDC, &Rect, hbrBlue);
303
304 Rect.left = x - 3;
305 Rect.top = y - 3;
306 Rect.right = x + 3;
307 Rect.bottom = y + 3;
308 FillRect(hDC, &Rect, hbrGray);
309
310 ReleaseDC(hWnd, hDC);
311 break;
312 }
313 case WM_RBUTTONDOWN:
314 {
315 ULONG x, y;
316 RECT Rect;
317 hDC = GetDC(hWnd);
318 x = LOWORD(lParam);
319 y = HIWORD(lParam);
320
321 Rect.left = x - 5;
322 Rect.top = y - 5;
323 Rect.right = x + 5;
324 Rect.bottom = y + 5;
325 FillRect(hDC, &Rect, hbrYellow);
326
327 Rect.left = x - 3;
328 Rect.top = y - 3;
329 Rect.right = x + 3;
330 Rect.bottom = y + 3;
331 FillRect(hDC, &Rect, hbrBlack);
332
333 ReleaseDC(hWnd, hDC);
334 break;
335 }
336 case WM_RBUTTONUP:
337 {
338 ULONG x, y;
339 RECT Rect;
340 hDC = GetDC(hWnd);
341 x = LOWORD(lParam);
342 y = HIWORD(lParam);
343
344 Rect.left = x - 5;
345 Rect.top = y - 5;
346 Rect.right = x + 5;
347 Rect.bottom = y + 5;
348 FillRect(hDC, &Rect, hbrYellow);
349
350 Rect.left = x - 3;
351 Rect.top = y - 3;
352 Rect.right = x + 3;
353 Rect.bottom = y + 3;
354 FillRect(hDC, &Rect, hbrGray);
355
356 ReleaseDC(hWnd, hDC);
357 break;
358 }
359
360 case WM_MOUSEMOVE:
361 {
362 int fwKeys;
363 int x;
364 int y;
365 RECT Rect;
366 int temp;
367 TCHAR text[256];
368
369 hDC = GetDC(hWnd);
370 fwKeys = wParam; // key flags
371 x = LOWORD(lParam); // horizontal position of cursor
372 y = HIWORD(lParam); // vertical position of cursor
373
374 Rect.left = 10;
375 Rect.top = 100;
376 Rect.right = 160;
377 Rect.bottom = 300;
378 FillRect(hDC, &Rect, hbrWhite);
379
380 temp = _sntprintf ( text, sizeof(text)/sizeof(*text), _T("x: %d"), x );
381 TextOut(hDC,10,100,text,strlen(text));
382 temp = _sntprintf ( text, sizeof(text)/sizeof(*text), _T("y: %d"), y );
383 TextOut(hDC,10,120,text,strlen(text));
384
385 Rect.left = x - 2;
386 Rect.top = y - 2;
387 Rect.right = x + 2;
388 Rect.bottom = y + 2;
389
390 switch ( fwKeys )
391 {
392 case MK_CONTROL:
393 TextOut(hDC,10,140,"Control",strlen("Control"));
394 break;
395 case MK_SHIFT:
396 TextOut(hDC,10,160,"Shift",strlen("Shift"));
397 break;
398 case MK_LBUTTON:
399 TextOut(hDC,10,180,"Left",strlen("Left"));
400 FillRect(hDC, &Rect, hbrRed);
401 break;
402 case MK_MBUTTON:
403 TextOut(hDC,10,200,"Middle",strlen("Middle"));
404 FillRect(hDC, &Rect, hbrBlue);
405 break;
406 case MK_RBUTTON:
407 TextOut(hDC,10,220,"Right",strlen("Right"));
408 FillRect(hDC, &Rect, hbrYellow);
409 break;
410 }
411 ReleaseDC(hWnd, hDC);
412 break;
413 }
414
415 case WM_HSCROLL:
416 {
417 int nPos;
418 int temp;
419 RECT Rect;
420 int nScrollCode;
421 HWND hwndScrollBar;
422 TCHAR text[256];
423 SCROLLINFO Scrollparameter;
424 nScrollCode = (int) LOWORD(wParam); // scroll bar value
425 nPos = (short int) HIWORD(wParam); // scroll box position
426 hwndScrollBar = (HWND) lParam; // handle to scroll bar
427 hDC = GetDC(hWnd);
428
429 Scrollparameter.cbSize = sizeof(Scrollparameter);
430 Scrollparameter.fMask = SIF_ALL;
431 GetScrollInfo ( hWnd, SB_HORZ, &Scrollparameter );
432
433 Rect.left = 200;
434 Rect.top = 100;
435 Rect.right = 350;
436 Rect.bottom = 300;
437 FillRect(hDC, &Rect, hbrWhite);
438
439 switch ( nScrollCode )
440 {
441 case SB_ENDSCROLL: //Ends scroll.
442 TextOut(hDC,200,120,"SB_ENDSCROLL ",16);
443 Scrollparameter.nPos = Scrollparameter.nPos;
444 break;
445 case SB_LEFT: //Scrolls to the upper left.
446 TextOut(hDC,200,140,"SB_LEFT ",16);
447 Scrollparameter.nPos = Scrollparameter.nMin;
448 break;
449 case SB_RIGHT: //Scrolls to the lower right.
450 TextOut(hDC,200,160,"SB_RIGHT ",16);
451 Scrollparameter.nPos = Scrollparameter.nMax;
452 break;
453 case SB_LINELEFT: //Scrolls left by one unit.
454 TextOut(hDC,200,180,"SB_LINELEFT ",16);
455 Scrollparameter.nPos--;
456 break;
457 case SB_LINERIGHT: //Scrolls right by one unit.
458 TextOut(hDC,200,200,"SB_LINERIGHT ",16);
459 Scrollparameter.nPos++;
460 break;
461 case SB_PAGELEFT: //Scrolls left by the width of the window.
462 TextOut(hDC,200,220,"SB_PAGELEFT ",16);
463 Scrollparameter.nPos -= Scrollparameter.nPage;
464 break;
465 case SB_PAGERIGHT: //Scrolls right by the width of the window.
466 TextOut(hDC,200,240,"PAGERIGHT ",16);
467 Scrollparameter.nPos += Scrollparameter.nPage;
468 break;
469 case SB_THUMBPOSITION: //The user has dragged the scroll box (thumb) and released the mouse button. The nPos parameter indicates the position of the scroll box at the end of the drag operation.
470 TextOut(hDC,200,260,"SB_THUMBPOSITION",16);
471 Scrollparameter.nPos = Scrollparameter.nTrackPos;
472 break;
473 case SB_THUMBTRACK: //
474 TextOut(hDC,200,280,"SB_THUMBTRACK ",16);
475 Scrollparameter.nPos = Scrollparameter.nTrackPos;
476 break;
477 }
478
479 SetScrollInfo(
480 hWnd, // handle to window with scroll bar
481 SB_HORZ, // scroll bar flag
482 &Scrollparameter, // pointer to structure with scroll parameters
483 1 // redraw flag
484 );
485 temp = _sntprintf ( text, sizeof(text)/sizeof(*text), _T("Horizontal: %d"), Scrollparameter.nPos );
486 TextOut(hDC,200,100,text,strlen(text));
487 ReleaseDC(hWnd, hDC);
488 return 0;
489 }
490
491 case WM_VSCROLL:
492 {
493 int nPos;
494 int temp;
495 RECT Rect;
496 int nScrollCode;
497 HWND hwndScrollBar;
498 TCHAR text[256];
499 SCROLLINFO Scrollparameter;
500 nScrollCode = (int) LOWORD(wParam); // scroll bar value
501 nPos = (short int) HIWORD(wParam); // scroll box position
502 hwndScrollBar = (HWND) lParam; // handle to scroll bar
503 hDC = GetDC(hWnd);
504
505 Scrollparameter.cbSize = sizeof(Scrollparameter);
506 Scrollparameter.fMask = SIF_ALL;
507 GetScrollInfo ( hWnd, SB_VERT, &Scrollparameter );
508
509 Rect.left = 400;
510 Rect.top = 100;
511 Rect.right = 550;
512 Rect.bottom = 300;
513 FillRect(hDC, &Rect, hbrWhite);
514
515 switch ( nScrollCode )
516 {
517 case SB_ENDSCROLL: //Ends scroll.
518 TextOut(hDC,400,120,"SB_ENDSCROLL ",16);
519 Scrollparameter.nPos = Scrollparameter.nPos;
520 break;
521 case SB_LEFT: //Scrolls to the upper left.
522 TextOut(hDC,400,140,"SB_LEFT ",16);
523 Scrollparameter.nPos = Scrollparameter.nMin;
524 break;
525 case SB_RIGHT: //Scrolls to the lower right.
526 TextOut(hDC,400,160,"SB_RIGHT ",16);
527 Scrollparameter.nPos = Scrollparameter.nMax;
528 break;
529 case SB_LINELEFT: //Scrolls left by one unit.
530 TextOut(hDC,400,180,"SB_LINELEFT ",16);
531 Scrollparameter.nPos--;
532 break;
533 case SB_LINERIGHT: //Scrolls right by one unit.
534 TextOut(hDC,400,200,"SB_LINERIGHT ",16);
535 Scrollparameter.nPos++;
536 break;
537 case SB_PAGELEFT: //Scrolls left by the width of the window.
538 TextOut(hDC,400,220,"SB_PAGELEFT ",16);
539 Scrollparameter.nPos -= Scrollparameter.nPage;
540 break;
541 case SB_PAGERIGHT: //Scrolls right by the width of the window.
542 TextOut(hDC,400,240,"PAGERIGHT ",16);
543 Scrollparameter.nPos += Scrollparameter.nPage;
544 break;
545 case SB_THUMBPOSITION: //The user has dragged the scroll box (thumb) and released the mouse button. The nPos parameter indicates the position of the scroll box at the end of the drag operation.
546 TextOut(hDC,400,260,"SB_THUMBPOSITION",16);
547 Scrollparameter.nPos = Scrollparameter.nTrackPos;
548 break;
549 case SB_THUMBTRACK: //
550 TextOut(hDC,400,280,"SB_THUMBTRACK ",16);
551 Scrollparameter.nPos = Scrollparameter.nTrackPos;
552 break;
553 }
554
555 SetScrollInfo(
556 hWnd, // handle to window with scroll bar
557 SB_VERT, // scroll bar flag
558 &Scrollparameter, // pointer to structure with scroll parameters
559 1 // redraw flag
560 );
561 temp = _sntprintf ( text, sizeof(text)/sizeof(*text), _T("Vertical: %d"), Scrollparameter.nPos );
562 TextOut(hDC,400,100,text,strlen(text));
563 ReleaseDC(hWnd, hDC);
564 return 0;
565 }
566
567 case WM_HOTKEY:
568 switch(wParam)
569 {
570 case CTRLC:
571 MessageBox(hWnd, "You just pressed Ctrl+C", "Hotkey", MB_OK | MB_ICONINFORMATION);
572 break;
573 case ALTF1:
574 MessageBox(hWnd, "You just pressed Ctrl+Alt+F1", "Hotkey", MB_OK | MB_ICONINFORMATION);
575 break;
576 }
577 break;
578
579 case WM_DESTROY:
580 UnregisterHotKey(hWnd, CTRLC);
581 UnregisterHotKey(hWnd, ALTF1);
582 PostQuitMessage(0);
583 DeleteObject ( hbrWhite );
584 DeleteObject ( hbrGray );
585 DeleteObject ( hbrBlack );
586 DeleteObject ( hbrRed );
587 DeleteObject ( hbrBlue );
588 DeleteObject ( hbrYellow );
589 break;
590
591 case WM_CREATE:
592 {
593 /* Register a Ctrl+Alt+C hotkey*/
594 RegisterHotKey(hWnd, CTRLC, MOD_CONTROL, VK_C);
595 RegisterHotKey(hWnd, ALTF1, MOD_CONTROL | MOD_ALT, VK_F1);
596
597 hbrWhite = CreateSolidBrush ( RGB(0xFF, 0xFF, 0xFF));
598 hbrGray = CreateSolidBrush ( RGB(0xAF, 0xAF, 0xAF));
599 hbrBlack = CreateSolidBrush ( RGB(0x00, 0x00, 0x00));
600 hbrRed = CreateSolidBrush ( RGB(0xFF, 0x00, 0x00));
601 hbrBlue = CreateSolidBrush ( RGB(0x00, 0x00, 0xFF));
602 hbrYellow = CreateSolidBrush ( RGB(0xFF, 0xFF, 0x00));
603
604 SCROLLINFO si;
605 si.cbSize = sizeof(si);
606 si.fMask = SIF_ALL;
607 si.nMin = 0;
608 si.nMax = 100;
609 si.nPage = 5;
610 si.nPos = 0;
611
612 SetScrollInfo ( hWnd, SB_HORZ, &si, FALSE );
613 SetScrollInfo ( hWnd, SB_VERT, &si, FALSE );
614
615
616 /* The window is being created. Create our button
617 * window now. */
618 TEXTMETRIC tm;
619
620 /* First we use the system fixed font size to choose
621 * a nice button size. */
622 hDC = GetDC (hWnd);
623 SelectObject (hDC, GetStockObject (SYSTEM_FIXED_FONT));
624 GetTextMetrics (hDC, &tm);
625 cx = tm.tmAveCharWidth * 30;
626 cy = (tm.tmHeight + tm.tmExternalLeading) * 2;
627 ReleaseDC (hWnd, hDC);
628
629 /* Now create the button */
630 hwndButton = CreateWindow (
631 "button", /* Builtin button class */
632 "Click Here",
633 WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
634 0, 0, cx, cy,
635 hWnd, /* Parent is this window. */
636 (HMENU) 1, /* Control ID: 1 */
637 ((LPCREATESTRUCT) lParam)->hInstance,
638 NULL
639 );
640
641 return 0;
642 break;
643 }
644
645 case WM_PAINT:
646 hDC = BeginPaint(hWnd, &ps);
647 TextOut(hDC, 10, 10, "Hello World from ReactOS!",
648 strlen("Hello World from ReactOS!"));
649 TextOut(hDC, 10, 80, "Press Ctrl+C or Ctrl+Alt+F1 to test Hotkey support.",
650 strlen("Press Ctrl+C or Ctrl+Alt+F1 to test Hotkey support."));
651 GetClientRect(hWnd, &clr);
652 GetWindowRect(hWnd, &wir);
653 sprintf(spr, "%lu,%lu,%lu,%lu ", clr.left, clr.top, clr.right, clr.bottom);
654 sprintf(sir, "%lu,%lu,%lu,%lu ", wir.left, wir.top, wir.right, wir.bottom);
655 TextOut(hDC, 10, 30, spr, 20);
656 TextOut(hDC, 10, 50, sir, 20);
657
658 /* Draw "Hello, World" in the middle of the upper
659 * half of the window. */
660 rc.bottom = rc.bottom / 2;
661 DrawText (hDC, "Hello, World", -1, &rc,
662 DT_SINGLELINE | DT_CENTER | DT_VCENTER);
663
664 EndPaint (hWnd, &ps);
665 return 0;
666 break;
667
668 case WM_SIZE:
669 /* The window size is changing. If the button exists
670 * then place it in the center of the bottom half of
671 * the window. */
672 if (hwndButton &&
673 (wParam == SIZEFULLSCREEN ||
674 wParam == SIZENORMAL)
675 )
676 {
677 rc.left = (LOWORD(lParam) - cx) / 2;
678 rc.top = HIWORD(lParam) * 3 / 4 - cy / 2;
679 MoveWindow (
680 hwndButton,
681 rc.left, rc.top, cx, cy, TRUE);
682 }
683 break;
684
685 case WM_COMMAND:
686 /* Check the control ID, notification code and
687 * control handle to see if this is a button click
688 * message from our child button. */
689 if (LOWORD(wParam) == 1 &&
690 HIWORD(wParam) == BN_CLICKED &&
691 (HWND) lParam == hwndButton)
692 {
693 /* Our button was clicked. Close the window. */
694 DestroyWindow (hWnd);
695 }
696 return 0;
697 break;
698
699 default:
700 return DefWindowProc(hWnd, msg, wParam, lParam);
701 }
702 return 0;
703 }