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 } 705