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 { WM_SETFONT, sent },
441 { WM_INITDIALOG, sent },
442 { WM_CHANGEUISTATE, sent|optional },
443 { WM_SHOWWINDOW, sent },
444 { WM_WINDOWPOSCHANGING, sent },
445 { WM_NCACTIVATE, sent|wparam, 1 },
446 { WM_GETICON, sent|optional },
447 { WM_GETICON, sent|optional },
448 { WM_GETICON, sent|optional },
449 { WM_GETTEXT, sent|optional },
450 { WM_ACTIVATE, sent|wparam, 1 },
451 { WM_WINDOWPOSCHANGING, sent },
452 { WM_NCPAINT, sent },
453 { WM_GETICON, sent|optional },
454 { WM_GETICON, sent|optional },
455 { WM_GETICON, sent|optional },
456 { WM_GETTEXT, sent|optional },
457 { WM_ERASEBKGND, sent },
458 { WM_CTLCOLORDLG, sent },
459 { WM_WINDOWPOSCHANGED, sent },
460 { WM_GETICON, sent|optional },
461 { WM_GETICON, sent|optional },
462 { WM_GETICON, sent|optional },
463 { WM_GETTEXT, sent|optional },
464 { WM_NCCALCSIZE, sent|optional },
465 { WM_NCPAINT, sent|optional },
466 { WM_GETICON, sent|optional },
467 { WM_GETICON, sent|optional },
468 { WM_GETICON, sent|optional },
469 { WM_GETTEXT, sent|optional },
470 { WM_ERASEBKGND, sent|optional },
471 { WM_CTLCOLORDLG, sent|optional },
472 { WM_PAINT, sent|optional },
473 { WM_CTLCOLORBTN, sent },
474 { WM_ENTERIDLE, sent|parent },
476 { WM_ENABLE, sent|parent|wparam, 1 },
477 { WM_WINDOWPOSCHANGING, sent },
478 { WM_WINDOWPOSCHANGED, sent },
479 { WM_GETICON, sent|optional },
480 { WM_GETICON, sent|optional },
481 { WM_GETICON, sent|optional },
482 { WM_GETTEXT, sent|optional },
483 { HCBT_ACTIVATE, hook },
484 { WM_NCACTIVATE, sent|wparam, 0 },
485 { WM_GETICON, sent|optional },
486 { WM_GETICON, sent|optional },
487 { WM_GETICON, sent|optional },
488 { WM_GETTEXT, sent|optional },
489 { WM_ACTIVATE, sent|wparam, 0 },
490 { WM_WINDOWPOSCHANGING, sent|optional },
491 { HCBT_SETFOCUS, hook },
492 { WM_IME_SETCONTEXT, sent|parent|wparam|defwinproc|optional, 1 },
493 { WM_SETFOCUS, sent|parent|defwinproc },
494 { WM_DESTROY, sent },
495 { WM_NCDESTROY, sent },
498 /* Creation of a modal dialog that is resized inside WM_INITDIALOG (32) */
499 static const struct message WmCreateModalDialogResizeSeq[] = { /* FIXME: add */
500 /* (inside dialog proc, handling WM_INITDIALOG) */
501 { WM_WINDOWPOSCHANGING, sent },
502 { WM_NCCALCSIZE, sent },
503 { WM_NCACTIVATE, sent|parent|wparam, 0 },
504 { WM_GETTEXT, sent|defwinproc },
505 { WM_ACTIVATE, sent|parent|wparam, 0 },
506 { WM_WINDOWPOSCHANGING, sent },
507 { WM_WINDOWPOSCHANGING, sent|parent },
508 { WM_NCACTIVATE, sent|wparam, 1 },
509 { WM_ACTIVATE, sent|wparam, 1 },
510 { WM_WINDOWPOSCHANGED, sent },
511 { WM_SIZE, sent|defwinproc },
512 /* (setting focus) */
513 { WM_SHOWWINDOW, sent|wparam, 1 },
514 { WM_WINDOWPOSCHANGING, sent },
515 { WM_NCPAINT, sent },
516 { WM_GETTEXT, sent|defwinproc },
517 { WM_ERASEBKGND, sent },
518 { WM_CTLCOLORDLG, sent|defwinproc },
519 { WM_WINDOWPOSCHANGED, sent },
521 /* (bunch of WM_CTLCOLOR* for each control) */
522 { WM_PAINT, sent|parent },
523 { WM_ENTERIDLE, sent|parent|wparam, 0 },
524 { WM_SETCURSOR, sent|parent },
527 /* SetMenu for NonVisible windows with size change*/
528 static const struct message WmSetMenuNonVisibleSizeChangeSeq[] = {
529 { WM_WINDOWPOSCHANGING, sent|wparam, 0 },
530 { WM_NCCALCSIZE, sent|wparam, 1 },
531 { WM_WINDOWPOSCHANGED, sent|wparam, 0 },
532 { WM_MOVE, sent|defwinproc },
533 { WM_SIZE, sent|defwinproc },
534 { WM_GETICON, sent|optional },
535 { WM_GETICON, sent|optional },
536 { WM_GETICON, sent|optional },
537 { WM_GETTEXT, sent|optional },
538 { WM_NCCALCSIZE, sent|wparam|optional, 1 },
541 /* SetMenu for NonVisible windows with no size change */
542 static const struct message WmSetMenuNonVisibleNoSizeChangeSeq[] = {
543 { WM_WINDOWPOSCHANGING, sent|wparam, 0 },
544 { WM_NCCALCSIZE, sent|wparam, 1 },
545 { WM_WINDOWPOSCHANGED, sent|wparam, 0 },
548 /* SetMenu for Visible windows with size change */
549 static const struct message WmSetMenuVisibleSizeChangeSeq[] = {
550 { WM_WINDOWPOSCHANGING, sent|wparam, 0 },
551 { WM_NCCALCSIZE, sent|wparam, 1 },
552 { WM_NCPAINT, sent|wparam, 1 },
553 { WM_GETTEXT, sent|defwinproc|optional },
554 { WM_ERASEBKGND, sent|optional },
555 { WM_ACTIVATE, sent|optional },
556 { WM_WINDOWPOSCHANGED, sent|wparam, 0 },
557 { WM_MOVE, sent|defwinproc },
558 { WM_SIZE, sent|defwinproc },
559 { WM_NCCALCSIZE, sent|wparam|optional, 1 },
560 { WM_NCPAINT, sent|wparam|optional, 1 },
561 { WM_ERASEBKGND, sent|optional },
564 /* SetMenu for Visible windows with no size change */
565 static const struct message WmSetMenuVisibleNoSizeChangeSeq[] = {
566 { WM_WINDOWPOSCHANGING, sent|wparam, 0 },
567 { WM_NCCALCSIZE, sent|wparam, 1 },
568 { WM_NCPAINT, sent|wparam, 1 },
569 { WM_GETTEXT, sent|defwinproc|optional },
570 { WM_ERASEBKGND, sent|optional },
571 { WM_ACTIVATE, sent|optional },
572 { WM_WINDOWPOSCHANGED, sent|wparam, 0 },
576 static const struct message WmSetRedrawFalseSeq[] =
578 { WM_SETREDRAW, sent|wparam, 0 },
582 static const struct message WmSetRedrawTrueSeq[] =
584 { WM_SETREDRAW, sent|wparam, 1 },
588 static int after_end_dialog;
589 static int sequence_cnt, sequence_size;
590 static struct message* sequence;
592 static void add_message(const struct message *msg)
597 sequence = HeapAlloc( GetProcessHeap(), 0, sequence_size * sizeof (struct message) );
599 if (sequence_cnt == sequence_size)
602 sequence = HeapReAlloc( GetProcessHeap(), 0, sequence, sequence_size * sizeof (struct message) );
606 sequence[sequence_cnt].message = msg->message;
607 sequence[sequence_cnt].flags = msg->flags;
608 sequence[sequence_cnt].wParam = msg->wParam;
609 sequence[sequence_cnt].lParam = msg->lParam;
614 static void flush_sequence()
616 HeapFree(GetProcessHeap(), 0, sequence);
618 sequence_cnt = sequence_size = 0;
621 static void ok_sequence(const struct message *expected, const char *context)
623 static const struct message end_of_sequence = { 0, 0, 0, 0 };
624 const struct message *actual;
626 add_message(&end_of_sequence);
630 while (expected->message && actual->message)
632 trace("expected %04x - actual %04x\n", expected->message, actual->message);
634 if (expected->message == actual->message)
636 if (expected->flags & wparam)
637 ok (expected->wParam == actual->wParam,
638 "%s: in msg 0x%04x expecting wParam 0x%x got 0x%x\n",
639 context, expected->message, expected->wParam, actual->wParam);
640 if (expected->flags & lparam)
641 ok (expected->lParam == actual->lParam,
642 "%s: in msg 0x%04x expecting lParam 0x%lx got 0x%lx\n",
643 context, expected->message, expected->lParam, actual->lParam);
644 ok ((expected->flags & defwinproc) == (actual->flags & defwinproc),
645 "%s: the msg 0x%04x should %shave been sent by DefWindowProc\n",
646 context, expected->message, (expected->flags & defwinproc) ? "" : "NOT ");
647 ok ((expected->flags & (sent|posted)) == (actual->flags & (sent|posted)),
648 "%s: the msg 0x%04x should have been %s\n",
649 context, expected->message, (expected->flags & posted) ? "posted" : "sent");
650 ok ((expected->flags & parent) == (actual->flags & parent),
651 "%s: the msg 0x%04x was expected in %s\n",
652 context, expected->message, (expected->flags & parent) ? "parent" : "child");
653 ok ((expected->flags & hook) == (actual->flags & hook),
654 "%s: the msg 0x%04x should have been sent by a hook\n",
655 context, expected->message);
659 else if (expected->flags & optional)
664 ok (FALSE, "%s: the msg 0x%04x was expected, but got msg 0x%04x instead\n",
665 context, expected->message, actual->message);
672 /* skip all optional trailing messages */
673 while (expected->message && (expected->flags & optional))
677 if (expected->message || actual->message)
678 ok (FALSE, "%s: the msg sequence is not complete (got 0x%04x)\n", context, actual->message);
684 static void test_WM_SETREDRAW(HWND hwnd)
686 DWORD style = GetWindowLongA(hwnd, GWL_STYLE);
690 SendMessageA(hwnd, WM_SETREDRAW, FALSE, 0);
691 ok_sequence(WmSetRedrawFalseSeq, "SetRedraw:FALSE");
693 ok(!(GetWindowLongA(hwnd, GWL_STYLE) & WS_VISIBLE), "WS_VISIBLE should NOT be set\n");
694 ok(!IsWindowVisible(hwnd), "IsWindowVisible() should return FALSE\n");
697 SendMessageA(hwnd, WM_SETREDRAW, TRUE, 0);
698 ok_sequence(WmSetRedrawTrueSeq, "SetRedraw:TRUE");
700 ok(GetWindowLongA(hwnd, GWL_STYLE) & WS_VISIBLE, "WS_VISIBLE should be set\n");
701 ok(IsWindowVisible(hwnd), "IsWindowVisible() should return TRUE\n");
703 /* restore original WS_VISIBLE state */
704 SetWindowLongA(hwnd, GWL_STYLE, style);
709 static INT_PTR CALLBACK TestModalDlgProcA(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
713 trace("dialog: %p, %04x, %08x, %08lx\n", hwnd, message, wParam, lParam);
715 msg.message = message;
716 msg.flags = sent|wparam|lparam;
721 if (message == WM_INITDIALOG) SetTimer( hwnd, 1, 100, NULL );
722 if (message == WM_TIMER) EndDialog( hwnd, 0 );
726 /* test if we receive the right sequence of messages */
727 static void test_messages(void)
729 HWND hwnd, hparent, hchild;
730 HWND hchild2, hbutton;
733 hwnd = CreateWindowExA(0, "TestWindowClass", "Test overlapped", WS_OVERLAPPEDWINDOW,
734 100, 100, 200, 200, 0, 0, 0, NULL);
735 ok (hwnd != 0, "Failed to create overlapped window\n");
736 ok_sequence(WmCreateOverlappedSeq, "CreateWindow:overlapped");
738 /* test WM_SETREDRAW on a not visible top level window */
739 test_WM_SETREDRAW(hwnd);
741 SetWindowPos(hwnd, 0,0,0,0,0, SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE);
742 ok_sequence(WmSWP_ShowOverlappedSeq, "SetWindowPos:SWP_SHOWWINDOW:overlapped");
743 ok(IsWindowVisible(hwnd), "window should be visible at this point\n");
745 ok(GetActiveWindow() == hwnd, "window should be active\n");
746 ok(GetFocus() == hwnd, "window should have input focus\n");
747 ShowWindow(hwnd, SW_HIDE);
748 ok_sequence(WmHideOverlappedSeq, "ShowWindow(SW_HIDE):overlapped");
750 ShowWindow(hwnd, SW_SHOW);
751 ok_sequence(WmShowOverlappedSeq, "ShowWindow(SW_SHOW):overlapped");
753 ok(GetActiveWindow() == hwnd, "window should be active\n");
754 ok(GetFocus() == hwnd, "window should have input focus\n");
755 SetWindowPos(hwnd, 0,0,0,0,0, SWP_HIDEWINDOW|SWP_NOSIZE|SWP_NOMOVE);
756 ok_sequence(WmSWP_HideOverlappedSeq, "SetWindowPos:SWP_HIDEWINDOW:overlapped");
757 ok(!IsWindowVisible(hwnd), "window should not be visible at this point\n");
759 /* test WM_SETREDRAW on a visible top level window */
760 ShowWindow(hwnd, SW_SHOW);
761 test_WM_SETREDRAW(hwnd);
764 ok_sequence(WmDestroyOverlappedSeq, "DestroyWindow:overlapped");
766 hparent = CreateWindowExA(0, "TestParentClass", "Test parent", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
767 100, 100, 200, 200, 0, 0, 0, NULL);
768 ok (hparent != 0, "Failed to create parent window\n");
771 hchild = CreateWindowExA(0, "TestWindowClass", "Test child", WS_CHILD | WS_MAXIMIZE,
772 0, 0, 10, 10, hparent, 0, 0, NULL);
773 ok (hchild != 0, "Failed to create child window\n");
774 ok_sequence(WmCreateMaximizedChildSeq, "CreateWindow:maximized child");
775 DestroyWindow(hchild);
778 hchild = CreateWindowExA(0, "TestWindowClass", "Test child", WS_CHILDWINDOW,
779 0, 0, 10, 10, hparent, 0, 0, NULL);
780 ok (hchild != 0, "Failed to create child window\n");
781 ok_sequence(WmCreateChildSeq, "CreateWindow:child");
783 hchild2 = CreateWindowExA(0, "SimpleWindowClass", "Test child2", WS_CHILDWINDOW,
784 100, 100, 50, 50, hparent, 0, 0, NULL);
785 ok (hchild2 != 0, "Failed to create child2 window\n");
788 hbutton = CreateWindowExA(0, "TestWindowClass", "Test button", WS_CHILDWINDOW,
789 0, 100, 50, 50, hchild, 0, 0, NULL);
790 ok (hbutton != 0, "Failed to create button window\n");
792 /* test WM_SETREDRAW on a not visible child window */
793 test_WM_SETREDRAW(hchild);
795 ShowWindow(hchild, SW_SHOW);
796 ok_sequence(WmShowChildSeq, "ShowWindow:child");
798 /* test WM_SETREDRAW on a visible child window */
799 test_WM_SETREDRAW(hchild);
804 MoveWindow(hchild, 10, 10, 20, 20, TRUE);
805 ok_sequence(WmResizingChildWithMoveWindowSeq, "MoveWindow:child");
807 DestroyWindow(hchild);
808 ok_sequence(WmDestroyChildSeq, "DestroyWindow:child");
809 DestroyWindow(hchild2);
810 DestroyWindow(hbutton);
813 hchild = CreateWindowExA(0, "TestWindowClass", "Test Child Popup", WS_CHILD | WS_POPUP,
814 0, 0, 100, 100, hparent, 0, 0, NULL);
815 ok (hchild != 0, "Failed to create child popup window\n");
816 ok_sequence(WmCreateChildPopupSeq, "CreateWindow:child_popup");
817 DestroyWindow(hchild);
819 /* test what happens to a window which sets WS_VISIBLE in WM_CREATE */
821 hchild = CreateWindowExA(0, "TestPopupClass", "Test Popup", WS_POPUP,
822 0, 0, 100, 100, hparent, 0, 0, NULL);
823 ok (hchild != 0, "Failed to create popup window\n");
824 ok_sequence(WmCreateInvisiblePopupSeq, "CreateWindow:invisible_popup");
825 ok(GetWindowLongA(hchild, GWL_STYLE) & WS_VISIBLE, "WS_VISIBLE should be set\n");
826 ok(IsWindowVisible(hchild), "IsWindowVisible() should return TRUE\n");
828 ShowWindow(hchild, SW_SHOW);
829 ok_sequence(WmShowVisiblePopupSeq, "CreateWindow:show_visible_popup");
831 SetWindowPos(hchild, 0,0,0,0,0, SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE|SWP_NOZORDER);
832 ok_sequence(WmShowVisiblePopupSeq_2, "CreateWindow:show_visible_popup_2");
834 SetWindowPos(hchild, 0,0,0,0,0, SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE);
835 ok_sequence(WmShowVisiblePopupSeq_3, "CreateWindow:show_visible_popup_3");
836 DestroyWindow(hchild);
838 /* this time add WS_VISIBLE for CreateWindowEx, but this fact actually
839 * changes nothing in message sequences.
842 hchild = CreateWindowExA(0, "TestPopupClass", "Test Popup", WS_POPUP | WS_VISIBLE,
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");
854 DestroyWindow(hchild);
857 hwnd = CreateWindowExA(WS_EX_DLGMODALFRAME, "TestDialogClass", NULL, WS_VISIBLE|WS_CAPTION|WS_SYSMENU|WS_DLGFRAME,
858 0, 0, 100, 100, hparent, 0, 0, NULL);
859 ok(hwnd != 0, "Failed to create custom dialog window\n");
860 ok_sequence(WmCreateCustomDialogSeq, "CreateCustomDialog");
863 after_end_dialog = 1;
864 EndDialog( hwnd, 0 );
865 ok_sequence(WmEndCustomDialogSeq, "EndCustomDialog");
868 after_end_dialog = 0;
871 DialogBoxA( 0, "TEST_DIALOG", hparent, TestModalDlgProcA );
872 ok_sequence(WmModalDialogSeq, "ModalDialog");
874 DestroyWindow(hparent);
877 /* Message sequence for SetMenu */
878 hmenu = CreateMenu();
879 ok (hmenu != 0, "Failed to create menu\n");
880 ok (InsertMenuA(hmenu, -1, MF_BYPOSITION, 0x1000, "foo"), "InsertMenu failed\n");
881 hwnd = CreateWindowExA(0, "TestWindowClass", "Test overlapped", WS_OVERLAPPEDWINDOW,
882 100, 100, 200, 200, 0, hmenu, 0, NULL);
883 ok_sequence(WmCreateOverlappedSeq, "CreateWindow:overlapped");
884 ok (SetMenu(hwnd, 0), "SetMenu\n");
885 ok_sequence(WmSetMenuNonVisibleSizeChangeSeq, "SetMenu:NonVisibleSizeChange");
886 ok (SetMenu(hwnd, 0), "SetMenu\n");
887 ok_sequence(WmSetMenuNonVisibleNoSizeChangeSeq, "SetMenu:NonVisibleNoSizeChange");
888 ShowWindow(hwnd, SW_SHOW);
890 ok (SetMenu(hwnd, 0), "SetMenu\n");
891 ok_sequence(WmSetMenuVisibleNoSizeChangeSeq, "SetMenu:VisibleNoSizeChange");
892 ok (SetMenu(hwnd, hmenu), "SetMenu\n");
893 ok_sequence(WmSetMenuVisibleSizeChangeSeq, "SetMenu:VisibleSizeChange");
898 static LRESULT WINAPI MsgCheckProcA(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
900 static long defwndproc_counter = 0;
904 trace("%p, %04x, %08x, %08lx\n", hwnd, message, wParam, lParam);
906 msg.message = message;
907 msg.flags = sent|wparam|lparam;
908 if (defwndproc_counter) msg.flags |= defwinproc;
913 if (message == WM_GETMINMAXINFO && (GetWindowLongA(hwnd, GWL_STYLE) & WS_CHILD))
915 HWND parent = GetParent(hwnd);
917 MINMAXINFO *minmax = (MINMAXINFO *)lParam;
919 GetClientRect(parent, &rc);
920 trace("parent %p client size = (%ld x %ld)\n", parent, rc.right, rc.bottom);
922 trace("ptReserved = (%ld,%ld)\n"
923 "ptMaxSize = (%ld,%ld)\n"
924 "ptMaxPosition = (%ld,%ld)\n"
925 "ptMinTrackSize = (%ld,%ld)\n"
926 "ptMaxTrackSize = (%ld,%ld)\n",
927 minmax->ptReserved.x, minmax->ptReserved.y,
928 minmax->ptMaxSize.x, minmax->ptMaxSize.y,
929 minmax->ptMaxPosition.x, minmax->ptMaxPosition.y,
930 minmax->ptMinTrackSize.x, minmax->ptMinTrackSize.y,
931 minmax->ptMaxTrackSize.x, minmax->ptMaxTrackSize.y);
933 ok(minmax->ptMaxSize.x == rc.right, "default width of maximized child %ld != %ld\n",
934 minmax->ptMaxSize.x, rc.right);
935 ok(minmax->ptMaxSize.y == rc.bottom, "default height of maximized child %ld != %ld\n",
936 minmax->ptMaxSize.y, rc.bottom);
939 defwndproc_counter++;
940 ret = DefWindowProcA(hwnd, message, wParam, lParam);
941 defwndproc_counter--;
946 static LRESULT WINAPI PopupMsgCheckProcA(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
948 static long defwndproc_counter = 0;
952 trace("popup: %p, %04x, %08x, %08lx\n", hwnd, message, wParam, lParam);
954 msg.message = message;
955 msg.flags = sent|wparam|lparam;
956 if (defwndproc_counter) msg.flags |= defwinproc;
961 if (message == WM_CREATE)
963 DWORD style = GetWindowLongA(hwnd, GWL_STYLE) | WS_VISIBLE;
964 SetWindowLongA(hwnd, GWL_STYLE, style);
967 defwndproc_counter++;
968 ret = DefWindowProcA(hwnd, message, wParam, lParam);
969 defwndproc_counter--;
974 static LRESULT WINAPI ParentMsgCheckProcA(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
976 static long defwndproc_counter = 0;
980 trace("parent: %p, %04x, %08x, %08lx\n", hwnd, message, wParam, lParam);
982 if (message == WM_PARENTNOTIFY || message == WM_CANCELMODE ||
983 message == WM_SETFOCUS || message == WM_KILLFOCUS ||
984 message == WM_ENABLE || message == WM_ENTERIDLE ||
985 message == WM_IME_SETCONTEXT)
987 msg.message = message;
988 msg.flags = sent|parent|wparam|lparam;
989 if (defwndproc_counter) msg.flags |= defwinproc;
995 defwndproc_counter++;
996 ret = DefWindowProcA(hwnd, message, wParam, lParam);
997 defwndproc_counter--;
1002 static LRESULT WINAPI TestDlgProcA(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
1004 static long defwndproc_counter = 0;
1008 trace("dialog: %p, %04x, %08x, %08lx\n", hwnd, message, wParam, lParam);
1010 DefDlgProcA(hwnd, DM_SETDEFID, 1, 0);
1011 ret = DefDlgProcA(hwnd, DM_GETDEFID, 0, 0);
1012 if (after_end_dialog)
1013 ok( ret == 0, "DM_GETDEFID should return 0 after EndDialog, got %lx\n", ret );
1015 ok(HIWORD(ret) == DC_HASDEFID, "DM_GETDEFID should return DC_HASDEFID, got %lx\n", ret);
1017 msg.message = message;
1018 msg.flags = sent|wparam|lparam;
1019 if (defwndproc_counter) msg.flags |= defwinproc;
1020 msg.wParam = wParam;
1021 msg.lParam = lParam;
1024 defwndproc_counter++;
1025 ret = DefDlgProcA(hwnd, message, wParam, lParam);
1026 defwndproc_counter--;
1031 static BOOL RegisterWindowClasses(void)
1036 cls.lpfnWndProc = MsgCheckProcA;
1039 cls.hInstance = GetModuleHandleA(0);
1041 cls.hCursor = LoadCursorA(0, (LPSTR)IDC_ARROW);
1042 cls.hbrBackground = GetStockObject(WHITE_BRUSH);
1043 cls.lpszMenuName = NULL;
1044 cls.lpszClassName = "TestWindowClass";
1045 if(!RegisterClassA(&cls)) return FALSE;
1047 cls.lpfnWndProc = PopupMsgCheckProcA;
1048 cls.lpszClassName = "TestPopupClass";
1049 if(!RegisterClassA(&cls)) return FALSE;
1051 cls.lpfnWndProc = ParentMsgCheckProcA;
1052 cls.lpszClassName = "TestParentClass";
1053 if(!RegisterClassA(&cls)) return FALSE;
1055 cls.lpfnWndProc = DefWindowProcA;
1056 cls.lpszClassName = "SimpleWindowClass";
1057 if(!RegisterClassA(&cls)) return FALSE;
1059 ok(GetClassInfoA(0, "#32770", &cls), "GetClassInfo failed\n");
1060 cls.lpfnWndProc = TestDlgProcA;
1061 cls.lpszClassName = "TestDialogClass";
1062 if(!RegisterClassA(&cls)) return FALSE;
1067 static HHOOK hCBT_hook;
1069 static LRESULT CALLBACK cbt_hook_proc(int nCode, WPARAM wParam, LPARAM lParam)
1073 trace("CBT: %d, %08x, %08lx\n", nCode, wParam, lParam);
1075 if (GetClassNameA((HWND)wParam, buf, sizeof(buf)))
1077 if (!strcmp(buf, "TestWindowClass") ||
1078 !strcmp(buf, "TestParentClass") ||
1079 !strcmp(buf, "TestPopupClass") ||
1080 !strcmp(buf, "SimpleWindowClass") ||
1081 !strcmp(buf, "TestDialogClass"))
1085 msg.message = nCode;
1087 msg.wParam = wParam;
1088 msg.lParam = lParam;
1092 return CallNextHookEx(hCBT_hook, nCode, wParam, lParam);
1097 if (!RegisterWindowClasses()) assert(0);
1099 hCBT_hook = SetWindowsHookExA(WH_CBT, cbt_hook_proc, 0, GetCurrentThreadId());
1104 UnhookWindowsHookEx(hCBT_hook);