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 int after_end_dialog;
603 static int sequence_cnt, sequence_size;
604 static struct message* sequence;
606 static void add_message(const struct message *msg)
611 sequence = HeapAlloc( GetProcessHeap(), 0, sequence_size * sizeof (struct message) );
613 if (sequence_cnt == sequence_size)
616 sequence = HeapReAlloc( GetProcessHeap(), 0, sequence, sequence_size * sizeof (struct message) );
620 sequence[sequence_cnt].message = msg->message;
621 sequence[sequence_cnt].flags = msg->flags;
622 sequence[sequence_cnt].wParam = msg->wParam;
623 sequence[sequence_cnt].lParam = msg->lParam;
628 static void flush_sequence()
630 HeapFree(GetProcessHeap(), 0, sequence);
632 sequence_cnt = sequence_size = 0;
635 static void ok_sequence(const struct message *expected, const char *context)
637 static const struct message end_of_sequence = { 0, 0, 0, 0 };
638 const struct message *actual;
640 add_message(&end_of_sequence);
644 while (expected->message && actual->message)
646 trace("expected %04x - actual %04x\n", expected->message, actual->message);
648 if (expected->message == actual->message)
650 if (expected->flags & wparam)
651 ok (expected->wParam == actual->wParam,
652 "%s: in msg 0x%04x expecting wParam 0x%x got 0x%x\n",
653 context, expected->message, expected->wParam, actual->wParam);
654 if (expected->flags & lparam)
655 ok (expected->lParam == actual->lParam,
656 "%s: in msg 0x%04x expecting lParam 0x%lx got 0x%lx\n",
657 context, expected->message, expected->lParam, actual->lParam);
658 ok ((expected->flags & defwinproc) == (actual->flags & defwinproc),
659 "%s: the msg 0x%04x should %shave been sent by DefWindowProc\n",
660 context, expected->message, (expected->flags & defwinproc) ? "" : "NOT ");
661 ok ((expected->flags & (sent|posted)) == (actual->flags & (sent|posted)),
662 "%s: the msg 0x%04x should have been %s\n",
663 context, expected->message, (expected->flags & posted) ? "posted" : "sent");
664 ok ((expected->flags & parent) == (actual->flags & parent),
665 "%s: the msg 0x%04x was expected in %s\n",
666 context, expected->message, (expected->flags & parent) ? "parent" : "child");
667 ok ((expected->flags & hook) == (actual->flags & hook),
668 "%s: the msg 0x%04x should have been sent by a hook\n",
669 context, expected->message);
673 else if (expected->flags & optional)
678 ok (FALSE, "%s: the msg 0x%04x was expected, but got msg 0x%04x instead\n",
679 context, expected->message, actual->message);
686 /* skip all optional trailing messages */
687 while (expected->message && (expected->flags & optional))
691 if (expected->message || actual->message)
692 ok (FALSE, "%s: the msg sequence is not complete (got 0x%04x)\n", context, actual->message);
698 static void test_WM_SETREDRAW(HWND hwnd)
700 DWORD style = GetWindowLongA(hwnd, GWL_STYLE);
704 SendMessageA(hwnd, WM_SETREDRAW, FALSE, 0);
705 ok_sequence(WmSetRedrawFalseSeq, "SetRedraw:FALSE");
707 ok(!(GetWindowLongA(hwnd, GWL_STYLE) & WS_VISIBLE), "WS_VISIBLE should NOT be set\n");
708 ok(!IsWindowVisible(hwnd), "IsWindowVisible() should return FALSE\n");
711 SendMessageA(hwnd, WM_SETREDRAW, TRUE, 0);
712 ok_sequence(WmSetRedrawTrueSeq, "SetRedraw:TRUE");
714 ok(GetWindowLongA(hwnd, GWL_STYLE) & WS_VISIBLE, "WS_VISIBLE should be set\n");
715 ok(IsWindowVisible(hwnd), "IsWindowVisible() should return TRUE\n");
717 /* restore original WS_VISIBLE state */
718 SetWindowLongA(hwnd, GWL_STYLE, style);
723 static INT_PTR CALLBACK TestModalDlgProcA(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
727 trace("dialog: %p, %04x, %08x, %08lx\n", hwnd, message, wParam, lParam);
729 msg.message = message;
730 msg.flags = sent|wparam|lparam;
735 if (message == WM_INITDIALOG) SetTimer( hwnd, 1, 100, NULL );
736 if (message == WM_TIMER) EndDialog( hwnd, 0 );
740 /* test if we receive the right sequence of messages */
741 static void test_messages(void)
743 HWND hwnd, hparent, hchild;
744 HWND hchild2, hbutton;
747 hwnd = CreateWindowExA(0, "TestWindowClass", "Test overlapped", WS_OVERLAPPEDWINDOW,
748 100, 100, 200, 200, 0, 0, 0, NULL);
749 ok (hwnd != 0, "Failed to create overlapped window\n");
750 ok_sequence(WmCreateOverlappedSeq, "CreateWindow:overlapped");
752 /* test WM_SETREDRAW on a not visible top level window */
753 test_WM_SETREDRAW(hwnd);
755 SetWindowPos(hwnd, 0,0,0,0,0, SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE);
756 ok_sequence(WmSWP_ShowOverlappedSeq, "SetWindowPos:SWP_SHOWWINDOW:overlapped");
757 ok(IsWindowVisible(hwnd), "window should be visible at this point\n");
759 ok(GetActiveWindow() == hwnd, "window should be active\n");
760 ok(GetFocus() == hwnd, "window should have input focus\n");
761 ShowWindow(hwnd, SW_HIDE);
762 ok_sequence(WmHideOverlappedSeq, "ShowWindow(SW_HIDE):overlapped");
764 ShowWindow(hwnd, SW_SHOW);
765 ok_sequence(WmShowOverlappedSeq, "ShowWindow(SW_SHOW):overlapped");
767 ok(GetActiveWindow() == hwnd, "window should be active\n");
768 ok(GetFocus() == hwnd, "window should have input focus\n");
769 SetWindowPos(hwnd, 0,0,0,0,0, SWP_HIDEWINDOW|SWP_NOSIZE|SWP_NOMOVE);
770 ok_sequence(WmSWP_HideOverlappedSeq, "SetWindowPos:SWP_HIDEWINDOW:overlapped");
771 ok(!IsWindowVisible(hwnd), "window should not be visible at this point\n");
773 /* test WM_SETREDRAW on a visible top level window */
774 ShowWindow(hwnd, SW_SHOW);
775 test_WM_SETREDRAW(hwnd);
778 ok_sequence(WmDestroyOverlappedSeq, "DestroyWindow:overlapped");
780 hparent = CreateWindowExA(0, "TestParentClass", "Test parent", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
781 100, 100, 200, 200, 0, 0, 0, NULL);
782 ok (hparent != 0, "Failed to create parent window\n");
785 hchild = CreateWindowExA(0, "TestWindowClass", "Test child", WS_CHILD | WS_MAXIMIZE,
786 0, 0, 10, 10, hparent, 0, 0, NULL);
787 ok (hchild != 0, "Failed to create child window\n");
788 ok_sequence(WmCreateMaximizedChildSeq, "CreateWindow:maximized child");
789 DestroyWindow(hchild);
792 hchild = CreateWindowExA(0, "TestWindowClass", "Test child", WS_CHILDWINDOW,
793 0, 0, 10, 10, hparent, 0, 0, NULL);
794 ok (hchild != 0, "Failed to create child window\n");
795 ok_sequence(WmCreateChildSeq, "CreateWindow:child");
797 hchild2 = CreateWindowExA(0, "SimpleWindowClass", "Test child2", WS_CHILDWINDOW,
798 100, 100, 50, 50, hparent, 0, 0, NULL);
799 ok (hchild2 != 0, "Failed to create child2 window\n");
802 hbutton = CreateWindowExA(0, "TestWindowClass", "Test button", WS_CHILDWINDOW,
803 0, 100, 50, 50, hchild, 0, 0, NULL);
804 ok (hbutton != 0, "Failed to create button window\n");
806 /* test WM_SETREDRAW on a not visible child window */
807 test_WM_SETREDRAW(hchild);
809 ShowWindow(hchild, SW_SHOW);
810 ok_sequence(WmShowChildSeq, "ShowWindow:child");
812 /* test WM_SETREDRAW on a visible child window */
813 test_WM_SETREDRAW(hchild);
818 MoveWindow(hchild, 10, 10, 20, 20, TRUE);
819 ok_sequence(WmResizingChildWithMoveWindowSeq, "MoveWindow:child");
821 DestroyWindow(hchild);
822 ok_sequence(WmDestroyChildSeq, "DestroyWindow:child");
823 DestroyWindow(hchild2);
824 DestroyWindow(hbutton);
827 hchild = CreateWindowExA(0, "TestWindowClass", "Test Child Popup", WS_CHILD | WS_POPUP,
828 0, 0, 100, 100, hparent, 0, 0, NULL);
829 ok (hchild != 0, "Failed to create child popup window\n");
830 ok_sequence(WmCreateChildPopupSeq, "CreateWindow:child_popup");
831 DestroyWindow(hchild);
833 /* test what happens to a window which sets WS_VISIBLE in WM_CREATE */
835 hchild = CreateWindowExA(0, "TestPopupClass", "Test Popup", WS_POPUP,
836 0, 0, 100, 100, hparent, 0, 0, NULL);
837 ok (hchild != 0, "Failed to create popup window\n");
838 ok_sequence(WmCreateInvisiblePopupSeq, "CreateWindow:invisible_popup");
839 ok(GetWindowLongA(hchild, GWL_STYLE) & WS_VISIBLE, "WS_VISIBLE should be set\n");
840 ok(IsWindowVisible(hchild), "IsWindowVisible() should return TRUE\n");
842 ShowWindow(hchild, SW_SHOW);
843 ok_sequence(WmShowVisiblePopupSeq, "CreateWindow:show_visible_popup");
845 SetWindowPos(hchild, 0,0,0,0,0, SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE|SWP_NOZORDER);
846 ok_sequence(WmShowVisiblePopupSeq_2, "CreateWindow:show_visible_popup_2");
848 SetWindowPos(hchild, 0,0,0,0,0, SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE);
849 ok_sequence(WmShowVisiblePopupSeq_3, "CreateWindow:show_visible_popup_3");
850 DestroyWindow(hchild);
852 /* this time add WS_VISIBLE for CreateWindowEx, but this fact actually
853 * changes nothing in message sequences.
856 hchild = CreateWindowExA(0, "TestPopupClass", "Test Popup", WS_POPUP | WS_VISIBLE,
857 0, 0, 100, 100, hparent, 0, 0, NULL);
858 ok (hchild != 0, "Failed to create popup window\n");
859 ok_sequence(WmCreateInvisiblePopupSeq, "CreateWindow:invisible_popup");
860 ok(GetWindowLongA(hchild, GWL_STYLE) & WS_VISIBLE, "WS_VISIBLE should be set\n");
861 ok(IsWindowVisible(hchild), "IsWindowVisible() should return TRUE\n");
863 ShowWindow(hchild, SW_SHOW);
864 ok_sequence(WmShowVisiblePopupSeq, "CreateWindow:show_visible_popup");
866 SetWindowPos(hchild, 0,0,0,0,0, SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE|SWP_NOZORDER);
867 ok_sequence(WmShowVisiblePopupSeq_2, "CreateWindow:show_visible_popup_2");
868 DestroyWindow(hchild);
871 hwnd = CreateWindowExA(WS_EX_DLGMODALFRAME, "TestDialogClass", NULL, WS_VISIBLE|WS_CAPTION|WS_SYSMENU|WS_DLGFRAME,
872 0, 0, 100, 100, hparent, 0, 0, NULL);
873 ok(hwnd != 0, "Failed to create custom dialog window\n");
874 ok_sequence(WmCreateCustomDialogSeq, "CreateCustomDialog");
877 after_end_dialog = 1;
878 EndDialog( hwnd, 0 );
879 ok_sequence(WmEndCustomDialogSeq, "EndCustomDialog");
882 after_end_dialog = 0;
885 DialogBoxA( 0, "TEST_DIALOG", hparent, TestModalDlgProcA );
886 ok_sequence(WmModalDialogSeq, "ModalDialog");
888 DestroyWindow(hparent);
891 /* Message sequence for SetMenu */
892 hmenu = CreateMenu();
893 ok (hmenu != 0, "Failed to create menu\n");
894 ok (InsertMenuA(hmenu, -1, MF_BYPOSITION, 0x1000, "foo"), "InsertMenu failed\n");
895 hwnd = CreateWindowExA(0, "TestWindowClass", "Test overlapped", WS_OVERLAPPEDWINDOW,
896 100, 100, 200, 200, 0, hmenu, 0, NULL);
897 ok_sequence(WmCreateOverlappedSeq, "CreateWindow:overlapped");
898 ok (SetMenu(hwnd, 0), "SetMenu\n");
899 ok_sequence(WmSetMenuNonVisibleSizeChangeSeq, "SetMenu:NonVisibleSizeChange");
900 ok (SetMenu(hwnd, 0), "SetMenu\n");
901 ok_sequence(WmSetMenuNonVisibleNoSizeChangeSeq, "SetMenu:NonVisibleNoSizeChange");
902 ShowWindow(hwnd, SW_SHOW);
904 ok (SetMenu(hwnd, 0), "SetMenu\n");
905 ok_sequence(WmSetMenuVisibleNoSizeChangeSeq, "SetMenu:VisibleNoSizeChange");
906 ok (SetMenu(hwnd, hmenu), "SetMenu\n");
907 ok_sequence(WmSetMenuVisibleSizeChangeSeq, "SetMenu:VisibleSizeChange");
909 ok(DrawMenuBar(hwnd), "DrawMenuBar\n");
910 ok_sequence(WmDrawMenuBarSeq, "DrawMenuBar");
915 static LRESULT WINAPI MsgCheckProcA(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
917 static long defwndproc_counter = 0;
921 trace("%p, %04x, %08x, %08lx\n", hwnd, message, wParam, lParam);
923 msg.message = message;
924 msg.flags = sent|wparam|lparam;
925 if (defwndproc_counter) msg.flags |= defwinproc;
930 if (message == WM_GETMINMAXINFO && (GetWindowLongA(hwnd, GWL_STYLE) & WS_CHILD))
932 HWND parent = GetParent(hwnd);
934 MINMAXINFO *minmax = (MINMAXINFO *)lParam;
936 GetClientRect(parent, &rc);
937 trace("parent %p client size = (%ld x %ld)\n", parent, rc.right, rc.bottom);
939 trace("ptReserved = (%ld,%ld)\n"
940 "ptMaxSize = (%ld,%ld)\n"
941 "ptMaxPosition = (%ld,%ld)\n"
942 "ptMinTrackSize = (%ld,%ld)\n"
943 "ptMaxTrackSize = (%ld,%ld)\n",
944 minmax->ptReserved.x, minmax->ptReserved.y,
945 minmax->ptMaxSize.x, minmax->ptMaxSize.y,
946 minmax->ptMaxPosition.x, minmax->ptMaxPosition.y,
947 minmax->ptMinTrackSize.x, minmax->ptMinTrackSize.y,
948 minmax->ptMaxTrackSize.x, minmax->ptMaxTrackSize.y);
950 ok(minmax->ptMaxSize.x == rc.right, "default width of maximized child %ld != %ld\n",
951 minmax->ptMaxSize.x, rc.right);
952 ok(minmax->ptMaxSize.y == rc.bottom, "default height of maximized child %ld != %ld\n",
953 minmax->ptMaxSize.y, rc.bottom);
956 defwndproc_counter++;
957 ret = DefWindowProcA(hwnd, message, wParam, lParam);
958 defwndproc_counter--;
963 static LRESULT WINAPI PopupMsgCheckProcA(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
965 static long defwndproc_counter = 0;
969 trace("popup: %p, %04x, %08x, %08lx\n", hwnd, message, wParam, lParam);
971 msg.message = message;
972 msg.flags = sent|wparam|lparam;
973 if (defwndproc_counter) msg.flags |= defwinproc;
978 if (message == WM_CREATE)
980 DWORD style = GetWindowLongA(hwnd, GWL_STYLE) | WS_VISIBLE;
981 SetWindowLongA(hwnd, GWL_STYLE, style);
984 defwndproc_counter++;
985 ret = DefWindowProcA(hwnd, message, wParam, lParam);
986 defwndproc_counter--;
991 static LRESULT WINAPI ParentMsgCheckProcA(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
993 static long defwndproc_counter = 0;
997 trace("parent: %p, %04x, %08x, %08lx\n", hwnd, message, wParam, lParam);
999 if (message == WM_PARENTNOTIFY || message == WM_CANCELMODE ||
1000 message == WM_SETFOCUS || message == WM_KILLFOCUS ||
1001 message == WM_ENABLE || message == WM_ENTERIDLE ||
1002 message == WM_IME_SETCONTEXT)
1004 msg.message = message;
1005 msg.flags = sent|parent|wparam|lparam;
1006 if (defwndproc_counter) msg.flags |= defwinproc;
1007 msg.wParam = wParam;
1008 msg.lParam = lParam;
1012 defwndproc_counter++;
1013 ret = DefWindowProcA(hwnd, message, wParam, lParam);
1014 defwndproc_counter--;
1019 static LRESULT WINAPI TestDlgProcA(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
1021 static long defwndproc_counter = 0;
1025 trace("dialog: %p, %04x, %08x, %08lx\n", hwnd, message, wParam, lParam);
1027 DefDlgProcA(hwnd, DM_SETDEFID, 1, 0);
1028 ret = DefDlgProcA(hwnd, DM_GETDEFID, 0, 0);
1029 if (after_end_dialog)
1030 ok( ret == 0, "DM_GETDEFID should return 0 after EndDialog, got %lx\n", ret );
1032 ok(HIWORD(ret) == DC_HASDEFID, "DM_GETDEFID should return DC_HASDEFID, got %lx\n", ret);
1034 msg.message = message;
1035 msg.flags = sent|wparam|lparam;
1036 if (defwndproc_counter) msg.flags |= defwinproc;
1037 msg.wParam = wParam;
1038 msg.lParam = lParam;
1041 defwndproc_counter++;
1042 ret = DefDlgProcA(hwnd, message, wParam, lParam);
1043 defwndproc_counter--;
1048 static BOOL RegisterWindowClasses(void)
1053 cls.lpfnWndProc = MsgCheckProcA;
1056 cls.hInstance = GetModuleHandleA(0);
1058 cls.hCursor = LoadCursorA(0, (LPSTR)IDC_ARROW);
1059 cls.hbrBackground = GetStockObject(WHITE_BRUSH);
1060 cls.lpszMenuName = NULL;
1061 cls.lpszClassName = "TestWindowClass";
1062 if(!RegisterClassA(&cls)) return FALSE;
1064 cls.lpfnWndProc = PopupMsgCheckProcA;
1065 cls.lpszClassName = "TestPopupClass";
1066 if(!RegisterClassA(&cls)) return FALSE;
1068 cls.lpfnWndProc = ParentMsgCheckProcA;
1069 cls.lpszClassName = "TestParentClass";
1070 if(!RegisterClassA(&cls)) return FALSE;
1072 cls.lpfnWndProc = DefWindowProcA;
1073 cls.lpszClassName = "SimpleWindowClass";
1074 if(!RegisterClassA(&cls)) return FALSE;
1076 ok(GetClassInfoA(0, "#32770", &cls), "GetClassInfo failed\n");
1077 cls.lpfnWndProc = TestDlgProcA;
1078 cls.lpszClassName = "TestDialogClass";
1079 if(!RegisterClassA(&cls)) return FALSE;
1084 static HHOOK hCBT_hook;
1086 static LRESULT CALLBACK cbt_hook_proc(int nCode, WPARAM wParam, LPARAM lParam)
1090 trace("CBT: %d, %08x, %08lx\n", nCode, wParam, lParam);
1092 if (GetClassNameA((HWND)wParam, buf, sizeof(buf)))
1094 if (!strcmp(buf, "TestWindowClass") ||
1095 !strcmp(buf, "TestParentClass") ||
1096 !strcmp(buf, "TestPopupClass") ||
1097 !strcmp(buf, "SimpleWindowClass") ||
1098 !strcmp(buf, "TestDialogClass") ||
1099 !strcmp(buf, "#32770"))
1103 msg.message = nCode;
1105 msg.wParam = wParam;
1106 msg.lParam = lParam;
1110 return CallNextHookEx(hCBT_hook, nCode, wParam, lParam);
1115 if (!RegisterWindowClasses()) assert(0);
1117 hCBT_hook = SetWindowsHookExA(WH_CBT, cbt_hook_proc, 0, GetCurrentThreadId());
1122 UnhookWindowsHookEx(hCBT_hook);