ReactOS  0.4.15-dev-499-g1f31905
msg.c
Go to the documentation of this file.
1 /*
2  * Unit tests for window message handling
3  *
4  * Copyright 1999 Ove Kaaven
5  * Copyright 2003 Dimitrie O. Paun
6  * Copyright 2004,2005,2016 Dmitry Timoshkov
7  *
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.
12  *
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.
17  *
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21  */
22 
23 #include <assert.h>
24 #include <limits.h>
25 #include <stdarg.h>
26 #include <stdio.h>
27 
28 #include "windef.h"
29 #include "winbase.h"
30 #include "wingdi.h"
31 #include "winuser.h"
32 #include "winnls.h"
33 #include "dbt.h"
34 
35 #include "wine/test.h"
36 
37 #define MDI_FIRST_CHILD_ID 2004
38 
39 /* undocumented SWP flags - from SDK 3.1 */
40 #define SWP_NOCLIENTSIZE 0x0800
41 #define SWP_NOCLIENTMOVE 0x1000
42 #define SWP_STATECHANGED 0x8000
43 
44 #define SW_NORMALNA 0xCC /* undoc. flag in MinMaximize */
45 
46 #ifndef WM_KEYF1
47 #define WM_KEYF1 0x004d
48 #endif
49 
50 #ifndef WM_SYSTIMER
51 #define WM_SYSTIMER 0x0118
52 #endif
53 
54 #define WND_PARENT_ID 1
55 #define WND_POPUP_ID 2
56 #define WND_CHILD_ID 3
57 
58 #ifndef WM_LBTRACKPOINT
59 #define WM_LBTRACKPOINT 0x0131
60 #endif
61 
62 #ifdef __i386__
63 #define ARCH "x86"
64 #elif defined __x86_64__
65 #define ARCH "amd64"
66 #elif defined __arm__
67 #define ARCH "arm"
68 #elif defined __aarch64__
69 #define ARCH "arm64"
70 #else
71 #define ARCH "none"
72 #endif
73 
74 static BOOL (WINAPI *pActivateActCtx)(HANDLE,ULONG_PTR*);
75 static HANDLE (WINAPI *pCreateActCtxW)(PCACTCTXW);
76 static BOOL (WINAPI *pDeactivateActCtx)(DWORD,ULONG_PTR);
77 static BOOL (WINAPI *pGetCurrentActCtx)(HANDLE *);
78 static BOOL (WINAPI *pQueryActCtxW)(DWORD,HANDLE,void*,ULONG,void*,SIZE_T,SIZE_T*);
79 static void (WINAPI *pReleaseActCtx)(HANDLE);
80 
81 /* encoded DRAWITEMSTRUCT into an LPARAM */
82 typedef struct
83 {
84  union
85  {
86  struct
87  {
88  UINT type : 4; /* ODT_* flags */
89  UINT ctl_id : 4; /* Control ID */
90  UINT item_id : 4; /* Menu item ID */
91  UINT action : 4; /* ODA_* flags */
92  UINT state : 16; /* ODS_* flags */
93  } item;
95  } u;
97 
98 /* encoded MEASUREITEMSTRUCT into a WPARAM */
99 typedef struct
100 {
101  union
102  {
103  struct
104  {
105  UINT CtlType : 4;
106  UINT CtlID : 4;
107  UINT itemID : 4;
108  UINT wParam : 20;
109  } item;
110  WPARAM wp;
111  } u;
113 
116 static HHOOK hKBD_hook;
117 static HHOOK hCBT_hook;
119 
120 static const WCHAR testWindowClassW[] =
121 { 'T','e','s','t','W','i','n','d','o','w','C','l','a','s','s','W',0 };
122 
124 
125 /*
126 FIXME: add tests for these
127 Window Edge Styles (Win31/Win95/98 look), in order of precedence:
128  WS_EX_DLGMODALFRAME: double border, WS_CAPTION allowed
129  WS_THICKFRAME: thick border
130  WS_DLGFRAME: double border, WS_CAPTION not allowed (but possibly shown anyway)
131  WS_BORDER (default for overlapped windows): single black border
132  none (default for child (and popup?) windows): no border
133 */
134 
135 typedef enum {
136  sent=0x1,
137  posted=0x2,
138  parent=0x4,
139  wparam=0x8,
140  lparam=0x10,
143  optional=0x80,
144  hook=0x100,
146  kbd_hook=0x400
147 } msg_flags_t;
148 
149 struct message {
150  UINT message; /* the WM_* code */
151  msg_flags_t flags; /* message props */
152  WPARAM wParam; /* expected value of wParam */
153  LPARAM lParam; /* expected value of lParam */
154  WPARAM wp_mask; /* mask for wParam checks */
155  LPARAM lp_mask; /* mask for lParam checks */
156 };
157 
159  UINT message; /* the WM_* code */
160  msg_flags_t flags; /* message props */
161  HWND hwnd; /* window that received the message */
162  WPARAM wParam; /* expected value of wParam */
163  LPARAM lParam; /* expected value of lParam */
164  int line; /* source line where logged */
165  const char *descr; /* description for trace output */
166  char output[512]; /* trace output */
167 };
168 
169 /* Empty message sequence */
170 static const struct message WmEmptySeq[] =
171 {
172  { 0 }
173 };
174 /* CreateWindow (for overlapped window, not initially visible) (16/32) */
175 static const struct message WmCreateOverlappedSeq[] = {
176  { HCBT_CREATEWND, hook },
177  { WM_GETMINMAXINFO, sent },
178  { WM_NCCREATE, sent },
179  { WM_NCCALCSIZE, sent|wparam, 0 },
180  { 0x0093, sent|defwinproc|optional },
181  { 0x0094, sent|defwinproc|optional },
182  { EVENT_OBJECT_REORDER, winevent_hook|wparam|lparam, 0, 0 },
183  { WM_CREATE, sent },
184  { EVENT_OBJECT_CREATE, winevent_hook|wparam|lparam, 0, 0 },
185  { 0 }
186 };
187 /* SetWindowPos(SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE)
188  * for a not visible overlapped window.
189  */
190 static const struct message WmSWP_ShowOverlappedSeq[] = {
192  { EVENT_OBJECT_SHOW, winevent_hook|wparam|lparam, 0, 0 },
193  { WM_NCPAINT, sent|wparam|optional, 1 },
196  { HCBT_ACTIVATE, hook },
197  { EVENT_SYSTEM_FOREGROUND, winevent_hook|wparam|lparam, 0, 0 },
198  { WM_NOTIFYFORMAT, sent|optional },
199  { WM_QUERYUISTATE, sent|optional },
201  { WM_WINDOWPOSCHANGING, sent|wparam|optional, SWP_NOSIZE|SWP_NOMOVE }, /* Win9x: SWP_NOSENDCHANGING */
202  { WM_ACTIVATEAPP, sent|wparam, 1 },
203  { WM_NCACTIVATE, sent },
205  { WM_ACTIVATE, sent|wparam, 1 },
206  { HCBT_SETFOCUS, hook },
209  { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
211  { WM_GETTEXT, sent|optional },
212  { WM_NCPAINT, sent|wparam|optional, 1 },
215  /* Win9x adds SWP_NOZORDER below */
217  { WM_GETTEXT, sent|optional },
219  { WM_NCPAINT, sent|wparam|optional, 1 },
221  { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 },
224  { WM_PAINT, sent|optional },
228  { 0 }
229 };
230 /* SetWindowPos(SWP_HIDEWINDOW|SWP_NOSIZE|SWP_NOMOVE)
231  * for a visible overlapped window.
232  */
233 static const struct message WmSWP_HideOverlappedSeq[] = {
235  { EVENT_OBJECT_HIDE, winevent_hook|wparam|lparam, 0, 0 },
242  { 0 }
243 };
244 
245 /* SetWindowPos(SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOMOVE)
246  * for a visible overlapped window.
247  */
248 static const struct message WmSWP_ResizeSeq[] = {
252  { WM_NCPAINT, sent|optional },
258  { WM_NCPAINT, sent|optional },
261  { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 },
262  { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam|optional, 0, 0 }, /* XP sends a duplicate */
263  { 0 }
264 };
265 
266 /* SetWindowPos(SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOMOVE)
267  * for a visible popup window.
268  */
269 static const struct message WmSWP_ResizePopupSeq[] = {
271  { WM_GETMINMAXINFO, sent|defwinproc|optional }, /* Win9x */
273  { WM_NCPAINT, sent|optional },
279  { WM_NCPAINT, sent|optional },
282  { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 },
283  { 0 }
284 };
285 
286 /* SetWindowPos(SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOSIZE)
287  * for a visible overlapped window.
288  */
289 static const struct message WmSWP_MoveSeq[] = {
291  { WM_NCPAINT, sent|optional },
295  { WM_MOVE, sent|defwinproc|wparam, 0 },
296  { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 },
297  { 0 }
298 };
299 /* Resize with SetWindowPos(SWP_NOZORDER)
300  * for a visible overlapped window
301  * SWP_NOZORDER is stripped by the logging code
302  */
303 static const struct message WmSWP_ResizeNoZOrder[] = {
304  { WM_WINDOWPOSCHANGING, sent|wparam, /*SWP_NOZORDER|*/SWP_NOACTIVATE },
307  { WM_NCPAINT, sent|optional },
310  { WM_WINDOWPOSCHANGED, sent|wparam|optional, /*SWP_NOZORDER|*/SWP_NOACTIVATE, 0,
314  { WM_NCCALCSIZE, sent|wparam|optional, 1 }, /* Win9x doesn't send it */
315  { WM_NCPAINT, sent|optional }, /* Win9x doesn't send it */
316  { WM_GETTEXT, sent|defwinproc|optional }, /* Win9x doesn't send it */
317  { WM_ERASEBKGND, sent|optional }, /* Win9x doesn't send it */
318  { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 },
319  { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 },
320  { 0 }
321 };
322 
323 /* Switch visible mdi children */
324 static const struct message WmSwitchChild[] = {
325  /* Switch MDI child */
326  { WM_MDIACTIVATE, sent },/* in the MDI client */
327  { WM_WINDOWPOSCHANGING, sent|wparam,SWP_NOSIZE|SWP_NOMOVE },/* in the 1st MDI child */
328  { EVENT_OBJECT_REORDER, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
329  { WM_CHILDACTIVATE, sent },/* in the 1st MDI child */
330  /* Deactivate 2nd MDI child */
331  { WM_NCACTIVATE, sent|wparam|defwinproc, 0 }, /* in the 2nd MDI child */
332  { WM_MDIACTIVATE, sent|defwinproc }, /* in the 2nd MDI child */
334  /* Preparing for maximize and maximize the 1st MDI child */
335  { WM_GETMINMAXINFO, sent|defwinproc }, /* in the 1st MDI child */
337  { WM_NCCALCSIZE, sent|wparam|defwinproc, 1 }, /* in the 1st MDI child */
338  { WM_CHILDACTIVATE, sent|defwinproc }, /* in the 1st MDI child */
340  { WM_SIZE, sent|defwinproc|wparam, SIZE_MAXIMIZED }, /* in the 1st MDI child */
341  /* Lock redraw 2nd MDI child */
342  { WM_SETREDRAW, sent|wparam|defwinproc, 0 }, /* in the 2nd MDI child */
344  /* Restore 2nd MDI child */
346  { WM_NCCALCSIZE, sent|wparam|defwinproc, 1 },/* in the 2nd MDI child */
347  { EVENT_OBJECT_SHOW, winevent_hook|wparam|lparam, 0, 0 }, /* in the 2nd MDI child */
349  { WM_SIZE, sent|defwinproc|wparam, SIZE_RESTORED }, /* in the 2nd MDI child */
350  { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, /* in the 2nd MDI child */
351  /* Redraw 2nd MDI child */
352  { WM_SETREDRAW, sent|wparam|defwinproc, 1 },/* in the 2nd MDI child */
353  /* Redraw MDI frame */
355  { WM_NCCALCSIZE, sent|wparam, 1 },/* in MDI frame */
357  { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, /* in MDI frame */
358  { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, /* in the 1st MDI child */
360  { WM_NCACTIVATE, sent|wparam|defwinproc, 1 }, /* in the 1st MDI child */
361  { HCBT_SETFOCUS, hook },
362  { WM_KILLFOCUS, sent|defwinproc }, /* in the 2nd MDI child */
363  { WM_IME_SETCONTEXT, sent|wparam|defwinproc|optional, 0 },/* in the 1st MDI child */
364  { WM_IME_SETCONTEXT, sent|wparam|optional, 1 }, /* in MDI client */
365  { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
366  { WM_SETFOCUS, sent },/* in the MDI client */
367  { HCBT_SETFOCUS, hook },
368  { WM_KILLFOCUS, sent },/* in the MDI client */
369  { WM_IME_SETCONTEXT, sent|wparam|optional, 0 }, /* in MDI client */
370  { WM_IME_SETCONTEXT, sent|wparam|defwinproc|optional, 1 }, /* in the 1st MDI child */
371  { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
372  { WM_SETFOCUS, sent|defwinproc }, /* in the 1st MDI child */
373  { WM_MDIACTIVATE, sent|defwinproc },/* in the 1st MDI child */
375  { 0 }
376 };
377 
378 /* Switch visible not maximized mdi children */
379 static const struct message WmSwitchNotMaximizedChild[] = {
380  /* Switch not maximized MDI child */
381  { WM_MDIACTIVATE, sent },/* in the MDI client */
382  { WM_WINDOWPOSCHANGING, sent|wparam,SWP_NOSIZE|SWP_NOMOVE },/* in the 2nd MDI child */
383  { EVENT_OBJECT_REORDER, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
384  { WM_CHILDACTIVATE, sent },/* in the 2nd MDI child */
385  /* Deactivate 1st MDI child */
386  { WM_NCACTIVATE, sent|wparam|defwinproc, 0 }, /* in the 1st MDI child */
387  { WM_MDIACTIVATE, sent|defwinproc }, /* in the 1st MDI child */
388  /* Activate 2nd MDI child */
390  { WM_NCACTIVATE, sent|wparam|defwinproc, 1 }, /* in the 2nd MDI child */
391  { HCBT_SETFOCUS, hook }, /* in the 1st MDI child */
392  { WM_KILLFOCUS, sent|defwinproc }, /* in the 1st MDI child */
393  { WM_IME_SETCONTEXT, sent|defwinproc|optional }, /* in the 1st MDI child */
394  { WM_IME_SETCONTEXT, sent|optional }, /* in the MDI client */
395  { WM_SETFOCUS, sent, 0 }, /* in the MDI client */
396  { HCBT_SETFOCUS, hook },
397  { WM_KILLFOCUS, sent }, /* in the MDI client */
398  { WM_IME_SETCONTEXT, sent|optional }, /* in the MDI client */
399  { WM_IME_SETCONTEXT, sent|defwinproc|optional }, /* in the 1st MDI child */
400  { WM_SETFOCUS, sent|defwinproc }, /* in the 2nd MDI child */
401  { WM_MDIACTIVATE, sent|defwinproc }, /* in the 2nd MDI child */
403  { 0 }
404 };
405 
406 
407 /* SetWindowPos(SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE|
408  SWP_NOZORDER|SWP_FRAMECHANGED)
409  * for a visible overlapped window with WS_CLIPCHILDREN style set.
410  */
411 static const struct message WmSWP_FrameChanged_clip[] = {
414  { WM_NCPAINT, sent|parent|optional }, /* wparam != 1 */
416  { WM_ERASEBKGND, sent|parent|optional }, /* FIXME: remove optional once Wine is fixed */
417  { WM_NCPAINT, sent }, /* wparam != 1 */
418  { WM_ERASEBKGND, sent },
420  { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 },
421  { WM_PAINT, sent },
422  { 0 }
423 };
424 /* SetWindowPos(SWP_NOSIZE|SWP_NOMOVE|SWP_DEFERERASE|SWP_NOACTIVATE|
425  SWP_NOZORDER|SWP_FRAMECHANGED)
426  * for a visible overlapped window.
427  */
428 static const struct message WmSWP_FrameChangedDeferErase[] = {
432  { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 },
434  { WM_NCPAINT, sent|beginpaint|parent|optional }, /* wparam != 1 */
436  { WM_PAINT, sent },
437  { WM_NCPAINT, sent|beginpaint }, /* wparam != 1 */
439  { 0 }
440 };
441 
442 /* SetWindowPos(SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE|
443  SWP_NOZORDER|SWP_FRAMECHANGED)
444  * for a visible overlapped window without WS_CLIPCHILDREN style set.
445  */
446 static const struct message WmSWP_FrameChanged_noclip[] = {
449  { WM_NCPAINT, sent|parent|optional }, /* wparam != 1 */
453  { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 },
454  { WM_PAINT, sent },
455  { WM_NCPAINT, sent|beginpaint }, /* wparam != 1 */
457  { 0 }
458 };
459 
460 /* ShowWindow(SW_SHOW) for a not visible overlapped window */
461 static const struct message WmShowOverlappedSeq[] = {
462  { WM_SHOWWINDOW, sent|wparam, 1 },
463  { WM_NCPAINT, sent|wparam|optional, 1 },
465  { EVENT_OBJECT_SHOW, winevent_hook|wparam|lparam, 0, 0 },
466  { WM_NCPAINT, sent|wparam|optional, 1 },
470  { EVENT_SYSTEM_FOREGROUND, winevent_hook|wparam|lparam, 0, 0 },
473  { WM_NCPAINT, sent|wparam|optional, 1 },
481  { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
483  { WM_GETTEXT, sent|optional },
484  { WM_NCPAINT, sent|wparam|optional, 1 },
487  /* Win9x adds SWP_NOZORDER below */
490  { WM_GETTEXT, sent|optional },
491  { WM_NCPAINT, sent|optional },
494 #if 0 /* CreateWindow/ShowWindow(SW_SHOW) also generates WM_SIZE/WM_MOVE
495  * messages. Does that mean that CreateWindow doesn't set initial
496  * window dimensions for overlapped windows?
497  */
498  { WM_SIZE, sent },
499  { WM_MOVE, sent },
500 #endif
501  { WM_PAINT, sent|optional },
503  { 0 }
504 };
505 /* ShowWindow(SW_SHOWMAXIMIZED) for a not visible overlapped window */
506 static const struct message WmShowMaxOverlappedSeq[] = {
508  { WM_GETMINMAXINFO, sent },
512  { EVENT_OBJECT_SHOW, winevent_hook|wparam|lparam, 0, 0 },
514  { EVENT_SYSTEM_FOREGROUND, winevent_hook|wparam|lparam, 0, 0 },
524  { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
526  { WM_GETTEXT, sent|optional },
527  { WM_NCPAINT, sent|wparam|optional, 1 },
530  /* Win9x adds SWP_NOZORDER below */
532  { WM_MOVE, sent|defwinproc },
534  { WM_GETTEXT, sent|optional },
536  { WM_NCPAINT, sent|optional },
538  { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 },
539  { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 },
542  { WM_PAINT, sent|optional },
545  { 0 }
546 };
547 /* ShowWindow(SW_RESTORE) for a not visible maximized overlapped window */
548 static const struct message WmShowRestoreMaxOverlappedSeq[] = {
550  { WM_GETTEXT, sent|optional },
554  { WM_NCPAINT, sent|optional },
561  { WM_NCPAINT, sent|optional },
563  { WM_PAINT, sent|optional },
568  { 0 }
569 };
570 /* ShowWindow(SW_RESTORE) for a not visible minimized overlapped window */
571 static const struct message WmShowRestoreMinOverlappedSeq[] = {
574  { WM_GETTEXT, sent|optional },
576  { WM_WINDOWPOSCHANGING, sent|optional }, /* SWP_NOSIZE|SWP_NOMOVE */
579  { WM_MOVE, sent|optional },
581  { WM_GETTEXT, sent|optional },
596  { WM_GETTEXT, sent|optional },
597  { WM_NCPAINT, sent|wparam|optional, 1 },
599  { WM_ERASEBKGND, sent },
601  { WM_MOVE, sent|defwinproc },
606  { WM_NCPAINT, sent|wparam|optional, 1 },
610  { WM_ACTIVATE, sent|wparam, 1 },
611  { WM_GETTEXT, sent|optional },
612  { WM_PAINT, sent|optional },
616  { 0 }
617 };
618 /* ShowWindow(SW_SHOWMINIMIZED) for a not visible overlapped window */
619 static const struct message WmShowMinOverlappedSeq[] = {
622  { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
626  { WM_GETTEXT, sent|optional },
630  { EVENT_OBJECT_REORDER, winevent_hook|wparam|lparam, 0, 0 },
631  { WM_NCPAINT, sent|optional },
634  { WM_MOVE, sent|defwinproc },
637  { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 },
638  { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 },
639  { EVENT_SYSTEM_MINIMIZESTART, winevent_hook|wparam|lparam, 0, 0 },
644 
645  /* Vista sometimes restores the window right away... */
656  { WM_GETTEXT, sent|optional },
662  { WM_NCPAINT, sent|optional },
671 
672  { WM_PAINT, sent|optional },
675  { 0 }
676 };
677 /* ShowWindow(SW_HIDE) for a visible overlapped window */
678 static const struct message WmHideOverlappedSeq[] = {
679  { WM_SHOWWINDOW, sent|wparam, 0 },
681  { EVENT_OBJECT_HIDE, winevent_hook|wparam|lparam, 0, 0 },
683  { WM_SIZE, sent|optional }, /* XP doesn't send it */
684  { WM_MOVE, sent|optional }, /* XP doesn't send it */
692  { 0 }
693 };
694 /* DestroyWindow for a visible overlapped window */
695 static const struct message WmDestroyOverlappedSeq[] = {
696  { HCBT_DESTROYWND, hook },
697  { 0x0090, sent|optional },
699  { EVENT_OBJECT_HIDE, winevent_hook|wparam|lparam, 0, 0 },
700  { 0x0090, sent|optional },
708  { EVENT_OBJECT_DESTROY, winevent_hook|wparam|lparam, 0, 0 },
709  { WM_DESTROY, sent },
710  { WM_NCDESTROY, sent },
711  { 0 }
712 };
713 /* CreateWindow(WS_MAXIMIZE|WS_VISIBLE) for popup window */
714 static const struct message WmCreateMaxPopupSeq[] = {
715  { HCBT_CREATEWND, hook },
716  { WM_NCCREATE, sent },
717  { WM_NCCALCSIZE, sent|wparam, 0 },
718  { WM_CREATE, sent },
719  { EVENT_OBJECT_CREATE, winevent_hook|wparam|lparam, 0, 0 },
721  { WM_MOVE, sent },
723  { WM_GETMINMAXINFO, sent },
727  { WM_MOVE, sent|defwinproc },
729  { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 },
730  { WM_SHOWWINDOW, sent|wparam, 1 },
732  { EVENT_OBJECT_SHOW, winevent_hook|wparam|lparam, 0, 0 },
733  { HCBT_ACTIVATE, hook },
734  { EVENT_SYSTEM_FOREGROUND, winevent_hook|wparam|lparam, 0, 0 },
737  { WM_NCPAINT, sent|wparam|optional, 1 },
740  { WM_ACTIVATEAPP, sent|wparam, 1 },
741  { WM_NCACTIVATE, sent },
742  { WM_ACTIVATE, sent|wparam, 1 },
743  { HCBT_SETFOCUS, hook },
746  { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
748  { WM_GETTEXT, sent|optional },
750  { WM_NCPAINT, sent|wparam|optional, 1 },
755  { 0 }
756 };
757 /* CreateWindow(WS_MAXIMIZE) for popup window, not initially visible */
758 static const struct message WmCreateInvisibleMaxPopupSeq[] = {
759  { HCBT_CREATEWND, hook },
760  { WM_NCCREATE, sent },
761  { WM_NCCALCSIZE, sent|wparam, 0 },
762  { WM_CREATE, sent },
763  { EVENT_OBJECT_CREATE, winevent_hook|wparam|lparam, 0, 0 },
765  { WM_MOVE, sent },
767  { WM_GETMINMAXINFO, sent },
771  { WM_MOVE, sent|defwinproc },
773  { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 },
774  { 0 }
775 };
776 /* ShowWindow(SW_SHOWMAXIMIZED) for a resized not visible popup window */
777 static const struct message WmShowMaxPopupResizedSeq[] = {
779  { WM_GETMINMAXINFO, sent },
782  { EVENT_OBJECT_SHOW, winevent_hook|wparam|lparam, 0, 0 },
783  { HCBT_ACTIVATE, hook },
784  { EVENT_SYSTEM_FOREGROUND, winevent_hook|wparam|lparam, 0, 0 },
787  { WM_NCPAINT, sent|wparam|optional, 1 },
790  { WM_ACTIVATEAPP, sent|wparam, 1 },
791  { WM_NCACTIVATE, sent },
792  { WM_ACTIVATE, sent|wparam, 1 },
793  { HCBT_SETFOCUS, hook },
796  { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
798  { WM_GETTEXT, sent|optional },
799  { WM_NCPAINT, sent|wparam|optional, 1 },
802  /* WinNT4.0 sends WM_MOVE */
805  { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 },
806  { 0 }
807 };
808 /* ShowWindow(SW_SHOWMAXIMIZED) for a not visible popup window */
809 static const struct message WmShowMaxPopupSeq[] = {
811  { WM_GETMINMAXINFO, sent },
814  { EVENT_OBJECT_SHOW, winevent_hook|wparam|lparam, 0, 0 },
815  { HCBT_ACTIVATE, hook },
816  { EVENT_SYSTEM_FOREGROUND, winevent_hook|wparam|lparam, 0, 0 },
819  { WM_NCPAINT, sent|wparam|optional, 1 },
822  { WM_ACTIVATEAPP, sent|wparam, 1 },
823  { WM_NCACTIVATE, sent },
824  { WM_ACTIVATE, sent|wparam, 1 },
825  { HCBT_SETFOCUS, hook },
828  { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
830  { WM_GETTEXT, sent|optional },
832  { WM_NCPAINT, sent|wparam|optional, 1 },
837  { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 },
839  { 0 }
840 };
841 /* CreateWindow(WS_VISIBLE) for popup window */
842 static const struct message WmCreatePopupSeq[] = {
843  { HCBT_CREATEWND, hook },
844  { WM_NCCREATE, sent },
845  { WM_NCCALCSIZE, sent|wparam, 0 },
846  { WM_CREATE, sent },
847  { EVENT_OBJECT_CREATE, winevent_hook|wparam|lparam, 0, 0 },
849  { WM_MOVE, sent },
850  { WM_SHOWWINDOW, sent|wparam, 1 },
852  { EVENT_OBJECT_SHOW, winevent_hook|wparam|lparam, 0, 0 },
853  { HCBT_ACTIVATE, hook },
854  { EVENT_SYSTEM_FOREGROUND, winevent_hook|wparam|lparam, 0, 0 },
857  { WM_NCPAINT, sent|wparam|optional, 1 },
860  { WM_ACTIVATEAPP, sent|wparam, 1 },
861  { WM_NCACTIVATE, sent },
862  { WM_ACTIVATE, sent|wparam, 1 },
863  { HCBT_SETFOCUS, hook },
866  { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
868  { WM_GETTEXT, sent|optional },
870  { WM_NCPAINT, sent|wparam|optional, 1 },
873  { 0 }
874 };
875 /* ShowWindow(SW_SHOWMAXIMIZED) for a visible popup window */
876 static const struct message WmShowVisMaxPopupSeq[] = {
878  { WM_GETMINMAXINFO, sent },
879  { WM_GETTEXT, sent|optional },
881  { WM_GETTEXT, sent|optional },
884  { WM_NCPAINT, sent|wparam|optional, 1 },
887  { WM_MOVE, sent|defwinproc },
889  { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 },
890  { 0 }
891 };
892 /* CreateWindow (for a child popup window, not initially visible) */
893 static const struct message WmCreateChildPopupSeq[] = {
894  { HCBT_CREATEWND, hook },
895  { WM_NCCREATE, sent },
896  { WM_NCCALCSIZE, sent|wparam, 0 },
897  { WM_CREATE, sent },
898  { EVENT_OBJECT_CREATE, winevent_hook|wparam|lparam, 0, 0 },
900  { WM_MOVE, sent },
901  { 0 }
902 };
903 /* CreateWindow (for a popup window, not initially visible,
904  * which sets WS_VISIBLE in WM_CREATE handler)
905  */
906 static const struct message WmCreateInvisiblePopupSeq[] = {
907  { HCBT_CREATEWND, hook },
908  { WM_NCCREATE, sent },
909  { WM_NCCALCSIZE, sent|wparam, 0 },
910  { WM_CREATE, sent },
911  { WM_STYLECHANGING, sent },
912  { WM_STYLECHANGED, sent },
913  { EVENT_OBJECT_CREATE, winevent_hook|wparam|lparam, 0, 0 },
915  { WM_MOVE, sent },
916  { 0 }
917 };
918 /* SetWindowPos(SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE|SWP_NOZORDER)
919  * for a popup window with WS_VISIBLE style set
920  */
921 static const struct message WmShowVisiblePopupSeq_2[] = {
923  { 0 }
924 };
925 /* SetWindowPos(SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE)
926  * for a popup window with WS_VISIBLE style set
927  */
928 static const struct message WmShowVisiblePopupSeq_3[] = {
930  { HCBT_ACTIVATE, hook },
931  { EVENT_SYSTEM_FOREGROUND, winevent_hook|wparam|lparam, 0, 0 },
934  { WM_NCACTIVATE, sent },
935  { WM_ACTIVATE, sent|wparam, 1 },
936  { HCBT_SETFOCUS, hook },
937  { WM_KILLFOCUS, sent|parent },
941  { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
943  { WM_GETTEXT, sent|optional },
945  { 0 }
946 };
947 /* CreateWindow (for a popup window with WS_VISIBLE style set and extreme location)
948  */
949 static const struct message WmShowPopupExtremeLocationSeq[] = {
950  { HCBT_CREATEWND, hook },
951  { WM_NCCREATE, sent },
952  { WM_NCCALCSIZE, sent|wparam, 0 },
953  { WM_CREATE, sent },
954  { EVENT_OBJECT_CREATE, winevent_hook|wparam|lparam, 0, 0 },
956  { WM_MOVE, sent },
957  { WM_SHOWWINDOW, sent|wparam, 1 },
959  { HCBT_ACTIVATE, hook },
962  { WM_ACTIVATEAPP, sent },
963  { WM_NCACTIVATE, sent },
964  { WM_ACTIVATE, sent },
968  { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
969  { HCBT_SETFOCUS, hook },
971  { WM_NCPAINT, sent|wparam, 1 },
972  { WM_ERASEBKGND, sent },
974  /* occasionally received on test machines */
975  { WM_NCPAINT, sent|optional },
977  { 0 }
978 };
979 /* CreateWindow (for a popup window with WS_VISIBLE style set)
980  */
981 static const struct message WmShowPopupFirstDrawSeq_1[] = {
982  { HCBT_CREATEWND, hook },
983  { WM_NCCREATE, sent },
984  { WM_NCCALCSIZE, sent|wparam, 0 },
985  { WM_CREATE, sent },
986  { EVENT_OBJECT_CREATE, winevent_hook|wparam|lparam, 0, 0 },
988  { WM_MOVE, sent },
989  { WM_SHOWWINDOW, sent|wparam, 1 },
991  { HCBT_ACTIVATE, hook },
994  { WM_ACTIVATEAPP, sent },
995  { WM_NCACTIVATE, sent },
996  { WM_ACTIVATE, sent },
1000  { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
1001  { HCBT_SETFOCUS, hook },
1003  { WM_NCPAINT, sent|wparam, 1 },
1004  { WM_ERASEBKGND, sent },
1006  { WM_PAINT, sent },
1007  /* occasionally received on test machines */
1010  { 0 }
1011 };
1012 /* CreateWindow (for a popup window that is shown with ShowWindow(SW_SHOWMAXIMIZED))
1013  */
1014 static const struct message WmShowPopupFirstDrawSeq_2[] = {
1015  { HCBT_CREATEWND, hook },
1016  { WM_NCCREATE, sent },
1017  { WM_NCCALCSIZE, sent|wparam, 0 },
1018  { WM_CREATE, sent },
1019  { EVENT_OBJECT_CREATE, winevent_hook|wparam|lparam, 0, 0 },
1021  { WM_MOVE, sent },
1023  { WM_GETMINMAXINFO, sent },
1025  { WM_NCCALCSIZE, sent|wparam, TRUE },
1026  { HCBT_ACTIVATE, hook },
1028  { WM_NCPAINT, sent|optional|wparam, 1 },
1032  { WM_ACTIVATEAPP, sent },
1033  { WM_NCACTIVATE, sent },
1034  { WM_ACTIVATE, sent },
1038  { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
1039  { HCBT_SETFOCUS, hook },
1041  { WM_NCPAINT, sent|wparam, 1 },
1042  { WM_ERASEBKGND, sent },
1044  { WM_MOVE, sent|defwinproc },
1045  { WM_SIZE, sent|defwinproc, 0 },
1046  { WM_PAINT, sent},
1047  /* occasionally received on test machines */
1050  { 0 }
1051 };
1052 static const struct message WmFirstDrawSetWindowPosSeq1[] = {
1053  { HCBT_CREATEWND, hook },
1054  { WM_NCCREATE, sent },
1055  { WM_NCCALCSIZE, sent|wparam, 0 },
1056  { WM_CREATE, sent },
1057  { EVENT_OBJECT_CREATE, winevent_hook|wparam|lparam, 0, 0 },
1059  { WM_MOVE, sent },
1061  { HCBT_ACTIVATE, hook },
1064  { WM_ACTIVATEAPP, sent },
1065  { WM_NCACTIVATE, sent },
1066  { WM_ACTIVATE, sent },
1070  { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
1071  { HCBT_SETFOCUS, hook },
1073  { WM_NCPAINT, sent|wparam, 1 },
1074  { WM_ERASEBKGND, sent },
1076  { WM_MOVE, sent|defwinproc },
1077  { 0 }
1078 };
1079 static const struct message WmFirstDrawSetWindowPosSeq2[] = {
1080  { HCBT_CREATEWND, hook },
1081  { WM_NCCREATE, sent },
1082  { WM_NCCALCSIZE, sent|wparam, 0 },
1083  { WM_CREATE, sent },
1084  { EVENT_OBJECT_CREATE, winevent_hook|wparam|lparam, 0, 0 },
1086  { WM_MOVE, sent },
1088  { HCBT_ACTIVATE, hook },
1091  { WM_ACTIVATEAPP, sent },
1092  { WM_NCACTIVATE, sent },
1093  { WM_ACTIVATE, sent },
1097  { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
1098  { HCBT_SETFOCUS, hook },
1101  { WM_MOVE, sent|defwinproc },
1102  { 0 }
1103 };
1104 static const struct message WmFirstDrawSetWindowPosSeq3[] = {
1105  { HCBT_CREATEWND, hook },
1106  { WM_NCCREATE, sent },
1107  { WM_NCCALCSIZE, sent|wparam, 0 },
1108  { WM_CREATE, sent },
1109  { EVENT_OBJECT_CREATE, winevent_hook|wparam|lparam, 0, 0 },
1111  { WM_MOVE, sent },
1113  /* Probably shouldn't happen, but not part of this test */
1117  { WM_ACTIVATE, sent|optional },
1120  { 0 }
1121 };
1122 static const struct message WmFirstDrawSetWindowPosSeq4[] = {
1123  { HCBT_CREATEWND, hook },
1124  { WM_NCCREATE, sent },
1125  { WM_NCCALCSIZE, sent|wparam, 0 },
1126  { WM_CREATE, sent },
1127  { EVENT_OBJECT_CREATE, winevent_hook|wparam|lparam, 0, 0 },
1129  { WM_MOVE, sent },
1131  { HCBT_ACTIVATE, hook },
1134  { WM_ACTIVATEAPP, sent },
1135  { WM_NCACTIVATE, sent },
1136  { WM_ACTIVATE, sent },
1140  { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
1141  { HCBT_SETFOCUS, hook },
1143  { WM_NCPAINT, sent|wparam, 1 },
1144  { WM_ERASEBKGND, sent },
1146  { 0 }
1147 };
1148 static const struct message WmFirstDrawSetWindowPosSeq5[] = {
1149  { HCBT_CREATEWND, hook },
1150  { WM_NCCREATE, sent },
1151  { WM_NCCALCSIZE, sent|wparam, 0 },
1152  { WM_CREATE, sent },
1153  { EVENT_OBJECT_CREATE, winevent_hook|wparam|lparam, 0, 0 },
1155  { WM_MOVE, sent },
1157  { HCBT_ACTIVATE, hook },
1160  { WM_ACTIVATEAPP, sent },
1161  { WM_NCACTIVATE, sent },
1162  { WM_ACTIVATE, sent },
1166  { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
1167  { HCBT_SETFOCUS, hook },
1170  { 0 }
1171 };
1172 static const struct message WmFirstDrawChildSeq1[] = {
1173  { 0 }
1174 };
1175 static const struct message WmFirstDrawChildSeq2[] = {
1176  { WM_NCPAINT, sent|wparam, 1 },
1177  { WM_ERASEBKGND, sent },
1178  /* occasionally received on test machines */
1179  { WM_NCPAINT, sent|optional },
1181  { 0 }
1182 };
1183 /* CreateWindow (for child window, not initially visible) */
1184 static const struct message WmCreateChildSeq[] = {
1185  { HCBT_CREATEWND, hook },
1186  { WM_NCCREATE, sent },
1187  /* child is inserted into parent's child list after WM_NCCREATE returns */
1188  { WM_NCCALCSIZE, sent|wparam, 0 },
1189  { WM_CREATE, sent },
1190  { EVENT_OBJECT_CREATE, winevent_hook|wparam|lparam, 0, 0 },
1192  { WM_MOVE, sent },
1194  { 0 }
1195 };
1196 /* CreateWindow (for maximized child window, not initially visible) */
1197 static const struct message WmCreateMaximizedChildSeq[] = {
1198  { HCBT_CREATEWND, hook },
1199  { WM_NCCREATE, sent },
1200  { WM_NCCALCSIZE, sent|wparam, 0 },
1201  { WM_CREATE, sent },
1202  { EVENT_OBJECT_CREATE, winevent_hook|wparam|lparam, 0, 0 },
1204  { WM_MOVE, sent },
1206  { WM_GETMINMAXINFO, sent },
1208  { WM_NCCALCSIZE, sent|wparam, 1 },
1211  { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 },
1213  { 0 }
1214 };
1215 /* CreateWindow (for a child window, initially visible) */
1216 static const struct message WmCreateVisibleChildSeq[] = {
1217  { HCBT_CREATEWND, hook },
1218  { WM_NCCREATE, sent },
1219  /* child is inserted into parent's child list after WM_NCCREATE returns */
1220  { WM_NCCALCSIZE, sent|wparam, 0 },
1221  { EVENT_OBJECT_REORDER, winevent_hook|wparam|lparam, 0, 0 },
1222  { WM_CREATE, sent },
1223  { EVENT_OBJECT_CREATE, winevent_hook|wparam|lparam, 0, 0 },
1225  { WM_MOVE, sent },
1227  { WM_SHOWWINDOW, sent|wparam, 1 },
1229  { EVENT_OBJECT_SHOW, winevent_hook|wparam|lparam, 0, 0 },
1232  { WM_NCCALCSIZE, sent|wparam|optional, 1 }, /* WinXP */
1233  { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 },
1234  { 0 }
1235 };
1236 /* ShowWindow(SW_SHOW) for a not visible child window */
1237 static const struct message WmShowChildSeq[] = {
1238  { WM_SHOWWINDOW, sent|wparam, 1 },
1240  { EVENT_OBJECT_SHOW, winevent_hook|wparam|lparam, 0, 0 },
1243  { 0 }
1244 };
1245 /* ShowWindow(SW_HIDE) for a visible child window */
1246 static const struct message WmHideChildSeq[] = {
1247  { WM_SHOWWINDOW, sent|wparam, 0 },
1249  { EVENT_OBJECT_HIDE, winevent_hook|wparam|lparam, 0, 0 },
1252  { 0 }
1253 };
1254 /* ShowWindow(SW_HIDE) for a visible child window checking all parent events*/
1255 static const struct message WmHideChildSeq2[] = {
1256  { WM_SHOWWINDOW, sent|wparam, 0 },
1258  { EVENT_OBJECT_HIDE, winevent_hook|wparam|lparam, 0, 0 },
1261  { 0 }
1262 };
1263 /* SetWindowPos(SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE)
1264  * for a not visible child window
1265  */
1266 static const struct message WmShowChildSeq_2[] = {
1268  { EVENT_OBJECT_SHOW, winevent_hook|wparam|lparam, 0, 0 },
1269  { WM_CHILDACTIVATE, sent },
1271  { 0 }
1272 };
1273 /* SetWindowPos(SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE)
1274  * for a not visible child window
1275  */
1276 static const struct message WmShowChildSeq_3[] = {
1278  { EVENT_OBJECT_SHOW, winevent_hook|wparam|lparam, 0, 0 },
1280  { 0 }
1281 };
1282 /* SetWindowPos(SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE)
1283  * for a visible child window with a caption
1284  */
1285 static const struct message WmShowChildSeq_4[] = {
1287  { WM_CHILDACTIVATE, sent },
1288  { 0 }
1289 };
1290 /* ShowWindow(SW_MINIMIZE) for child with invisible parent */
1291 static const struct message WmShowChildInvisibleParentSeq_1[] = {
1294  { WM_NCCALCSIZE, sent|wparam, 1 },
1295  { EVENT_OBJECT_SHOW, winevent_hook|wparam|lparam, 0, 0 },
1298  { WM_MOVE, sent|defwinproc },
1300  { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 },
1301  { EVENT_SYSTEM_MINIMIZESTART, winevent_hook|wparam|lparam, 0, 0 },
1302  /* FIXME: Wine creates an icon/title window while Windows doesn't */
1304  { WM_GETTEXT, sent|optional },
1305  { 0 }
1306 };
1307 /* repeated ShowWindow(SW_MINIMIZE) for child with invisible parent */
1310  { 0 }
1311 };
1312 /* ShowWindow(SW_MAXIMIZE) for child with invisible parent */
1313 static const struct message WmShowChildInvisibleParentSeq_2[] = {
1315  { WM_GETMINMAXINFO, sent },
1317  { WM_NCCALCSIZE, sent|wparam, 1 },
1318  { EVENT_OBJECT_SHOW, winevent_hook|wparam|lparam, 0, 0 },
1319  { WM_CHILDACTIVATE, sent },
1322  { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 },
1323  { 0 }
1324 };
1325 /* repeated ShowWindow(SW_MAXIMIZE) for child with invisible parent */
1328  { 0 }
1329 };
1330 /* ShowWindow(SW_SHOWMINIMIZED) for child with invisible parent */
1331 static const struct message WmShowChildInvisibleParentSeq_3[] = {
1334  { WM_NCCALCSIZE, sent|wparam, 1 },
1335  { EVENT_OBJECT_SHOW, winevent_hook|wparam|lparam, 0, 0 },
1336  { WM_CHILDACTIVATE, sent },
1338  { WM_MOVE, sent|defwinproc },
1340  { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 },
1341  { EVENT_SYSTEM_MINIMIZESTART, winevent_hook|wparam|lparam, 0, 0 },
1342  /* FIXME: Wine creates an icon/title window while Windows doesn't */
1344  { WM_GETTEXT, sent|optional },
1345  { 0 }
1346 };
1347 /* repeated ShowWindow(SW_SHOWMINIMIZED) for child with invisible parent */
1350  { 0 }
1351 };
1352 /* ShowWindow(SW_SHOWMINNOACTIVE) for child with invisible parent */
1353 static const struct message WmShowChildInvisibleParentSeq_4[] = {
1356  { WM_NCCALCSIZE, sent|wparam, 1 },
1357  { EVENT_OBJECT_SHOW, winevent_hook|wparam|lparam, 0, 0 },
1359  { WM_MOVE, sent|defwinproc },
1361  { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 },
1362  { EVENT_SYSTEM_MINIMIZESTART, winevent_hook|wparam|lparam, 0, 0 },
1363  /* FIXME: Wine creates an icon/title window while Windows doesn't */
1365  { WM_GETTEXT, sent|optional },
1366  { 0 }
1367 };
1368 /* repeated ShowWindow(SW_SHOWMINNOACTIVE) for child with invisible parent */
1371  { 0 }
1372 };
1373 /* ShowWindow(SW_SHOW) for child with invisible parent */
1374 static const struct message WmShowChildInvisibleParentSeq_5[] = {
1375  { WM_SHOWWINDOW, sent|wparam, 1 },
1376  { 0 }
1377 };
1378 /* ShowWindow(SW_HIDE) for child with invisible parent */
1379 static const struct message WmHideChildInvisibleParentSeq[] = {
1380  { WM_SHOWWINDOW, sent|wparam, 0 },
1381  { 0 }
1382 };
1383 /* SetWindowPos(SWP_SHOWWINDOW) for child with invisible parent */
1384 static const struct message WmShowChildInvisibleParentSeq_6[] = {
1386  { EVENT_OBJECT_SHOW, winevent_hook|wparam|lparam, 0, 0 },
1388  { 0 }
1389 };
1390 /* SetWindowPos(SWP_HIDEWINDOW) for child with invisible parent */
1391 static const struct message WmHideChildInvisibleParentSeq_2[] = {
1393  { EVENT_OBJECT_HIDE, winevent_hook|wparam|lparam, 0, 0 },
1395  { 0 }
1396 };
1397 /* DestroyWindow for a visible child window */
1398 static const struct message WmDestroyChildSeq[] = {
1399  { HCBT_DESTROYWND, hook },
1400  { 0x0090, sent|optional },
1402  { WM_SHOWWINDOW, sent|wparam, 0 },
1404  { EVENT_OBJECT_HIDE, winevent_hook|wparam|lparam, 0, 0 },
1407  { HCBT_SETFOCUS, hook }, /* set focus to a parent */
1408  { WM_KILLFOCUS, sent },
1411  { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
1412  { WM_SETFOCUS, sent|parent },
1413  { EVENT_OBJECT_DESTROY, winevent_hook|wparam|lparam, 0, 0 },
1414  { WM_DESTROY, sent },
1415  { WM_DESTROY, sent|optional }, /* some other (IME?) window */
1416  { WM_NCDESTROY, sent|optional }, /* some other (IME?) window */
1417  { WM_NCDESTROY, sent },
1418  { 0 }
1419 };
1420 /* visible child window destroyed by thread exit */
1421 static const struct message WmExitThreadSeq[] = {
1422  { WM_NCDESTROY, sent }, /* actually in grandchild */
1423  { WM_PAINT, sent|parent },
1425  { 0 }
1426 };
1427 /* DestroyWindow for a visible child window with invisible parent */
1428 static const struct message WmDestroyInvisibleChildSeq[] = {
1429  { HCBT_DESTROYWND, hook },
1430  { 0x0090, sent|optional },
1432  { WM_SHOWWINDOW, sent|wparam, 0 },
1433  { EVENT_OBJECT_DESTROY, winevent_hook|wparam|lparam, 0, 0 },
1434  { WM_DESTROY, sent },
1435  { WM_NCDESTROY, sent },
1436  { 0 }
1437 };
1438 /* Resizing child window with MoveWindow (32) */
1441  { WM_NCCALCSIZE, sent|wparam, 1 },
1445  { WM_MOVE, sent|defwinproc },
1447  { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 },
1448  { 0 }
1449 };
1450 /* Creation of a custom dialog (32) */
1451 static const struct message WmCreateCustomDialogSeq[] = {
1452  { HCBT_CREATEWND, hook },
1453  { WM_GETMINMAXINFO, sent },
1454  { WM_NCCREATE, sent },
1455  { WM_NCCALCSIZE, sent|wparam, 0 },
1456  { EVENT_OBJECT_REORDER, winevent_hook|wparam|lparam, 0, 0 },
1457  { WM_CREATE, sent },
1458  { EVENT_OBJECT_CREATE, winevent_hook|wparam|lparam, 0, 0 },
1459  { WM_NOTIFYFORMAT, sent|optional },
1460  { WM_QUERYUISTATE, sent|optional },
1465  { WM_SHOWWINDOW, sent|wparam, 1 },
1467  { EVENT_OBJECT_SHOW, winevent_hook|wparam|lparam, 0, 0 },
1468  { HCBT_ACTIVATE, hook },
1469  { EVENT_SYSTEM_FOREGROUND, winevent_hook|wparam|lparam, 0, 0 },
1470 
1471 
1473 
1475 
1476  { WM_NCACTIVATE, sent },
1480  { EVENT_OBJECT_DEFACTIONCHANGE, winevent_hook|wparam|lparam|optional, OBJID_CLIENT, 0 },
1481  { WM_ACTIVATE, sent|wparam, 1 },
1482  { WM_GETTEXT, sent|optional },
1483  { WM_KILLFOCUS, sent|parent },
1487  { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
1488  { WM_SETFOCUS, sent },
1490  { WM_NCPAINT, sent|wparam, 1 },
1493  { WM_ERASEBKGND, sent },
1496  { WM_GETTEXT, sent|optional },
1497  { WM_GETTEXT, sent|optional },
1499  { WM_NCPAINT, sent|optional },
1504  { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 },
1506  { WM_MOVE, sent },
1507  { 0 }
1508 };
1509 /* Calling EndDialog for a custom dialog (32) */
1510 static const struct message WmEndCustomDialogSeq[] = {
1512  { EVENT_OBJECT_HIDE, winevent_hook|wparam|lparam, 0, 0 },
1514  { WM_GETTEXT, sent|optional },
1515  { HCBT_ACTIVATE, hook },
1516  { WM_NCACTIVATE, sent|wparam, 0 },
1519  { WM_ACTIVATE, sent|wparam, 0 },
1520  { EVENT_SYSTEM_FOREGROUND, winevent_hook|wparam|lparam, 0, 0 },
1525  { HCBT_SETFOCUS, hook },
1526  { WM_KILLFOCUS, sent },
1530  { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
1532  { 0 }
1533 };
1534 /* ShowWindow(SW_SHOW) for a custom dialog (initially invisible) */
1535 static const struct message WmShowCustomDialogSeq[] = {
1536  { WM_SHOWWINDOW, sent|wparam, 1 },
1538  { EVENT_OBJECT_SHOW, winevent_hook|wparam|lparam, 0, 0 },
1539  { HCBT_ACTIVATE, hook },
1540  { EVENT_SYSTEM_FOREGROUND, winevent_hook|wparam|lparam, 0, 0 },
1541 
1543 
1546  { WM_NCACTIVATE, sent },
1547  { WM_ACTIVATE, sent|wparam, 1 },
1548  { WM_GETTEXT, sent|optional },
1549 
1550  { WM_KILLFOCUS, sent|parent },
1554  { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
1555  { WM_SETFOCUS, sent },
1557  { WM_NCPAINT, sent|wparam, 1 },
1558  { WM_ERASEBKGND, sent },
1561  { 0 }
1562 };
1563 /* Creation and destruction of a modal dialog (32) */
1564 static const struct message WmModalDialogSeq[] = {
1565  { WM_CANCELMODE, sent|parent },
1566  { HCBT_SETFOCUS, hook },
1567  { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
1568  { WM_KILLFOCUS, sent|parent },
1570  { EVENT_OBJECT_STATECHANGE, winevent_hook|wparam|lparam, 0, 0 },
1571  { WM_ENABLE, sent|parent|wparam, 0 },
1572  { HCBT_CREATEWND, hook },
1573  { EVENT_OBJECT_REORDER, winevent_hook|wparam|lparam, 0, 0 },
1574  { EVENT_OBJECT_CREATE, winevent_hook|wparam|lparam, 0, 0 },
1575  { WM_SETFONT, sent },
1576  { WM_INITDIALOG, sent },
1577  { WM_CHANGEUISTATE, sent|optional },
1578  { WM_UPDATEUISTATE, sent|optional },
1579  { WM_SHOWWINDOW, sent },
1580  { HCBT_ACTIVATE, hook },
1581  { EVENT_SYSTEM_FOREGROUND, winevent_hook|wparam|lparam, 0, 0 },
1584  { WM_NCACTIVATE, sent },
1585  { WM_GETTEXT, sent|optional },
1586  { WM_ACTIVATE, sent|wparam, 1 },
1588  { EVENT_OBJECT_SHOW, winevent_hook|wparam|lparam, 0, 0 },
1589  { WM_NCPAINT, sent|optional },
1590  { WM_GETTEXT, sent|optional },
1594  { WM_GETTEXT, sent|optional },
1596  { WM_NCPAINT, sent|optional },
1597  { WM_GETTEXT, sent|optional },
1600  { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 },
1601  { WM_PAINT, sent|optional },
1624  { WM_TIMER, sent },
1625  { EVENT_OBJECT_STATECHANGE, winevent_hook|wparam|lparam, 0, 0 },
1626  { WM_ENABLE, sent|parent|wparam, 1 },
1628  { EVENT_OBJECT_HIDE, winevent_hook|wparam|lparam, 0, 0 },
1630  { WM_GETTEXT, sent|optional },
1631  { HCBT_ACTIVATE, hook },
1632  { WM_NCACTIVATE, sent|wparam, 0 },
1633  { WM_GETTEXT, sent|optional },
1634  { WM_ACTIVATE, sent|wparam, 0 },
1635  { EVENT_SYSTEM_FOREGROUND, winevent_hook|wparam|lparam, 0, 0 },
1638  { HCBT_SETFOCUS, hook },
1640  { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
1642  { EVENT_SYSTEM_DIALOGEND, winevent_hook|wparam|lparam, 0, 0 },
1643  { HCBT_DESTROYWND, hook },
1644  { 0x0090, sent|optional },
1645  { EVENT_OBJECT_DESTROY, winevent_hook|wparam|lparam, 0, 0 },
1646  { WM_DESTROY, sent },
1647  { WM_NCDESTROY, sent },
1648  { 0 }
1649 };
1650 static const struct message WmModalDialogSeq_2[] = {
1651  { WM_CANCELMODE, sent },
1652  { HCBT_SETFOCUS, hook },
1653  { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
1654  { WM_KILLFOCUS, sent },
1656  { EVENT_OBJECT_STATECHANGE, winevent_hook|wparam|lparam, 0, 0 },
1657  { WM_ENABLE, sent|wparam, 0 },
1658  { HCBT_CREATEWND, hook },
1659  { EVENT_OBJECT_REORDER, winevent_hook|wparam|lparam, 0, 0 },
1660  { EVENT_OBJECT_CREATE, winevent_hook|wparam|lparam, 0, 0 },
1661  { WM_SETFONT, sent },
1662  { WM_INITDIALOG, sent },
1663  { WM_CHANGEUISTATE, sent|optional },
1664  { WM_UPDATEUISTATE, sent|optional },
1665  { WM_ENABLE, sent|wparam, 1 },
1667  { EVENT_OBJECT_HIDE, winevent_hook|wparam|lparam, 0, 0 },
1668  { WM_CHANGEUISTATE, sent|optional },
1669  { WM_UPDATEUISTATE, sent|optional },
1670  { HCBT_DESTROYWND, hook },
1671  { 0x0090, sent|optional },
1672  { EVENT_OBJECT_DESTROY, winevent_hook|wparam|lparam, 0, 0 },
1673  { WM_DESTROY, sent },
1674  { WM_NCDESTROY, sent },
1675  { 0 }
1676 };
1677 /* SetMenu for NonVisible windows with size change*/
1680  { WM_NCCALCSIZE, sent|wparam, 1 },
1681  { EVENT_OBJECT_REORDER, winevent_hook|wparam|lparam, 0, 0 },
1683  { WM_MOVE, sent|defwinproc },
1685  { WM_NCCALCSIZE,sent|wparam|optional, 1 }, /* XP */
1686  { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 },
1687  { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam|optional, 0, 0 }, /* XP sends a duplicate */
1688  { WM_GETTEXT, sent|optional },
1690  { 0 }
1691 };
1692 /* SetMenu for NonVisible windows with no size change */
1695  { WM_NCCALCSIZE, sent|wparam, 1 },
1697  { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 },
1698  { 0 }
1699 };
1700 /* SetMenu for Visible windows with size change */
1701 static const struct message WmSetMenuVisibleSizeChangeSeq[] = {
1703  { WM_NCCALCSIZE, sent|wparam, 1 },
1704  { 0x0093, sent|defwinproc|optional },
1705  { EVENT_OBJECT_REORDER, winevent_hook|wparam|lparam, 0, 0 },
1706  { WM_NCPAINT, sent|optional }, /* wparam != 1 */
1707  { 0x0093, sent|defwinproc|optional },
1708  { 0x0093, sent|defwinproc|optional },
1709  { 0x0091, sent|defwinproc|optional },
1710  { 0x0092, sent|defwinproc|optional },
1713  { WM_ACTIVATE, sent|optional },
1715  { WM_MOVE, sent|defwinproc },
1717  { 0x0093, sent|optional },
1719  { 0x0093, sent|defwinproc|optional },
1720  { WM_NCPAINT, sent|optional }, /* wparam != 1 */
1721  { 0x0093, sent|defwinproc|optional },
1722  { 0x0093, sent|defwinproc|optional },
1723  { 0x0091, sent|defwinproc|optional },
1724  { 0x0092, sent|defwinproc|optional },
1726  { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 },
1727  { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam|optional, 0, 0 }, /* XP sends a duplicate */
1728  { 0 }
1729 };
1730 /* SetMenu for Visible windows with no size change */
1731 static const struct message WmSetMenuVisibleNoSizeChangeSeq[] = {
1733  { WM_NCCALCSIZE, sent|wparam, 1 },
1734  { WM_NCPAINT, sent|optional }, /* wparam != 1 */
1737  { WM_ACTIVATE, sent|optional },
1739  { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 },
1740  { 0 }
1741 };
1742 /* DrawMenuBar for a visible window */
1743 static const struct message WmDrawMenuBarSeq[] =
1744 {
1746  { WM_NCCALCSIZE, sent|wparam, 1 },
1747  { 0x0093, sent|defwinproc|optional },
1748  { WM_NCPAINT, sent|optional }, /* wparam != 1 */
1749  { 0x0093, sent|defwinproc|optional },
1750  { 0x0093, sent|defwinproc|optional },
1751  { 0x0091, sent|defwinproc|optional },
1752  { 0x0092, sent|defwinproc|optional },
1756  { 0x0093, sent|optional },
1757  { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 },
1758  { 0 }
1759 };
1760 
1761 static const struct message WmSetRedrawFalseSeq[] =
1762 {
1763  { WM_SETREDRAW, sent|wparam, 0 },
1764  { 0 }
1765 };
1766 
1767 static const struct message WmSetRedrawTrueSeq[] =
1768 {
1769  { WM_SETREDRAW, sent|wparam, 1 },
1770  { 0 }
1771 };
1772 
1773 static const struct message WmEnableWindowSeq_1[] =
1774 {
1775  { WM_CANCELMODE, sent|wparam|lparam, 0, 0 },
1776  { EVENT_OBJECT_STATECHANGE, winevent_hook|wparam|lparam, 0, 0 },
1778  { WM_KILLFOCUS, sent|optional },
1779  { WM_ENABLE, sent|wparam|lparam, FALSE, 0 },
1780  { 0 }
1781 };
1782 
1783 static const struct message WmEnableWindowSeq_2[] =
1784 {
1785  { WM_CANCELMODE, sent|wparam|lparam, 0, 0 },
1786  { EVENT_OBJECT_STATECHANGE, winevent_hook|wparam|lparam, 0, 0 },
1787  { 0 }
1788 };
1789 
1790 static const struct message WmEnableWindowSeq_3[] =
1791 {
1792  { EVENT_OBJECT_STATECHANGE, winevent_hook|wparam|lparam, 0, 0 },
1793  { WM_ENABLE, sent|wparam|lparam, TRUE, 0 },
1794  { 0 }
1795 };
1796 
1797 static const struct message WmEnableWindowSeq_4[] =
1798 {
1799  { EVENT_OBJECT_STATECHANGE, winevent_hook|wparam|lparam, 0, 0 },
1800  { 0 }
1801 };
1802 
1803 static const struct message WmGetScrollRangeSeq[] =
1804 {
1805  { SBM_GETRANGE, sent },
1806  { 0 }
1807 };
1808 static const struct message WmGetScrollInfoSeq[] =
1809 {
1810  { SBM_GETSCROLLINFO, sent },
1811  { 0 }
1812 };
1813 static const struct message WmSetScrollRangeSeq[] =
1814 {
1815  /* MSDN claims that Windows sends SBM_SETRANGE message, but win2k SP4
1816  sends SBM_SETSCROLLINFO.
1817  */
1818  { SBM_SETSCROLLINFO, sent },
1819  { 0 }
1820 };
1821 /* SetScrollRange for a window without a non-client area */
1822 static const struct message WmSetScrollRangeHSeq_empty[] =
1823 {
1824  { EVENT_OBJECT_VALUECHANGE, winevent_hook|wparam|lparam, OBJID_HSCROLL, 0 },
1825  { 0 }
1826 };
1827 static const struct message WmSetScrollRangeVSeq_empty[] =
1828 {
1829  { EVENT_OBJECT_VALUECHANGE, winevent_hook|wparam|lparam, OBJID_VSCROLL, 0 },
1830  { 0 }
1831 };
1832 static const struct message WmSetScrollRangeHVSeq[] =
1833 {
1835  { WM_NCCALCSIZE, sent|wparam, 1 },
1839  { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 },
1840  { EVENT_OBJECT_VALUECHANGE, winevent_hook|lparam|optional, 0/*OBJID_HSCROLL or OBJID_VSCROLL*/, 0 },
1841  { 0 }
1842 };
1843 /* SetScrollRange for a window with a non-client area */
1844 static const struct message WmSetScrollRangeHV_NC_Seq[] =
1845 {
1847  { WM_NCCALCSIZE, sent|wparam, 1 },
1848  { EVENT_OBJECT_REORDER, winevent_hook|wparam|lparam, 0, 0 },
1849  { WM_NCPAINT, sent|optional },
1850  { WM_STYLECHANGING, sent|defwinproc|optional },
1851  { WM_STYLECHANGED, sent|defwinproc|optional },
1852  { WM_STYLECHANGING, sent|defwinproc|optional },
1853  { WM_STYLECHANGED, sent|defwinproc|optional },
1854  { WM_STYLECHANGING, sent|defwinproc|optional },
1855  { WM_STYLECHANGED, sent|defwinproc|optional },
1856  { WM_STYLECHANGING, sent|defwinproc|optional },
1857  { WM_STYLECHANGED, sent|defwinproc|optional },
1861  { WM_CTLCOLORDLG, sent|defwinproc|optional }, /* sent to a parent of the dialog */
1864  { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 },
1865  { EVENT_OBJECT_VALUECHANGE, winevent_hook|lparam|optional, 0/*OBJID_HSCROLL or OBJID_VSCROLL*/, 0 },
1866  { WM_GETTEXT, sent|optional },
1867  { WM_GETTEXT, sent|optional },
1868  { WM_GETTEXT, sent|optional },
1869  { WM_GETTEXT, sent|optional },
1870  { 0 }
1871 };
1872 /* test if we receive the right sequence of messages */
1873 /* after calling ShowWindow( SW_SHOWNA) */
1874 static const struct message WmSHOWNAChildInvisParInvis[] = {
1875  { WM_SHOWWINDOW, sent|wparam, 1 },
1876  { 0 }
1877 };
1878 static const struct message WmSHOWNAChildVisParInvis[] = {
1879  { WM_SHOWWINDOW, sent|wparam, 1 },
1880  { 0 }
1881 };
1882 static const struct message WmSHOWNAChildVisParVis[] = {
1883  { WM_SHOWWINDOW, sent|wparam, 1 },
1885  { 0 }
1886 };
1887 static const struct message WmSHOWNAChildInvisParVis[] = {
1888  { WM_SHOWWINDOW, sent|wparam, 1 },
1890  { EVENT_OBJECT_SHOW, winevent_hook|wparam|lparam, 0, 0 },
1893  { 0 }
1894 };
1895 static const struct message WmSHOWNATopVisible[] = {
1896  { WM_SHOWWINDOW, sent|wparam, 1 },
1898  { WM_NCPAINT, sent|wparam|optional, 1 },
1902  { 0 }
1903 };
1904 static const struct message WmSHOWNATopInvisible[] = {
1905  { WM_NOTIFYFORMAT, sent|optional },
1906  { WM_QUERYUISTATE, sent|optional },
1911  { WM_SHOWWINDOW, sent|wparam, 1 },
1913  { EVENT_OBJECT_SHOW, winevent_hook|wparam|lparam, 0, 0 },
1914  { WM_NCPAINT, sent|wparam|optional, 1 },
1919  { WM_NCPAINT, sent|wparam|optional, 1 },
1921  { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 },
1923  { WM_MOVE, sent },
1924  { 0 }
1925 };
1926 
1927 static const struct message WmTrackPopupMenu[] = {
1928  { HCBT_CREATEWND, hook },
1930  { WM_INITMENU, sent|lparam, 0, 0 },
1931  { WM_INITMENUPOPUP, sent|lparam, 0, 0 },
1932  { 0x0093, sent|optional },
1933  { 0x0094, sent|optional },
1934  { 0x0094, sent|optional },
1935  { WM_ENTERIDLE, sent|wparam, 2 },
1936  { WM_CAPTURECHANGED, sent },
1937  { HCBT_DESTROYWND, hook },
1938  { WM_UNINITMENUPOPUP, sent|lparam, 0, 0 },
1939  { WM_MENUSELECT, sent|wparam|lparam, 0xffff0000, 0 },
1940  { WM_EXITMENULOOP, sent|wparam|lparam, 1, 0 },
1941  { 0 }
1942 };
1943 
1944 static const struct message WmTrackPopupMenuEsc[] = {
1945  { 0 }
1946 };
1947 
1948 static const struct message WmTrackPopupMenuCapture[] = {
1949  { HCBT_CREATEWND, hook },
1951  { WM_CAPTURECHANGED, sent },
1952  { WM_INITMENU, sent|lparam, 0, 0 },
1953  { WM_INITMENUPOPUP, sent|lparam, 0, 0 },
1954  { 0x0093, sent|optional },
1955  { 0x0094, sent|optional },
1956  { 0x0094, sent|optional },
1957  { WM_ENTERIDLE, sent|wparam, 2 },
1958  { WM_CAPTURECHANGED, sent },
1959  { HCBT_DESTROYWND, hook },
1960  { WM_UNINITMENUPOPUP, sent|lparam, 0, 0 },
1961  { WM_MENUSELECT, sent|wparam|lparam, 0xffff0000, 0 },
1962  { WM_EXITMENULOOP, sent|wparam|lparam, 1, 0 },
1963  { 0 }
1964 };
1965 
1966 static const struct message WmTrackPopupMenuEmpty[] = {
1967  { HCBT_CREATEWND, hook },
1969  { WM_INITMENU, sent|lparam, 0, 0 },
1970  { WM_INITMENUPOPUP, sent|lparam, 0, 0 },
1971  { 0x0093, sent|optional },
1972  { 0x0094, sent|optional },
1973  { 0x0094, sent|optional },
1974  { WM_CAPTURECHANGED, sent },
1975  { WM_EXITMENULOOP, sent|wparam|lparam, 1, 0 },
1976  { HCBT_DESTROYWND, hook },
1977  { WM_UNINITMENUPOPUP, sent|lparam, 0, 0 },
1978  { 0 }
1979 };
1980 
1981 static const struct message WmTrackPopupMenuAbort[] = {
1982  { HCBT_CREATEWND, hook },
1984  { WM_INITMENU, sent|lparam, 0, 0 },
1985  { WM_INITMENUPOPUP, sent|lparam, 0, 0 },
1986  { 0x0093, sent|optional },
1987  { 0x0094, sent|optional },
1988  { 0x0094, sent|optional },
1989  { WM_CAPTURECHANGED, sent },
1990  { HCBT_DESTROYWND, hook },
1991  { WM_UNINITMENUPOPUP, sent|lparam, 0, 0 },
1992  { WM_MENUSELECT, sent|wparam|lparam, 0xffff0000, 0 },
1993  { WM_EXITMENULOOP, sent|wparam|lparam, 1, 0 },
1994  { 0 }
1995 };
1996 
1999 static struct recvd_message* sequence;
2002 
2003 /* user32 functions */
2004 static HWND (WINAPI *pGetAncestor)(HWND,UINT);
2005 static BOOL (WINAPI *pGetMenuInfo)(HMENU,LPCMENUINFO);
2006 static void (WINAPI *pNotifyWinEvent)(DWORD, HWND, LONG, LONG);
2007 static BOOL (WINAPI *pSetMenuInfo)(HMENU,LPCMENUINFO);
2009 static BOOL (WINAPI *pTrackMouseEvent)(TRACKMOUSEEVENT*);
2010 static BOOL (WINAPI *pUnhookWinEvent)(HWINEVENTHOOK);
2011 static BOOL (WINAPI *pGetMonitorInfoA)(HMONITOR,LPMONITORINFO);
2012 static HMONITOR (WINAPI *pMonitorFromPoint)(POINT,DWORD);
2013 static BOOL (WINAPI *pUpdateLayeredWindow)(HWND,HDC,POINT*,SIZE*,HDC,POINT*,COLORREF,BLENDFUNCTION*,DWORD);
2014 static UINT_PTR (WINAPI *pSetSystemTimer)(HWND, UINT_PTR, UINT, TIMERPROC);
2015 static UINT_PTR (WINAPI *pKillSystemTimer)(HWND, UINT_PTR);
2016 static UINT_PTR (WINAPI *pSetCoalescableTimer)(HWND, UINT_PTR, UINT, TIMERPROC, ULONG);
2017 /* kernel32 functions */
2018 static BOOL (WINAPI *pGetCPInfoExA)(UINT, DWORD, LPCPINFOEXA);
2019 
2020 static void init_procs(void)
2021 {
2022  HMODULE user32 = GetModuleHandleA("user32.dll");
2023  HMODULE kernel32 = GetModuleHandleA("kernel32.dll");
2024 
2025 #define GET_PROC(dll, func) \
2026  p ## func = (void*)GetProcAddress(dll, #func); \
2027  if(!p ## func) { \
2028  trace("GetProcAddress(%s) failed\n", #func); \
2029  }
2030 
2031  GET_PROC(user32, GetAncestor)
2032  GET_PROC(user32, GetMenuInfo)
2033  GET_PROC(user32, NotifyWinEvent)
2034  GET_PROC(user32, SetMenuInfo)
2035  GET_PROC(user32, SetWinEventHook)
2036  GET_PROC(user32, TrackMouseEvent)
2037  GET_PROC(user32, UnhookWinEvent)
2038  GET_PROC(user32, GetMonitorInfoA)
2039  GET_PROC(user32, MonitorFromPoint)
2040  GET_PROC(user32, UpdateLayeredWindow)
2041  GET_PROC(user32, SetSystemTimer)
2042  GET_PROC(user32, KillSystemTimer)
2043  GET_PROC(user32, SetCoalescableTimer)
2044 
2045  GET_PROC(kernel32, GetCPInfoExA)
2046 
2047 #undef GET_PROC
2048 }
2049 
2050 static const char *get_winpos_flags(UINT flags)
2051 {
2052  static char buffer[300];
2053 
2054  buffer[0] = 0;
2055 #define DUMP(flag) do { if (flags & flag) { strcat( buffer, "|" #flag ); flags &= ~flag; } } while(0)
2056  DUMP( SWP_SHOWWINDOW );
2057  DUMP( SWP_HIDEWINDOW );
2058  DUMP( SWP_NOACTIVATE );
2060  DUMP( SWP_NOCOPYBITS );
2063  DUMP( SWP_DEFERERASE );
2065  DUMP( SWP_NOZORDER );
2066  DUMP( SWP_NOREDRAW );
2067  DUMP( SWP_NOSIZE );
2068  DUMP( SWP_NOMOVE );
2071  if (flags) sprintf(buffer + strlen(buffer),"|0x%04x", flags);
2072  return buffer + 1;
2073 #undef DUMP
2074 }
2075 
2077 {
2078  /* these are always ignored */
2079  return (message >= 0xc000 ||
2080  message == WM_GETICON ||
2081  message == WM_GETOBJECT ||
2082  message == WM_TIMECHANGE ||
2083  message == WM_DISPLAYCHANGE ||
2084  message == WM_DEVICECHANGE ||
2086 }
2087 
2088 static unsigned hash_Ly_W(const WCHAR *str)
2089 {
2090  unsigned hash = 0;
2091 
2092  for (; *str; str++)
2093  hash = hash * 1664525u + (unsigned char)(*str) + 1013904223u;
2094 
2095  return hash;
2096 }
2097 
2098 static unsigned hash_Ly(const char *str)
2099 {
2100  unsigned hash = 0;
2101 
2102  for (; *str; str++)
2103  hash = hash * 1664525u + (unsigned char)(*str) + 1013904223u;
2104 
2105  return hash;
2106 }
2107 
2108 #define add_message(msg) add_message_(__LINE__,msg);
2109 static void add_message_(int line, const struct recvd_message *msg)
2110 {
2111  struct recvd_message *seq;
2112 
2114  if (!sequence)
2115  {
2116  sequence_size = 10;
2117  sequence = HeapAlloc( GetProcessHeap(), 0, sequence_size * sizeof(*sequence) );
2118  }
2119  if (sequence_cnt == sequence_size)
2120  {
2121  sequence_size *= 2;
2123  }
2124  assert(sequence);
2125 
2126  seq = &sequence[sequence_cnt++];
2127  seq->hwnd = msg->hwnd;
2128  seq->message = msg->message;
2129  seq->flags = msg->flags;
2130  seq->wParam = msg->wParam;
2131  seq->lParam = msg->lParam;
2132  seq->line = line;
2133  seq->descr = msg->descr;
2134  seq->output[0] = 0;
2136 
2137  if (msg->descr)
2138  {
2139  if (msg->flags & hook)
2140  {
2141  static const char * const CBT_code_name[10] =
2142  {
2143  "HCBT_MOVESIZE",
2144  "HCBT_MINMAX",
2145  "HCBT_QS",
2146  "HCBT_CREATEWND",
2147  "HCBT_DESTROYWND",
2148  "HCBT_ACTIVATE",
2149  "HCBT_CLICKSKIPPED",
2150  "HCBT_KEYSKIPPED",
2151  "HCBT_SYSCOMMAND",
2152  "HCBT_SETFOCUS"
2153  };
2154  const char *code_name = (msg->message <= HCBT_SETFOCUS) ? CBT_code_name[msg->message] : "Unknown";
2155 
2156  sprintf( seq->output, "%s: hook %d (%s) wp %08lx lp %08lx",
2157  msg->descr, msg->message, code_name, msg->wParam, msg->lParam );
2158  }
2159  else if (msg->flags & winevent_hook)
2160  {
2161  sprintf( seq->output, "%s: winevent %p %08x %08lx %08lx",
2162  msg->descr, msg->hwnd, msg->message, msg->wParam, msg->lParam );
2163  }
2164  else
2165  {
2166  switch (msg->message)
2167  {
2168  case WM_WINDOWPOSCHANGING:
2169  case WM_WINDOWPOSCHANGED:
2170  {
2171  WINDOWPOS *winpos = (WINDOWPOS *)msg->lParam;
2172 
2173  sprintf( seq->output, "%s: %p WM_WINDOWPOS%s wp %08lx lp %08lx after %p x %d y %d cx %d cy %d flags %s",
2174  msg->descr, msg->hwnd,
2175  (msg->message == WM_WINDOWPOSCHANGING) ? "CHANGING" : "CHANGED",
2176  msg->wParam, msg->lParam, winpos->hwndInsertAfter,
2177  winpos->x, winpos->y, winpos->cx, winpos->cy,
2178  get_winpos_flags(winpos->flags) );
2179 
2180  /* Log only documented flags, win2k uses 0x1000 and 0x2000
2181  * in the high word for internal purposes
2182  */
2183  seq->wParam = winpos->flags & 0xffff;
2184  /* We are not interested in the flags that don't match under XP and Win9x */
2185  seq->wParam &= ~SWP_NOZORDER;
2186  break;
2187  }
2188 
2189  case WM_DRAWITEM:
2190  {
2191  DRAW_ITEM_STRUCT di;
2192  DRAWITEMSTRUCT *dis = (DRAWITEMSTRUCT *)msg->lParam;
2193 
2194  sprintf( seq->output, "%s: %p WM_DRAWITEM: type %x, ctl_id %x, item_id %x, action %x, state %x",
2195  msg->descr, msg->hwnd, dis->CtlType, dis->CtlID,
2196  dis->itemID, dis->itemAction, dis->itemState);
2197 
2198  di.u.lp = 0;
2199  di.u.item.type = dis->CtlType;
2200  di.u.item.ctl_id = dis->CtlID;
2201  if (dis->CtlType == ODT_LISTBOX ||
2202  dis->CtlType == ODT_COMBOBOX ||
2203  dis->CtlType == ODT_MENU)
2204  di.u.item.item_id = dis->itemID;
2205  di.u.item.action = dis->itemAction;
2206  di.u.item.state = dis->itemState;
2207 
2208  seq->lParam = di.u.lp;
2209  break;
2210  }
2211 
2212  case WM_MEASUREITEM:
2213  {
2215  MEASUREITEMSTRUCT *mis = (MEASUREITEMSTRUCT *)msg->lParam;
2216  BOOL is_unicode_data = TRUE;
2217 
2218  sprintf( seq->output, "%s: %p WM_MEASUREITEM: CtlType %#x, CtlID %#x, itemID %#x, itemData %#lx",