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