2 * Unit tests for window message handling
4 * Copyright 1999 Ove Kaaven
5 * Copyright 2003 Dimitrie O. Paun
6 * Copyright 2004 Dmitry Timoshkov
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
31 #include "wine/test.h"
35 FIXME: add tests for these
36 Window Edge Styles (Win31/Win95/98 look), in order of precedence:
37 WS_EX_DLGMODALFRAME: double border, WS_CAPTION allowed
38 WS_THICKFRAME: thick border
39 WS_DLGFRAME: double border, WS_CAPTION not allowed (but possibly shown anyway)
40 WS_BORDER (default for overlapped windows): single black border
41 none (default for child (and popup?) windows): no border
45 sent=0x1, posted=0x2, parent=0x4, wparam=0x8, lparam=0x10,
46 defwinproc=0x20, optional=0x40, hook=0x80
50 UINT message; /* the WM_* code */
51 msg_flags_t flags; /* message props */
52 WPARAM wParam; /* expected value of wParam */
53 LPARAM lParam; /* expected value of lParam */
56 /* CreateWindow (for overlapped window, not initially visible) (16/32) */
57 static const struct message WmCreateOverlappedSeq[] = {
58 { HCBT_CREATEWND, hook },
59 { WM_GETMINMAXINFO, sent },
60 { WM_NCCREATE, sent },
61 { WM_NCCALCSIZE, sent|wparam, 0 },
65 /* SetWindowPos(SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE)
66 * for a not visible overlapped window.
68 static const struct message WmSWP_ShowOverlappedSeq[] = {
69 { WM_WINDOWPOSCHANGING, sent|wparam, 0 },
70 { WM_NCPAINT, sent|wparam|optional, 1 },
71 { WM_GETTEXT, sent|defwinproc|optional },
72 { WM_ERASEBKGND, sent|optional },
73 { HCBT_ACTIVATE, hook },
74 { WM_QUERYNEWPALETTE, sent|wparam|lparam|optional, 0, 0 },
75 { WM_WINDOWPOSCHANGING, sent|wparam|optional, 0 }, /* Win9x: SWP_NOSENDCHANGING */
76 { WM_ACTIVATEAPP, sent|wparam, 1 },
77 { WM_NCACTIVATE, sent|wparam, 1 },
78 { WM_GETTEXT, sent|defwinproc|optional },
79 { WM_ACTIVATE, sent|wparam, 1 },
80 { HCBT_SETFOCUS, hook },
81 { WM_IME_SETCONTEXT, sent|wparam|defwinproc|optional, 1 },
82 { WM_SETFOCUS, sent|wparam|defwinproc, 0 },
83 { WM_NCPAINT, sent|wparam|optional, 1 },
84 { WM_GETTEXT, sent|defwinproc|optional },
85 { WM_ERASEBKGND, sent|optional },
86 { WM_WINDOWPOSCHANGED, sent|wparam, 0 },
87 { WM_NCCALCSIZE, sent|wparam|optional, 1 },
88 { WM_NCPAINT, sent|wparam|optional, 1 },
89 { WM_ERASEBKGND, sent|optional },
92 /* SetWindowPos(SWP_HIDEWINDOW|SWP_NOSIZE|SWP_NOMOVE)
93 * for a visible overlapped window.
95 static const struct message WmSWP_HideOverlappedSeq[] = {
96 { WM_WINDOWPOSCHANGING, sent|wparam, 0 },
97 { WM_WINDOWPOSCHANGED, sent|wparam, 0 },
100 /* ShowWindow(SW_SHOW) for a not visible overlapped window */
101 static const struct message WmShowOverlappedSeq[] = {
102 { WM_SHOWWINDOW, sent|wparam, 1 },
103 { WM_NCPAINT, sent|wparam|optional, 1 },
104 { WM_WINDOWPOSCHANGING, sent|wparam, 0 },
105 { WM_NCPAINT, sent|wparam|optional, 1 },
106 { WM_GETTEXT, sent|defwinproc|optional },
107 { WM_ERASEBKGND, sent|optional },
108 { HCBT_ACTIVATE, hook },
109 { WM_QUERYNEWPALETTE, sent|wparam|lparam|optional, 0, 0 },
110 { WM_WINDOWPOSCHANGING, sent|wparam, 0 },
111 { WM_ACTIVATEAPP, sent|wparam, 1 },
112 { WM_NCACTIVATE, sent|wparam, 1 },
113 { WM_GETTEXT, sent|defwinproc|optional },
114 { WM_ACTIVATE, sent|wparam, 1 },
115 { HCBT_SETFOCUS, hook },
116 { WM_IME_SETCONTEXT, sent|wparam|defwinproc|optional, 1 },
117 { WM_SETFOCUS, sent|wparam|defwinproc, 0 },
118 { WM_NCPAINT, sent|wparam|optional, 1 },
119 { WM_GETTEXT, sent|defwinproc|optional },
120 { WM_ERASEBKGND, sent|optional },
121 { WM_WINDOWPOSCHANGED, sent|wparam, 0 },
122 { WM_NCCALCSIZE, sent|optional },
123 { WM_NCPAINT, sent|optional },
124 { WM_ERASEBKGND, sent|optional },
125 #if 0 /* CreateWindow/ShowWindow(SW_SHOW) also generates WM_SIZE/WM_MOVE
126 * messages. Does that mean that CreateWindow doesn't set initial
127 * window dimensions for overlapped windows?
134 /* ShowWindow(SW_HIDE) for a visible overlapped window */
135 static const struct message WmHideOverlappedSeq[] = {
136 { WM_SHOWWINDOW, sent|wparam, 0 },
137 { WM_WINDOWPOSCHANGING, sent|wparam, 0 },
138 { WM_WINDOWPOSCHANGED, sent|wparam, 0 },
141 { WM_NCACTIVATE, sent|wparam, 0 },
142 { WM_ACTIVATE, sent|wparam, 0 },
143 { WM_ACTIVATEAPP, sent|wparam, 0 },
144 { WM_KILLFOCUS, sent|wparam, 0 },
145 { WM_IME_SETCONTEXT, sent|wparam|optional, 0 },
148 /* DestroyWindow for a visible overlapped window */
149 static const struct message WmDestroyOverlappedSeq[] = {
150 { HCBT_DESTROYWND, hook },
151 { WM_WINDOWPOSCHANGING, sent|wparam, 0 },
152 { WM_WINDOWPOSCHANGED, sent|wparam, 0 },
153 { WM_NCACTIVATE, sent|wparam, 0 },
154 { WM_ACTIVATE, sent|wparam, 0 },
155 { WM_ACTIVATEAPP, sent|wparam, 0 },
156 { WM_KILLFOCUS, sent|wparam, 0 },
157 { WM_IME_SETCONTEXT, sent|wparam|optional, 0 },
158 { WM_DESTROY, sent },
159 { WM_NCDESTROY, sent },
162 /* CreateWindow (for a child popup window, not initially visible) */
163 static const struct message WmCreateChildPopupSeq[] = {
164 { HCBT_CREATEWND, hook },
165 { WM_NCCREATE, sent },
166 { WM_NCCALCSIZE, sent|wparam, 0 },
172 /* CreateWindow (for a popup window, not initially visible,
173 * which sets WS_VISIBLE in WM_CREATE handler)
175 static const struct message WmCreateInvisiblePopupSeq[] = {
176 { HCBT_CREATEWND, hook },
177 { WM_NCCREATE, sent },
178 { WM_NCCALCSIZE, sent|wparam, 0 },
180 { WM_STYLECHANGING, sent },
181 { WM_STYLECHANGED, sent },
186 /* ShowWindow (for a popup window with WS_VISIBLE style set) */
187 static const struct message WmShowVisiblePopupSeq[] = {
190 /* SetWindowPos(SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE|SWP_NOZORDER)
191 * for a popup window with WS_VISIBLE style set
193 static const struct message WmShowVisiblePopupSeq_2[] = {
194 { WM_WINDOWPOSCHANGING, sent|wparam, 0 },
197 /* SetWindowPos(SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE)
198 * for a popup window with WS_VISIBLE style set
200 static const struct message WmShowVisiblePopupSeq_3[] = {
201 { WM_WINDOWPOSCHANGING, sent|wparam, 0 },
202 { HCBT_ACTIVATE, hook },
203 { WM_QUERYNEWPALETTE, sent|wparam|lparam|optional, 0, 0 },
204 { WM_WINDOWPOSCHANGING, sent|wparam, 0 },
205 { WM_NCACTIVATE, sent|wparam, 1 },
206 { WM_ACTIVATE, sent|wparam, 1 },
207 { HCBT_SETFOCUS, hook },
208 { WM_KILLFOCUS, sent|parent },
209 { WM_IME_SETCONTEXT, sent|parent|wparam|optional, 0 },
210 { WM_IME_SETCONTEXT, sent|wparam|defwinproc|optional, 1 },
211 { WM_SETFOCUS, sent|defwinproc },
214 /* CreateWindow (for child window, not initially visible) */
215 static const struct message WmCreateChildSeq[] = {
216 { HCBT_CREATEWND, hook },
217 { WM_NCCREATE, sent },
218 /* child is inserted into parent's child list after WM_NCCREATE returns */
219 { WM_NCCALCSIZE, sent|wparam, 0 },
223 { WM_PARENTNOTIFY, sent|parent|wparam, WM_CREATE },
226 /* CreateWindow (for maximized child window, not initially visible) */
227 static const struct message WmCreateMaximizedChildSeq[] = {
228 { HCBT_CREATEWND, hook },
229 { WM_NCCREATE, sent },
230 { WM_NCCALCSIZE, sent|wparam, 0 },
234 { HCBT_MINMAX, hook|lparam, 0, SW_MAXIMIZE },
235 { WM_GETMINMAXINFO, sent },
236 { WM_WINDOWPOSCHANGING, sent },
237 { WM_NCCALCSIZE, sent },
238 { WM_WINDOWPOSCHANGED, sent },
239 { WM_SIZE, sent|defwinproc },
240 { WM_PARENTNOTIFY, sent|parent|wparam, WM_CREATE },
243 /* ShowWindow(SW_SHOW) for a not visible child window */
244 static const struct message WmShowChildSeq[] = {
245 { WM_SHOWWINDOW, sent|wparam, 1 },
246 { WM_WINDOWPOSCHANGING, sent|wparam, 0 },
247 { WM_ERASEBKGND, sent|parent|optional },
248 { WM_WINDOWPOSCHANGED, sent|wparam, 0 },
251 /* DestroyWindow for a visible child window */
252 static const struct message WmDestroyChildSeq[] = {
253 { HCBT_DESTROYWND, hook },
254 { WM_PARENTNOTIFY, sent|parent|wparam, WM_DESTROY },
255 { WM_SHOWWINDOW, sent|wparam, 0 },
256 { WM_WINDOWPOSCHANGING, sent|wparam, 0 },
257 { WM_ERASEBKGND, sent|parent|optional },
258 { WM_WINDOWPOSCHANGED, sent|wparam, 0 },
259 { HCBT_SETFOCUS, hook }, /* set focus to a parent */
260 { WM_KILLFOCUS, sent },
261 { WM_IME_SETCONTEXT, sent|wparam|optional, 0 },
262 { WM_IME_SETCONTEXT, sent|wparam|parent|optional, 1 },
263 { WM_SETFOCUS, sent|parent },
264 { WM_DESTROY, sent },
265 { WM_DESTROY, sent|optional }, /* a bug in win2k sp4 ? */
266 { WM_NCDESTROY, sent },
267 { WM_NCDESTROY, sent|optional }, /* a bug in win2k sp4 ? */
270 /* Moving the mouse in nonclient area */
271 static const struct message WmMouseMoveInNonClientAreaSeq[] = { /* FIXME: add */
272 { WM_NCHITTEST, sent },
273 { WM_SETCURSOR, sent },
274 { WM_NCMOUSEMOVE, posted },
277 /* Moving the mouse in client area */
278 static const struct message WmMouseMoveInClientAreaSeq[] = { /* FIXME: add */
279 { WM_NCHITTEST, sent },
280 { WM_SETCURSOR, sent },
281 { WM_MOUSEMOVE, posted },
284 /* Moving by dragging the title bar (after WM_NCHITTEST and WM_SETCURSOR) (outline move) */
285 static const struct message WmDragTitleBarSeq[] = { /* FIXME: add */
286 { WM_NCLBUTTONDOWN, sent|wparam, HTCAPTION },
287 { WM_SYSCOMMAND, sent|defwinproc|wparam, SC_MOVE+2 },
288 { WM_GETMINMAXINFO, sent|defwinproc },
289 { WM_ENTERSIZEMOVE, sent|defwinproc },
290 { WM_WINDOWPOSCHANGING, sent|defwinproc },
291 { WM_WINDOWPOSCHANGED, sent|defwinproc },
292 { WM_MOVE, sent|defwinproc },
293 { WM_EXITSIZEMOVE, sent|defwinproc },
296 /* Sizing by dragging the thick borders (after WM_NCHITTEST and WM_SETCURSOR) (outline move) */
297 static const struct message WmDragThickBordersBarSeq[] = { /* FIXME: add */
298 { WM_NCLBUTTONDOWN, sent|wparam, 0xd },
299 { WM_SYSCOMMAND, sent|defwinproc|wparam, 0xf004 },
300 { WM_GETMINMAXINFO, sent|defwinproc },
301 { WM_ENTERSIZEMOVE, sent|defwinproc },
302 { WM_SIZING, sent|defwinproc|wparam, 4}, /* one for each mouse movement */
303 { WM_WINDOWPOSCHANGING, sent|defwinproc },
304 { WM_GETMINMAXINFO, sent|defwinproc },
305 { WM_NCCALCSIZE, sent|defwinproc|wparam, 1 },
306 { WM_NCPAINT, sent|defwinproc|wparam, 1 },
307 { WM_GETTEXT, sent|defwinproc },
308 { WM_ERASEBKGND, sent|defwinproc },
309 { WM_WINDOWPOSCHANGED, sent|defwinproc },
310 { WM_MOVE, sent|defwinproc },
311 { WM_SIZE, sent|defwinproc },
312 { WM_EXITSIZEMOVE, sent|defwinproc },
315 /* Resizing child window with MoveWindow (32) */
316 static const struct message WmResizingChildWithMoveWindowSeq[] = {
317 { WM_WINDOWPOSCHANGING, sent },
318 { WM_NCCALCSIZE, sent|wparam, 1 },
319 { WM_ERASEBKGND, sent|optional },
320 { WM_WINDOWPOSCHANGED, sent },
321 { WM_MOVE, sent|defwinproc },
322 { WM_SIZE, sent|defwinproc },
325 /* Clicking on inactive button */
326 static const struct message WmClickInactiveButtonSeq[] = { /* FIXME: add */
327 { WM_NCHITTEST, sent },
328 { WM_PARENTNOTIFY, sent|parent|wparam, WM_LBUTTONDOWN },
329 { WM_MOUSEACTIVATE, sent },
330 { WM_MOUSEACTIVATE, sent|parent|defwinproc },
331 { WM_SETCURSOR, sent },
332 { WM_SETCURSOR, sent|parent|defwinproc },
333 { WM_LBUTTONDOWN, posted },
334 { WM_KILLFOCUS, posted|parent },
335 { WM_SETFOCUS, posted },
336 { WM_CTLCOLORBTN, posted|parent },
337 { BM_SETSTATE, posted },
338 { WM_CTLCOLORBTN, posted|parent },
339 { WM_LBUTTONUP, posted },
340 { BM_SETSTATE, posted },
341 { WM_CTLCOLORBTN, posted|parent },
342 { WM_COMMAND, posted|parent },
345 /* Reparenting a button (16/32) */
346 /* The last child (button) reparented gets topmost for its new parent. */
347 static const struct message WmReparentButtonSeq[] = { /* FIXME: add */
348 { WM_SHOWWINDOW, sent|wparam, 0 },
349 { WM_WINDOWPOSCHANGING, sent|wparam, SWP_HIDEWINDOW|SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER },
350 { WM_ERASEBKGND, sent|parent },
351 { WM_WINDOWPOSCHANGED, sent|wparam, SWP_HIDEWINDOW|SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER },
352 { WM_WINDOWPOSCHANGING, sent|wparam, SWP_NOSIZE|SWP_NOZORDER },
353 { WM_CHILDACTIVATE, sent },
354 { WM_WINDOWPOSCHANGED, sent|wparam, SWP_NOSIZE|SWP_NOREDRAW|SWP_NOZORDER },
355 { WM_MOVE, sent|defwinproc },
356 { WM_SHOWWINDOW, sent|wparam, 1 },
359 /* Creation of a custom dialog (32) */
360 static const struct message WmCreateCustomDialogSeq[] = {
361 { HCBT_CREATEWND, hook },
362 { WM_GETMINMAXINFO, sent },
363 { WM_NCCREATE, sent },
364 { WM_NCCALCSIZE, sent|wparam, 0 },
366 { WM_SHOWWINDOW, sent|wparam, 1 },
367 { HCBT_ACTIVATE, hook },
368 { WM_QUERYNEWPALETTE, sent|wparam|lparam|optional, 0, 0 },
369 { WM_WINDOWPOSCHANGING, sent|wparam, 0 },
370 { WM_NCACTIVATE, sent|wparam, 1 },
371 { WM_GETTEXT, sent|optional|defwinproc },
372 { WM_GETICON, sent|optional|defwinproc },
373 { WM_GETICON, sent|optional|defwinproc },
374 { WM_GETICON, sent|optional|defwinproc },
375 { WM_GETTEXT, sent|optional|defwinproc },
376 { WM_ACTIVATE, sent|wparam, 1 },
377 { WM_KILLFOCUS, sent|parent },
378 { WM_IME_SETCONTEXT, sent|parent|wparam|optional, 0 },
379 { WM_IME_SETCONTEXT, sent|wparam|optional, 1 },
380 { WM_SETFOCUS, sent },
381 { WM_GETDLGCODE, sent|defwinproc|wparam, 0 },
382 { WM_WINDOWPOSCHANGING, sent|wparam, 0 },
383 { WM_NCPAINT, sent|wparam, 1 },
384 { WM_GETTEXT, sent|optional|defwinproc },
385 { WM_GETICON, sent|optional|defwinproc },
386 { WM_GETICON, sent|optional|defwinproc },
387 { WM_GETICON, sent|optional|defwinproc },
388 { WM_GETTEXT, sent|optional|defwinproc },
389 { WM_ERASEBKGND, sent },
390 { WM_CTLCOLORDLG, sent|defwinproc },
391 { WM_WINDOWPOSCHANGED, sent|wparam, 0 },
392 { WM_GETTEXT, sent|optional },
393 { WM_GETICON, sent|optional },
394 { WM_GETICON, sent|optional },
395 { WM_GETICON, sent|optional },
396 { WM_GETTEXT, sent|optional },
397 { WM_NCCALCSIZE, sent|optional },
398 { WM_NCPAINT, sent|optional },
399 { WM_GETTEXT, sent|optional|defwinproc },
400 { WM_GETICON, sent|optional|defwinproc },
401 { WM_GETICON, sent|optional|defwinproc },
402 { WM_GETICON, sent|optional|defwinproc },
403 { WM_GETTEXT, sent|optional|defwinproc },
404 { WM_ERASEBKGND, sent|optional },
405 { WM_CTLCOLORDLG, sent|optional|defwinproc },
410 /* Calling EndDialog for a custom dialog (32) */
411 static const struct message WmEndCustomDialogSeq[] = {
412 { WM_WINDOWPOSCHANGING, sent },
413 { WM_WINDOWPOSCHANGED, sent },
414 { WM_GETTEXT, sent|optional },
415 { WM_GETICON, sent|optional },
416 { WM_GETICON, sent|optional },
417 { WM_GETICON, sent|optional },
418 { HCBT_ACTIVATE, hook },
419 { WM_NCACTIVATE, sent|wparam, 0 },
420 { WM_GETTEXT, sent|optional|defwinproc },
421 { WM_GETICON, sent|optional|defwinproc },
422 { WM_GETICON, sent|optional|defwinproc },
423 { WM_GETICON, sent|optional|defwinproc },
424 { WM_GETTEXT, sent|optional|defwinproc },
425 { WM_ACTIVATE, sent|wparam, 0 },
426 { WM_WINDOWPOSCHANGING, sent|optional },
427 { HCBT_SETFOCUS, hook },
428 { WM_KILLFOCUS, sent },
429 { WM_IME_SETCONTEXT, sent|wparam|optional, 0 },
430 { WM_IME_SETCONTEXT, sent|parent|wparam|defwinproc|optional, 1 },
431 { WM_SETFOCUS, sent|parent|defwinproc },
434 /* Creation and destruction of a modal dialog (32) */
435 static const struct message WmModalDialogSeq[] = {
436 { WM_CANCELMODE, sent|parent },
437 { WM_KILLFOCUS, sent|parent },
438 { WM_IME_SETCONTEXT, sent|parent|wparam|optional, 0 },
439 { WM_ENABLE, sent|parent|wparam, 0 },
440 { HCBT_CREATEWND, hook },
441 { WM_SETFONT, sent },
442 { WM_INITDIALOG, sent },
443 { WM_CHANGEUISTATE, sent|optional },
444 { WM_SHOWWINDOW, sent },
445 { HCBT_ACTIVATE, hook },
446 { WM_WINDOWPOSCHANGING, sent },
447 { WM_NCACTIVATE, sent|wparam, 1 },
448 { WM_GETICON, sent|optional },
449 { WM_GETICON, sent|optional },
450 { WM_GETICON, sent|optional },
451 { WM_GETTEXT, sent|optional },
452 { WM_ACTIVATE, sent|wparam, 1 },
453 { WM_WINDOWPOSCHANGING, sent },
454 { WM_NCPAINT, sent },
455 { WM_GETICON, sent|optional },
456 { WM_GETICON, sent|optional },
457 { WM_GETICON, sent|optional },
458 { WM_GETTEXT, sent|optional },
459 { WM_ERASEBKGND, sent },
460 { WM_CTLCOLORDLG, sent },
461 { WM_WINDOWPOSCHANGED, sent },
462 { WM_GETICON, sent|optional },
463 { WM_GETICON, sent|optional },
464 { WM_GETICON, sent|optional },
465 { WM_GETTEXT, sent|optional },
466 { WM_NCCALCSIZE, sent|optional },
467 { WM_NCPAINT, sent|optional },
468 { WM_GETICON, sent|optional },
469 { WM_GETICON, sent|optional },
470 { WM_GETICON, sent|optional },
471 { WM_GETTEXT, sent|optional },
472 { WM_ERASEBKGND, sent|optional },
473 { WM_CTLCOLORDLG, sent|optional },
474 { WM_PAINT, sent|optional },
475 { WM_CTLCOLORBTN, sent },
476 { WM_ENTERIDLE, sent|parent },
478 { WM_ENABLE, sent|parent|wparam, 1 },
479 { WM_WINDOWPOSCHANGING, sent },
480 { WM_WINDOWPOSCHANGED, sent },
481 { WM_GETICON, sent|optional },
482 { WM_GETICON, sent|optional },
483 { WM_GETICON, sent|optional },
484 { WM_GETTEXT, sent|optional },
485 { HCBT_ACTIVATE, hook },
486 { WM_NCACTIVATE, sent|wparam, 0 },
487 { WM_GETICON, sent|optional },
488 { WM_GETICON, sent|optional },
489 { WM_GETICON, sent|optional },
490 { WM_GETTEXT, sent|optional },
491 { WM_ACTIVATE, sent|wparam, 0 },
492 { WM_WINDOWPOSCHANGING, sent|optional },
493 { HCBT_SETFOCUS, hook },
494 { WM_IME_SETCONTEXT, sent|parent|wparam|defwinproc|optional, 1 },
495 { WM_SETFOCUS, sent|parent|defwinproc },
496 { HCBT_DESTROYWND, hook },
497 { WM_DESTROY, sent },
498 { WM_NCDESTROY, sent },
501 /* Creation of a modal dialog that is resized inside WM_INITDIALOG (32) */
502 static const struct message WmCreateModalDialogResizeSeq[] = { /* FIXME: add */
503 /* (inside dialog proc, handling WM_INITDIALOG) */
504 { WM_WINDOWPOSCHANGING, sent },
505 { WM_NCCALCSIZE, sent },
506 { WM_NCACTIVATE, sent|parent|wparam, 0 },
507 { WM_GETTEXT, sent|defwinproc },
508 { WM_ACTIVATE, sent|parent|wparam, 0 },
509 { WM_WINDOWPOSCHANGING, sent },
510 { WM_WINDOWPOSCHANGING, sent|parent },
511 { WM_NCACTIVATE, sent|wparam, 1 },
512 { WM_ACTIVATE, sent|wparam, 1 },
513 { WM_WINDOWPOSCHANGED, sent },
514 { WM_SIZE, sent|defwinproc },
515 /* (setting focus) */
516 { WM_SHOWWINDOW, sent|wparam, 1 },
517 { WM_WINDOWPOSCHANGING, sent },
518 { WM_NCPAINT, sent },
519 { WM_GETTEXT, sent|defwinproc },
520 { WM_ERASEBKGND, sent },
521 { WM_CTLCOLORDLG, sent|defwinproc },
522 { WM_WINDOWPOSCHANGED, sent },
524 /* (bunch of WM_CTLCOLOR* for each control) */
525 { WM_PAINT, sent|parent },
526 { WM_ENTERIDLE, sent|parent|wparam, 0 },
527 { WM_SETCURSOR, sent|parent },
530 /* SetMenu for NonVisible windows with size change*/
531 static const struct message WmSetMenuNonVisibleSizeChangeSeq[] = {
532 { WM_WINDOWPOSCHANGING, sent|wparam, 0 },
533 { WM_NCCALCSIZE, sent|wparam, 1 },
534 { WM_WINDOWPOSCHANGED, sent|wparam, 0 },
535 { WM_MOVE, sent|defwinproc },
536 { WM_SIZE, sent|defwinproc },
537 { WM_GETICON, sent|optional },
538 { WM_GETICON, sent|optional },
539 { WM_GETICON, sent|optional },
540 { WM_GETTEXT, sent|optional },
541 { WM_NCCALCSIZE, sent|wparam|optional, 1 },
544 /* SetMenu for NonVisible windows with no size change */
545 static const struct message WmSetMenuNonVisibleNoSizeChangeSeq[] = {
546 { WM_WINDOWPOSCHANGING, sent|wparam, 0 },
547 { WM_NCCALCSIZE, sent|wparam, 1 },
548 { WM_WINDOWPOSCHANGED, sent|wparam, 0 },
551 /* SetMenu for Visible windows with size change */
552 static const struct message WmSetMenuVisibleSizeChangeSeq[] = {
553 { WM_WINDOWPOSCHANGING, sent|wparam, 0 },
554 { WM_NCCALCSIZE, sent|wparam, 1 },
555 { WM_NCPAINT, sent|wparam, 1 },
556 { WM_GETTEXT, sent|defwinproc|optional },
557 { WM_ERASEBKGND, sent|optional },
558 { WM_ACTIVATE, sent|optional },
559 { WM_WINDOWPOSCHANGED, sent|wparam, 0 },
560 { WM_MOVE, sent|defwinproc },
561 { WM_SIZE, sent|defwinproc },
562 { WM_NCCALCSIZE, sent|wparam|optional, 1 },
563 { WM_NCPAINT, sent|wparam|optional, 1 },
564 { WM_ERASEBKGND, sent|optional },
567 /* SetMenu for Visible windows with no size change */
568 static const struct message WmSetMenuVisibleNoSizeChangeSeq[] = {
569 { WM_WINDOWPOSCHANGING, sent|wparam, 0 },
570 { WM_NCCALCSIZE, sent|wparam, 1 },
571 { WM_NCPAINT, sent|wparam, 1 },
572 { WM_GETTEXT, sent|defwinproc|optional },
573 { WM_ERASEBKGND, sent|optional },
574 { WM_ACTIVATE, sent|optional },
575 { WM_WINDOWPOSCHANGED, sent|wparam, 0 },
578 /* DrawMenuBar for a visible window */
579 static const struct message WmDrawMenuBarSeq[] =
581 { WM_WINDOWPOSCHANGING, sent|wparam, 0 },
582 { WM_NCCALCSIZE, sent|wparam, 1 },
583 { WM_NCPAINT, sent|wparam, 1 },
584 { WM_GETTEXT, sent|defwinproc|optional },
585 { WM_ERASEBKGND, sent|optional },
586 { WM_WINDOWPOSCHANGED, sent|wparam, 0 },
590 static const struct message WmSetRedrawFalseSeq[] =
592 { WM_SETREDRAW, sent|wparam, 0 },
596 static const struct message WmSetRedrawTrueSeq[] =
598 { WM_SETREDRAW, sent|wparam, 1 },
602 static const struct message WmEnableWindowSeq[] =
604 { WM_CANCELMODE, sent },
609 static int after_end_dialog;
610 static int sequence_cnt, sequence_size;
611 static struct message* sequence;
613 static void add_message(const struct message *msg)
618 sequence = HeapAlloc( GetProcessHeap(), 0, sequence_size * sizeof (struct message) );
620 if (sequence_cnt == sequence_size)
623 sequence = HeapReAlloc( GetProcessHeap(), 0, sequence, sequence_size * sizeof (struct message) );
627 sequence[sequence_cnt].message = msg->message;
628 sequence[sequence_cnt].flags = msg->flags;
629 sequence[sequence_cnt].wParam = msg->wParam;
630 sequence[sequence_cnt].lParam = msg->lParam;
635 static void flush_sequence()
637 HeapFree(GetProcessHeap(), 0, sequence);
639 sequence_cnt = sequence_size = 0;
642 static void ok_sequence(const struct message *expected, const char *context)
644 static const struct message end_of_sequence = { 0, 0, 0, 0 };
645 const struct message *actual;
647 add_message(&end_of_sequence);
651 while (expected->message && actual->message)
653 trace("expected %04x - actual %04x\n", expected->message, actual->message);
655 if (expected->message == actual->message)
657 if (expected->flags & wparam)
658 ok (expected->wParam == actual->wParam,
659 "%s: in msg 0x%04x expecting wParam 0x%x got 0x%x\n",
660 context, expected->message, expected->wParam, actual->wParam);
661 if (expected->flags & lparam)
662 ok (expected->lParam == actual->lParam,
663 "%s: in msg 0x%04x expecting lParam 0x%lx got 0x%lx\n",
664 context, expected->message, expected->lParam, actual->lParam);
665 ok ((expected->flags & defwinproc) == (actual->flags & defwinproc),
666 "%s: the msg 0x%04x should %shave been sent by DefWindowProc\n",
667 context, expected->message, (expected->flags & defwinproc) ? "" : "NOT ");
668 ok ((expected->flags & (sent|posted)) == (actual->flags & (sent|posted)),
669 "%s: the msg 0x%04x should have been %s\n",
670 context, expected->message, (expected->flags & posted) ? "posted" : "sent");
671 ok ((expected->flags & parent) == (actual->flags & parent),
672 "%s: the msg 0x%04x was expected in %s\n",
673 context, expected->message, (expected->flags & parent) ? "parent" : "child");
674 ok ((expected->flags & hook) == (actual->flags & hook),
675 "%s: the msg 0x%04x should have been sent by a hook\n",
676 context, expected->message);
680 else if (expected->flags & optional)
685 ok (FALSE, "%s: the msg 0x%04x was expected, but got msg 0x%04x instead\n",
686 context, expected->message, actual->message);
693 /* skip all optional trailing messages */
694 while (expected->message && (expected->flags & optional))
698 if (expected->message || actual->message)
699 ok (FALSE, "%s: the msg sequence is not complete (got 0x%04x)\n", context, actual->message);
705 static void test_WM_SETREDRAW(HWND hwnd)
707 DWORD style = GetWindowLongA(hwnd, GWL_STYLE);
711 SendMessageA(hwnd, WM_SETREDRAW, FALSE, 0);
712 ok_sequence(WmSetRedrawFalseSeq, "SetRedraw:FALSE");
714 ok(!(GetWindowLongA(hwnd, GWL_STYLE) & WS_VISIBLE), "WS_VISIBLE should NOT be set\n");
715 ok(!IsWindowVisible(hwnd), "IsWindowVisible() should return FALSE\n");
718 SendMessageA(hwnd, WM_SETREDRAW, TRUE, 0);
719 ok_sequence(WmSetRedrawTrueSeq, "SetRedraw:TRUE");
721 ok(GetWindowLongA(hwnd, GWL_STYLE) & WS_VISIBLE, "WS_VISIBLE should be set\n");
722 ok(IsWindowVisible(hwnd), "IsWindowVisible() should return TRUE\n");
724 /* restore original WS_VISIBLE state */
725 SetWindowLongA(hwnd, GWL_STYLE, style);
730 static INT_PTR CALLBACK TestModalDlgProcA(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
734 trace("dialog: %p, %04x, %08x, %08lx\n", hwnd, message, wParam, lParam);
736 msg.message = message;
737 msg.flags = sent|wparam|lparam;
742 if (message == WM_INITDIALOG) SetTimer( hwnd, 1, 100, NULL );
743 if (message == WM_TIMER) EndDialog( hwnd, 0 );
747 /* test if we receive the right sequence of messages */
748 static void test_messages(void)
750 HWND hwnd, hparent, hchild;
751 HWND hchild2, hbutton;
754 hwnd = CreateWindowExA(0, "TestWindowClass", "Test overlapped", WS_OVERLAPPEDWINDOW,
755 100, 100, 200, 200, 0, 0, 0, NULL);
756 ok (hwnd != 0, "Failed to create overlapped window\n");
757 ok_sequence(WmCreateOverlappedSeq, "CreateWindow:overlapped");
759 /* test WM_SETREDRAW on a not visible top level window */
760 test_WM_SETREDRAW(hwnd);
762 SetWindowPos(hwnd, 0,0,0,0,0, SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE);
763 ok_sequence(WmSWP_ShowOverlappedSeq, "SetWindowPos:SWP_SHOWWINDOW:overlapped");
764 ok(IsWindowVisible(hwnd), "window should be visible at this point\n");
766 ok(GetActiveWindow() == hwnd, "window should be active\n");
767 ok(GetFocus() == hwnd, "window should have input focus\n");
768 ShowWindow(hwnd, SW_HIDE);
769 ok_sequence(WmHideOverlappedSeq, "ShowWindow(SW_HIDE):overlapped");
771 ShowWindow(hwnd, SW_SHOW);
772 ok_sequence(WmShowOverlappedSeq, "ShowWindow(SW_SHOW):overlapped");
774 ok(GetActiveWindow() == hwnd, "window should be active\n");
775 ok(GetFocus() == hwnd, "window should have input focus\n");
776 SetWindowPos(hwnd, 0,0,0,0,0, SWP_HIDEWINDOW|SWP_NOSIZE|SWP_NOMOVE);
777 ok_sequence(WmSWP_HideOverlappedSeq, "SetWindowPos:SWP_HIDEWINDOW:overlapped");
778 ok(!IsWindowVisible(hwnd), "window should not be visible at this point\n");
780 /* test WM_SETREDRAW on a visible top level window */
781 ShowWindow(hwnd, SW_SHOW);
782 test_WM_SETREDRAW(hwnd);
785 ok_sequence(WmDestroyOverlappedSeq, "DestroyWindow:overlapped");
787 hparent = CreateWindowExA(0, "TestParentClass", "Test parent", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
788 100, 100, 200, 200, 0, 0, 0, NULL);
789 ok (hparent != 0, "Failed to create parent window\n");
792 hchild = CreateWindowExA(0, "TestWindowClass", "Test child", WS_CHILD | WS_MAXIMIZE,
793 0, 0, 10, 10, hparent, 0, 0, NULL);
794 ok (hchild != 0, "Failed to create child window\n");
795 ok_sequence(WmCreateMaximizedChildSeq, "CreateWindow:maximized child");
796 DestroyWindow(hchild);
799 hchild = CreateWindowExA(0, "TestWindowClass", "Test child", WS_CHILDWINDOW,
800 0, 0, 10, 10, hparent, 0, 0, NULL);
801 ok (hchild != 0, "Failed to create child window\n");
802 ok_sequence(WmCreateChildSeq, "CreateWindow:child");
804 hchild2 = CreateWindowExA(0, "SimpleWindowClass", "Test child2", WS_CHILDWINDOW,
805 100, 100, 50, 50, hparent, 0, 0, NULL);
806 ok (hchild2 != 0, "Failed to create child2 window\n");
809 hbutton = CreateWindowExA(0, "TestWindowClass", "Test button", WS_CHILDWINDOW,
810 0, 100, 50, 50, hchild, 0, 0, NULL);
811 ok (hbutton != 0, "Failed to create button window\n");
813 /* test WM_SETREDRAW on a not visible child window */
814 test_WM_SETREDRAW(hchild);
816 ShowWindow(hchild, SW_SHOW);
817 ok_sequence(WmShowChildSeq, "ShowWindow:child");
819 /* test WM_SETREDRAW on a visible child window */
820 test_WM_SETREDRAW(hchild);
825 MoveWindow(hchild, 10, 10, 20, 20, TRUE);
826 ok_sequence(WmResizingChildWithMoveWindowSeq, "MoveWindow:child");
828 DestroyWindow(hchild);
829 ok_sequence(WmDestroyChildSeq, "DestroyWindow:child");
830 DestroyWindow(hchild2);
831 DestroyWindow(hbutton);
834 hchild = CreateWindowExA(0, "TestWindowClass", "Test Child Popup", WS_CHILD | WS_POPUP,
835 0, 0, 100, 100, hparent, 0, 0, NULL);
836 ok (hchild != 0, "Failed to create child popup window\n");
837 ok_sequence(WmCreateChildPopupSeq, "CreateWindow:child_popup");
838 DestroyWindow(hchild);
840 /* test what happens to a window which sets WS_VISIBLE in WM_CREATE */
842 hchild = CreateWindowExA(0, "TestPopupClass", "Test Popup", WS_POPUP,
843 0, 0, 100, 100, hparent, 0, 0, NULL);
844 ok (hchild != 0, "Failed to create popup window\n");
845 ok_sequence(WmCreateInvisiblePopupSeq, "CreateWindow:invisible_popup");
846 ok(GetWindowLongA(hchild, GWL_STYLE) & WS_VISIBLE, "WS_VISIBLE should be set\n");
847 ok(IsWindowVisible(hchild), "IsWindowVisible() should return TRUE\n");
849 ShowWindow(hchild, SW_SHOW);
850 ok_sequence(WmShowVisiblePopupSeq, "CreateWindow:show_visible_popup");
852 SetWindowPos(hchild, 0,0,0,0,0, SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE|SWP_NOZORDER);
853 ok_sequence(WmShowVisiblePopupSeq_2, "CreateWindow:show_visible_popup_2");
855 SetWindowPos(hchild, 0,0,0,0,0, SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE);
856 ok_sequence(WmShowVisiblePopupSeq_3, "CreateWindow:show_visible_popup_3");
857 DestroyWindow(hchild);
859 /* this time add WS_VISIBLE for CreateWindowEx, but this fact actually
860 * changes nothing in message sequences.
863 hchild = CreateWindowExA(0, "TestPopupClass", "Test Popup", WS_POPUP | WS_VISIBLE,
864 0, 0, 100, 100, hparent, 0, 0, NULL);
865 ok (hchild != 0, "Failed to create popup window\n");
866 ok_sequence(WmCreateInvisiblePopupSeq, "CreateWindow:invisible_popup");
867 ok(GetWindowLongA(hchild, GWL_STYLE) & WS_VISIBLE, "WS_VISIBLE should be set\n");
868 ok(IsWindowVisible(hchild), "IsWindowVisible() should return TRUE\n");
870 ShowWindow(hchild, SW_SHOW);
871 ok_sequence(WmShowVisiblePopupSeq, "CreateWindow:show_visible_popup");
873 SetWindowPos(hchild, 0,0,0,0,0, SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE|SWP_NOZORDER);
874 ok_sequence(WmShowVisiblePopupSeq_2, "CreateWindow:show_visible_popup_2");
875 DestroyWindow(hchild);
878 hwnd = CreateWindowExA(WS_EX_DLGMODALFRAME, "TestDialogClass", NULL, WS_VISIBLE|WS_CAPTION|WS_SYSMENU|WS_DLGFRAME,
879 0, 0, 100, 100, hparent, 0, 0, NULL);
880 ok(hwnd != 0, "Failed to create custom dialog window\n");
881 ok_sequence(WmCreateCustomDialogSeq, "CreateCustomDialog");
884 after_end_dialog = 1;
885 EndDialog( hwnd, 0 );
886 ok_sequence(WmEndCustomDialogSeq, "EndCustomDialog");
889 after_end_dialog = 0;
892 DialogBoxA( 0, "TEST_DIALOG", hparent, TestModalDlgProcA );
893 ok_sequence(WmModalDialogSeq, "ModalDialog");
895 DestroyWindow(hparent);
898 /* Message sequence for SetMenu */
899 hmenu = CreateMenu();
900 ok (hmenu != 0, "Failed to create menu\n");
901 ok (InsertMenuA(hmenu, -1, MF_BYPOSITION, 0x1000, "foo"), "InsertMenu failed\n");
902 hwnd = CreateWindowExA(0, "TestWindowClass", "Test overlapped", WS_OVERLAPPEDWINDOW,
903 100, 100, 200, 200, 0, hmenu, 0, NULL);
904 ok_sequence(WmCreateOverlappedSeq, "CreateWindow:overlapped");
905 ok (SetMenu(hwnd, 0), "SetMenu\n");
906 ok_sequence(WmSetMenuNonVisibleSizeChangeSeq, "SetMenu:NonVisibleSizeChange");
907 ok (SetMenu(hwnd, 0), "SetMenu\n");
908 ok_sequence(WmSetMenuNonVisibleNoSizeChangeSeq, "SetMenu:NonVisibleNoSizeChange");
909 ShowWindow(hwnd, SW_SHOW);
911 ok (SetMenu(hwnd, 0), "SetMenu\n");
912 ok_sequence(WmSetMenuVisibleNoSizeChangeSeq, "SetMenu:VisibleNoSizeChange");
913 ok (SetMenu(hwnd, hmenu), "SetMenu\n");
914 ok_sequence(WmSetMenuVisibleSizeChangeSeq, "SetMenu:VisibleSizeChange");
916 ok(DrawMenuBar(hwnd), "DrawMenuBar\n");
917 ok_sequence(WmDrawMenuBarSeq, "DrawMenuBar");
922 /* Message sequence for EnableWindow */
923 hparent = CreateWindowExA(0, "TestWindowClass", "Test parent", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
924 100, 100, 200, 200, 0, 0, 0, NULL);
925 ok (hparent != 0, "Failed to create parent window\n");
926 hchild = CreateWindowExA(0, "TestWindowClass", "Test child", WS_CHILDWINDOW | WS_VISIBLE,
927 0, 0, 10, 10, hparent, 0, 0, NULL);
928 ok (hchild != 0, "Failed to create child window\n");
933 EnableWindow(hparent, FALSE);
934 ok_sequence(WmEnableWindowSeq, "EnableWindow");
936 DestroyWindow(hparent);
940 static LRESULT WINAPI MsgCheckProcA(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
942 static long defwndproc_counter = 0;
946 trace("%p, %04x, %08x, %08lx\n", hwnd, message, wParam, lParam);
948 msg.message = message;
949 msg.flags = sent|wparam|lparam;
950 if (defwndproc_counter) msg.flags |= defwinproc;
955 if (message == WM_GETMINMAXINFO && (GetWindowLongA(hwnd, GWL_STYLE) & WS_CHILD))
957 HWND parent = GetParent(hwnd);
959 MINMAXINFO *minmax = (MINMAXINFO *)lParam;
961 GetClientRect(parent, &rc);
962 trace("parent %p client size = (%ld x %ld)\n", parent, rc.right, rc.bottom);
964 trace("ptReserved = (%ld,%ld)\n"
965 "ptMaxSize = (%ld,%ld)\n"
966 "ptMaxPosition = (%ld,%ld)\n"
967 "ptMinTrackSize = (%ld,%ld)\n"
968 "ptMaxTrackSize = (%ld,%ld)\n",
969 minmax->ptReserved.x, minmax->ptReserved.y,
970 minmax->ptMaxSize.x, minmax->ptMaxSize.y,
971 minmax->ptMaxPosition.x, minmax->ptMaxPosition.y,
972 minmax->ptMinTrackSize.x, minmax->ptMinTrackSize.y,
973 minmax->ptMaxTrackSize.x, minmax->ptMaxTrackSize.y);
975 ok(minmax->ptMaxSize.x == rc.right, "default width of maximized child %ld != %ld\n",
976 minmax->ptMaxSize.x, rc.right);
977 ok(minmax->ptMaxSize.y == rc.bottom, "default height of maximized child %ld != %ld\n",
978 minmax->ptMaxSize.y, rc.bottom);
981 defwndproc_counter++;
982 ret = DefWindowProcA(hwnd, message, wParam, lParam);
983 defwndproc_counter--;
988 static LRESULT WINAPI PopupMsgCheckProcA(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
990 static long defwndproc_counter = 0;
994 trace("popup: %p, %04x, %08x, %08lx\n", hwnd, message, wParam, lParam);
996 msg.message = message;
997 msg.flags = sent|wparam|lparam;
998 if (defwndproc_counter) msg.flags |= defwinproc;
1000 msg.lParam = lParam;
1003 if (message == WM_CREATE)
1005 DWORD style = GetWindowLongA(hwnd, GWL_STYLE) | WS_VISIBLE;
1006 SetWindowLongA(hwnd, GWL_STYLE, style);
1009 defwndproc_counter++;
1010 ret = DefWindowProcA(hwnd, message, wParam, lParam);
1011 defwndproc_counter--;
1016 static LRESULT WINAPI ParentMsgCheckProcA(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
1018 static long defwndproc_counter = 0;
1022 trace("parent: %p, %04x, %08x, %08lx\n", hwnd, message, wParam, lParam);
1024 if (message == WM_PARENTNOTIFY || message == WM_CANCELMODE ||
1025 message == WM_SETFOCUS || message == WM_KILLFOCUS ||
1026 message == WM_ENABLE || message == WM_ENTERIDLE ||
1027 message == WM_IME_SETCONTEXT)
1029 msg.message = message;
1030 msg.flags = sent|parent|wparam|lparam;
1031 if (defwndproc_counter) msg.flags |= defwinproc;
1032 msg.wParam = wParam;
1033 msg.lParam = lParam;
1037 defwndproc_counter++;
1038 ret = DefWindowProcA(hwnd, message, wParam, lParam);
1039 defwndproc_counter--;
1044 static LRESULT WINAPI TestDlgProcA(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
1046 static long defwndproc_counter = 0;
1050 trace("dialog: %p, %04x, %08x, %08lx\n", hwnd, message, wParam, lParam);
1052 DefDlgProcA(hwnd, DM_SETDEFID, 1, 0);
1053 ret = DefDlgProcA(hwnd, DM_GETDEFID, 0, 0);
1054 if (after_end_dialog)
1055 ok( ret == 0, "DM_GETDEFID should return 0 after EndDialog, got %lx\n", ret );
1057 ok(HIWORD(ret) == DC_HASDEFID, "DM_GETDEFID should return DC_HASDEFID, got %lx\n", ret);
1059 msg.message = message;
1060 msg.flags = sent|wparam|lparam;
1061 if (defwndproc_counter) msg.flags |= defwinproc;
1062 msg.wParam = wParam;
1063 msg.lParam = lParam;
1066 defwndproc_counter++;
1067 ret = DefDlgProcA(hwnd, message, wParam, lParam);
1068 defwndproc_counter--;
1073 static BOOL RegisterWindowClasses(void)
1078 cls.lpfnWndProc = MsgCheckProcA;
1081 cls.hInstance = GetModuleHandleA(0);
1083 cls.hCursor = LoadCursorA(0, (LPSTR)IDC_ARROW);
1084 cls.hbrBackground = GetStockObject(WHITE_BRUSH);
1085 cls.lpszMenuName = NULL;
1086 cls.lpszClassName = "TestWindowClass";
1087 if(!RegisterClassA(&cls)) return FALSE;
1089 cls.lpfnWndProc = PopupMsgCheckProcA;
1090 cls.lpszClassName = "TestPopupClass";
1091 if(!RegisterClassA(&cls)) return FALSE;
1093 cls.lpfnWndProc = ParentMsgCheckProcA;
1094 cls.lpszClassName = "TestParentClass";
1095 if(!RegisterClassA(&cls)) return FALSE;
1097 cls.lpfnWndProc = DefWindowProcA;
1098 cls.lpszClassName = "SimpleWindowClass";
1099 if(!RegisterClassA(&cls)) return FALSE;
1101 ok(GetClassInfoA(0, "#32770", &cls), "GetClassInfo failed\n");
1102 cls.lpfnWndProc = TestDlgProcA;
1103 cls.lpszClassName = "TestDialogClass";
1104 if(!RegisterClassA(&cls)) return FALSE;
1109 static HHOOK hCBT_hook;
1111 static LRESULT CALLBACK cbt_hook_proc(int nCode, WPARAM wParam, LPARAM lParam)
1115 trace("CBT: %d, %08x, %08lx\n", nCode, wParam, lParam);
1117 if (GetClassNameA((HWND)wParam, buf, sizeof(buf)))
1119 if (!strcmp(buf, "TestWindowClass") ||
1120 !strcmp(buf, "TestParentClass") ||
1121 !strcmp(buf, "TestPopupClass") ||
1122 !strcmp(buf, "SimpleWindowClass") ||
1123 !strcmp(buf, "TestDialogClass") ||
1124 !strcmp(buf, "#32770"))
1128 msg.message = nCode;
1130 msg.wParam = wParam;
1131 msg.lParam = lParam;
1135 return CallNextHookEx(hCBT_hook, nCode, wParam, lParam);
1140 if (!RegisterWindowClasses()) assert(0);
1142 hCBT_hook = SetWindowsHookExA(WH_CBT, cbt_hook_proc, 0, GetCurrentThreadId());
1147 UnhookWindowsHookEx(hCBT_hook);