update for HEAD-2003091401
[reactos.git] / apps / tests / SampleWindow / window.c
1 /*
2  * A basic example of Win32 programming in C.
3  *
4  * This source code is in the PUBLIC DOMAIN and has NO WARRANTY.
5  *
6  * Colin Peters <colinp at ma.kcom.ne.jp>
7  */
8 #include <windows.h>
9 #include <string.h>
10
11 /*
12  * This is the window function for the main window. Whenever a message is
13  * dispatched using DispatchMessage (or sent with SendMessage) this function
14  * gets called with the contents of the message.
15  */
16 LRESULT CALLBACK
17 MainWndProc (HWND hwnd, UINT nMsg, WPARAM wParam, LPARAM lParam)
18 {
19         /* The window handle for the "Click Me" button. */
20         static HWND   hwndButton = 0;
21         static int    cx, cy;          /* Height and width of our button. */
22
23         HDC           hdc;             /* A device context used for drawing */
24         PAINTSTRUCT   ps;              /* Also used during window drawing */
25         RECT          rc;              /* A rectangle used during drawing */
26
27         /*
28          * Perform processing based on what kind of message we got.
29          */
30         switch (nMsg)
31         {
32                 case WM_CREATE:
33                 {
34                         /* The window is being created. Create our button
35                          * window now. */
36                         TEXTMETRIC        tm;
37
38                         /* First we use the system fixed font size to choose
39                          * a nice button size. */
40                         hdc = GetDC (hwnd);
41                         SelectObject (hdc, GetStockObject (SYSTEM_FIXED_FONT));
42                         GetTextMetrics (hdc, &tm);
43                         cx = tm.tmAveCharWidth * 30;
44                         cy = (tm.tmHeight + tm.tmExternalLeading) * 2;
45                         ReleaseDC (hwnd, hdc);
46
47                         /* Now create the button */
48                         hwndButton = CreateWindow (
49                                 "button",         /* Builtin button class */
50                                 "Click Here",
51                                 WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
52                                 0, 0, cx, cy,
53                                 hwnd,             /* Parent is this window. */
54                                 (HMENU) 1,        /* Control ID: 1 */
55                                 ((LPCREATESTRUCT) lParam)->hInstance,
56                                 NULL
57                                 );
58
59                         return 0;
60                         break;
61                 }
62
63                 case WM_DESTROY:
64                         /* The window is being destroyed, close the application
65                          * (the child button gets destroyed automatically). */
66                         PostQuitMessage (0);
67                         return 0;
68                         break;
69
70                 case WM_PAINT:
71                         /* The window needs to be painted (redrawn). */
72                         hdc = BeginPaint (hwnd, &ps);
73                         GetClientRect (hwnd, &rc);
74
75                         /* Draw "Hello, World" in the middle of the upper
76                          * half of the window. */
77                         rc.bottom = rc.bottom / 2;
78                         DrawText (hdc, "Hello, World", -1, &rc,
79                                 DT_SINGLELINE | DT_CENTER | DT_VCENTER);
80
81                         EndPaint (hwnd, &ps);
82                         return 0;
83                         break;
84
85                 case WM_SIZE:
86                         /* The window size is changing. If the button exists
87                          * then place it in the center of the bottom half of
88                          * the window. */
89                         if (hwndButton &&
90                                 (wParam == SIZEFULLSCREEN ||
91                                  wParam == SIZENORMAL)
92                            )
93                         {
94                                 rc.left = (LOWORD(lParam) - cx) / 2;
95                                 rc.top = HIWORD(lParam) * 3 / 4 - cy / 2;
96                                 MoveWindow (
97                                         hwndButton,
98                                         rc.left, rc.top, cx, cy, TRUE);
99                         }
100                         break;
101
102                 case WM_COMMAND:
103                         /* Check the control ID, notification code and
104                          * control handle to see if this is a button click
105                          * message from our child button. */
106                         if (LOWORD(wParam) == 1 &&
107                             HIWORD(wParam) == BN_CLICKED &&
108                             (HWND) lParam == hwndButton)
109                         {
110                                 /* Our button was clicked. Close the window. */
111                                 DestroyWindow (hwnd);
112                         }
113                         return 0;
114                         break;
115         }
116
117         /* If we don't handle a message completely we hand it to the system
118          * provided default window function. */
119         return DefWindowProc (hwnd, nMsg, wParam, lParam);
120 }
121
122
123 int STDCALL
124 WinMain (HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpCmd, int nShow)
125 {
126         HWND         hwndMain;        /* Handle for the main window. */
127         MSG          msg;             /* A Win32 message structure. */
128         WNDCLASSEX   wndclass;        /* A window class structure. */
129         char*        szMainWndClass = "WinTestWin";
130                                       /* The name of the main window class */
131
132         /*
133          * First we create a window class for our main window.
134          */
135
136         /* Initialize the entire structure to zero. */
137         memset (&wndclass, 0, sizeof(WNDCLASSEX));
138
139         /* This class is called WinTestWin */
140         wndclass.lpszClassName = szMainWndClass;
141
142         /* cbSize gives the size of the structure for extensibility. */
143         wndclass.cbSize = sizeof(WNDCLASSEX);
144
145         /* All windows of this class redraw when resized. */
146         wndclass.style = CS_HREDRAW | CS_VREDRAW;
147
148         /* All windows of this class use the MainWndProc window function. */
149         wndclass.lpfnWndProc = MainWndProc;
150
151         /* This class is used with the current program instance. */
152         wndclass.hInstance = hInst;
153
154         /* Use standard application icon and arrow cursor provided by the OS */
155         wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION);
156         wndclass.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
157         wndclass.hCursor = LoadCursor (NULL, IDC_ARROW);
158
159         /* Color the background white */
160         wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH);
161
162         /*
163          * Now register the window class for use.
164          */
165         RegisterClassEx (&wndclass);
166
167         /*
168          * Create our main window using that window class.
169          */
170         hwndMain = CreateWindow (
171                 szMainWndClass,             /* Class name */
172                 "Hello",                    /* Caption */
173                 WS_OVERLAPPEDWINDOW,        /* Style */
174                 CW_USEDEFAULT,              /* Initial x (use default) */
175                 CW_USEDEFAULT,              /* Initial y (use default) */
176                 CW_USEDEFAULT,              /* Initial x size (use default) */
177                 CW_USEDEFAULT,              /* Initial y size (use default) */
178                 NULL,                       /* No parent window */
179                 NULL,                       /* No menu */
180                 hInst,                      /* This program instance */
181                 NULL                        /* Creation parameters */
182                 );
183         
184         /*
185          * Display the window which we just created (using the nShow
186          * passed by the OS, which allows for start minimized and that
187          * sort of thing).
188          */
189         ShowWindow (hwndMain, nShow);
190         UpdateWindow (hwndMain);
191
192         /*
193          * The main message loop. All messages being sent to the windows
194          * of the application (or at least the primary thread) are retrieved
195          * by the GetMessage call, then translated (mainly for keyboard
196          * messages) and dispatched to the appropriate window procedure.
197          * This is the simplest kind of message loop. More complex loops
198          * are required for idle processing or handling modeless dialog
199          * boxes. When one of the windows calls PostQuitMessage GetMessage
200          * will return zero and the wParam of the message will be filled
201          * with the argument to PostQuitMessage. The loop will end and
202          * the application will close.
203          */
204         while (GetMessage (&msg, NULL, 0, 0))
205         {
206                 TranslateMessage (&msg);
207                 DispatchMessage (&msg);
208         }
209         return msg.wParam;
210 }
211
212 /* EOF */