SetMenu should always call SetWindowPos whether the window is visible
[wine.git] / dlls / user / tests / msg.c
blob3bf3d42ba585e8b4e0dbef06bf044c76bbf74d25
1 /*
2 * Unit tests for window message handling
4 * Copyright 1999 Ove Kaaven
5 * Copyright 2003 Dimitrie O. Paun
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #include <assert.h>
23 #include <stdlib.h>
24 #include <stdarg.h>
25 #include <stdio.h>
27 #include "windef.h"
28 #include "winbase.h"
29 #include "wingdi.h"
30 #include "winuser.h"
32 #include "wine/test.h"
36 FIXME: add tests for these
37 Window Edge Styles (Win31/Win95/98 look), in order of precedence:
38 WS_EX_DLGMODALFRAME: double border, WS_CAPTION allowed
39 WS_THICKFRAME: thick border
40 WS_DLGFRAME: double border, WS_CAPTION not allowed (but possibly shown anyway)
41 WS_BORDER (default for overlapped windows): single black border
42 none (default for child (and popup?) windows): no border
45 typedef enum {
46 sent=0x1, posted=0x2, parent=0x4, wparam=0x8, lparam=0x10,
47 defwinproc=0x20
48 } msg_flags_t;
50 struct message {
51 UINT message; /* the WM_* code */
52 msg_flags_t flags; /* message props */
53 WPARAM wParam; /* expacted value of wParam */
54 LPARAM lParam; /* expacted value of lParam */
57 /* CreateWindow (for overlapped window, not initially visible) (16/32) */
58 static struct message WmCreateOverlappedSeq[] = {
59 { WM_GETMINMAXINFO, sent },
60 { WM_NCCREATE, sent },
61 { WM_NCCALCSIZE, sent|wparam, 0 },
62 { WM_CREATE, sent },
63 { 0 }
65 /* ShowWindow (for overlapped window) (16/32) */
66 static struct message WmShowOverlappedSeq[] = {
67 { WM_SHOWWINDOW, sent|wparam, 1 },
68 { WM_WINDOWPOSCHANGING, sent|wparam, /*FIXME: SWP_NOMOVE|SWP_NOSIZE|SWP_SHOWWINDOW*/ 0 },
69 /* FIXME: WM_QUERYNEWPALETTE, if in 256-color mode */
70 { WM_WINDOWPOSCHANGING, sent|wparam, /*FIXME: SWP_NOMOVE|SWP_NOSIZE*/ 0 },
71 { WM_ACTIVATEAPP, sent|wparam, 1 },
72 { WM_NCACTIVATE, sent|wparam, 1 },
73 { WM_GETTEXT, sent|defwinproc },
74 { WM_ACTIVATE, sent|wparam, 1 },
75 { WM_SETFOCUS, sent|wparam|defwinproc, 0 },
76 { WM_NCPAINT, sent|wparam, 1 },
77 { WM_GETTEXT, sent|defwinproc },
78 { WM_ERASEBKGND, sent },
79 { WM_WINDOWPOSCHANGED, sent|wparam, SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER|SWP_SHOWWINDOW },
80 { WM_SIZE, sent },
81 { WM_MOVE, sent },
82 { 0 }
85 /* DestroyWindow (for overlapped window) (32) */
86 static struct message WmDestroyOverlappedSeq[] = {
87 { WM_WINDOWPOSCHANGING, sent|wparam, 0 },
88 { WM_WINDOWPOSCHANGED, sent|wparam, 0 },
89 { WM_NCACTIVATE, sent|wparam, 0 },
90 { WM_ACTIVATE, sent|wparam, 0 },
91 { WM_ACTIVATEAPP, sent|wparam, 0 },
92 { WM_KILLFOCUS, sent|wparam, 0 },
93 { WM_DESTROY, sent },
94 { WM_NCDESTROY, sent },
95 { 0 }
97 /* CreateWindow (for child window, not initially visible) */
98 static struct message WmCreateChildSeq[] = {
99 { WM_NCCREATE, sent },
100 /* child is inserted into parent's child list after WM_NCCREATE returns */
101 { WM_NCCALCSIZE, sent|wparam, 0 },
102 { WM_CREATE, sent },
103 { WM_SIZE, sent },
104 { WM_MOVE, sent },
105 { WM_PARENTNOTIFY, sent|parent|wparam, 1 },
106 { 0 }
108 /* ShowWindow (for child window) */
109 static struct message WmShowChildSeq[] = {
110 { WM_SHOWWINDOW, sent|wparam, 1 },
111 { WM_WINDOWPOSCHANGING, sent|wparam, 0 },
112 { WM_ERASEBKGND, sent|parent },
113 { WM_WINDOWPOSCHANGED, sent|wparam, 0 },
114 { 0 }
116 /* DestroyWindow (for child window) */
117 static struct message WmDestroyChildSeq[] = {
118 { WM_PARENTNOTIFY, sent|parent|wparam, 2 },
119 { WM_SHOWWINDOW, sent|wparam, 0 },
120 { WM_WINDOWPOSCHANGING, sent|wparam, 0 },
121 { WM_ERASEBKGND, sent|parent },
122 { WM_WINDOWPOSCHANGED, sent|wparam, 0 },
123 { WM_DESTROY, sent },
124 { WM_NCDESTROY, sent },
125 { 0 }
127 /* Moving the mouse in nonclient area */
128 static struct message WmMouseMoveInNonClientAreaSeq[] = { /* FIXME: add */
129 { WM_NCHITTEST, sent },
130 { WM_SETCURSOR, sent },
131 { WM_NCMOUSEMOVE, posted },
132 { 0 }
134 /* Moving the mouse in client area */
135 static struct message WmMouseMoveInClientAreaSeq[] = { /* FIXME: add */
136 { WM_NCHITTEST, sent },
137 { WM_SETCURSOR, sent },
138 { WM_MOUSEMOVE, posted },
139 { 0 }
141 /* Moving by dragging the title bar (after WM_NCHITTEST and WM_SETCURSOR) (outline move) */
142 static struct message WmDragTitleBarSeq[] = { /* FIXME: add */
143 { WM_NCLBUTTONDOWN, sent|wparam, HTCAPTION },
144 { WM_SYSCOMMAND, sent|defwinproc|wparam, SC_MOVE+2 },
145 { WM_GETMINMAXINFO, sent|defwinproc },
146 { WM_ENTERSIZEMOVE, sent|defwinproc },
147 { WM_WINDOWPOSCHANGING, sent|defwinproc },
148 { WM_WINDOWPOSCHANGED, sent|defwinproc },
149 { WM_MOVE, sent|defwinproc },
150 { WM_EXITSIZEMOVE, sent|defwinproc },
151 { 0 }
153 /* Sizing by dragging the thick borders (after WM_NCHITTEST and WM_SETCURSOR) (outline move) */
154 static struct message WmDragThinkBordersBarSeq[] = { /* FIXME: add */
155 { WM_NCLBUTTONDOWN, sent|wparam, 0xd },
156 { WM_SYSCOMMAND, sent|defwinproc|wparam, 0xf004 },
157 { WM_GETMINMAXINFO, sent|defwinproc },
158 { WM_ENTERSIZEMOVE, sent|defwinproc },
159 { WM_SIZING, sent|defwinproc|wparam, 4}, /* one for each mouse movement */
160 { WM_WINDOWPOSCHANGING, sent|defwinproc },
161 { WM_GETMINMAXINFO, sent|defwinproc },
162 { WM_NCCALCSIZE, sent|defwinproc|wparam, 1 },
163 { WM_NCPAINT, sent|defwinproc|wparam, 1 },
164 { WM_GETTEXT, sent|defwinproc },
165 { WM_ERASEBKGND, sent|defwinproc },
166 { WM_WINDOWPOSCHANGED, sent|defwinproc },
167 { WM_MOVE, sent|defwinproc },
168 { WM_SIZE, sent|defwinproc },
169 { WM_EXITSIZEMOVE, sent|defwinproc },
170 { 0 }
172 /* Resizing child window with MoveWindow (32) */
173 static struct message WmResizingChildWithMoveWindowSeq[] = {
174 { WM_WINDOWPOSCHANGING, sent },
175 { WM_NCCALCSIZE, sent|wparam, 1 },
176 { WM_ERASEBKGND, sent },
177 { WM_WINDOWPOSCHANGED, sent },
178 { WM_MOVE, sent|defwinproc },
179 { WM_SIZE, sent|defwinproc },
180 { 0 }
182 /* Clicking on inactive button */
183 static struct message WmClickInactiveButtonSeq[] = { /* FIXME: add */
184 { WM_NCHITTEST, sent },
185 { WM_PARENTNOTIFY, sent|parent|wparam, WM_LBUTTONDOWN },
186 { WM_MOUSEACTIVATE, sent },
187 { WM_MOUSEACTIVATE, sent|parent|defwinproc },
188 { WM_SETCURSOR, sent },
189 { WM_SETCURSOR, sent|parent|defwinproc },
190 { WM_LBUTTONDOWN, posted },
191 { WM_KILLFOCUS, posted|parent },
192 { WM_SETFOCUS, posted },
193 { WM_CTLCOLORBTN, posted|parent },
194 { BM_SETSTATE, posted },
195 { WM_CTLCOLORBTN, posted|parent },
196 { WM_LBUTTONUP, posted },
197 { BM_SETSTATE, posted },
198 { WM_CTLCOLORBTN, posted|parent },
199 { WM_COMMAND, posted|parent },
200 { 0 }
202 /* Reparenting a button (16/32) */
203 /* The last child (button) reparented gets topmost for its new parent. */
204 static struct message WmReparentButtonSeq[] = { /* FIXME: add */
205 { WM_SHOWWINDOW, sent|wparam, 0 },
206 { WM_WINDOWPOSCHANGING, sent|wparam, SWP_HIDEWINDOW|SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER },
207 { WM_ERASEBKGND, sent|parent },
208 { WM_WINDOWPOSCHANGED, sent|wparam, SWP_HIDEWINDOW|SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER },
209 { WM_WINDOWPOSCHANGING, sent|wparam, SWP_NOSIZE|SWP_NOZORDER },
210 { WM_CHILDACTIVATE, sent },
211 { WM_WINDOWPOSCHANGED, sent|wparam, SWP_NOSIZE|SWP_NOREDRAW|SWP_NOZORDER },
212 { WM_MOVE, sent|defwinproc },
213 { WM_SHOWWINDOW, sent|wparam, 1 },
214 { 0 }
216 /* Creation of a modal dialog (32) */
217 static struct message WmCreateModalDialogSeq[] = { /* FIXME: add */
218 { WM_CANCELMODE, sent|parent },
219 { WM_KILLFOCUS, sent|parent },
220 { WM_ENABLE, sent|parent|wparam, 0 },
221 /* (window proc creation messages not tracked yet, because...) */
222 { WM_SETFONT, sent },
223 { WM_INITDIALOG, sent },
224 /* (...the window proc message hook was installed here, IsVisible still FALSE) */
225 { WM_NCACTIVATE, sent|parent|wparam, 0 },
226 { WM_GETTEXT, sent|defwinproc },
227 { WM_ACTIVATE, sent|parent|wparam, 0 },
228 { WM_WINDOWPOSCHANGING, sent },
229 { WM_WINDOWPOSCHANGING, sent|parent },
230 { WM_NCACTIVATE, sent|wparam, 1 },
231 { WM_ACTIVATE, sent|wparam, 1 },
232 /* (setting focus) */
233 { WM_SHOWWINDOW, sent|wparam, 1 },
234 { WM_WINDOWPOSCHANGING, sent },
235 { WM_NCPAINT, sent },
236 { WM_GETTEXT, sent|defwinproc },
237 { WM_ERASEBKGND, sent },
238 { WM_CTLCOLORDLG, sent|defwinproc },
239 { WM_WINDOWPOSCHANGED, sent },
240 { WM_PAINT, sent },
241 /* FIXME: (bunch of WM_CTLCOLOR* for each control) */
242 { WM_PAINT, sent|parent },
243 { WM_ENTERIDLE, sent|parent|wparam, 0},
244 { WM_SETCURSOR, sent|parent },
245 { 0 }
247 /* Destruction of a modal dialog (32) */
248 static struct message WmDestroyModalDialogSeq[] = { /* FIXME: add */
249 /* (inside dialog proc: EndDialog is called) */
250 { WM_ENABLE, sent|parent|wparam, 1 },
251 { WM_SETFOCUS, sent },
252 { WM_WINDOWPOSCHANGING, sent },
253 { WM_NCPAINT, sent|parent },
254 { WM_GETTEXT, sent|defwinproc },
255 { WM_ERASEBKGND, sent|parent },
256 { WM_WINDOWPOSCHANGED, sent },
257 { WM_NCACTIVATE, sent|wparam, 0 },
258 { WM_ACTIVATE, sent|wparam, 0 },
259 { WM_WINDOWPOSCHANGING, sent },
260 { WM_WINDOWPOSCHANGING, sent|parent },
261 { WM_NCACTIVATE, sent|parent|wparam, 1 },
262 { WM_GETTEXT, sent|defwinproc },
263 { WM_ACTIVATE, sent|parent|wparam, 1 },
264 { WM_KILLFOCUS, sent },
265 { WM_SETFOCUS, sent|parent },
266 { WM_DESTROY, sent },
267 { WM_NCDESTROY, sent },
268 { 0 }
270 /* Creation of a modal dialog that is resized inside WM_INITDIALOG (32) */
271 static struct message WmCreateModalDialogResizeSeq[] = { /* FIXME: add */
272 /* (inside dialog proc, handling WM_INITDIALOG) */
273 { WM_WINDOWPOSCHANGING, sent },
274 { WM_NCCALCSIZE, sent },
275 { WM_NCACTIVATE, sent|parent|wparam, 0 },
276 { WM_GETTEXT, sent|defwinproc },
277 { WM_ACTIVATE, sent|parent|wparam, 0 },
278 { WM_WINDOWPOSCHANGING, sent },
279 { WM_WINDOWPOSCHANGING, sent|parent },
280 { WM_NCACTIVATE, sent|wparam, 1 },
281 { WM_ACTIVATE, sent|wparam, 1 },
282 { WM_WINDOWPOSCHANGED, sent },
283 { WM_SIZE, sent|defwinproc },
284 /* (setting focus) */
285 { WM_SHOWWINDOW, sent|wparam, 1 },
286 { WM_WINDOWPOSCHANGING, sent },
287 { WM_NCPAINT, sent },
288 { WM_GETTEXT, sent|defwinproc },
289 { WM_ERASEBKGND, sent },
290 { WM_CTLCOLORDLG, sent|defwinproc },
291 { WM_WINDOWPOSCHANGED, sent },
292 { WM_PAINT, sent },
293 /* (bunch of WM_CTLCOLOR* for each control) */
294 { WM_PAINT, sent|parent },
295 { WM_ENTERIDLE, sent|parent|wparam, 0 },
296 { WM_SETCURSOR, sent|parent },
297 { 0 }
299 /* SetMenu for NonVisible windows with size change*/
300 static struct message WmSetMenuNonVisibleSizeChangeSeq[] = {
301 { WM_WINDOWPOSCHANGING, sent|wparam, 0 },
302 { WM_NCCALCSIZE, sent|wparam, 1 },
303 { WM_WINDOWPOSCHANGED, sent|wparam, 0 },
304 { WM_MOVE, sent },
305 { WM_SIZE, sent },
306 { 0 }
308 /* SetMenu for NonVisible windows with no size change */
309 static struct message WmSetMenuNonVisibleNoSizeChangeSeq[] = {
310 { WM_WINDOWPOSCHANGING, sent|wparam, 0 },
311 { WM_NCCALCSIZE, sent|wparam, 1 },
312 { WM_WINDOWPOSCHANGED, sent|wparam, 0 },
313 { 0 }
315 /* SetMenu for Visible windows with size change */
316 static struct message WmSetMenuVisibleSizeChangeSeq[] = {
317 { WM_WINDOWPOSCHANGING, sent|wparam, 0 },
318 { WM_NCCALCSIZE, sent|wparam, 1 },
319 { WM_NCPAINT, sent|wparam, 1 },
320 { WM_GETTEXT, sent },
321 { WM_ACTIVATE, sent },
322 { WM_WINDOWPOSCHANGED, sent|wparam, 0 },
323 { WM_MOVE, sent },
324 { WM_SIZE, sent },
325 { 0 }
327 /* SetMenu for Visible windows with no size change */
328 static struct message WmSetMenuVisibleNoSizeChangeSeq[] = {
329 { WM_WINDOWPOSCHANGING, sent|wparam, 0 },
330 { WM_NCCALCSIZE, sent|wparam, 1 },
331 { WM_NCPAINT, sent|wparam, 1 },
332 { WM_GETTEXT, sent },
333 { WM_ACTIVATE, sent },
334 { WM_WINDOWPOSCHANGED, sent|wparam, 0 },
335 { 0 }
338 static int sequence_cnt, sequence_size;
339 static struct message* sequence;
341 static void add_message(struct message msg)
343 if (!sequence)
344 sequence = malloc ( (sequence_size = 10) * sizeof (struct message) );
345 if (sequence_cnt == sequence_size)
346 sequence = realloc ( sequence, (sequence_size *= 2) * sizeof (struct message) );
347 assert(sequence);
348 sequence[sequence_cnt++] = msg;
351 static void flush_sequence()
353 free(sequence);
354 sequence = 0;
355 sequence_cnt = sequence_size = 0;
358 static void ok_sequence(struct message *expected, const char *context)
360 static struct message end_of_sequence = { 0, 0, 0, 0 };
361 struct message *actual = sequence;
363 add_message(end_of_sequence);
365 /* naive sequence comparison. Would be nice to use a regexp engine here */
366 while (expected->message || actual->message)
368 if (expected->message == actual->message)
370 if (expected->flags & wparam)
371 ok (expected->wParam == actual->wParam,
372 "%s: in msg 0x%04x expecting wParam 0x%x got 0x%x\n",
373 context, expected->message, expected->wParam, actual->wParam);
374 if (expected->flags & lparam)
375 ok (expected->lParam == actual->lParam,
376 "%s: in msg 0x%04x expecting lParam 0x%lx got 0x%lx\n",
377 context, expected->message, expected->lParam, actual->lParam);
378 /* FIXME: should we check defwinproc? */
379 ok ((expected->flags & (sent|posted)) == (actual->flags & (sent|posted)),
380 "%s: the msg 0x%04x should have been %s\n",
381 context, expected->message, (expected->flags & posted) ? "posted" : "sent");
382 ok ((expected->flags & parent) == (actual->flags & parent),
383 "%s: the msg 0x%04x was expected in %s\n",
384 context, expected->message, (expected->flags & parent) ? "parent" : "child");
385 expected++;
386 actual++;
388 else if (expected->message && ((expected + 1)->message == actual->message) )
390 todo_wine {
391 ok (FALSE, "%s: the msg 0x%04x was not received\n", context, expected->message);
392 expected++;
395 else if (actual->message && (expected->message == (actual + 1)->message) )
397 todo_wine {
398 ok (FALSE, "%s: the msg 0x%04x was not expected\n", context, actual->message);
399 actual++;
402 else
404 todo_wine {
405 ok (FALSE, "%s: the msg 0x%04x was expected, but got msg 0x%04x instead\n",
406 context, expected->message, actual->message);
407 expected++;
408 actual++;
413 flush_sequence();
416 /* test if we receive the right sequence of messages */
417 static void test_messages(void)
419 HWND hwnd, hparent, hchild;
420 HWND hchild2, hbutton;
421 HMENU hmenu;
423 hwnd = CreateWindowExA(0, "TestWindowClass", "Test overlapped", WS_OVERLAPPEDWINDOW,
424 100, 100, 200, 200, 0, 0, 0, NULL);
425 ok (hwnd != 0, "Failed to create overlapped window\n");
426 ok_sequence(WmCreateOverlappedSeq, "CreateWindow:overlapped");
428 ShowWindow(hwnd, TRUE);
429 ok_sequence(WmShowOverlappedSeq, "ShowWindow:overlapped");
431 DestroyWindow(hwnd);
432 ok_sequence(WmDestroyOverlappedSeq, "DestroyWindow:overlapped");
434 hparent = CreateWindowExA(0, "TestParentClass", "Test parent", WS_OVERLAPPEDWINDOW,
435 100, 100, 200, 200, 0, 0, 0, NULL);
436 ok (hparent != 0, "Failed to create parent window\n");
437 flush_sequence();
439 hchild = CreateWindowExA(0, "TestWindowClass", "Test child", WS_CHILDWINDOW,
440 0, 0, 10, 10, hparent, 0, 0, NULL);
441 ok (hchild != 0, "Failed to create child window\n");
442 ok_sequence(WmCreateChildSeq, "CreateWindow:child");
444 hchild2 = CreateWindowExA(0, "SimpleWindowClass", "Test child2", WS_CHILDWINDOW,
445 100, 100, 50, 50, hparent, 0, 0, NULL);
446 ok (hchild2 != 0, "Failed to create child2 window\n");
447 flush_sequence();
449 hbutton = CreateWindowExA(0, "TestWindowClass", "Test button", WS_CHILDWINDOW,
450 0, 100, 50, 50, hchild, 0, 0, NULL);
451 ok (hbutton != 0, "Failed to create button window\n");
452 flush_sequence();
454 ShowWindow(hchild, TRUE);
455 ok_sequence(WmShowChildSeq, "ShowWindow:child");
457 MoveWindow(hchild, 10, 10, 20, 20, TRUE);
458 ok_sequence(WmResizingChildWithMoveWindowSeq, "MoveWindow:child");
460 DestroyWindow(hchild);
461 ok_sequence(WmDestroyChildSeq, "DestroyWindow:child");
462 DestroyWindow(hchild2);
463 DestroyWindow(hbutton);
464 DestroyWindow(hparent);
465 flush_sequence();
467 /* Message sequence for SetMenu */
468 hmenu = CreateMenu();
469 ok (hmenu != 0, "Failed to create menu\n");
470 ok (InsertMenuA(hmenu, -1, MF_BYPOSITION, 0x1000, "foo"), "InsertMenu failed\n");
471 hwnd = CreateWindowExA(0, "TestWindowClass", "Test overlapped", WS_OVERLAPPEDWINDOW,
472 100, 100, 200, 200, 0, hmenu, 0, NULL);
473 ok_sequence(WmCreateOverlappedSeq, "CreateWindow:overlapped");
474 ok (SetMenu(hwnd, 0), "SetMenu");
475 ok_sequence(WmSetMenuNonVisibleSizeChangeSeq, "SetMenu:NonVisibleSizeChange");
476 ok (SetMenu(hwnd, 0), "SetMenu");
477 ok_sequence(WmSetMenuNonVisibleNoSizeChangeSeq, "SetMenu:NonVisibleNoSizeChange");
478 ShowWindow(hwnd, TRUE);
479 flush_sequence();
480 ok (SetMenu(hwnd, 0), "SetMenu");
481 ok_sequence(WmSetMenuVisibleNoSizeChangeSeq, "SetMenu:VisibleNoSizeChange");
482 ok (SetMenu(hwnd, hmenu), "SetMenu");
483 ok_sequence(WmSetMenuVisibleSizeChangeSeq, "SetMenu:VisibleSizeChange");
484 DestroyWindow(hwnd);
488 static LRESULT WINAPI MsgCheckProcA(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
490 struct message msg = { message, sent|wparam|lparam, wParam, lParam };
492 add_message(msg);
493 return DefWindowProcA(hwnd, message, wParam, lParam);
496 static BOOL RegisterWindowClasses(void)
498 WNDCLASSA cls;
500 cls.style = 0;
501 cls.lpfnWndProc = MsgCheckProcA;
502 cls.cbClsExtra = 0;
503 cls.cbWndExtra = 0;
504 cls.hInstance = GetModuleHandleA(0);
505 cls.hIcon = 0;
506 cls.hCursor = LoadCursorA(0, (LPSTR)IDC_ARROW);
507 cls.hbrBackground = GetStockObject(WHITE_BRUSH);
508 cls.lpszMenuName = NULL;
509 cls.lpszClassName = "TestWindowClass";
511 if(!RegisterClassA(&cls)) return FALSE;
513 cls.style = 0;
514 cls.lpfnWndProc = DefWindowProcA;
515 cls.cbClsExtra = 0;
516 cls.cbWndExtra = 0;
517 cls.hInstance = GetModuleHandleA(0);
518 cls.hIcon = 0;
519 cls.hCursor = LoadCursorA(0, (LPSTR)IDC_ARROW);
520 cls.hbrBackground = GetStockObject(WHITE_BRUSH);
521 cls.lpszMenuName = NULL;
522 cls.lpszClassName = "TestParentClass";
524 if(!RegisterClassA(&cls)) return FALSE;
526 cls.style = 0;
527 cls.lpfnWndProc = DefWindowProcA;
528 cls.cbClsExtra = 0;
529 cls.cbWndExtra = 0;
530 cls.hInstance = GetModuleHandleA(0);
531 cls.hIcon = 0;
532 cls.hCursor = LoadCursorA(0, (LPSTR)IDC_ARROW);
533 cls.hbrBackground = GetStockObject(WHITE_BRUSH);
534 cls.lpszMenuName = NULL;
535 cls.lpszClassName = "SimpleWindowClass";
537 if(!RegisterClassA(&cls)) return FALSE;
539 return TRUE;
542 START_TEST(msg)
544 if (!RegisterWindowClasses()) assert(0);
546 test_messages();