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