2 * Unit tests for window message handling
4 * Copyright 1999 Ove Kaaven
5 * Copyright 2003 Dimitrie O. Paun
6 * Copyright 2004, 2005 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
27 #define _WIN32_WINNT 0x0501 /* For WM_CHANGEUISTATE,QS_RAWINPUT */
35 #include "wine/test.h"
37 #define MDI_FIRST_CHILD_ID 2004
39 /* undocumented SWP flags - from SDK 3.1 */
40 #define SWP_NOCLIENTSIZE 0x0800
41 #define SWP_NOCLIENTMOVE 0x1000
42 #define SWP_STATECHANGED 0x8000
44 #define SW_NORMALNA 0xCC /* undoc. flag in MinMaximize */
47 #define WM_SYSTIMER 0x0118
50 #define WND_PARENT_ID 1
51 #define WND_POPUP_ID 2
52 #define WND_CHILD_ID 3
54 static BOOL test_DestroyWindow_flag
;
55 static HWINEVENTHOOK hEvent_hook
;
57 static HWND (WINAPI
*pGetAncestor
)(HWND
,UINT
);
59 static void dump_winpos_flags(UINT flags
);
62 FIXME: add tests for these
63 Window Edge Styles (Win31/Win95/98 look), in order of precedence:
64 WS_EX_DLGMODALFRAME: double border, WS_CAPTION allowed
65 WS_THICKFRAME: thick border
66 WS_DLGFRAME: double border, WS_CAPTION not allowed (but possibly shown anyway)
67 WS_BORDER (default for overlapped windows): single black border
68 none (default for child (and popup?) windows): no border
85 UINT message
; /* the WM_* code */
86 msg_flags_t flags
; /* message props */
87 WPARAM wParam
; /* expected value of wParam */
88 LPARAM lParam
; /* expected value of lParam */
91 /* Empty message sequence */
92 static const struct message WmEmptySeq
[] =
96 /* CreateWindow (for overlapped window, not initially visible) (16/32) */
97 static const struct message WmCreateOverlappedSeq
[] = {
98 { HCBT_CREATEWND
, hook
},
99 { WM_GETMINMAXINFO
, sent
},
100 { WM_NCCREATE
, sent
},
101 { WM_NCCALCSIZE
, sent
|wparam
, 0 },
102 { EVENT_OBJECT_REORDER
, winevent_hook
|wparam
|lparam
, 0, 0 },
104 { EVENT_OBJECT_CREATE
, winevent_hook
|wparam
|lparam
, 0, 0 },
107 /* SetWindowPos(SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE)
108 * for a not visible overlapped window.
110 static const struct message WmSWP_ShowOverlappedSeq
[] = {
111 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
},
112 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, 0, 0 },
113 { WM_NCPAINT
, sent
|wparam
|optional
, 1 },
114 { WM_GETTEXT
, sent
|defwinproc
|optional
},
115 { WM_ERASEBKGND
, sent
|optional
},
116 { HCBT_ACTIVATE
, hook
},
117 { EVENT_SYSTEM_FOREGROUND
, winevent_hook
|wparam
|lparam
, 0, 0 },
118 { WM_QUERYNEWPALETTE
, sent
|wparam
|lparam
|optional
, 0, 0 },
119 { WM_WINDOWPOSCHANGING
, sent
|wparam
|optional
, SWP_NOSIZE
|SWP_NOMOVE
}, /* Win9x: SWP_NOSENDCHANGING */
120 { WM_ACTIVATEAPP
, sent
|wparam
, 1 },
121 { WM_NCACTIVATE
, sent
|wparam
, 1 },
122 { WM_GETTEXT
, sent
|defwinproc
|optional
},
123 { WM_ACTIVATE
, sent
|wparam
, 1 },
124 { HCBT_SETFOCUS
, hook
},
125 { WM_IME_SETCONTEXT
, sent
|wparam
|defwinproc
|optional
, 1 },
126 { WM_IME_NOTIFY
, sent
|wparam
|defwinproc
|optional
, 2 },
127 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
128 { WM_SETFOCUS
, sent
|wparam
|defwinproc
, 0 },
129 { WM_NCPAINT
, sent
|wparam
|optional
, 1 },
130 { WM_GETTEXT
, sent
|defwinproc
|optional
},
131 { WM_ERASEBKGND
, sent
|optional
},
132 /* Win9x adds SWP_NOZORDER below */
133 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
134 { WM_NCCALCSIZE
, sent
|wparam
|optional
, 1 },
135 { WM_NCPAINT
, sent
|wparam
|optional
, 1 },
136 { WM_ERASEBKGND
, sent
|optional
},
137 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
140 /* SetWindowPos(SWP_HIDEWINDOW|SWP_NOSIZE|SWP_NOMOVE)
141 * for a visible overlapped window.
143 static const struct message WmSWP_HideOverlappedSeq
[] = {
144 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_HIDEWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
},
145 { EVENT_OBJECT_HIDE
, winevent_hook
|wparam
|lparam
, 0, 0 },
146 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_HIDEWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
150 /* SetWindowPos(SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOMOVE)
151 * for a visible overlapped window.
153 static const struct message WmSWP_ResizeSeq
[] = {
154 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_NOACTIVATE
|SWP_NOMOVE
},
155 { WM_GETMINMAXINFO
, sent
|defwinproc
},
156 { WM_NCCALCSIZE
, sent
|wparam
, TRUE
},
157 { WM_NCPAINT
, sent
|optional
},
158 { WM_GETTEXT
, sent
|defwinproc
|optional
},
159 { WM_ERASEBKGND
, sent
|optional
},
160 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_NOACTIVATE
|SWP_NOMOVE
|SWP_NOCLIENTMOVE
},
161 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_RESTORED
},
162 { WM_NCCALCSIZE
, sent
|wparam
|optional
, TRUE
},
163 { WM_NCPAINT
, sent
|optional
},
164 { WM_GETTEXT
, sent
|defwinproc
|optional
},
165 { WM_ERASEBKGND
, sent
|optional
},
166 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
167 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
|optional
, 0, 0 }, /* XP sends a duplicate */
171 /* SetWindowPos(SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOMOVE)
172 * for a visible popup window.
174 static const struct message WmSWP_ResizePopupSeq
[] = {
175 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_NOACTIVATE
|SWP_NOMOVE
},
176 { WM_GETMINMAXINFO
, sent
|defwinproc
|optional
}, /* Win9x */
177 { WM_NCCALCSIZE
, sent
|wparam
, TRUE
},
178 { WM_NCPAINT
, sent
|optional
},
179 { WM_GETTEXT
, sent
|defwinproc
|optional
},
180 { WM_ERASEBKGND
, sent
|optional
},
181 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_NOACTIVATE
|SWP_NOMOVE
|SWP_NOCLIENTMOVE
},
182 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_RESTORED
},
183 { WM_NCCALCSIZE
, sent
|wparam
|optional
, TRUE
},
184 { WM_NCPAINT
, sent
|optional
},
185 { WM_GETTEXT
, sent
|defwinproc
|optional
},
186 { WM_ERASEBKGND
, sent
|optional
},
187 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
191 /* SetWindowPos(SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOSIZE)
192 * for a visible overlapped window.
194 static const struct message WmSWP_MoveSeq
[] = {
195 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_NOACTIVATE
|SWP_NOSIZE
},
196 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOCLIENTSIZE
},
197 { WM_MOVE
, sent
|defwinproc
|wparam
, 0 },
198 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
201 /* Resize with SetWindowPos(SWP_NOZORDER)
202 * for a visible overlapped window
203 * SWP_NOZORDER is stripped by the logging code
205 static const struct message WmSWP_ResizeNoZOrder
[] = {
206 { WM_WINDOWPOSCHANGING
, sent
|wparam
, 0/*SWP_NOZORDER*/ },
207 { WM_GETMINMAXINFO
, sent
|defwinproc
},
208 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
209 { WM_NCPAINT
, sent
},
210 { WM_GETTEXT
, sent
|defwinproc
|optional
},
211 { WM_ERASEBKGND
, sent
|optional
}, /* FIXME: remove optional once Wine is fixed */
212 { WM_WINDOWPOSCHANGED
, sent
|wparam
, /*SWP_NOZORDER|*/SWP_NOMOVE
|SWP_NOCLIENTMOVE
},
213 { WM_SIZE
, sent
|defwinproc
|wparam
, 0 },
214 { WM_NCCALCSIZE
, sent
|wparam
|optional
, 1 }, /* Win9x doesn't send it */
215 { WM_NCPAINT
, sent
|optional
}, /* Win9x doesn't send it */
216 { WM_GETTEXT
, sent
|defwinproc
|optional
}, /* Win9x doesn't send it */
217 { WM_ERASEBKGND
, sent
|optional
}, /* Win9x doesn't send it */
221 /* SetWindowPos(SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE|
222 SWP_NOZORDER|SWP_FRAMECHANGED)
223 * for a visible overlapped window with WS_CLIPCHILDREN style set.
225 static const struct message WmSWP_FrameChanged_clip
[] = {
226 { WM_WINDOWPOSCHANGING
, sent
|wparam
|parent
, SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOACTIVATE
|SWP_FRAMECHANGED
},
227 { WM_NCCALCSIZE
, sent
|wparam
|parent
, 1 },
228 { WM_NCPAINT
, sent
|parent
}, /* wparam != 1 */
229 { WM_GETTEXT
, sent
|parent
|defwinproc
|optional
},
230 { WM_ERASEBKGND
, sent
|parent
|optional
}, /* FIXME: remove optional once Wine is fixed */
231 { WM_NCPAINT
, sent
}, /* wparam != 1 */
232 { WM_ERASEBKGND
, sent
},
233 { WM_WINDOWPOSCHANGED
, sent
|wparam
|parent
, SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOACTIVATE
|SWP_FRAMECHANGED
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
234 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
238 /* SetWindowPos(SWP_NOSIZE|SWP_NOMOVE|SWP_DEFERERASE|SWP_NOACTIVATE|
239 SWP_NOZORDER|SWP_FRAMECHANGED)
240 * for a visible overlapped window.
242 static const struct message WmSWP_FrameChangedDeferErase
[] = {
243 { WM_WINDOWPOSCHANGING
, sent
|wparam
|parent
, SWP_NOSIZE
|SWP_NOMOVE
|SWP_DEFERERASE
|SWP_NOACTIVATE
|SWP_FRAMECHANGED
},
244 { WM_NCCALCSIZE
, sent
|wparam
|parent
, 1 },
245 { WM_WINDOWPOSCHANGED
, sent
|wparam
|parent
, SWP_NOSIZE
|SWP_NOMOVE
|SWP_DEFERERASE
|SWP_NOACTIVATE
|SWP_FRAMECHANGED
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
246 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
247 { WM_PAINT
, sent
|parent
},
248 { WM_NCPAINT
, sent
|beginpaint
|parent
}, /* wparam != 1 */
249 { WM_GETTEXT
, sent
|beginpaint
|parent
|defwinproc
|optional
},
251 { WM_NCPAINT
, sent
|beginpaint
}, /* wparam != 1 */
252 { WM_ERASEBKGND
, sent
|beginpaint
},
256 /* SetWindowPos(SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE|
257 SWP_NOZORDER|SWP_FRAMECHANGED)
258 * for a visible overlapped window without WS_CLIPCHILDREN style set.
260 static const struct message WmSWP_FrameChanged_noclip
[] = {
261 { WM_WINDOWPOSCHANGING
, sent
|wparam
|parent
, SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOACTIVATE
|SWP_FRAMECHANGED
},
262 { WM_NCCALCSIZE
, sent
|wparam
|parent
, 1 },
263 { WM_NCPAINT
, sent
|parent
}, /* wparam != 1 */
264 { WM_GETTEXT
, sent
|parent
|defwinproc
|optional
},
265 { WM_ERASEBKGND
, sent
|parent
|optional
}, /* FIXME: remove optional once Wine is fixed */
266 { WM_WINDOWPOSCHANGED
, sent
|wparam
|parent
, SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOACTIVATE
|SWP_FRAMECHANGED
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
267 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
269 { WM_NCPAINT
, sent
|beginpaint
}, /* wparam != 1 */
270 { WM_ERASEBKGND
, sent
|beginpaint
},
274 /* ShowWindow(SW_SHOW) for a not visible overlapped window */
275 static const struct message WmShowOverlappedSeq
[] = {
276 { WM_SHOWWINDOW
, sent
|wparam
, 1 },
277 { WM_NCPAINT
, sent
|wparam
|optional
, 1 },
278 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
},
279 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, 0, 0 },
280 { WM_NCPAINT
, sent
|wparam
|optional
, 1 },
281 { WM_GETTEXT
, sent
|defwinproc
|optional
},
282 { WM_ERASEBKGND
, sent
|optional
},
283 { HCBT_ACTIVATE
, hook
},
284 { EVENT_SYSTEM_FOREGROUND
, winevent_hook
|wparam
|lparam
, 0, 0 },
285 { WM_QUERYNEWPALETTE
, sent
|wparam
|lparam
|optional
, 0, 0 },
286 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_NOSIZE
|SWP_NOMOVE
},
287 { WM_NCPAINT
, sent
|wparam
|optional
, 1 },
288 { WM_ACTIVATEAPP
, sent
|wparam
, 1 },
289 { WM_NCACTIVATE
, sent
|wparam
, 1 },
290 { WM_GETTEXT
, sent
|defwinproc
|optional
},
291 { WM_ACTIVATE
, sent
|wparam
, 1 },
292 { HCBT_SETFOCUS
, hook
},
293 { WM_IME_SETCONTEXT
, sent
|wparam
|defwinproc
|optional
, 1 },
294 { WM_IME_NOTIFY
, sent
|wparam
|defwinproc
|optional
, 2 },
295 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
296 { WM_SETFOCUS
, sent
|wparam
|defwinproc
, 0 },
297 { WM_NCPAINT
, sent
|wparam
|optional
, 1 },
298 { WM_GETTEXT
, sent
|defwinproc
|optional
},
299 { WM_ERASEBKGND
, sent
|optional
},
300 /* Win9x adds SWP_NOZORDER below */
301 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
302 { WM_NCCALCSIZE
, sent
|optional
},
303 { WM_NCPAINT
, sent
|optional
},
304 { WM_ERASEBKGND
, sent
|optional
},
305 #if 0 /* CreateWindow/ShowWindow(SW_SHOW) also generates WM_SIZE/WM_MOVE
306 * messages. Does that mean that CreateWindow doesn't set initial
307 * window dimensions for overlapped windows?
314 /* ShowWindow(SW_SHOWMAXIMIZED) for a not visible overlapped window */
315 static const struct message WmShowMaxOverlappedSeq
[] = {
316 { HCBT_MINMAX
, hook
|lparam
, 0, SW_MAXIMIZE
},
317 { WM_GETMINMAXINFO
, sent
},
318 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_FRAMECHANGED
|0x8000 },
319 { WM_GETMINMAXINFO
, sent
|defwinproc
},
320 { WM_NCCALCSIZE
, sent
|wparam
, TRUE
},
321 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, 0, 0 },
322 { HCBT_ACTIVATE
, hook
},
323 { EVENT_SYSTEM_FOREGROUND
, winevent_hook
|wparam
|lparam
, 0, 0 },
324 { WM_QUERYNEWPALETTE
, sent
|wparam
|lparam
|optional
, 0, 0 },
325 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_NOSIZE
|SWP_NOMOVE
},
326 { WM_ACTIVATEAPP
, sent
|wparam
, 1 },
327 { WM_NCACTIVATE
, sent
|wparam
, 1 },
328 { WM_GETTEXT
, sent
|defwinproc
|optional
},
329 { WM_ACTIVATE
, sent
|wparam
, 1 },
330 { HCBT_SETFOCUS
, hook
},
331 { WM_IME_SETCONTEXT
, sent
|wparam
|defwinproc
|optional
, 1 },
332 { WM_IME_NOTIFY
, sent
|wparam
|defwinproc
|optional
, 2 },
333 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
334 { WM_SETFOCUS
, sent
|wparam
|defwinproc
, 0 },
335 { WM_NCPAINT
, sent
|wparam
|optional
, 1 },
336 { WM_GETTEXT
, sent
|defwinproc
|optional
},
337 { WM_ERASEBKGND
, sent
|optional
},
338 /* Win9x adds SWP_NOZORDER below */
339 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_FRAMECHANGED
|0x8000 },
340 { WM_MOVE
, sent
|defwinproc
},
341 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_MAXIMIZED
},
342 { WM_NCCALCSIZE
, sent
|optional
},
343 { WM_NCPAINT
, sent
|optional
},
344 { WM_ERASEBKGND
, sent
|optional
},
345 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
346 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
349 /* ShowWindow(SW_SHOWMINIMIZED) for a not visible overlapped window */
350 static const struct message WmShowMinOverlappedSeq
[] = {
351 { HCBT_MINMAX
, hook
|lparam
, 0, SW_MINIMIZE
},
352 { HCBT_SETFOCUS
, hook
},
353 { WM_KILLFOCUS
, sent
},
354 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 0 },
355 { WM_IME_NOTIFY
, sent
|wparam
|optional
|defwinproc
, 1 },
356 { WM_GETTEXT
, sent
|optional
},
357 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_NOCOPYBITS
|SWP_SHOWWINDOW
|SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_STATECHANGED
},
358 { WM_GETMINMAXINFO
, sent
|defwinproc
},
359 { WM_NCCALCSIZE
, sent
|wparam
, TRUE
},
360 { WM_NCPAINT
, sent
},
361 { WM_GETTEXT
, sent
|defwinproc
|optional
},
362 { WM_WINDOWPOSCHANGED
, sent
},
363 { WM_MOVE
, sent
|defwinproc
},
364 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_MINIMIZED
},
365 { WM_NCCALCSIZE
, sent
|optional
},
366 { WM_NCACTIVATE
, sent
|wparam
, 0 },
367 { WM_GETTEXT
, sent
|defwinproc
|optional
},
368 { WM_ACTIVATE
, sent
},
369 { WM_ACTIVATEAPP
, sent
|wparam
, 0 },
372 /* ShowWindow(SW_HIDE) for a visible overlapped window */
373 static const struct message WmHideOverlappedSeq
[] = {
374 { WM_SHOWWINDOW
, sent
|wparam
, 0 },
375 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_HIDEWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
},
376 { EVENT_OBJECT_HIDE
, winevent_hook
|wparam
|lparam
, 0, 0 },
377 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_HIDEWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
378 { WM_SIZE
, sent
|optional
}, /* XP doesn't send it */
379 { WM_MOVE
, sent
|optional
}, /* XP doesn't send it */
380 { WM_NCACTIVATE
, sent
|wparam
, 0 },
381 { WM_ACTIVATE
, sent
|wparam
, 0 },
382 { WM_ACTIVATEAPP
, sent
|wparam
, 0 },
383 { WM_KILLFOCUS
, sent
|wparam
, 0 },
384 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 0 },
385 { WM_IME_NOTIFY
, sent
|wparam
|optional
|defwinproc
, 1 },
388 /* DestroyWindow for a visible overlapped window */
389 static const struct message WmDestroyOverlappedSeq
[] = {
390 { HCBT_DESTROYWND
, hook
},
391 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_HIDEWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
392 { EVENT_OBJECT_HIDE
, winevent_hook
|wparam
|lparam
, 0, 0 },
393 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_HIDEWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
394 { WM_NCACTIVATE
, sent
|wparam
, 0 },
395 { WM_ACTIVATE
, sent
|wparam
, 0 },
396 { WM_ACTIVATEAPP
, sent
|wparam
, 0 },
397 { WM_KILLFOCUS
, sent
|wparam
, 0 },
398 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 0 },
399 { WM_IME_NOTIFY
, sent
|wparam
|optional
|defwinproc
, 1 },
400 { EVENT_OBJECT_DESTROY
, winevent_hook
|wparam
|lparam
, 0, 0 },
401 { WM_DESTROY
, sent
},
402 { WM_NCDESTROY
, sent
},
405 /* CreateWindow(WS_MAXIMIZE|WS_VISIBLE) for popup window */
406 static const struct message WmCreateMaxPopupSeq
[] = {
407 { HCBT_CREATEWND
, hook
},
408 { WM_NCCREATE
, sent
},
409 { WM_NCCALCSIZE
, sent
|wparam
, 0 },
411 { WM_SIZE
, sent
|wparam
, SIZE_RESTORED
},
413 { HCBT_MINMAX
, hook
|lparam
, 0, SW_MAXIMIZE
},
414 { WM_GETMINMAXINFO
, sent
},
415 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_NOACTIVATE
|SWP_FRAMECHANGED
|0x8000 },
416 { WM_NCCALCSIZE
, sent
|wparam
, TRUE
},
417 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_NOACTIVATE
|SWP_FRAMECHANGED
|SWP_NOREDRAW
|0x8000 },
418 { WM_MOVE
, sent
|defwinproc
},
419 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_MAXIMIZED
},
420 { WM_SHOWWINDOW
, sent
|wparam
, 1 },
421 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
},
422 { HCBT_ACTIVATE
, hook
},
423 { WM_QUERYNEWPALETTE
, sent
|wparam
|lparam
|optional
, 0, 0 },
424 { WM_WINDOWPOSCHANGING
, sent
|wparam
|optional
, SWP_NOSIZE
|SWP_NOMOVE
},
425 { WM_ACTIVATEAPP
, sent
|wparam
, 1 },
426 { WM_NCACTIVATE
, sent
|wparam
, 1 },
427 { WM_ACTIVATE
, sent
|wparam
, 1 },
428 { HCBT_SETFOCUS
, hook
},
429 { WM_IME_SETCONTEXT
, sent
|wparam
|defwinproc
|optional
, 1 },
430 { WM_IME_NOTIFY
, sent
|wparam
|defwinproc
|optional
, 2 },
431 { WM_SETFOCUS
, sent
|wparam
|defwinproc
, 0 },
432 { WM_SYNCPAINT
, sent
|wparam
|optional
, 4 },
433 { WM_NCPAINT
, sent
|wparam
|optional
, 1 },
434 { WM_ERASEBKGND
, sent
|optional
},
435 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_NOCLIENTMOVE
|SWP_NOCLIENTSIZE
|SWP_SHOWWINDOW
|SWP_NOMOVE
|SWP_NOSIZE
},
438 /* CreateWindow(WS_MAXIMIZE) for popup window, not initially visible */
439 static const struct message WmCreateInvisibleMaxPopupSeq
[] = {
440 { HCBT_CREATEWND
, hook
},
441 { WM_NCCREATE
, sent
},
442 { WM_NCCALCSIZE
, sent
|wparam
, 0 },
444 { WM_SIZE
, sent
|wparam
, SIZE_RESTORED
},
446 { HCBT_MINMAX
, hook
|lparam
, 0, SW_MAXIMIZE
},
447 { WM_GETMINMAXINFO
, sent
},
448 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_NOACTIVATE
|SWP_FRAMECHANGED
|0x8000 },
449 { WM_NCCALCSIZE
, sent
|wparam
, TRUE
},
450 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_NOACTIVATE
|SWP_FRAMECHANGED
|SWP_NOREDRAW
|0x8000 },
451 { WM_MOVE
, sent
|defwinproc
},
452 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_MAXIMIZED
},
455 /* ShowWindow(SW_SHOWMAXIMIZED) for a resized not visible popup window */
456 static const struct message WmShowMaxPopupResizedSeq
[] = {
457 { HCBT_MINMAX
, hook
|lparam
, 0, SW_MAXIMIZE
},
458 { WM_GETMINMAXINFO
, sent
},
459 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_FRAMECHANGED
},
460 { WM_NCCALCSIZE
, sent
|wparam
, TRUE
},
461 { HCBT_ACTIVATE
, hook
},
462 { WM_QUERYNEWPALETTE
, sent
|wparam
|lparam
|optional
, 0, 0 },
463 { WM_WINDOWPOSCHANGING
, sent
|wparam
|optional
, SWP_NOSIZE
|SWP_NOMOVE
},
464 { WM_ACTIVATEAPP
, sent
|wparam
, 1 },
465 { WM_NCACTIVATE
, sent
|wparam
, 1 },
466 { WM_ACTIVATE
, sent
|wparam
, 1 },
467 { HCBT_SETFOCUS
, hook
},
468 { WM_IME_SETCONTEXT
, sent
|wparam
|defwinproc
|optional
, 1 },
469 { WM_IME_NOTIFY
, sent
|wparam
|defwinproc
|optional
, 2 },
470 { WM_SETFOCUS
, sent
|wparam
|defwinproc
, 0 },
471 { WM_NCPAINT
, sent
|wparam
|optional
, 1 },
472 { WM_ERASEBKGND
, sent
|optional
},
473 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_NOCLIENTMOVE
|SWP_SHOWWINDOW
|SWP_FRAMECHANGED
|SWP_NOMOVE
},
474 /* WinNT4.0 sends WM_MOVE */
475 { WM_MOVE
, sent
|defwinproc
|optional
},
476 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_MAXIMIZED
},
479 /* ShowWindow(SW_SHOWMAXIMIZED) for a not visible popup window */
480 static const struct message WmShowMaxPopupSeq
[] = {
481 { HCBT_MINMAX
, hook
|lparam
, 0, SW_MAXIMIZE
},
482 { WM_GETMINMAXINFO
, sent
},
483 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_FRAMECHANGED
},
484 { WM_NCCALCSIZE
, sent
|wparam
, TRUE
},
485 { HCBT_ACTIVATE
, hook
},
486 { WM_QUERYNEWPALETTE
, sent
|wparam
|lparam
|optional
, 0, 0 },
487 { WM_WINDOWPOSCHANGING
, sent
|wparam
|optional
, SWP_NOSIZE
|SWP_NOMOVE
},
488 { WM_ACTIVATEAPP
, sent
|wparam
, 1 },
489 { WM_NCACTIVATE
, sent
|wparam
, 1 },
490 { WM_ACTIVATE
, sent
|wparam
, 1 },
491 { HCBT_SETFOCUS
, hook
},
492 { WM_IME_SETCONTEXT
, sent
|wparam
|defwinproc
|optional
, 1 },
493 { WM_IME_NOTIFY
, sent
|wparam
|defwinproc
|optional
, 2 },
494 { WM_SETFOCUS
, sent
|wparam
|defwinproc
, 0 },
495 { WM_SYNCPAINT
, sent
|wparam
|optional
, 4 },
496 { WM_NCPAINT
, sent
|wparam
|optional
, 1 },
497 { WM_ERASEBKGND
, sent
|optional
},
498 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
|SWP_SHOWWINDOW
|SWP_FRAMECHANGED
|SWP_NOMOVE
|SWP_NOSIZE
},
501 /* CreateWindow(WS_VISIBLE) for popup window */
502 static const struct message WmCreatePopupSeq
[] = {
503 { HCBT_CREATEWND
, hook
},
504 { WM_NCCREATE
, sent
},
505 { WM_NCCALCSIZE
, sent
|wparam
, 0 },
507 { WM_SIZE
, sent
|wparam
, SIZE_RESTORED
},
509 { WM_SHOWWINDOW
, sent
|wparam
, 1 },
510 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
},
511 { HCBT_ACTIVATE
, hook
},
512 { WM_QUERYNEWPALETTE
, sent
|wparam
|lparam
|optional
, 0, 0 },
513 { WM_WINDOWPOSCHANGING
, sent
|wparam
|optional
, SWP_NOSIZE
|SWP_NOMOVE
},
514 { WM_NCPAINT
, sent
|wparam
|optional
, 1 },
515 { WM_ERASEBKGND
, sent
|optional
},
516 { WM_ACTIVATEAPP
, sent
|wparam
, 1 },
517 { WM_NCACTIVATE
, sent
|wparam
, 1 },
518 { WM_ACTIVATE
, sent
|wparam
, 1 },
519 { HCBT_SETFOCUS
, hook
},
520 { WM_IME_SETCONTEXT
, sent
|wparam
|defwinproc
|optional
, 1 },
521 { WM_IME_NOTIFY
, sent
|wparam
|defwinproc
|optional
, 2 },
522 { WM_SETFOCUS
, sent
|wparam
|defwinproc
, 0 },
523 { WM_SYNCPAINT
, sent
|wparam
|optional
, 4 },
524 { WM_NCPAINT
, sent
|wparam
|optional
, 1 },
525 { WM_ERASEBKGND
, sent
|optional
},
526 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_NOCLIENTMOVE
|SWP_NOCLIENTSIZE
|SWP_SHOWWINDOW
|SWP_NOMOVE
|SWP_NOSIZE
},
529 /* ShowWindow(SW_SHOWMAXIMIZED) for a visible popup window */
530 static const struct message WmShowVisMaxPopupSeq
[] = {
531 { HCBT_MINMAX
, hook
|lparam
, 0, SW_MAXIMIZE
},
532 { WM_GETMINMAXINFO
, sent
},
533 { WM_GETTEXT
, sent
|optional
},
534 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|0x8000 },
535 { WM_NCCALCSIZE
, sent
|wparam
, TRUE
},
536 { WM_QUERYNEWPALETTE
, sent
|wparam
|lparam
|optional
, 0, 0 },
537 { WM_NCPAINT
, sent
|wparam
|optional
, 1 },
538 { WM_ERASEBKGND
, sent
|optional
},
539 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|0x8000 },
540 { WM_MOVE
, sent
|defwinproc
},
541 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_MAXIMIZED
},
544 /* CreateWindow (for a child popup window, not initially visible) */
545 static const struct message WmCreateChildPopupSeq
[] = {
546 { HCBT_CREATEWND
, hook
},
547 { WM_NCCREATE
, sent
},
548 { WM_NCCALCSIZE
, sent
|wparam
, 0 },
550 { EVENT_OBJECT_CREATE
, winevent_hook
|wparam
|lparam
, 0, 0 },
551 { WM_SIZE
, sent
|wparam
, SIZE_RESTORED
},
555 /* CreateWindow (for a popup window, not initially visible,
556 * which sets WS_VISIBLE in WM_CREATE handler)
558 static const struct message WmCreateInvisiblePopupSeq
[] = {
559 { HCBT_CREATEWND
, hook
},
560 { WM_NCCREATE
, sent
},
561 { WM_NCCALCSIZE
, sent
|wparam
, 0 },
563 { WM_STYLECHANGING
, sent
},
564 { WM_STYLECHANGED
, sent
},
565 { EVENT_OBJECT_CREATE
, winevent_hook
|wparam
|lparam
, 0, 0 },
566 { WM_SIZE
, sent
|wparam
, SIZE_RESTORED
},
570 /* SetWindowPos(SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE|SWP_NOZORDER)
571 * for a popup window with WS_VISIBLE style set
573 static const struct message WmShowVisiblePopupSeq_2
[] = {
574 { WM_WINDOWPOSCHANGING
, sent
|wparam
, 0 },
577 /* SetWindowPos(SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE)
578 * for a popup window with WS_VISIBLE style set
580 static const struct message WmShowVisiblePopupSeq_3
[] = {
581 { WM_WINDOWPOSCHANGING
, sent
|wparam
, 0 },
582 { HCBT_ACTIVATE
, hook
},
583 { EVENT_SYSTEM_FOREGROUND
, winevent_hook
|wparam
|lparam
, 0, 0 },
584 { WM_QUERYNEWPALETTE
, sent
|wparam
|lparam
|optional
, 0, 0 },
585 { WM_WINDOWPOSCHANGING
, sent
|wparam
, 0 },
586 { WM_NCACTIVATE
, sent
|wparam
, 1 },
587 { WM_ACTIVATE
, sent
|wparam
, 1 },
588 { HCBT_SETFOCUS
, hook
},
589 { WM_KILLFOCUS
, sent
|parent
},
590 { WM_IME_SETCONTEXT
, sent
|parent
|wparam
|optional
, 0 },
591 { WM_IME_SETCONTEXT
, sent
|wparam
|defwinproc
|optional
, 1 },
592 { WM_IME_NOTIFY
, sent
|wparam
|defwinproc
|optional
, 2 },
593 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
594 { WM_SETFOCUS
, sent
|defwinproc
},
597 /* CreateWindow (for child window, not initially visible) */
598 static const struct message WmCreateChildSeq
[] = {
599 { HCBT_CREATEWND
, hook
},
600 { WM_NCCREATE
, sent
},
601 /* child is inserted into parent's child list after WM_NCCREATE returns */
602 { WM_NCCALCSIZE
, sent
|wparam
, 0 },
604 { EVENT_OBJECT_CREATE
, winevent_hook
|wparam
|lparam
, 0, 0 },
605 { WM_SIZE
, sent
|wparam
, SIZE_RESTORED
},
607 { WM_PARENTNOTIFY
, sent
|parent
|wparam
, WM_CREATE
},
610 /* CreateWindow (for maximized child window, not initially visible) */
611 static const struct message WmCreateMaximizedChildSeq
[] = {
612 { HCBT_CREATEWND
, hook
},
613 { WM_NCCREATE
, sent
},
614 { WM_NCCALCSIZE
, sent
|wparam
, 0 },
616 { EVENT_OBJECT_CREATE
, winevent_hook
|wparam
|lparam
, 0, 0 },
617 { WM_SIZE
, sent
|wparam
, SIZE_RESTORED
},
619 { HCBT_MINMAX
, hook
|lparam
, 0, SW_MAXIMIZE
},
620 { WM_GETMINMAXINFO
, sent
},
621 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|0x8000 },
622 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
623 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOMOVE
|SWP_NOREDRAW
|SWP_NOCLIENTMOVE
|0x8000 },
624 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_MAXIMIZED
},
625 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
626 { WM_PARENTNOTIFY
, sent
|parent
|wparam
, WM_CREATE
},
629 /* CreateWindow (for a child window, initially visible) */
630 static const struct message WmCreateVisibleChildSeq
[] = {
631 { HCBT_CREATEWND
, hook
},
632 { WM_NCCREATE
, sent
},
633 /* child is inserted into parent's child list after WM_NCCREATE returns */
634 { WM_NCCALCSIZE
, sent
|wparam
, 0 },
635 { EVENT_OBJECT_REORDER
, winevent_hook
|wparam
|lparam
, 0, 0 },
637 { EVENT_OBJECT_CREATE
, winevent_hook
|wparam
|lparam
, 0, 0 },
638 { WM_SIZE
, sent
|wparam
, SIZE_RESTORED
},
640 { WM_PARENTNOTIFY
, sent
|parent
|wparam
, WM_CREATE
},
641 { WM_SHOWWINDOW
, sent
|wparam
, 1 },
642 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOACTIVATE
},
643 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, 0, 0 },
644 { WM_ERASEBKGND
, sent
|parent
|optional
},
645 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOACTIVATE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
646 { WM_NCCALCSIZE
, sent
|wparam
|optional
, 1 }, /* WinXP */
647 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
650 /* ShowWindow(SW_SHOW) for a not visible child window */
651 static const struct message WmShowChildSeq
[] = {
652 { WM_SHOWWINDOW
, sent
|wparam
, 1 },
653 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
654 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, 0, 0 },
655 { WM_ERASEBKGND
, sent
|parent
|optional
},
656 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
659 /* ShowWindow(SW_HIDE) for a visible child window */
660 static const struct message WmHideChildSeq
[] = {
661 { WM_SHOWWINDOW
, sent
|wparam
, 0 },
662 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_HIDEWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
663 { EVENT_OBJECT_HIDE
, winevent_hook
|wparam
|lparam
, 0, 0 },
664 { WM_ERASEBKGND
, sent
|parent
|optional
},
665 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_HIDEWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
668 /* SetWindowPos(SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE)
669 * for a not visible child window
671 static const struct message WmShowChildSeq_2
[] = {
672 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
},
673 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, 0, 0 },
674 { WM_CHILDACTIVATE
, sent
},
675 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
678 /* SetWindowPos(SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE)
679 * for a not visible child window
681 static const struct message WmShowChildSeq_3
[] = {
682 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOACTIVATE
},
683 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, 0, 0 },
684 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOACTIVATE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
687 /* SetWindowPos(SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE)
688 * for a visible child window with a caption
690 static const struct message WmShowChildSeq_4
[] = {
691 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
},
692 { WM_CHILDACTIVATE
, sent
},
695 /* ShowWindow(SW_MINIMIZE) for child with invisible parent */
696 static const struct message WmShowChildInvisibleParentSeq_1
[] = {
697 { HCBT_MINMAX
, hook
|lparam
, 0, SW_MINIMIZE
},
698 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOCOPYBITS
|0x8000 },
699 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
700 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOREDRAW
|SWP_NOCOPYBITS
|0x8000 },
701 { WM_MOVE
, sent
|defwinproc
},
702 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_MINIMIZED
},
703 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
704 /* FIXME: Wine creates an icon/title window while Windows doesn't */
705 { WM_PARENTNOTIFY
, sent
|parent
|wparam
|optional
, WM_CREATE
},
706 { WM_GETTEXT
, sent
|optional
},
709 /* repeated ShowWindow(SW_MINIMIZE) for child with invisible parent */
710 static const struct message WmShowChildInvisibleParentSeq_1r
[] = {
711 { HCBT_MINMAX
, hook
|lparam
, 0, SW_MINIMIZE
},
714 /* ShowWindow(SW_MAXIMIZE) for child with invisible parent */
715 static const struct message WmShowChildInvisibleParentSeq_2
[] = {
716 { HCBT_MINMAX
, hook
|lparam
, 0, SW_MAXIMIZE
},
717 { WM_GETMINMAXINFO
, sent
},
718 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_FRAMECHANGED
|0x8000 },
719 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
720 { WM_CHILDACTIVATE
, sent
},
721 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_FRAMECHANGED
|SWP_NOMOVE
|SWP_NOREDRAW
|SWP_NOCLIENTMOVE
|0x8000 },
722 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_MAXIMIZED
},
723 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
726 /* repeated ShowWindow(SW_MAXIMIZE) for child with invisible parent */
727 static const struct message WmShowChildInvisibleParentSeq_2r
[] = {
728 { HCBT_MINMAX
, hook
|lparam
, 0, SW_MAXIMIZE
},
731 /* ShowWindow(SW_SHOWMINIMIZED) for child with invisible parent */
732 static const struct message WmShowChildInvisibleParentSeq_3
[] = {
733 { HCBT_MINMAX
, hook
|lparam
, 0, SW_SHOWMINIMIZED
},
734 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_FRAMECHANGED
|SWP_NOCOPYBITS
|0x8000 },
735 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
736 { WM_CHILDACTIVATE
, sent
},
737 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_FRAMECHANGED
|SWP_NOREDRAW
|SWP_NOCOPYBITS
|0x8000 },
738 { WM_MOVE
, sent
|defwinproc
},
739 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_MINIMIZED
},
740 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
741 /* FIXME: Wine creates an icon/title window while Windows doesn't */
742 { WM_PARENTNOTIFY
, sent
|parent
|wparam
|optional
, WM_CREATE
},
743 { WM_GETTEXT
, sent
|optional
},
746 /* repeated ShowWindow(SW_SHOWMINIMIZED) for child with invisible parent */
747 static const struct message WmShowChildInvisibleParentSeq_3r
[] = {
748 { HCBT_MINMAX
, hook
|lparam
, 0, SW_SHOWMINIMIZED
},
751 /* ShowWindow(SW_SHOWMINNOACTIVE) for child with invisible parent */
752 static const struct message WmShowChildInvisibleParentSeq_4
[] = {
753 { HCBT_MINMAX
, hook
|lparam
, 0, SW_SHOWMINNOACTIVE
},
754 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOCOPYBITS
|0x8000 },
755 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
756 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOREDRAW
|SWP_NOCOPYBITS
|0x8000 },
757 { WM_MOVE
, sent
|defwinproc
},
758 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_MINIMIZED
},
759 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
760 /* FIXME: Wine creates an icon/title window while Windows doesn't */
761 { WM_PARENTNOTIFY
, sent
|parent
|wparam
|optional
, WM_CREATE
},
762 { WM_GETTEXT
, sent
|optional
},
765 /* repeated ShowWindow(SW_SHOWMINNOACTIVE) for child with invisible parent */
766 static const struct message WmShowChildInvisibleParentSeq_4r
[] = {
767 { HCBT_MINMAX
, hook
|lparam
, 0, SW_SHOWMINNOACTIVE
},
770 /* ShowWindow(SW_SHOW) for child with invisible parent */
771 static const struct message WmShowChildInvisibleParentSeq_5
[] = {
772 { WM_SHOWWINDOW
, sent
|wparam
, 1 },
775 /* ShowWindow(SW_HIDE) for child with invisible parent */
776 static const struct message WmHideChildInvisibleParentSeq
[] = {
777 { WM_SHOWWINDOW
, sent
|wparam
, 0 },
780 /* SetWindowPos(SWP_SHOWWINDOW) for child with invisible parent */
781 static const struct message WmShowChildInvisibleParentSeq_6
[] = {
782 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOACTIVATE
},
783 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, 0, 0 },
784 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOACTIVATE
|SWP_NOREDRAW
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
787 /* SetWindowPos(SWP_HIDEWINDOW) for child with invisible parent */
788 static const struct message WmHideChildInvisibleParentSeq_2
[] = {
789 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_HIDEWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
790 { EVENT_OBJECT_HIDE
, winevent_hook
|wparam
|lparam
, 0, 0 },
791 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_HIDEWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOREDRAW
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
794 /* DestroyWindow for a visible child window */
795 static const struct message WmDestroyChildSeq
[] = {
796 { HCBT_DESTROYWND
, hook
},
797 { WM_PARENTNOTIFY
, sent
|parent
|wparam
, WM_DESTROY
},
798 { WM_SHOWWINDOW
, sent
|wparam
, 0 },
799 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_HIDEWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
800 { EVENT_OBJECT_HIDE
, winevent_hook
|wparam
|lparam
, 0, 0 },
801 { WM_ERASEBKGND
, sent
|parent
|optional
},
802 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_HIDEWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
803 { HCBT_SETFOCUS
, hook
}, /* set focus to a parent */
804 { WM_KILLFOCUS
, sent
},
805 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 0 },
806 { WM_IME_SETCONTEXT
, sent
|wparam
|parent
|optional
, 1 },
807 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
808 { WM_SETFOCUS
, sent
|parent
},
809 { EVENT_OBJECT_DESTROY
, winevent_hook
|wparam
|lparam
, 0, 0 },
810 { WM_DESTROY
, sent
},
811 { WM_DESTROY
, sent
|optional
}, /* some other (IME?) window */
812 { WM_NCDESTROY
, sent
|optional
}, /* some other (IME?) window */
813 { WM_NCDESTROY
, sent
},
816 /* DestroyWindow for a visible child window with invisible parent */
817 static const struct message WmDestroyInvisibleChildSeq
[] = {
818 { HCBT_DESTROYWND
, hook
},
819 { WM_PARENTNOTIFY
, sent
|parent
|wparam
, WM_DESTROY
},
820 { WM_SHOWWINDOW
, sent
|wparam
, 0 },
821 { EVENT_OBJECT_DESTROY
, winevent_hook
|wparam
|lparam
, 0, 0 },
822 { WM_DESTROY
, sent
},
823 { WM_NCDESTROY
, sent
},
826 /* Moving the mouse in nonclient area */
827 static const struct message WmMouseMoveInNonClientAreaSeq
[] = { /* FIXME: add */
828 { WM_NCHITTEST
, sent
},
829 { WM_SETCURSOR
, sent
},
830 { WM_NCMOUSEMOVE
, posted
},
833 /* Moving the mouse in client area */
834 static const struct message WmMouseMoveInClientAreaSeq
[] = { /* FIXME: add */
835 { WM_NCHITTEST
, sent
},
836 { WM_SETCURSOR
, sent
},
837 { WM_MOUSEMOVE
, posted
},
840 /* Moving by dragging the title bar (after WM_NCHITTEST and WM_SETCURSOR) (outline move) */
841 static const struct message WmDragTitleBarSeq
[] = { /* FIXME: add */
842 { WM_NCLBUTTONDOWN
, sent
|wparam
, HTCAPTION
},
843 { WM_SYSCOMMAND
, sent
|defwinproc
|wparam
, SC_MOVE
+2 },
844 { WM_GETMINMAXINFO
, sent
|defwinproc
},
845 { WM_ENTERSIZEMOVE
, sent
|defwinproc
},
846 { WM_WINDOWPOSCHANGING
, sent
|wparam
|defwinproc
, 0 },
847 { WM_WINDOWPOSCHANGED
, sent
|wparam
|defwinproc
, 0 },
848 { WM_MOVE
, sent
|defwinproc
},
849 { WM_EXITSIZEMOVE
, sent
|defwinproc
},
852 /* Sizing by dragging the thick borders (after WM_NCHITTEST and WM_SETCURSOR) (outline move) */
853 static const struct message WmDragThickBordersBarSeq
[] = { /* FIXME: add */
854 { WM_NCLBUTTONDOWN
, sent
|wparam
, 0xd },
855 { WM_SYSCOMMAND
, sent
|defwinproc
|wparam
, 0xf004 },
856 { WM_GETMINMAXINFO
, sent
|defwinproc
},
857 { WM_ENTERSIZEMOVE
, sent
|defwinproc
},
858 { WM_SIZING
, sent
|defwinproc
|wparam
, 4}, /* one for each mouse movement */
859 { WM_WINDOWPOSCHANGING
, sent
|wparam
|defwinproc
, 0 },
860 { WM_GETMINMAXINFO
, sent
|defwinproc
},
861 { WM_NCCALCSIZE
, sent
|defwinproc
|wparam
, 1 },
862 { WM_NCPAINT
, sent
|defwinproc
|wparam
, 1 },
863 { WM_GETTEXT
, sent
|defwinproc
},
864 { WM_ERASEBKGND
, sent
|defwinproc
},
865 { WM_WINDOWPOSCHANGED
, sent
|wparam
|defwinproc
, 0 },
866 { WM_MOVE
, sent
|defwinproc
},
867 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_RESTORED
},
868 { WM_EXITSIZEMOVE
, sent
|defwinproc
},
871 /* Resizing child window with MoveWindow (32) */
872 static const struct message WmResizingChildWithMoveWindowSeq
[] = {
873 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_NOACTIVATE
},
874 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
875 { WM_ERASEBKGND
, sent
|optional
},
876 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_NOACTIVATE
},
877 { WM_MOVE
, sent
|defwinproc
},
878 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_RESTORED
},
879 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
882 /* Clicking on inactive button */
883 static const struct message WmClickInactiveButtonSeq
[] = { /* FIXME: add */
884 { WM_NCHITTEST
, sent
},
885 { WM_PARENTNOTIFY
, sent
|parent
|wparam
, WM_LBUTTONDOWN
},
886 { WM_MOUSEACTIVATE
, sent
},
887 { WM_MOUSEACTIVATE
, sent
|parent
|defwinproc
},
888 { WM_SETCURSOR
, sent
},
889 { WM_SETCURSOR
, sent
|parent
|defwinproc
},
890 { WM_LBUTTONDOWN
, posted
},
891 { WM_KILLFOCUS
, posted
|parent
},
892 { WM_SETFOCUS
, posted
},
893 { WM_CTLCOLORBTN
, posted
|parent
},
894 { BM_SETSTATE
, posted
},
895 { WM_CTLCOLORBTN
, posted
|parent
},
896 { WM_LBUTTONUP
, posted
},
897 { BM_SETSTATE
, posted
},
898 { WM_CTLCOLORBTN
, posted
|parent
},
899 { WM_COMMAND
, posted
|parent
},
902 /* Reparenting a button (16/32) */
903 /* The last child (button) reparented gets topmost for its new parent. */
904 static const struct message WmReparentButtonSeq
[] = { /* FIXME: add */
905 { WM_SHOWWINDOW
, sent
|wparam
, 0 },
906 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_HIDEWINDOW
|SWP_NOACTIVATE
|SWP_NOMOVE
|SWP_NOSIZE
},
907 { EVENT_OBJECT_HIDE
, winevent_hook
|wparam
|lparam
, 0, 0 },
908 { WM_ERASEBKGND
, sent
|parent
},
909 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_HIDEWINDOW
|SWP_NOACTIVATE
|SWP_NOMOVE
|SWP_NOSIZE
},
910 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_NOSIZE
},
911 { WM_CHILDACTIVATE
, sent
},
912 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_NOSIZE
|SWP_NOREDRAW
},
913 { WM_MOVE
, sent
|defwinproc
},
914 { WM_SHOWWINDOW
, sent
|wparam
, 1 },
917 /* Creation of a custom dialog (32) */
918 static const struct message WmCreateCustomDialogSeq
[] = {
919 { HCBT_CREATEWND
, hook
},
920 { WM_GETMINMAXINFO
, sent
},
921 { WM_NCCREATE
, sent
},
922 { WM_NCCALCSIZE
, sent
|wparam
, 0 },
923 { EVENT_OBJECT_REORDER
, winevent_hook
|wparam
|lparam
, 0, 0 },
925 { EVENT_OBJECT_CREATE
, winevent_hook
|wparam
|lparam
, 0, 0 },
926 { WM_SHOWWINDOW
, sent
|wparam
, 1 },
927 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
},
928 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, 0, 0 },
929 { HCBT_ACTIVATE
, hook
},
930 { EVENT_SYSTEM_FOREGROUND
, winevent_hook
|wparam
|lparam
, 0, 0 },
933 { WM_QUERYNEWPALETTE
, sent
|wparam
|lparam
|optional
, 0, 0 },
935 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_NOSIZE
|SWP_NOMOVE
},
937 { WM_NCACTIVATE
, sent
|wparam
, 1 },
938 { WM_GETTEXT
, sent
|optional
|defwinproc
},
939 { WM_GETTEXT
, sent
|optional
|defwinproc
},
940 { EVENT_OBJECT_DEFACTIONCHANGE
, winevent_hook
|wparam
|lparam
|optional
, OBJID_CLIENT
, 0 },
941 { WM_ACTIVATE
, sent
|wparam
, 1 },
942 { WM_KILLFOCUS
, sent
|parent
},
943 { WM_IME_SETCONTEXT
, sent
|parent
|wparam
|optional
, 0 },
944 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 1 },
945 { WM_IME_NOTIFY
, sent
|wparam
|defwinproc
|optional
, 2 },
946 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
947 { WM_SETFOCUS
, sent
},
948 { WM_GETDLGCODE
, sent
|defwinproc
|wparam
, 0 },
949 { WM_NCPAINT
, sent
|wparam
, 1 },
950 { WM_GETTEXT
, sent
|optional
|defwinproc
},
951 { WM_GETTEXT
, sent
|optional
|defwinproc
},
952 { WM_ERASEBKGND
, sent
},
953 { WM_CTLCOLORDLG
, sent
|defwinproc
},
954 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
955 { WM_GETTEXT
, sent
|optional
},
956 { WM_GETTEXT
, sent
|optional
},
957 { WM_NCCALCSIZE
, sent
|optional
},
958 { WM_NCPAINT
, sent
|optional
},
959 { WM_GETTEXT
, sent
|optional
|defwinproc
},
960 { WM_GETTEXT
, sent
|optional
|defwinproc
},
961 { WM_ERASEBKGND
, sent
|optional
},
962 { WM_CTLCOLORDLG
, sent
|optional
|defwinproc
},
963 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
964 { WM_SIZE
, sent
|wparam
, SIZE_RESTORED
},
968 /* Calling EndDialog for a custom dialog (32) */
969 static const struct message WmEndCustomDialogSeq
[] = {
970 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_HIDEWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
971 { EVENT_OBJECT_HIDE
, winevent_hook
|wparam
|lparam
, 0, 0 },
972 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_HIDEWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
973 { WM_GETTEXT
, sent
|optional
},
974 { HCBT_ACTIVATE
, hook
},
975 { WM_NCACTIVATE
, sent
|wparam
, 0 },
976 { WM_GETTEXT
, sent
|optional
|defwinproc
},
977 { WM_GETTEXT
, sent
|optional
|defwinproc
},
978 { WM_ACTIVATE
, sent
|wparam
, 0 },
979 { EVENT_SYSTEM_FOREGROUND
, winevent_hook
|wparam
|lparam
, 0, 0 },
980 { WM_WINDOWPOSCHANGING
, sent
|wparam
|optional
, SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
981 { HCBT_SETFOCUS
, hook
},
982 { WM_KILLFOCUS
, sent
},
983 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 0 },
984 { WM_IME_SETCONTEXT
, sent
|parent
|wparam
|defwinproc
|optional
, 1 },
985 { WM_IME_NOTIFY
, sent
|wparam
|optional
, 1 },
986 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
987 { WM_SETFOCUS
, sent
|parent
|defwinproc
},
990 /* ShowWindow(SW_SHOW) for a custom dialog (initially invisible) */
991 static const struct message WmShowCustomDialogSeq
[] = {
992 { WM_SHOWWINDOW
, sent
|wparam
, 1 },
993 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
},
994 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, 0, 0 },
995 { HCBT_ACTIVATE
, hook
},
996 { EVENT_SYSTEM_FOREGROUND
, winevent_hook
|wparam
|lparam
, 0, 0 },
998 { WM_QUERYNEWPALETTE
, sent
|wparam
|lparam
|optional
, 0, 0 },
1000 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_NOSIZE
|SWP_NOMOVE
},
1001 { WM_ACTIVATEAPP
, sent
|wparam
|optional
, 1 },
1002 { WM_NCACTIVATE
, sent
|wparam
, 1 },
1003 { WM_ACTIVATE
, sent
|wparam
, 1 },
1005 { WM_KILLFOCUS
, sent
|parent
},
1006 { WM_IME_SETCONTEXT
, sent
|parent
|wparam
|optional
, 0 },
1007 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 1 },
1008 { WM_IME_NOTIFY
, sent
|wparam
|defwinproc
|optional
, 2 },
1009 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
1010 { WM_SETFOCUS
, sent
},
1011 { WM_GETDLGCODE
, sent
|defwinproc
|wparam
, 0 },
1012 { WM_NCPAINT
, sent
|wparam
, 1 },
1013 { WM_ERASEBKGND
, sent
},
1014 { WM_CTLCOLORDLG
, sent
|defwinproc
},
1015 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
1018 /* Creation and destruction of a modal dialog (32) */
1019 static const struct message WmModalDialogSeq
[] = {
1020 { WM_CANCELMODE
, sent
|parent
},
1021 { HCBT_SETFOCUS
, hook
},
1022 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
1023 { WM_KILLFOCUS
, sent
|parent
},
1024 { WM_IME_SETCONTEXT
, sent
|parent
|wparam
|optional
, 0 },
1025 { EVENT_OBJECT_STATECHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
1026 { WM_ENABLE
, sent
|parent
|wparam
, 0 },
1027 { HCBT_CREATEWND
, hook
},
1028 { EVENT_OBJECT_REORDER
, winevent_hook
|wparam
|lparam
, 0, 0 },
1029 { EVENT_OBJECT_CREATE
, winevent_hook
|wparam
|lparam
, 0, 0 },
1030 { WM_SETFONT
, sent
},
1031 { WM_INITDIALOG
, sent
},
1032 { WM_CHANGEUISTATE
, sent
|optional
},
1033 { WM_UPDATEUISTATE
, sent
|optional
},
1034 { WM_SHOWWINDOW
, sent
},
1035 { HCBT_ACTIVATE
, hook
},
1036 { EVENT_SYSTEM_FOREGROUND
, winevent_hook
|wparam
|lparam
, 0, 0 },
1037 { WM_QUERYNEWPALETTE
, sent
|wparam
|lparam
|optional
, 0, 0 },
1038 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_NOSIZE
|SWP_NOMOVE
},
1039 { WM_NCACTIVATE
, sent
|wparam
, 1 },
1040 { WM_GETTEXT
, sent
|optional
},
1041 { WM_ACTIVATE
, sent
|wparam
, 1 },
1042 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOACTIVATE
},
1043 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, 0, 0 },
1044 { WM_NCPAINT
, sent
},
1045 { WM_GETTEXT
, sent
|optional
},
1046 { WM_ERASEBKGND
, sent
},
1047 { WM_CTLCOLORDLG
, sent
},
1048 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOACTIVATE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
1049 { WM_GETTEXT
, sent
|optional
},
1050 { WM_NCCALCSIZE
, sent
|optional
},
1051 { WM_NCPAINT
, sent
|optional
},
1052 { WM_GETTEXT
, sent
|optional
},
1053 { WM_ERASEBKGND
, sent
|optional
},
1054 { WM_CTLCOLORDLG
, sent
|optional
},
1055 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
1056 { WM_PAINT
, sent
|optional
},
1057 { WM_CTLCOLORBTN
, sent
},
1058 { WM_ENTERIDLE
, sent
|parent
|optional
},
1059 { WM_ENTERIDLE
, sent
|parent
|optional
},
1060 { WM_ENTERIDLE
, sent
|parent
|optional
},
1061 { WM_ENTERIDLE
, sent
|parent
|optional
},
1062 { WM_ENTERIDLE
, sent
|parent
|optional
},
1063 { WM_ENTERIDLE
, sent
|parent
|optional
},
1064 { WM_ENTERIDLE
, sent
|parent
|optional
},
1065 { WM_ENTERIDLE
, sent
|parent
|optional
},
1066 { WM_ENTERIDLE
, sent
|parent
|optional
},
1067 { WM_ENTERIDLE
, sent
|parent
|optional
},
1068 { WM_ENTERIDLE
, sent
|parent
|optional
},
1069 { WM_ENTERIDLE
, sent
|parent
|optional
},
1070 { WM_ENTERIDLE
, sent
|parent
|optional
},
1071 { WM_ENTERIDLE
, sent
|parent
|optional
},
1072 { WM_ENTERIDLE
, sent
|parent
|optional
},
1073 { WM_ENTERIDLE
, sent
|parent
|optional
},
1074 { WM_ENTERIDLE
, sent
|parent
|optional
},
1075 { WM_ENTERIDLE
, sent
|parent
|optional
},
1076 { WM_ENTERIDLE
, sent
|parent
|optional
},
1077 { WM_ENTERIDLE
, sent
|parent
|optional
},
1079 { EVENT_OBJECT_STATECHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
1080 { WM_ENABLE
, sent
|parent
|wparam
, 1 },
1081 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_HIDEWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOACTIVATE
},
1082 { EVENT_OBJECT_HIDE
, winevent_hook
|wparam
|lparam
, 0, 0 },
1083 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_HIDEWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOACTIVATE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
1084 { WM_GETTEXT
, sent
|optional
},
1085 { HCBT_ACTIVATE
, hook
},
1086 { WM_NCACTIVATE
, sent
|wparam
, 0 },
1087 { WM_GETTEXT
, sent
|optional
},
1088 { WM_ACTIVATE
, sent
|wparam
, 0 },
1089 { EVENT_SYSTEM_FOREGROUND
, winevent_hook
|wparam
|lparam
, 0, 0 },
1090 { WM_WINDOWPOSCHANGING
, sent
|optional
},
1091 { HCBT_SETFOCUS
, hook
},
1092 { WM_IME_SETCONTEXT
, sent
|parent
|wparam
|defwinproc
|optional
, 1 },
1093 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
1094 { WM_SETFOCUS
, sent
|parent
|defwinproc
},
1095 { EVENT_SYSTEM_DIALOGEND
, winevent_hook
|wparam
|lparam
, 0, 0 },
1096 { HCBT_DESTROYWND
, hook
},
1097 { EVENT_OBJECT_DESTROY
, winevent_hook
|wparam
|lparam
, 0, 0 },
1098 { WM_DESTROY
, sent
},
1099 { WM_NCDESTROY
, sent
},
1102 /* Creation of a modal dialog that is resized inside WM_INITDIALOG (32) */
1103 static const struct message WmCreateModalDialogResizeSeq
[] = { /* FIXME: add */
1104 /* (inside dialog proc, handling WM_INITDIALOG) */
1105 { WM_WINDOWPOSCHANGING
, sent
|wparam
, 0 },
1106 { WM_NCCALCSIZE
, sent
},
1107 { WM_NCACTIVATE
, sent
|parent
|wparam
, 0 },
1108 { WM_GETTEXT
, sent
|defwinproc
},
1109 { WM_ACTIVATE
, sent
|parent
|wparam
, 0 },
1110 { WM_WINDOWPOSCHANGING
, sent
|wparam
, 0 },
1111 { WM_WINDOWPOSCHANGING
, sent
|parent
},
1112 { WM_NCACTIVATE
, sent
|wparam
, 1 },
1113 { WM_ACTIVATE
, sent
|wparam
, 1 },
1114 { WM_WINDOWPOSCHANGED
, sent
|wparam
, 0 },
1115 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_RESTORED
},
1116 /* (setting focus) */
1117 { WM_SHOWWINDOW
, sent
|wparam
, 1 },
1118 { WM_WINDOWPOSCHANGING
, sent
|wparam
, 0 },
1119 { WM_NCPAINT
, sent
},
1120 { WM_GETTEXT
, sent
|defwinproc
},
1121 { WM_ERASEBKGND
, sent
},
1122 { WM_CTLCOLORDLG
, sent
|defwinproc
},
1123 { WM_WINDOWPOSCHANGED
, sent
|wparam
, 0 },
1125 /* (bunch of WM_CTLCOLOR* for each control) */
1126 { WM_PAINT
, sent
|parent
},
1127 { WM_ENTERIDLE
, sent
|parent
|wparam
, 0 },
1128 { WM_SETCURSOR
, sent
|parent
},
1131 /* SetMenu for NonVisible windows with size change*/
1132 static const struct message WmSetMenuNonVisibleSizeChangeSeq
[] = {
1133 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
1134 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
1135 { EVENT_OBJECT_REORDER
, winevent_hook
|wparam
|lparam
, 0, 0 },
1136 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOREDRAW
},
1137 { WM_MOVE
, sent
|defwinproc
},
1138 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_RESTORED
},
1139 { WM_NCCALCSIZE
,sent
|wparam
|optional
, 1 }, /* XP */
1140 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
1141 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
|optional
, 0, 0 }, /* XP sends a duplicate */
1142 { WM_GETTEXT
, sent
|optional
},
1143 { WM_NCCALCSIZE
, sent
|wparam
|optional
, 1 },
1146 /* SetMenu for NonVisible windows with no size change */
1147 static const struct message WmSetMenuNonVisibleNoSizeChangeSeq
[] = {
1148 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
1149 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
1150 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOREDRAW
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
1151 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
1154 /* SetMenu for Visible windows with size change */
1155 static const struct message WmSetMenuVisibleSizeChangeSeq
[] = {
1156 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
1157 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
1158 { EVENT_OBJECT_REORDER
, winevent_hook
|wparam
|lparam
, 0, 0 },
1159 { WM_NCPAINT
, sent
}, /* wparam != 1 */
1160 { WM_GETTEXT
, sent
|defwinproc
|optional
},
1161 { WM_ERASEBKGND
, sent
|optional
},
1162 { WM_ACTIVATE
, sent
|optional
},
1163 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
1164 { WM_MOVE
, sent
|defwinproc
},
1165 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_RESTORED
},
1166 { WM_NCCALCSIZE
, sent
|wparam
|optional
, 1 },
1167 { WM_NCPAINT
, sent
|optional
}, /* wparam != 1 */
1168 { WM_ERASEBKGND
, sent
|optional
},
1169 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
1170 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
|optional
, 0, 0 }, /* XP sends a duplicate */
1173 /* SetMenu for Visible windows with no size change */
1174 static const struct message WmSetMenuVisibleNoSizeChangeSeq
[] = {
1175 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
1176 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
1177 { WM_NCPAINT
, sent
}, /* wparam != 1 */
1178 { WM_GETTEXT
, sent
|defwinproc
|optional
},
1179 { WM_ERASEBKGND
, sent
|optional
},
1180 { WM_ACTIVATE
, sent
|optional
},
1181 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
1182 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
1185 /* DrawMenuBar for a visible window */
1186 static const struct message WmDrawMenuBarSeq
[] =
1188 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
1189 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
1190 { WM_NCPAINT
, sent
}, /* wparam != 1 */
1191 { WM_GETTEXT
, sent
|defwinproc
|optional
},
1192 { WM_ERASEBKGND
, sent
|optional
},
1193 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
1194 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
1198 static const struct message WmSetRedrawFalseSeq
[] =
1200 { WM_SETREDRAW
, sent
|wparam
, 0 },
1204 static const struct message WmSetRedrawTrueSeq
[] =
1206 { WM_SETREDRAW
, sent
|wparam
, 1 },
1210 static const struct message WmEnableWindowSeq_1
[] =
1212 { WM_CANCELMODE
, sent
|wparam
|lparam
, 0, 0 },
1213 { EVENT_OBJECT_STATECHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
1214 { WM_ENABLE
, sent
|wparam
|lparam
, FALSE
, 0 },
1218 static const struct message WmEnableWindowSeq_2
[] =
1220 { EVENT_OBJECT_STATECHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
1221 { WM_ENABLE
, sent
|wparam
|lparam
, TRUE
, 0 },
1225 static const struct message WmGetScrollRangeSeq
[] =
1227 { SBM_GETRANGE
, sent
},
1230 static const struct message WmGetScrollInfoSeq
[] =
1232 { SBM_GETSCROLLINFO
, sent
},
1235 static const struct message WmSetScrollRangeSeq
[] =
1237 /* MSDN claims that Windows sends SBM_SETRANGE message, but win2k SP4
1238 sends SBM_SETSCROLLINFO.
1240 { SBM_SETSCROLLINFO
, sent
},
1243 /* SetScrollRange for a window without a non-client area */
1244 static const struct message WmSetScrollRangeHSeq_empty
[] =
1246 { EVENT_OBJECT_VALUECHANGE
, winevent_hook
|wparam
|lparam
, OBJID_HSCROLL
, 0 },
1249 static const struct message WmSetScrollRangeVSeq_empty
[] =
1251 { EVENT_OBJECT_VALUECHANGE
, winevent_hook
|wparam
|lparam
, OBJID_VSCROLL
, 0 },
1254 static const struct message WmSetScrollRangeHVSeq
[] =
1256 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOMOVE
|SWP_NOSIZE
},
1257 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
1258 { WM_GETTEXT
, sent
|defwinproc
|optional
},
1259 { WM_ERASEBKGND
, sent
|optional
},
1260 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOMOVE
|SWP_NOSIZE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
1261 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
1262 { EVENT_OBJECT_VALUECHANGE
, winevent_hook
|lparam
|optional
, 0/*OBJID_HSCROLL or OBJID_VSCROLL*/, 0 },
1265 /* SetScrollRange for a window with a non-client area */
1266 static const struct message WmSetScrollRangeHV_NC_Seq
[] =
1268 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOMOVE
|SWP_NOSIZE
},
1269 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
1270 { EVENT_OBJECT_REORDER
, winevent_hook
|wparam
|lparam
, 0, 0 },
1271 { WM_NCPAINT
, sent
|optional
},
1272 { WM_GETTEXT
, sent
|defwinproc
|optional
},
1273 { WM_GETTEXT
, sent
|defwinproc
|optional
},
1274 { WM_ERASEBKGND
, sent
|optional
},
1275 { WM_CTLCOLORDLG
, sent
|defwinproc
|optional
}, /* sent to a parent of the dialog */
1276 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOMOVE
|SWP_NOSIZE
|SWP_NOCLIENTMOVE
},
1277 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_RESTORED
},
1278 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
1279 { EVENT_OBJECT_VALUECHANGE
, winevent_hook
|lparam
|optional
, 0/*OBJID_HSCROLL or OBJID_VSCROLL*/, 0 },
1280 { WM_GETTEXT
, sent
|optional
},
1281 { WM_GETTEXT
, sent
|optional
},
1282 { WM_GETTEXT
, sent
|optional
},
1283 { WM_GETTEXT
, sent
|optional
},
1286 /* test if we receive the right sequence of messages */
1287 /* after calling ShowWindow( SW_SHOWNA) */
1288 static const struct message WmSHOWNAChildInvisParInvis
[] = {
1289 { WM_SHOWWINDOW
, sent
|wparam
, 1 },
1292 static const struct message WmSHOWNAChildVisParInvis
[] = {
1293 { WM_SHOWWINDOW
, sent
|wparam
, 1 },
1296 static const struct message WmSHOWNAChildVisParVis
[] = {
1297 { WM_SHOWWINDOW
, sent
|wparam
, 1 },
1298 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOACTIVATE
},
1301 static const struct message WmSHOWNAChildInvisParVis
[] = {
1302 { WM_SHOWWINDOW
, sent
|wparam
, 1 },
1303 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
1304 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, 0, 0 },
1305 { WM_ERASEBKGND
, sent
|optional
},
1306 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOACTIVATE
|SWP_NOCLIENTMOVE
},
1309 static const struct message WmSHOWNATopVisible
[] = {
1310 { WM_SHOWWINDOW
, sent
|wparam
, 1 },
1311 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOACTIVATE
},
1314 static const struct message WmSHOWNATopInvisible
[] = {
1315 { WM_SHOWWINDOW
, sent
|wparam
, 1 },
1316 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
1317 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, 0, 0 },
1318 { WM_NCPAINT
, sent
|wparam
, 1 },
1319 { WM_GETTEXT
, sent
|defwinproc
|optional
},
1320 { WM_ERASEBKGND
, sent
|optional
},
1321 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
1322 { WM_NCCALCSIZE
, sent
|wparam
|optional
, 1 },
1323 { WM_NCPAINT
, sent
|wparam
|optional
, 1 },
1324 { WM_ERASEBKGND
, sent
|optional
},
1325 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
1326 { WM_SIZE
, sent
|wparam
, SIZE_RESTORED
},
1331 static int after_end_dialog
, test_def_id
;
1332 static int sequence_cnt
, sequence_size
;
1333 static struct message
* sequence
;
1334 static int log_all_parent_messages
;
1336 static void add_message(const struct message
*msg
)
1341 sequence
= HeapAlloc( GetProcessHeap(), 0, sequence_size
* sizeof (struct message
) );
1343 if (sequence_cnt
== sequence_size
)
1346 sequence
= HeapReAlloc( GetProcessHeap(), 0, sequence
, sequence_size
* sizeof (struct message
) );
1350 sequence
[sequence_cnt
].message
= msg
->message
;
1351 sequence
[sequence_cnt
].flags
= msg
->flags
;
1352 sequence
[sequence_cnt
].wParam
= msg
->wParam
;
1353 sequence
[sequence_cnt
].lParam
= msg
->lParam
;
1358 /* try to make sure pending X events have been processed before continuing */
1359 static void flush_events(void)
1363 DWORD time
= GetTickCount() + diff
;
1367 MsgWaitForMultipleObjects( 0, NULL
, FALSE
, diff
, QS_ALLINPUT
);
1368 while (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
1369 diff
= time
- GetTickCount();
1373 static void flush_sequence(void)
1375 HeapFree(GetProcessHeap(), 0, sequence
);
1377 sequence_cnt
= sequence_size
= 0;
1380 #define ok_sequence( exp, contx, todo) \
1381 ok_sequence_( (exp), (contx), (todo), __FILE__, __LINE__)
1384 static void ok_sequence_(const struct message
*expected
, const char *context
, int todo
,
1385 const char *file
, int line
)
1387 static const struct message end_of_sequence
= { 0, 0, 0, 0 };
1388 const struct message
*actual
;
1391 add_message(&end_of_sequence
);
1395 while (expected
->message
&& actual
->message
)
1397 trace_( file
, line
)("expected %04x - actual %04x\n", expected
->message
, actual
->message
);
1399 if (expected
->message
== actual
->message
)
1401 if (expected
->flags
& wparam
)
1403 if (expected
->wParam
!= actual
->wParam
&& todo
)
1407 ok_( file
, line
) (FALSE
,
1408 "%s: in msg 0x%04x expecting wParam 0x%lx got 0x%lx\n",
1409 context
, expected
->message
, expected
->wParam
, actual
->wParam
);
1413 ok_( file
, line
) (expected
->wParam
== actual
->wParam
,
1414 "%s: in msg 0x%04x expecting wParam 0x%lx got 0x%lx\n",
1415 context
, expected
->message
, expected
->wParam
, actual
->wParam
);
1417 if (expected
->flags
& lparam
)
1419 if (expected
->lParam
!= actual
->lParam
&& todo
)
1423 ok_( file
, line
) (FALSE
,
1424 "%s: in msg 0x%04x expecting lParam 0x%lx got 0x%lx\n",
1425 context
, expected
->message
, expected
->lParam
, actual
->lParam
);
1429 ok_( file
, line
) (expected
->lParam
== actual
->lParam
,
1430 "%s: in msg 0x%04x expecting lParam 0x%lx got 0x%lx\n",
1431 context
, expected
->message
, expected
->lParam
, actual
->lParam
);
1433 if ((expected
->flags
& defwinproc
) != (actual
->flags
& defwinproc
) && todo
)
1437 ok_( file
, line
) (FALSE
,
1438 "%s: the msg 0x%04x should %shave been sent by DefWindowProc\n",
1439 context
, expected
->message
, (expected
->flags
& defwinproc
) ? "" : "NOT ");
1443 ok_( file
, line
) ((expected
->flags
& defwinproc
) == (actual
->flags
& defwinproc
),
1444 "%s: the msg 0x%04x should %shave been sent by DefWindowProc\n",
1445 context
, expected
->message
, (expected
->flags
& defwinproc
) ? "" : "NOT ");
1446 ok_( file
, line
) ((expected
->flags
& beginpaint
) == (actual
->flags
& beginpaint
),
1447 "%s: the msg 0x%04x should %shave been sent by BeginPaint\n",
1448 context
, expected
->message
, (expected
->flags
& beginpaint
) ? "" : "NOT ");
1449 ok_( file
, line
) ((expected
->flags
& (sent
|posted
)) == (actual
->flags
& (sent
|posted
)),
1450 "%s: the msg 0x%04x should have been %s\n",
1451 context
, expected
->message
, (expected
->flags
& posted
) ? "posted" : "sent");
1452 ok_( file
, line
) ((expected
->flags
& parent
) == (actual
->flags
& parent
),
1453 "%s: the msg 0x%04x was expected in %s\n",
1454 context
, expected
->message
, (expected
->flags
& parent
) ? "parent" : "child");
1455 ok_( file
, line
) ((expected
->flags
& hook
) == (actual
->flags
& hook
),
1456 "%s: the msg 0x%04x should have been sent by a hook\n",
1457 context
, expected
->message
);
1458 ok_( file
, line
) ((expected
->flags
& winevent_hook
) == (actual
->flags
& winevent_hook
),
1459 "%s: the msg 0x%04x should have been sent by a winevent hook\n",
1460 context
, expected
->message
);
1464 /* silently drop winevent messages if there is no support for them */
1465 else if ((expected
->flags
& optional
) || ((expected
->flags
& winevent_hook
) && !hEvent_hook
))
1471 ok_( file
, line
) (FALSE
, "%s: the msg 0x%04x was expected, but got msg 0x%04x instead\n",
1472 context
, expected
->message
, actual
->message
);
1479 ok_( file
, line
) (FALSE
, "%s: the msg 0x%04x was expected, but got msg 0x%04x instead\n",
1480 context
, expected
->message
, actual
->message
);
1486 /* skip all optional trailing messages */
1487 while (expected
->message
&& ((expected
->flags
& optional
) ||
1488 ((expected
->flags
& winevent_hook
) && !hEvent_hook
)))
1494 if (expected
->message
|| actual
->message
) {
1496 ok_( file
, line
) (FALSE
, "%s: the msg sequence is not complete: expected %04x - actual %04x\n",
1497 context
, expected
->message
, actual
->message
);
1503 if (expected
->message
|| actual
->message
)
1504 ok_( file
, line
) (FALSE
, "%s: the msg sequence is not complete: expected %04x - actual %04x\n",
1505 context
, expected
->message
, actual
->message
);
1507 if( todo
&& !failcount
) /* succeeded yet marked todo */
1509 ok_( file
, line
)( TRUE
, "%s: marked \"todo_wine\" but succeeds\n", context
);
1515 /******************************** MDI test **********************************/
1517 /* CreateWindow for MDI frame window, initially visible */
1518 static const struct message WmCreateMDIframeSeq
[] = {
1519 { HCBT_CREATEWND
, hook
},
1520 { WM_GETMINMAXINFO
, sent
},
1521 { WM_NCCREATE
, sent
},
1522 { WM_NCCALCSIZE
, sent
|wparam
, 0 },
1523 { EVENT_OBJECT_REORDER
, winevent_hook
|wparam
|lparam
, 0, 0 },
1524 { WM_CREATE
, sent
},
1525 { EVENT_OBJECT_CREATE
, winevent_hook
|wparam
|lparam
, 0, 0 },
1526 { WM_SHOWWINDOW
, sent
|wparam
, 1 },
1527 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
},
1528 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, 0, 0 },
1529 { HCBT_ACTIVATE
, hook
},
1530 { EVENT_SYSTEM_FOREGROUND
, winevent_hook
|wparam
|lparam
, 0, 0 },
1531 { WM_QUERYNEWPALETTE
, sent
|wparam
|lparam
|optional
, 0, 0 },
1532 { WM_WINDOWPOSCHANGING
, sent
|wparam
|optional
, SWP_NOSIZE
|SWP_NOMOVE
}, /* XP */
1533 { WM_ACTIVATEAPP
, sent
|wparam
|optional
, 1 }, /* Win9x doesn't send it */
1534 { WM_NCACTIVATE
, sent
|wparam
, 1 },
1535 { WM_GETTEXT
, sent
|defwinproc
|optional
},
1536 { WM_ACTIVATE
, sent
|wparam
, 1 },
1537 { WM_WINDOWPOSCHANGING
, sent
|wparam
|optional
, SWP_NOSIZE
|SWP_NOMOVE
}, /* Win9x */
1538 { HCBT_SETFOCUS
, hook
},
1539 { WM_IME_SETCONTEXT
, sent
|wparam
|defwinproc
|optional
, 1 },
1540 { WM_IME_NOTIFY
, sent
|wparam
|defwinproc
|optional
, 2 },
1541 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
1542 { WM_SETFOCUS
, sent
|wparam
|defwinproc
, 0 },
1543 /* Win9x adds SWP_NOZORDER below */
1544 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
1545 { WM_NCCALCSIZE
, sent
|wparam
|optional
, 1 }, /* XP */
1546 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
1547 { WM_SIZE
, sent
|wparam
, SIZE_RESTORED
},
1551 /* DestroyWindow for MDI frame window, initially visible */
1552 static const struct message WmDestroyMDIframeSeq
[] = {
1553 { HCBT_DESTROYWND
, hook
},
1554 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_HIDEWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
1555 { EVENT_OBJECT_HIDE
, winevent_hook
|wparam
|lparam
, 0, 0 },
1556 { WM_NCACTIVATE
, sent
|wparam
|optional
, 0 }, /* Win9x */
1557 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_HIDEWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
1558 { WM_NCACTIVATE
, sent
|wparam
|optional
, 0 }, /* XP */
1559 { WM_ACTIVATE
, sent
|wparam
|optional
, 0 }, /* Win9x */
1560 { WM_ACTIVATEAPP
, sent
|wparam
|optional
, 0 }, /* Win9x */
1561 { EVENT_OBJECT_HIDE
, winevent_hook
|wparam
|lparam
, OBJID_CARET
, 0 },
1562 { EVENT_OBJECT_DESTROY
, winevent_hook
|wparam
|lparam
, 0, 0 },
1563 { WM_DESTROY
, sent
},
1564 { WM_NCDESTROY
, sent
},
1567 /* CreateWindow for MDI client window, initially visible */
1568 static const struct message WmCreateMDIclientSeq
[] = {
1569 { HCBT_CREATEWND
, hook
},
1570 { WM_NCCREATE
, sent
},
1571 { WM_NCCALCSIZE
, sent
|wparam
, 0 },
1572 { EVENT_OBJECT_REORDER
, winevent_hook
|wparam
|lparam
|optional
, 0, 0 },
1573 { WM_CREATE
, sent
},
1574 { EVENT_OBJECT_REORDER
, winevent_hook
|wparam
|lparam
|optional
, 0, 0 },
1575 { EVENT_OBJECT_CREATE
, winevent_hook
|wparam
|lparam
, 0, 0 },
1576 { WM_SIZE
, sent
|wparam
, SIZE_RESTORED
},
1578 { WM_PARENTNOTIFY
, sent
|wparam
, WM_CREATE
}, /* in MDI frame */
1579 { WM_SHOWWINDOW
, sent
|wparam
, 1 },
1580 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
1581 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, 0, 0 },
1582 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
1585 /* ShowWindow(SW_SHOW) for MDI client window */
1586 static const struct message WmShowMDIclientSeq
[] = {
1587 { WM_SHOWWINDOW
, sent
|wparam
, 1 },
1588 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
1589 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, 0, 0 },
1590 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
1593 /* ShowWindow(SW_HIDE) for MDI client window */
1594 static const struct message WmHideMDIclientSeq
[] = {
1595 { WM_SHOWWINDOW
, sent
|wparam
, 0 },
1596 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_HIDEWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
1597 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
|optional
, 0, 0 }, /* win2000 */
1598 { EVENT_OBJECT_HIDE
, winevent_hook
|wparam
|lparam
|optional
, 0, 0 }, /* XP */
1599 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_HIDEWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
1602 /* DestroyWindow for MDI client window, initially visible */
1603 static const struct message WmDestroyMDIclientSeq
[] = {
1604 { HCBT_DESTROYWND
, hook
},
1605 { WM_PARENTNOTIFY
, sent
|wparam
, WM_DESTROY
}, /* in MDI frame */
1606 { WM_SHOWWINDOW
, sent
|wparam
, 0 },
1607 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_HIDEWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
1608 { EVENT_OBJECT_HIDE
, winevent_hook
|wparam
|lparam
, 0, 0 },
1609 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_HIDEWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
1610 { EVENT_OBJECT_DESTROY
, winevent_hook
|wparam
|lparam
, 0, 0 },
1611 { WM_DESTROY
, sent
},
1612 { WM_NCDESTROY
, sent
},
1615 /* CreateWindow for MDI child window, initially visible */
1616 static const struct message WmCreateMDIchildVisibleSeq
[] = {
1617 { HCBT_CREATEWND
, hook
},
1618 { WM_NCCREATE
, sent
},
1619 { WM_NCCALCSIZE
, sent
|wparam
, 0 },
1620 { WM_CREATE
, sent
},
1621 { EVENT_OBJECT_CREATE
, winevent_hook
|wparam
|lparam
, 0, 0 },
1622 { WM_SIZE
, sent
|wparam
, SIZE_RESTORED
},
1624 /* Win2k sends wparam set to
1625 * MAKEWPARAM(WM_CREATE, MDI_FIRST_CHILD_ID + nTotalCreated),
1626 * while Win9x doesn't bother to set child window id according to
1627 * CLIENTCREATESTRUCT.idFirstChild
1629 { WM_PARENTNOTIFY
, sent
/*|wparam, WM_CREATE*/ }, /* in MDI client */
1630 { WM_SHOWWINDOW
, sent
|wparam
, 1 },
1631 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
1632 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, 0, 0 },
1633 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
1634 { WM_MDIREFRESHMENU
, sent
/*|wparam|lparam, 0, 0*/ },
1635 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
},
1636 { WM_CHILDACTIVATE
, sent
|wparam
|lparam
, 0, 0 },
1637 { WM_WINDOWPOSCHANGING
, sent
|wparam
|defwinproc
, SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
1639 /* Win9x: message sequence terminates here. */
1641 { WM_NCACTIVATE
, sent
|wparam
|defwinproc
, 1 },
1642 { HCBT_SETFOCUS
, hook
}, /* in MDI client */
1643 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 1 }, /* in MDI client */
1644 { WM_IME_NOTIFY
, sent
|wparam
|optional
, 2 }, /* in MDI client */
1645 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
1646 { WM_SETFOCUS
, sent
}, /* in MDI client */
1647 { HCBT_SETFOCUS
, hook
},
1648 { WM_KILLFOCUS
, sent
}, /* in MDI client */
1649 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 0 }, /* in MDI client */
1650 { WM_IME_SETCONTEXT
, sent
|wparam
|defwinproc
|optional
, 1 },
1651 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
1652 { WM_SETFOCUS
, sent
|defwinproc
},
1653 { WM_MDIACTIVATE
, sent
|defwinproc
},
1656 /* CreateWindow for MDI child window with invisible parent */
1657 static const struct message WmCreateMDIchildInvisibleParentSeq
[] = {
1658 { HCBT_CREATEWND
, hook
},
1659 { WM_GETMINMAXINFO
, sent
},
1660 { WM_NCCREATE
, sent
},
1661 { WM_NCCALCSIZE
, sent
|wparam
, 0 },
1662 { EVENT_OBJECT_REORDER
, winevent_hook
|wparam
|lparam
|optional
, 0, 0 },
1663 { WM_CREATE
, sent
},
1664 { EVENT_OBJECT_CREATE
, winevent_hook
|wparam
|lparam
, 0, 0 },
1665 { WM_SIZE
, sent
|wparam
, SIZE_RESTORED
},
1667 { WM_PARENTNOTIFY
, sent
/*|wparam, WM_CREATE*/ }, /* in MDI client */
1668 { WM_SHOWWINDOW
, sent
|wparam
, 1 },
1669 { WM_MDIREFRESHMENU
, sent
}, /* in MDI client */
1670 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
},
1671 { WM_CHILDACTIVATE
, sent
|wparam
|lparam
, 0, 0 },
1672 { WM_WINDOWPOSCHANGING
, sent
|wparam
|defwinproc
, SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
1674 /* Win9x: message sequence terminates here. */
1676 { WM_NCACTIVATE
, sent
|wparam
|defwinproc
, 1 },
1677 { HCBT_SETFOCUS
, hook
}, /* in MDI client */
1678 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 1 }, /* in MDI client */
1679 { WM_IME_NOTIFY
, sent
|wparam
|optional
, 2 }, /* in MDI client */
1680 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
1681 { WM_SETFOCUS
, sent
}, /* in MDI client */
1682 { HCBT_SETFOCUS
, hook
},
1683 { WM_KILLFOCUS
, sent
}, /* in MDI client */
1684 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 0 }, /* in MDI client */
1685 { WM_IME_SETCONTEXT
, sent
|wparam
|defwinproc
|optional
, 1 },
1686 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
1687 { WM_SETFOCUS
, sent
|defwinproc
},
1688 { WM_MDIACTIVATE
, sent
|defwinproc
},
1691 /* DestroyWindow for MDI child window, initially visible */
1692 static const struct message WmDestroyMDIchildVisibleSeq
[] = {
1693 { HCBT_DESTROYWND
, hook
},
1694 /* Win2k sends wparam set to
1695 * MAKEWPARAM(WM_DESTROY, MDI_FIRST_CHILD_ID + nTotalCreated),
1696 * while Win9x doesn't bother to set child window id according to
1697 * CLIENTCREATESTRUCT.idFirstChild
1699 { WM_PARENTNOTIFY
, sent
/*|wparam, WM_DESTROY*/ }, /* in MDI client */
1700 { WM_SHOWWINDOW
, sent
|wparam
, 0 },
1701 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_HIDEWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
1702 { EVENT_OBJECT_HIDE
, winevent_hook
|wparam
|lparam
, 0, 0 },
1703 { WM_ERASEBKGND
, sent
|parent
|optional
},
1704 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_HIDEWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
1706 /* { WM_DESTROY, sent }
1707 * Win9x: message sequence terminates here.
1710 { HCBT_SETFOCUS
, hook
}, /* set focus to MDI client */
1711 { WM_KILLFOCUS
, sent
},
1712 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 0 },
1713 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 1 }, /* in MDI client */
1714 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
1715 { WM_SETFOCUS
, sent
}, /* in MDI client */
1717 { HCBT_SETFOCUS
, hook
}, /* MDI client sets focus back to MDI child */
1718 { WM_KILLFOCUS
, sent
}, /* in MDI client */
1719 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 0 }, /* in MDI client */
1720 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 1 },
1721 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
1722 { WM_SETFOCUS
, sent
}, /* in MDI client */
1724 { EVENT_OBJECT_DESTROY
, winevent_hook
|wparam
|lparam
, 0, 0 },
1726 { HCBT_SETFOCUS
, hook
}, /* set focus to MDI client */
1727 { WM_KILLFOCUS
, sent
},
1728 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 0 },
1729 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 1 }, /* in MDI client */
1730 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
1731 { WM_SETFOCUS
, sent
}, /* in MDI client */
1733 { HCBT_SETFOCUS
, hook
}, /* MDI client sets focus back to MDI child */
1734 { WM_KILLFOCUS
, sent
}, /* in MDI client */
1735 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 0 }, /* in MDI client */
1736 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 1 },
1737 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
1738 { WM_SETFOCUS
, sent
}, /* in MDI client */
1740 { WM_DESTROY
, sent
},
1742 { HCBT_SETFOCUS
, hook
}, /* set focus to MDI client */
1743 { WM_KILLFOCUS
, sent
},
1744 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 0 },
1745 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 1 }, /* in MDI client */
1746 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
1747 { WM_SETFOCUS
, sent
}, /* in MDI client */
1749 { HCBT_SETFOCUS
, hook
}, /* MDI client sets focus back to MDI child */
1750 { WM_KILLFOCUS
, sent
}, /* in MDI client */
1751 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 0 }, /* in MDI client */
1752 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 1 },
1753 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
1754 { WM_SETFOCUS
, sent
}, /* in MDI client */
1756 { WM_NCDESTROY
, sent
},
1759 /* CreateWindow for MDI child window, initially invisible */
1760 static const struct message WmCreateMDIchildInvisibleSeq
[] = {
1761 { HCBT_CREATEWND
, hook
},
1762 { WM_NCCREATE
, sent
},
1763 { WM_NCCALCSIZE
, sent
|wparam
, 0 },
1764 { WM_CREATE
, sent
},
1765 { EVENT_OBJECT_CREATE
, winevent_hook
|wparam
|lparam
, 0, 0 },
1766 { WM_SIZE
, sent
|wparam
, SIZE_RESTORED
},
1768 /* Win2k sends wparam set to
1769 * MAKEWPARAM(WM_CREATE, MDI_FIRST_CHILD_ID + nTotalCreated),
1770 * while Win9x doesn't bother to set child window id according to
1771 * CLIENTCREATESTRUCT.idFirstChild
1773 { WM_PARENTNOTIFY
, sent
/*|wparam, WM_CREATE*/ }, /* in MDI client */
1776 /* DestroyWindow for MDI child window, initially invisible */
1777 static const struct message WmDestroyMDIchildInvisibleSeq
[] = {
1778 { HCBT_DESTROYWND
, hook
},
1779 /* Win2k sends wparam set to
1780 * MAKEWPARAM(WM_DESTROY, MDI_FIRST_CHILD_ID + nTotalCreated),
1781 * while Win9x doesn't bother to set child window id according to
1782 * CLIENTCREATESTRUCT.idFirstChild
1784 { WM_PARENTNOTIFY
, sent
/*|wparam, WM_DESTROY*/ }, /* in MDI client */
1785 { EVENT_OBJECT_DESTROY
, winevent_hook
|wparam
|lparam
, 0, 0 },
1786 { WM_DESTROY
, sent
},
1787 { WM_NCDESTROY
, sent
},
1788 /* FIXME: Wine destroys an icon/title window while Windows doesn't */
1789 { WM_PARENTNOTIFY
, sent
|wparam
|optional
, WM_DESTROY
}, /* MDI client */
1792 /* CreateWindow for the 1st MDI child window, initially visible and maximized */
1793 static const struct message WmCreateMDIchildVisibleMaxSeq1
[] = {
1794 { HCBT_CREATEWND
, hook
},
1795 { WM_NCCREATE
, sent
},
1796 { WM_NCCALCSIZE
, sent
|wparam
, 0 },
1797 { WM_CREATE
, sent
},
1798 { EVENT_OBJECT_CREATE
, winevent_hook
|wparam
|lparam
, 0, 0 },
1799 { WM_SIZE
, sent
|wparam
, SIZE_RESTORED
},
1801 { HCBT_MINMAX
, hook
|lparam
, 0, SW_MAXIMIZE
},
1802 { WM_GETMINMAXINFO
, sent
},
1803 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|0x8000 },
1804 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
1805 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOREDRAW
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
|0x8000 },
1806 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_MAXIMIZED
},
1808 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
1809 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
1810 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
1811 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI frame */
1812 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI child */
1813 /* Win2k sends wparam set to
1814 * MAKEWPARAM(WM_CREATE, MDI_FIRST_CHILD_ID + nTotalCreated),
1815 * while Win9x doesn't bother to set child window id according to
1816 * CLIENTCREATESTRUCT.idFirstChild
1818 { WM_PARENTNOTIFY
, sent
/*|wparam, WM_CREATE*/ }, /* in MDI client */
1819 { WM_SHOWWINDOW
, sent
|wparam
, 1 },
1820 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
1821 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, 0, 0 },
1822 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
1823 { WM_MDIREFRESHMENU
, sent
/*|wparam|lparam, 0, 0*/ },
1824 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
},
1825 { WM_CHILDACTIVATE
, sent
|wparam
|lparam
, 0, 0 },
1826 { WM_WINDOWPOSCHANGING
, sent
|wparam
|defwinproc
, SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
1828 /* Win9x: message sequence terminates here. */
1830 { WM_NCACTIVATE
, sent
|wparam
|defwinproc
, 1 },
1831 { HCBT_SETFOCUS
, hook
}, /* in MDI client */
1832 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 1 }, /* in MDI client */
1833 { WM_IME_NOTIFY
, sent
|wparam
|optional
, 2 }, /* in MDI client */
1834 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
1835 { WM_SETFOCUS
, sent
}, /* in MDI client */
1836 { HCBT_SETFOCUS
, hook
},
1837 { WM_KILLFOCUS
, sent
}, /* in MDI client */
1838 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 0 }, /* in MDI client */
1839 { WM_IME_SETCONTEXT
, sent
|wparam
|defwinproc
|optional
, 1 },
1840 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
1841 { WM_SETFOCUS
, sent
|defwinproc
},
1842 { WM_MDIACTIVATE
, sent
|defwinproc
},
1844 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
1845 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
1846 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
1847 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI frame */
1850 /* CreateWindow for the 2nd MDI child window, initially visible and maximized */
1851 static const struct message WmCreateMDIchildVisibleMaxSeq2
[] = {
1852 /* restore the 1st MDI child */
1853 { WM_SETREDRAW
, sent
|wparam
, 0 },
1854 { HCBT_MINMAX
, hook
|lparam
, 0, SW_SHOWNORMAL
},
1855 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|0x8000 },
1856 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
1857 { WM_CHILDACTIVATE
, sent
|wparam
|lparam
, 0, 0 },
1858 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOREDRAW
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
|0x8000 },
1859 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_RESTORED
},
1861 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
1862 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
1863 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
1864 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI frame */
1865 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI child */
1866 { WM_SETREDRAW
, sent
|wparam
, 1 }, /* in the 1st MDI child */
1867 /* create the 2nd MDI child */
1868 { HCBT_CREATEWND
, hook
},
1869 { WM_NCCREATE
, sent
},
1870 { WM_NCCALCSIZE
, sent
|wparam
, 0 },
1871 { WM_CREATE
, sent
},
1872 { EVENT_OBJECT_CREATE
, winevent_hook
|wparam
|lparam
, 0, 0 },
1873 { WM_SIZE
, sent
|wparam
, SIZE_RESTORED
},
1875 { HCBT_MINMAX
, hook
|lparam
, 0, SW_MAXIMIZE
},
1876 { WM_GETMINMAXINFO
, sent
},
1877 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|0x8000 },
1878 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
1879 { EVENT_OBJECT_REORDER
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
1880 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOREDRAW
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
|0x8000 },
1881 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_MAXIMIZED
},
1883 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
1884 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
1885 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
1886 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI frame */
1887 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI child */
1888 /* Win2k sends wparam set to
1889 * MAKEWPARAM(WM_CREATE, MDI_FIRST_CHILD_ID + nTotalCreated),
1890 * while Win9x doesn't bother to set child window id according to
1891 * CLIENTCREATESTRUCT.idFirstChild
1893 { WM_PARENTNOTIFY
, sent
/*|wparam, WM_CREATE*/ }, /* in MDI client */
1894 { WM_SHOWWINDOW
, sent
|wparam
, 1 },
1895 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
1896 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, 0, 0 },
1897 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
1898 { WM_MDIREFRESHMENU
, sent
/*|wparam|lparam, 0, 0*/ },
1899 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
},
1900 { WM_CHILDACTIVATE
, sent
|wparam
|lparam
, 0, 0 },
1902 { WM_NCACTIVATE
, sent
|wparam
|defwinproc
, 0 }, /* in the 1st MDI child */
1903 { WM_MDIACTIVATE
, sent
|defwinproc
}, /* in the 1st MDI child */
1905 { WM_WINDOWPOSCHANGING
, sent
|wparam
|defwinproc
, SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
1907 /* Win9x: message sequence terminates here. */
1909 { WM_NCACTIVATE
, sent
|wparam
|defwinproc
, 1 },
1910 { HCBT_SETFOCUS
, hook
},
1911 { WM_KILLFOCUS
, sent
|defwinproc
}, /* in the 1st MDI child */
1912 { WM_IME_SETCONTEXT
, sent
|wparam
|defwinproc
|optional
, 0 }, /* in the 1st MDI child */
1913 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 1 }, /* in MDI client */
1914 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
1915 { WM_SETFOCUS
, sent
}, /* in MDI client */
1916 { HCBT_SETFOCUS
, hook
},
1917 { WM_KILLFOCUS
, sent
}, /* in MDI client */
1918 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 0 }, /* in MDI client */
1919 { WM_IME_SETCONTEXT
, sent
|wparam
|defwinproc
|optional
, 1 },
1920 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
1921 { WM_SETFOCUS
, sent
|defwinproc
},
1923 { WM_MDIACTIVATE
, sent
|defwinproc
},
1925 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
1926 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
1927 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
1928 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI frame */
1931 /* WM_MDICREATE MDI child window, initially visible and maximized */
1932 static const struct message WmCreateMDIchildVisibleMaxSeq3
[] = {
1933 { WM_MDICREATE
, sent
},
1934 { HCBT_CREATEWND
, hook
},
1935 { WM_NCCREATE
, sent
},
1936 { WM_NCCALCSIZE
, sent
|wparam
, 0 },
1937 { WM_CREATE
, sent
},
1938 { EVENT_OBJECT_CREATE
, winevent_hook
|wparam
|lparam
, 0, 0 },
1939 { WM_SIZE
, sent
|wparam
, SIZE_RESTORED
},
1941 { HCBT_MINMAX
, hook
|lparam
, 0, SW_MAXIMIZE
},
1942 { WM_GETMINMAXINFO
, sent
},
1943 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|0x8000 },
1944 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
1945 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOREDRAW
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
|0x8000 },
1946 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_MAXIMIZED
},
1949 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
1950 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
1951 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
1952 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI frame */
1953 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI child */
1955 /* Win2k sends wparam set to
1956 * MAKEWPARAM(WM_CREATE, MDI_FIRST_CHILD_ID + nTotalCreated),
1957 * while Win9x doesn't bother to set child window id according to
1958 * CLIENTCREATESTRUCT.idFirstChild
1960 { WM_PARENTNOTIFY
, sent
/*|wparam, WM_CREATE*/ }, /* in MDI client */
1961 { WM_SHOWWINDOW
, sent
|wparam
, 1 },
1962 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
1964 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, 0, 0 },
1966 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
1967 { WM_MDIREFRESHMENU
, sent
/*|wparam|lparam, 0, 0*/ },
1968 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
},
1970 { WM_CHILDACTIVATE
, sent
|wparam
|lparam
, 0, 0 },
1971 { WM_WINDOWPOSCHANGING
, sent
|wparam
|defwinproc
, SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
1973 /* Win9x: message sequence terminates here. */
1975 { WM_NCACTIVATE
, sent
|wparam
|defwinproc
, 1 },
1976 { WM_SETFOCUS
, sent
|optional
}, /* in MDI client */
1977 { HCBT_SETFOCUS
, hook
}, /* in MDI client */
1978 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 1 }, /* in MDI client */
1979 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
|optional
, OBJID_CLIENT
, 0 },
1980 { WM_SETFOCUS
, sent
|optional
}, /* in MDI client */
1981 { HCBT_SETFOCUS
, hook
|optional
},
1982 { WM_KILLFOCUS
, sent
}, /* in MDI client */
1983 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 0 }, /* in MDI client */
1984 { WM_IME_SETCONTEXT
, sent
|wparam
|defwinproc
|optional
, 1 },
1985 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
1986 { WM_SETFOCUS
, sent
|defwinproc
},
1988 { WM_MDIACTIVATE
, sent
|defwinproc
},
1991 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
1992 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
1993 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
1994 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
1997 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
1998 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
1999 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
2000 { WM_MOVE
, sent
|defwinproc
},
2001 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_RESTORED
},
2004 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_NOACTIVATE
},
2005 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
2006 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_NOACTIVATE
|SWP_NOMOVE
|SWP_NOCLIENTMOVE
},
2007 { WM_SIZE
, sent
|wparam
, SIZE_RESTORED
},
2010 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_NOACTIVATE
},
2011 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
2012 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_NOACTIVATE
|SWP_NOMOVE
|SWP_NOCLIENTMOVE
},
2013 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_MAXIMIZED
},
2015 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI child */
2016 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI client */
2017 { WM_NCCALCSIZE
, sent
|wparam
|optional
, 1 }, /* XP sends it to MDI frame */
2018 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI frame */
2019 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* XP sends a duplicate */
2023 /* CreateWindow for the 1st MDI child window, initially invisible and maximized */
2024 static const struct message WmCreateMDIchildInvisibleMaxSeq4
[] = {
2025 { HCBT_CREATEWND
, hook
},
2026 { WM_GETMINMAXINFO
, sent
},
2027 { WM_NCCREATE
, sent
},
2028 { WM_NCCALCSIZE
, sent
|wparam
, 0 },
2029 { EVENT_OBJECT_REORDER
, winevent_hook
|wparam
|lparam
, 0, 0 },
2030 { WM_CREATE
, sent
},
2031 { EVENT_OBJECT_CREATE
, winevent_hook
|wparam
|lparam
, 0, 0 },
2032 { WM_SIZE
, sent
|wparam
, SIZE_RESTORED
},
2034 { HCBT_MINMAX
, hook
|lparam
, 0, SW_MAXIMIZE
},
2035 { WM_GETMINMAXINFO
, sent
},
2036 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|0x8000 },
2037 { WM_GETMINMAXINFO
, sent
|defwinproc
},
2038 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
2039 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOREDRAW
|SWP_NOCLIENTSIZE
|0x8000 },
2040 { WM_MOVE
, sent
|defwinproc
},
2041 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_MAXIMIZED
},
2043 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
2044 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
2045 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
2046 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI frame */
2047 { WM_NCCALCSIZE
, sent
|wparam
|optional
, 1 }, /* MDI child */
2048 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI child */
2049 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI child */
2050 /* Win2k sends wparam set to
2051 * MAKEWPARAM(WM_CREATE, MDI_FIRST_CHILD_ID + nTotalCreated),
2052 * while Win9x doesn't bother to set child window id according to
2053 * CLIENTCREATESTRUCT.idFirstChild
2055 { WM_PARENTNOTIFY
, sent
/*|wparam, WM_CREATE*/ }, /* in MDI client */
2058 /* WM_SYSCOMMAND/SC_CLOSE for the 2nd MDI child window, initially visible and maximized */
2059 static const struct message WmDestroyMDIchildVisibleMaxSeq2
[] = {
2060 { WM_SYSCOMMAND
, sent
|wparam
, SC_CLOSE
},
2061 { HCBT_SYSCOMMAND
, hook
},
2062 { WM_CLOSE
, sent
|defwinproc
},
2063 { WM_MDIDESTROY
, sent
}, /* in MDI client */
2065 /* bring the 1st MDI child to top */
2066 { WM_WINDOWPOSCHANGING
, sent
|wparam
|defwinproc
, SWP_NOSIZE
|SWP_NOMOVE
}, /* in the 1st MDI child */
2067 { WM_WINDOWPOSCHANGING
, sent
|wparam
|defwinproc
, SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
}, /* in the 2nd MDI child */
2069 { EVENT_OBJECT_REORDER
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
2071 { WM_CHILDACTIVATE
, sent
|defwinproc
|wparam
|lparam
, 0, 0 }, /* in the 1st MDI child */
2072 { WM_NCACTIVATE
, sent
|wparam
|defwinproc
, 0 }, /* in the 1st MDI child */
2073 { WM_MDIACTIVATE
, sent
|defwinproc
}, /* in the 1st MDI child */
2075 /* maximize the 1st MDI child */
2076 { HCBT_MINMAX
, hook
|lparam
, 0, SW_MAXIMIZE
},
2077 { WM_GETMINMAXINFO
, sent
|defwinproc
},
2078 { WM_WINDOWPOSCHANGING
, sent
|wparam
|defwinproc
, SWP_FRAMECHANGED
|0x8000 },
2079 { WM_NCCALCSIZE
, sent
|defwinproc
|wparam
, 1 },
2080 { WM_CHILDACTIVATE
, sent
|defwinproc
|wparam
|lparam
, 0, 0 },
2081 { WM_WINDOWPOSCHANGED
, sent
|wparam
|defwinproc
, SWP_FRAMECHANGED
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOREDRAW
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
|0x8000 },
2082 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_MAXIMIZED
},
2084 /* restore the 2nd MDI child */
2085 { WM_SETREDRAW
, sent
|defwinproc
|wparam
, 0 },
2086 { HCBT_MINMAX
, hook
|lparam
, 0, SW_NORMALNA
},
2087 { WM_WINDOWPOSCHANGING
, sent
|wparam
|defwinproc
, SWP_NOACTIVATE
|SWP_FRAMECHANGED
|SWP_SHOWWINDOW
|0x8000 },
2088 { WM_NCCALCSIZE
, sent
|defwinproc
|wparam
, 1 },
2090 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, 0, 0 },
2092 { WM_WINDOWPOSCHANGED
, sent
|wparam
|defwinproc
, SWP_NOACTIVATE
|SWP_FRAMECHANGED
|SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOREDRAW
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
|0x8000 },
2093 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_RESTORED
},
2095 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI frame */
2097 { WM_SETREDRAW
, sent
|defwinproc
|wparam
, 1 },
2099 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
2100 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
2101 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
2102 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI frame */
2103 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI child */
2105 /* bring the 1st MDI child to top */
2106 { WM_WINDOWPOSCHANGING
, sent
|wparam
|defwinproc
, SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
2107 { WM_NCACTIVATE
, sent
|wparam
|defwinproc
, 1 },
2108 { HCBT_SETFOCUS
, hook
},
2109 { WM_KILLFOCUS
, sent
|defwinproc
},
2110 { WM_IME_SETCONTEXT
, sent
|wparam
|defwinproc
|optional
, 0 },
2111 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 1 }, /* in MDI client */
2112 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
2113 { WM_SETFOCUS
, sent
}, /* in MDI client */
2114 { HCBT_SETFOCUS
, hook
},
2115 { WM_KILLFOCUS
, sent
}, /* in MDI client */
2116 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 0 }, /* in MDI client */
2117 { WM_IME_SETCONTEXT
, sent
|wparam
|defwinproc
|optional
, 1 },
2118 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
2119 { WM_SETFOCUS
, sent
|defwinproc
},
2120 { WM_MDIACTIVATE
, sent
|defwinproc
},
2121 { WM_WINDOWPOSCHANGED
, sent
|wparam
|defwinproc
, SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOREDRAW
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
2123 /* apparently ShowWindow(SW_SHOW) on an MDI client */
2124 { WM_SHOWWINDOW
, sent
|wparam
, 1 },
2125 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
2126 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, 0, 0 },
2127 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
2128 { WM_MDIREFRESHMENU
, sent
},
2130 { HCBT_DESTROYWND
, hook
},
2131 /* Win2k sends wparam set to
2132 * MAKEWPARAM(WM_DESTROY, MDI_FIRST_CHILD_ID + nTotalCreated),
2133 * while Win9x doesn't bother to set child window id according to
2134 * CLIENTCREATESTRUCT.idFirstChild
2136 { WM_PARENTNOTIFY
, sent
/*|wparam, WM_DESTROY*/ }, /* in MDI client */
2137 { WM_SHOWWINDOW
, sent
|defwinproc
|wparam
, 0 },
2138 { WM_WINDOWPOSCHANGING
, sent
|wparam
|defwinproc
, SWP_HIDEWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
2139 { EVENT_OBJECT_HIDE
, winevent_hook
|wparam
|lparam
, 0, 0 },
2140 { WM_ERASEBKGND
, sent
|parent
|optional
},
2141 { WM_WINDOWPOSCHANGED
, sent
|wparam
|defwinproc
, SWP_HIDEWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
2143 { EVENT_OBJECT_DESTROY
, winevent_hook
|wparam
|lparam
, 0, 0 },
2144 { WM_DESTROY
, sent
|defwinproc
},
2145 { WM_NCDESTROY
, sent
|defwinproc
},
2148 /* WM_MDIDESTROY for the single MDI child window, initially visible and maximized */
2149 static const struct message WmDestroyMDIchildVisibleMaxSeq1
[] = {
2150 { WM_MDIDESTROY
, sent
}, /* in MDI client */
2151 { WM_SHOWWINDOW
, sent
|wparam
, 0 },
2152 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_HIDEWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
2153 { EVENT_OBJECT_HIDE
, winevent_hook
|wparam
|lparam
, 0, 0 },
2154 { WM_ERASEBKGND
, sent
|parent
|optional
},
2155 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_HIDEWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
2157 { HCBT_SETFOCUS
, hook
},
2158 { WM_KILLFOCUS
, sent
},
2159 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 0 },
2160 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 1 }, /* in MDI client */
2161 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
2162 { WM_SETFOCUS
, sent
}, /* in MDI client */
2163 { HCBT_SETFOCUS
, hook
},
2164 { WM_KILLFOCUS
, sent
}, /* in MDI client */
2165 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 0 }, /* in MDI client */
2166 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 1 },
2167 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
2168 { WM_SETFOCUS
, sent
},
2171 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
2172 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
2173 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOREDRAW
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
2174 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI child */
2177 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
2178 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
2179 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
2180 { WM_MOVE
, sent
|defwinproc
},
2181 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_RESTORED
},
2184 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_NOACTIVATE
},
2185 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
2186 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_NOACTIVATE
|SWP_NOMOVE
|SWP_NOCLIENTMOVE
},
2187 { WM_SIZE
, sent
|wparam
, SIZE_RESTORED
},
2190 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_NOACTIVATE
},
2191 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
2192 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_NOACTIVATE
|SWP_NOMOVE
|SWP_NOREDRAW
|SWP_NOCLIENTMOVE
},
2193 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_MAXIMIZED
},
2196 { WM_WINDOWPOSCHANGING
, sent
|wparam
|defwinproc
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
2197 { WM_NCCALCSIZE
, sent
|wparam
|defwinproc
, 1 },
2198 { WM_WINDOWPOSCHANGED
, sent
|wparam
|defwinproc
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOREDRAW
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
2199 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI child */
2202 { WM_WINDOWPOSCHANGING
, sent
|wparam
|defwinproc
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
2203 { WM_NCCALCSIZE
, sent
|wparam
|defwinproc
, 1 },
2204 { WM_WINDOWPOSCHANGED
, sent
|wparam
|defwinproc
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
2205 { WM_MOVE
, sent
|defwinproc
},
2206 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_RESTORED
},
2209 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_NOACTIVATE
},
2210 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
2211 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_NOACTIVATE
|SWP_NOMOVE
|SWP_NOCLIENTMOVE
},
2212 { WM_SIZE
, sent
|wparam
, SIZE_RESTORED
},
2215 { WM_WINDOWPOSCHANGING
, sent
|wparam
|defwinproc
, SWP_NOACTIVATE
},
2216 { WM_NCCALCSIZE
, sent
|wparam
|defwinproc
, 1 },
2217 { WM_WINDOWPOSCHANGED
, sent
|wparam
|defwinproc
, SWP_NOACTIVATE
|SWP_NOMOVE
|SWP_NOREDRAW
|SWP_NOCLIENTMOVE
},
2218 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_MAXIMIZED
},
2219 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI child */
2220 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI client */
2222 { WM_NCCALCSIZE
, sent
|wparam
|defwinproc
|optional
, 1 }, /* XP sends it to MDI frame */
2224 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI frame */
2225 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI child */
2226 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI client */
2227 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI frame */
2228 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* XP sends a duplicate */
2231 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
2232 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
2233 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
2234 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI frame */
2236 { WM_NCACTIVATE
, sent
|wparam
, 0 },
2237 { WM_MDIACTIVATE
, sent
},
2239 { HCBT_MINMAX
, hook
|lparam
, 0, SW_SHOWNORMAL
},
2240 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_SHOWWINDOW
|0x8000 },
2241 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
2243 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, 0, 0 },
2245 { WM_CHILDACTIVATE
, sent
|wparam
|lparam
, 0, 0 },
2246 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_SHOWWINDOW
|SWP_NOMOVE
|SWP_NOCLIENTMOVE
|0x8000 },
2247 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_RESTORED
},
2250 { WM_WINDOWPOSCHANGING
, sent
|wparam
|defwinproc
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
2251 { WM_NCCALCSIZE
, sent
|wparam
|defwinproc
, 1 },
2252 { WM_WINDOWPOSCHANGED
, sent
|wparam
|defwinproc
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
2253 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI child */
2256 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
2257 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
2258 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
2259 { WM_MOVE
, sent
|defwinproc
},
2260 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_RESTORED
},
2263 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_NOACTIVATE
},
2264 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
2265 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_NOACTIVATE
|SWP_NOMOVE
|SWP_NOCLIENTMOVE
},
2266 { WM_SIZE
, sent
|wparam
, SIZE_RESTORED
},
2267 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI child */
2268 { WM_NCCALCSIZE
, sent
|wparam
|optional
, 1 }, /* XP */
2269 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI client */
2270 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI frame */
2271 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* XP sends a duplicate */
2273 { HCBT_SETFOCUS
, hook
},
2274 { WM_KILLFOCUS
, sent
},
2275 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 0 },
2276 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 1 }, /* in MDI client */
2277 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
2278 { WM_SETFOCUS
, sent
}, /* in MDI client */
2280 { WM_MDIREFRESHMENU
, sent
}, /* in MDI client */
2282 { HCBT_DESTROYWND
, hook
},
2283 /* Win2k sends wparam set to
2284 * MAKEWPARAM(WM_DESTROY, MDI_FIRST_CHILD_ID + nTotalCreated),
2285 * while Win9x doesn't bother to set child window id according to
2286 * CLIENTCREATESTRUCT.idFirstChild
2288 { WM_PARENTNOTIFY
, sent
/*|wparam, WM_DESTROY*/ }, /* in MDI client */
2290 { WM_SHOWWINDOW
, sent
|wparam
, 0 },
2291 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_HIDEWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
2292 { EVENT_OBJECT_HIDE
, winevent_hook
|wparam
|lparam
, 0, 0 },
2293 { WM_ERASEBKGND
, sent
|parent
|optional
},
2294 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_HIDEWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
2296 { EVENT_OBJECT_DESTROY
, winevent_hook
|wparam
|lparam
, 0, 0 },
2297 { WM_DESTROY
, sent
},
2298 { WM_NCDESTROY
, sent
},
2301 /* ShowWindow(SW_MAXIMIZE) for a not visible MDI child window */
2302 static const struct message WmMaximizeMDIchildInvisibleSeq
[] = {
2303 { HCBT_MINMAX
, hook
|lparam
, 0, SW_MAXIMIZE
},
2304 { WM_GETMINMAXINFO
, sent
},
2305 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_FRAMECHANGED
|0x8000 },
2306 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
2307 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, 0, 0 },
2308 { WM_CHILDACTIVATE
, sent
|wparam
|lparam
, 0, 0 },
2310 { WM_WINDOWPOSCHANGING
, sent
|wparam
|defwinproc
, SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
2311 { WM_NCACTIVATE
, sent
|wparam
|defwinproc
, 1 },
2312 { HCBT_SETFOCUS
, hook
},
2313 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 1 }, /* in MDI client */
2314 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
2315 { WM_SETFOCUS
, sent
}, /* in MDI client */
2316 { HCBT_SETFOCUS
, hook
},
2317 { WM_KILLFOCUS
, sent
}, /* in MDI client */
2318 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 0 }, /* in MDI client */
2319 { WM_IME_SETCONTEXT
, sent
|wparam
|defwinproc
|optional
, 1 },
2320 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
2321 { WM_SETFOCUS
, sent
|defwinproc
},
2322 { WM_MDIACTIVATE
, sent
|defwinproc
},
2323 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_FRAMECHANGED
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
|0x8000 },
2324 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_MAXIMIZED
},
2326 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
2327 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
2328 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
2329 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI frame */
2330 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI child */
2333 /* ShowWindow(SW_MAXIMIZE) for a not visible maximized MDI child window */
2334 static const struct message WmMaximizeMDIchildInvisibleSeq2
[] = {
2335 { HCBT_MINMAX
, hook
|lparam
, 0, SW_MAXIMIZE
},
2336 { WM_GETMINMAXINFO
, sent
},
2337 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_FRAMECHANGED
},
2338 { WM_GETMINMAXINFO
, sent
|defwinproc
},
2339 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
2340 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, 0, 0 },
2341 { WM_CHILDACTIVATE
, sent
|wparam
|lparam
, 0, 0 },
2343 { WM_WINDOWPOSCHANGING
, sent
|wparam
|defwinproc
, SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
2344 { WM_NCACTIVATE
, sent
|wparam
|defwinproc
, 1 },
2345 { HCBT_SETFOCUS
, hook
},
2346 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 1 }, /* in MDI client */
2347 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
2348 { WM_SETFOCUS
, sent
}, /* in MDI client */
2349 { HCBT_SETFOCUS
, hook
},
2350 { WM_KILLFOCUS
, sent
}, /* in MDI client */
2351 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 0 }, /* in MDI client */
2352 { WM_IME_SETCONTEXT
, sent
|wparam
|defwinproc
|optional
, 1 },
2353 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
2354 { WM_SETFOCUS
, sent
|defwinproc
},
2355 { WM_MDIACTIVATE
, sent
|defwinproc
},
2356 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_FRAMECHANGED
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
2357 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI child */
2360 /* WM_MDIMAXIMIZE for an MDI child window with invisible parent */
2361 static const struct message WmMaximizeMDIchildInvisibleParentSeq
[] = {
2362 { WM_MDIMAXIMIZE
, sent
}, /* in MDI client */
2363 { HCBT_MINMAX
, hook
|lparam
, 0, SW_MAXIMIZE
},
2364 { WM_GETMINMAXINFO
, sent
},
2365 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|0x8000 },
2366 { WM_GETMINMAXINFO
, sent
|defwinproc
},
2367 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
2368 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
|optional
, 0, 0 }, /* XP doesn't send it */
2369 { WM_CHILDACTIVATE
, sent
|wparam
|lparam
, 0, 0 },
2370 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOREDRAW
|0x8000 },
2371 { WM_MOVE
, sent
|defwinproc
},
2372 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_MAXIMIZED
},
2374 { WM_WINDOWPOSCHANGING
, sent
|wparam
|defwinproc
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
2375 { WM_NCCALCSIZE
, sent
|wparam
|defwinproc
, 1 },
2376 { WM_WINDOWPOSCHANGED
, sent
|wparam
|defwinproc
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOREDRAW
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
2377 { WM_NCCALCSIZE
, sent
|wparam
|defwinproc
|optional
, 1 },
2378 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
|optional
, 0, 0 }, /* MDI child XP */
2379 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
|optional
, 0, 0 }, /* MDI client XP */
2381 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
2382 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
2383 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
2384 { WM_MOVE
, sent
|defwinproc
},
2385 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_RESTORED
},
2386 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
|optional
, 0, 0 }, /* MDI frame win2000 */
2388 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_NOACTIVATE
},
2389 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
2390 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_NOACTIVATE
|SWP_NOMOVE
|SWP_NOREDRAW
|SWP_NOCLIENTMOVE
},
2391 { WM_SIZE
, sent
|wparam
, SIZE_RESTORED
},
2393 { WM_WINDOWPOSCHANGING
, sent
|wparam
|defwinproc
, SWP_NOACTIVATE
},
2394 { WM_GETMINMAXINFO
, sent
|defwinproc
},
2395 { WM_NCCALCSIZE
, sent
|wparam
|defwinproc
, 1 },
2396 { WM_WINDOWPOSCHANGED
, sent
|wparam
|defwinproc
, SWP_NOACTIVATE
|SWP_NOMOVE
|SWP_NOREDRAW
|SWP_NOCLIENTMOVE
},
2397 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_MAXIMIZED
},
2398 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
|optional
, 0, 0 }, /* MDI child win2000 */
2399 { WM_NCCALCSIZE
, sent
|wparam
|defwinproc
|optional
, 1 },
2400 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
|optional
, 0, 0 }, /* MDI child XP */
2401 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
|optional
, 0, 0 }, /* MDI child XP */
2402 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
|optional
, 0, 0 }, /* MDI client XP */
2404 { WM_NCCALCSIZE
, sent
|wparam
|optional
, 1 },
2405 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
|optional
, 0, 0 }, /* MDI frame XP */
2406 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
|optional
, 0, 0 }, /* MDI frame XP */
2407 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
|optional
, 0, 0 }, /* MDI child XP */
2410 /* ShowWindow(SW_MAXIMIZE) for a visible MDI child window */
2411 static const struct message WmMaximizeMDIchildVisibleSeq
[] = {
2412 { HCBT_MINMAX
, hook
|lparam
, 0, SW_MAXIMIZE
},
2413 { WM_GETMINMAXINFO
, sent
},
2414 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|0x8000 },
2415 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
2416 { WM_CHILDACTIVATE
, sent
|wparam
|lparam
, 0, 0 },
2417 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
|0x8000 },
2418 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_MAXIMIZED
},
2420 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
2421 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
2422 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
2423 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI frame */
2424 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI child */
2427 /* ShowWindow(SW_RESTORE) for a visible maximized MDI child window */
2428 static const struct message WmRestoreMDIchildVisibleSeq
[] = {
2429 { HCBT_MINMAX
, hook
|lparam
, 0, SW_RESTORE
},
2430 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|0x8000 },
2431 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
2432 { WM_CHILDACTIVATE
, sent
|wparam
|lparam
, 0, 0 },
2433 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
|0x8000 },
2434 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_RESTORED
},
2436 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
2437 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
2438 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
2439 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI frame */
2440 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI child */
2443 /* ShowWindow(SW_RESTORE) for a visible minimized MDI child window */
2444 static const struct message WmRestoreMDIchildVisibleSeq_2
[] = {
2445 { HCBT_MINMAX
, hook
|lparam
, 0, SW_RESTORE
},
2446 { WM_QUERYOPEN
, sent
|wparam
|lparam
, 0, 0 },
2447 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOCOPYBITS
|0x8000 },
2448 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
2449 { WM_CHILDACTIVATE
, sent
|wparam
|lparam
, 0, 0 },
2450 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOCOPYBITS
|SWP_NOCLIENTSIZE
|0x8000 },
2451 { WM_MOVE
, sent
|defwinproc
},
2452 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_RESTORED
},
2453 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI child */
2454 { EVENT_SYSTEM_MINIMIZEEND
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI child */
2455 { HCBT_SETFOCUS
, hook
},
2456 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 1 },
2457 { WM_IME_NOTIFY
, sent
|wparam
|defwinproc
|optional
, 2 },
2458 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
2459 { WM_SETFOCUS
, sent
},
2462 /* ShowWindow(SW_MINIMIZE) for a visible restored MDI child window */
2463 static const struct message WmMinimizeMDIchildVisibleSeq
[] = {
2464 { HCBT_MINMAX
, hook
|lparam
, 0, SW_MINIMIZE
},
2465 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOCOPYBITS
|0x8000 },
2466 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
2467 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOCOPYBITS
|SWP_NOCLIENTSIZE
|0x8000 },
2468 { WM_MOVE
, sent
|defwinproc
},
2469 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_MINIMIZED
},
2470 { WM_CHILDACTIVATE
, sent
|wparam
|lparam
|defwinproc
, 0, 0 },
2471 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI child */
2472 { EVENT_SYSTEM_MINIMIZESTART
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI child */
2473 /* FIXME: Wine creates an icon/title window while Windows doesn't */
2474 { WM_PARENTNOTIFY
, sent
|parent
|wparam
|optional
, WM_CREATE
}, /* MDI client */
2477 /* ShowWindow(SW_RESTORE) for a not visible MDI child window */
2478 static const struct message WmRestoreMDIchildInisibleSeq
[] = {
2479 { HCBT_MINMAX
, hook
|lparam
, 0, SW_RESTORE
},
2480 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_FRAMECHANGED
|0x8000 },
2481 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
2482 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, 0, 0 },
2483 { WM_CHILDACTIVATE
, sent
|wparam
|lparam
, 0, 0 },
2484 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_FRAMECHANGED
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
|0x8000 },
2485 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_RESTORED
},
2487 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
2488 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
2489 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
2490 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI frame */
2491 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI child */
2495 static HWND mdi_client
;
2496 static WNDPROC old_mdi_client_proc
;
2498 static LRESULT WINAPI
mdi_client_hook_proc(HWND hwnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
2502 /* do not log painting messages */
2503 if (message
!= WM_PAINT
&&
2504 message
!= WM_NCPAINT
&&
2505 message
!= WM_SYNCPAINT
&&
2506 message
!= WM_ERASEBKGND
&&
2507 message
!= WM_NCPAINT
&&
2508 message
!= WM_NCHITTEST
&&
2509 message
!= WM_GETTEXT
&&
2510 message
!= WM_MDIGETACTIVE
&&
2511 message
!= WM_GETICON
&&
2512 message
!= WM_DEVICECHANGE
)
2514 trace("mdi client: %p, %04x, %08lx, %08lx\n", hwnd
, message
, wParam
, lParam
);
2518 case WM_WINDOWPOSCHANGING
:
2519 case WM_WINDOWPOSCHANGED
:
2521 WINDOWPOS
*winpos
= (WINDOWPOS
*)lParam
;
2523 trace("%s\n", (message
== WM_WINDOWPOSCHANGING
) ? "WM_WINDOWPOSCHANGING" : "WM_WINDOWPOSCHANGED");
2524 trace("%p after %p, x %d, y %d, cx %d, cy %d flags %08x\n",
2525 winpos
->hwnd
, winpos
->hwndInsertAfter
,
2526 winpos
->x
, winpos
->y
, winpos
->cx
, winpos
->cy
, winpos
->flags
);
2527 dump_winpos_flags(winpos
->flags
);
2529 /* Log only documented flags, win2k uses 0x1000 and 0x2000
2530 * in the high word for internal purposes
2532 wParam
= winpos
->flags
& 0xffff;
2533 /* We are not interested in the flags that don't match under XP and Win9x */
2534 wParam
&= ~(SWP_NOZORDER
);
2539 msg
.message
= message
;
2540 msg
.flags
= sent
|wparam
|lparam
;
2541 msg
.wParam
= wParam
;
2542 msg
.lParam
= lParam
;
2546 return CallWindowProcA(old_mdi_client_proc
, hwnd
, message
, wParam
, lParam
);
2549 static LRESULT WINAPI
mdi_child_wnd_proc(HWND hwnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
2551 static long defwndproc_counter
= 0;
2555 /* do not log painting messages */
2556 if (message
!= WM_PAINT
&&
2557 message
!= WM_NCPAINT
&&
2558 message
!= WM_SYNCPAINT
&&
2559 message
!= WM_ERASEBKGND
&&
2560 message
!= WM_NCPAINT
&&
2561 message
!= WM_NCHITTEST
&&
2562 message
!= WM_GETTEXT
&&
2563 message
!= WM_GETICON
&&
2564 message
!= WM_DEVICECHANGE
)
2566 trace("mdi child: %p, %04x, %08lx, %08lx\n", hwnd
, message
, wParam
, lParam
);
2570 case WM_WINDOWPOSCHANGING
:
2571 case WM_WINDOWPOSCHANGED
:
2573 WINDOWPOS
*winpos
= (WINDOWPOS
*)lParam
;
2575 trace("%s\n", (message
== WM_WINDOWPOSCHANGING
) ? "WM_WINDOWPOSCHANGING" : "WM_WINDOWPOSCHANGED");
2576 trace("%p after %p, x %d, y %d, cx %d, cy %d flags %08x\n",
2577 winpos
->hwnd
, winpos
->hwndInsertAfter
,
2578 winpos
->x
, winpos
->y
, winpos
->cx
, winpos
->cy
, winpos
->flags
);
2579 dump_winpos_flags(winpos
->flags
);
2581 /* Log only documented flags, win2k uses 0x1000 and 0x2000
2582 * in the high word for internal purposes
2584 wParam
= winpos
->flags
& 0xffff;
2585 /* We are not interested in the flags that don't match under XP and Win9x */
2586 wParam
&= ~(SWP_NOZORDER
);
2590 case WM_MDIACTIVATE
:
2592 HWND active
, client
= GetParent(hwnd
);
2594 active
= (HWND
)SendMessageA(client
, WM_MDIGETACTIVE
, 0, 0);
2596 if (hwnd
== (HWND
)lParam
) /* if we are being activated */
2597 ok (active
== (HWND
)lParam
, "new active %p != active %p\n", (HWND
)lParam
, active
);
2599 ok (active
== (HWND
)wParam
, "old active %p != active %p\n", (HWND
)wParam
, active
);
2604 msg
.message
= message
;
2605 msg
.flags
= sent
|wparam
|lparam
;
2606 if (defwndproc_counter
) msg
.flags
|= defwinproc
;
2607 msg
.wParam
= wParam
;
2608 msg
.lParam
= lParam
;
2612 defwndproc_counter
++;
2613 ret
= DefMDIChildProcA(hwnd
, message
, wParam
, lParam
);
2614 defwndproc_counter
--;
2619 static LRESULT WINAPI
mdi_frame_wnd_proc(HWND hwnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
2621 static long defwndproc_counter
= 0;
2625 /* do not log painting messages */
2626 if (message
!= WM_PAINT
&&
2627 message
!= WM_NCPAINT
&&
2628 message
!= WM_SYNCPAINT
&&
2629 message
!= WM_ERASEBKGND
&&
2630 message
!= WM_NCPAINT
&&
2631 message
!= WM_NCHITTEST
&&
2632 message
!= WM_GETTEXT
&&
2633 message
!= WM_GETICON
&&
2634 message
!= WM_DEVICECHANGE
)
2636 trace("mdi frame: %p, %04x, %08lx, %08lx\n", hwnd
, message
, wParam
, lParam
);
2640 case WM_WINDOWPOSCHANGING
:
2641 case WM_WINDOWPOSCHANGED
:
2643 WINDOWPOS
*winpos
= (WINDOWPOS
*)lParam
;
2645 trace("%s\n", (message
== WM_WINDOWPOSCHANGING
) ? "WM_WINDOWPOSCHANGING" : "WM_WINDOWPOSCHANGED");
2646 trace("%p after %p, x %d, y %d, cx %d, cy %d flags %08x\n",
2647 winpos
->hwnd
, winpos
->hwndInsertAfter
,
2648 winpos
->x
, winpos
->y
, winpos
->cx
, winpos
->cy
, winpos
->flags
);
2649 dump_winpos_flags(winpos
->flags
);
2651 /* Log only documented flags, win2k uses 0x1000 and 0x2000
2652 * in the high word for internal purposes
2654 wParam
= winpos
->flags
& 0xffff;
2655 /* We are not interested in the flags that don't match under XP and Win9x */
2656 wParam
&= ~(SWP_NOZORDER
);
2661 msg
.message
= message
;
2662 msg
.flags
= sent
|wparam
|lparam
;
2663 if (defwndproc_counter
) msg
.flags
|= defwinproc
;
2664 msg
.wParam
= wParam
;
2665 msg
.lParam
= lParam
;
2669 defwndproc_counter
++;
2670 ret
= DefFrameProcA(hwnd
, mdi_client
, message
, wParam
, lParam
);
2671 defwndproc_counter
--;
2676 static BOOL
mdi_RegisterWindowClasses(void)
2681 cls
.lpfnWndProc
= mdi_frame_wnd_proc
;
2684 cls
.hInstance
= GetModuleHandleA(0);
2686 cls
.hCursor
= LoadCursorA(0, (LPSTR
)IDC_ARROW
);
2687 cls
.hbrBackground
= GetStockObject(WHITE_BRUSH
);
2688 cls
.lpszMenuName
= NULL
;
2689 cls
.lpszClassName
= "MDI_frame_class";
2690 if (!RegisterClassA(&cls
)) return FALSE
;
2692 cls
.lpfnWndProc
= mdi_child_wnd_proc
;
2693 cls
.lpszClassName
= "MDI_child_class";
2694 if (!RegisterClassA(&cls
)) return FALSE
;
2696 if (!GetClassInfoA(0, "MDIClient", &cls
)) assert(0);
2697 old_mdi_client_proc
= cls
.lpfnWndProc
;
2698 cls
.hInstance
= GetModuleHandleA(0);
2699 cls
.lpfnWndProc
= mdi_client_hook_proc
;
2700 cls
.lpszClassName
= "MDI_client_class";
2701 if (!RegisterClassA(&cls
)) assert(0);
2706 static void test_mdi_messages(void)
2708 MDICREATESTRUCTA mdi_cs
;
2709 CLIENTCREATESTRUCT client_cs
;
2710 HWND mdi_frame
, mdi_child
, mdi_child2
, active_child
;
2712 HMENU hMenu
= CreateMenu();
2714 assert(mdi_RegisterWindowClasses());
2718 trace("creating MDI frame window\n");
2719 mdi_frame
= CreateWindowExA(0, "MDI_frame_class", "MDI frame window",
2720 WS_CAPTION
| WS_SYSMENU
| WS_MINIMIZEBOX
|
2721 WS_MAXIMIZEBOX
| WS_VISIBLE
,
2722 100, 100, CW_USEDEFAULT
, CW_USEDEFAULT
,
2723 GetDesktopWindow(), hMenu
,
2724 GetModuleHandleA(0), NULL
);
2726 ok_sequence(WmCreateMDIframeSeq
, "Create MDI frame window", FALSE
);
2728 ok(GetActiveWindow() == mdi_frame
, "wrong active window %p\n", GetActiveWindow());
2729 ok(GetFocus() == mdi_frame
, "wrong focus window %p\n", GetFocus());
2731 trace("creating MDI client window\n");
2732 client_cs
.hWindowMenu
= 0;
2733 client_cs
.idFirstChild
= MDI_FIRST_CHILD_ID
;
2734 mdi_client
= CreateWindowExA(0, "MDI_client_class",
2736 WS_CHILD
| WS_VISIBLE
| MDIS_ALLCHILDSTYLES
,
2738 mdi_frame
, 0, GetModuleHandleA(0), &client_cs
);
2740 ok_sequence(WmCreateMDIclientSeq
, "Create visible MDI client window", FALSE
);
2742 ok(GetActiveWindow() == mdi_frame
, "wrong active window %p\n", GetActiveWindow());
2743 ok(GetFocus() == mdi_frame
, "input focus should be on MDI frame not on %p\n", GetFocus());
2745 active_child
= (HWND
)SendMessageA(mdi_client
, WM_MDIGETACTIVE
, 0, (LPARAM
)&zoomed
);
2746 ok(!active_child
, "wrong active MDI child %p\n", active_child
);
2747 ok(!zoomed
, "wrong zoomed state %d\n", zoomed
);
2752 trace("creating invisible MDI child window\n");
2753 mdi_child
= CreateWindowExA(WS_EX_MDICHILD
, "MDI_child_class", "MDI child",
2755 0, 0, CW_USEDEFAULT
, CW_USEDEFAULT
,
2756 mdi_client
, 0, GetModuleHandleA(0), NULL
);
2760 ShowWindow(mdi_child
, SW_SHOWNORMAL
);
2761 ok_sequence(WmShowChildSeq
, "ShowWindow(SW_SHOWNORMAL) MDI child window", FALSE
);
2763 ok(GetWindowLongA(mdi_child
, GWL_STYLE
) & WS_VISIBLE
, "MDI child should be visible\n");
2764 ok(IsWindowVisible(mdi_child
), "MDI child should be visible\n");
2766 ok(GetActiveWindow() == mdi_frame
, "wrong active window %p\n", GetActiveWindow());
2767 ok(GetFocus() == 0, "wrong focus window %p\n", GetFocus());
2769 active_child
= (HWND
)SendMessageA(mdi_client
, WM_MDIGETACTIVE
, 0, (LPARAM
)&zoomed
);
2770 ok(!active_child
, "wrong active MDI child %p\n", active_child
);
2771 ok(!zoomed
, "wrong zoomed state %d\n", zoomed
);
2773 ShowWindow(mdi_child
, SW_HIDE
);
2774 ok_sequence(WmHideChildSeq
, "ShowWindow(SW_HIDE) MDI child window", FALSE
);
2777 ShowWindow(mdi_child
, SW_SHOW
);
2778 ok_sequence(WmShowChildSeq
, "ShowWindow(SW_SHOW) MDI child window", FALSE
);
2780 ok(GetWindowLongA(mdi_child
, GWL_STYLE
) & WS_VISIBLE
, "MDI child should be visible\n");
2781 ok(IsWindowVisible(mdi_child
), "MDI child should be visible\n");
2783 ok(GetActiveWindow() == mdi_frame
, "wrong active window %p\n", GetActiveWindow());
2784 ok(GetFocus() == 0, "wrong focus window %p\n", GetFocus());
2786 active_child
= (HWND
)SendMessageA(mdi_client
, WM_MDIGETACTIVE
, 0, (LPARAM
)&zoomed
);
2787 ok(!active_child
, "wrong active MDI child %p\n", active_child
);
2788 ok(!zoomed
, "wrong zoomed state %d\n", zoomed
);
2790 DestroyWindow(mdi_child
);
2793 trace("creating visible MDI child window\n");
2794 mdi_child
= CreateWindowExA(WS_EX_MDICHILD
, "MDI_child_class", "MDI child",
2795 WS_CHILD
| WS_VISIBLE
,
2796 0, 0, CW_USEDEFAULT
, CW_USEDEFAULT
,
2797 mdi_client
, 0, GetModuleHandleA(0), NULL
);
2799 ok_sequence(WmCreateMDIchildVisibleSeq
, "Create visible MDI child window", FALSE
);
2801 ok(GetWindowLongA(mdi_child
, GWL_STYLE
) & WS_VISIBLE
, "MDI child should be visible\n");
2802 ok(IsWindowVisible(mdi_child
), "MDI child should be visible\n");
2804 ok(GetActiveWindow() == mdi_frame
, "wrong active window %p\n", GetActiveWindow());
2805 ok(GetFocus() == mdi_child
, "wrong focus window %p\n", GetFocus());
2807 active_child
= (HWND
)SendMessageA(mdi_client
, WM_MDIGETACTIVE
, 0, (LPARAM
)&zoomed
);
2808 ok(active_child
== mdi_child
, "wrong active MDI child %p\n", active_child
);
2809 ok(!zoomed
, "wrong zoomed state %d\n", zoomed
);
2812 DestroyWindow(mdi_child
);
2813 ok_sequence(WmDestroyMDIchildVisibleSeq
, "Destroy visible MDI child window", TRUE
);
2815 ok(GetActiveWindow() == mdi_frame
, "wrong active window %p\n", GetActiveWindow());
2816 ok(GetFocus() == 0, "wrong focus window %p\n", GetFocus());
2818 /* Win2k: MDI client still returns a just destroyed child as active
2819 * Win9x: MDI client returns 0
2821 active_child
= (HWND
)SendMessageA(mdi_client
, WM_MDIGETACTIVE
, 0, (LPARAM
)&zoomed
);
2822 ok(active_child
== mdi_child
|| /* win2k */
2823 !active_child
, /* win9x */
2824 "wrong active MDI child %p\n", active_child
);
2825 ok(!zoomed
, "wrong zoomed state %d\n", zoomed
);
2829 trace("creating invisible MDI child window\n");
2830 mdi_child2
= CreateWindowExA(WS_EX_MDICHILD
, "MDI_child_class", "MDI child",
2832 0, 0, CW_USEDEFAULT
, CW_USEDEFAULT
,
2833 mdi_client
, 0, GetModuleHandleA(0), NULL
);
2835 ok_sequence(WmCreateMDIchildInvisibleSeq
, "Create invisible MDI child window", FALSE
);
2837 ok(!(GetWindowLongA(mdi_child2
, GWL_STYLE
) & WS_VISIBLE
), "MDI child should not be visible\n");
2838 ok(!IsWindowVisible(mdi_child2
), "MDI child should not be visible\n");
2840 ok(GetActiveWindow() == mdi_frame
, "wrong active window %p\n", GetActiveWindow());
2841 ok(GetFocus() == 0, "wrong focus window %p\n", GetFocus());
2843 /* Win2k: MDI client still returns a just destroyed child as active
2844 * Win9x: MDI client returns mdi_child2
2846 active_child
= (HWND
)SendMessageA(mdi_client
, WM_MDIGETACTIVE
, 0, (LPARAM
)&zoomed
);
2847 ok(active_child
== mdi_child
|| /* win2k */
2848 active_child
== mdi_child2
, /* win9x */
2849 "wrong active MDI child %p\n", active_child
);
2850 ok(!zoomed
, "wrong zoomed state %d\n", zoomed
);
2853 ShowWindow(mdi_child2
, SW_MAXIMIZE
);
2854 ok_sequence(WmMaximizeMDIchildInvisibleSeq
, "ShowWindow(SW_MAXIMIZE):invisible MDI child", FALSE
);
2856 ok(GetWindowLongA(mdi_child2
, GWL_STYLE
) & WS_VISIBLE
, "MDI child should be visible\n");
2857 ok(IsWindowVisible(mdi_child2
), "MDI child should be visible\n");
2859 active_child
= (HWND
)SendMessageA(mdi_client
, WM_MDIGETACTIVE
, 0, (LPARAM
)&zoomed
);
2860 ok(active_child
== mdi_child2
, "wrong active MDI child %p\n", active_child
);
2861 ok(zoomed
, "wrong zoomed state %d\n", zoomed
);
2864 ok(GetActiveWindow() == mdi_frame
, "wrong active window %p\n", GetActiveWindow());
2865 ok(GetFocus() == mdi_child2
|| /* win2k */
2866 GetFocus() == 0, /* win9x */
2867 "wrong focus window %p\n", GetFocus());
2872 ShowWindow(mdi_child2
, SW_HIDE
);
2873 ok_sequence(WmHideChildSeq
, "ShowWindow(SW_HIDE):MDI child", FALSE
);
2875 ShowWindow(mdi_child2
, SW_RESTORE
);
2876 ok_sequence(WmRestoreMDIchildInisibleSeq
, "ShowWindow(SW_RESTORE):invisible MDI child", FALSE
);
2879 ok(GetWindowLongA(mdi_child2
, GWL_STYLE
) & WS_VISIBLE
, "MDI child should be visible\n");
2880 ok(IsWindowVisible(mdi_child2
), "MDI child should be visible\n");
2882 active_child
= (HWND
)SendMessageA(mdi_client
, WM_MDIGETACTIVE
, 0, (LPARAM
)&zoomed
);
2883 ok(active_child
== mdi_child2
, "wrong active MDI child %p\n", active_child
);
2884 ok(!zoomed
, "wrong zoomed state %d\n", zoomed
);
2890 ShowWindow(mdi_child2
, SW_HIDE
);
2891 ok_sequence(WmHideChildSeq
, "ShowWindow(SW_HIDE):MDI child", FALSE
);
2893 ShowWindow(mdi_child2
, SW_SHOW
);
2894 ok_sequence(WmShowChildSeq
, "ShowWindow(SW_SHOW):MDI child", FALSE
);
2896 ok(GetActiveWindow() == mdi_frame
, "wrong active window %p\n", GetActiveWindow());
2897 ok(GetFocus() == 0, "wrong focus window %p\n", GetFocus());
2899 ShowWindow(mdi_child2
, SW_MAXIMIZE
);
2900 ok_sequence(WmMaximizeMDIchildVisibleSeq
, "ShowWindow(SW_MAXIMIZE):MDI child", FALSE
);
2902 ok(GetActiveWindow() == mdi_frame
, "wrong active window %p\n", GetActiveWindow());
2903 ok(GetFocus() == 0, "wrong focus window %p\n", GetFocus());
2905 ShowWindow(mdi_child2
, SW_RESTORE
);
2906 ok_sequence(WmRestoreMDIchildVisibleSeq
, "ShowWindow(SW_RESTORE):maximized MDI child", FALSE
);
2908 ok(GetActiveWindow() == mdi_frame
, "wrong active window %p\n", GetActiveWindow());
2909 ok(GetFocus() == 0, "wrong focus window %p\n", GetFocus());
2911 ShowWindow(mdi_child2
, SW_MINIMIZE
);
2912 ok_sequence(WmMinimizeMDIchildVisibleSeq
, "ShowWindow(SW_MINIMIZE):MDI child", TRUE
);
2914 ok(GetActiveWindow() == mdi_frame
, "wrong active window %p\n", GetActiveWindow());
2915 ok(GetFocus() == 0, "wrong focus window %p\n", GetFocus());
2917 active_child
= (HWND
)SendMessageA(mdi_client
, WM_MDIGETACTIVE
, 0, (LPARAM
)&zoomed
);
2918 ok(active_child
== mdi_child2
, "wrong active MDI child %p\n", active_child
);
2919 ok(!zoomed
, "wrong zoomed state %d\n", zoomed
);
2922 ShowWindow(mdi_child2
, SW_RESTORE
);
2923 ok_sequence(WmRestoreMDIchildVisibleSeq_2
, "ShowWindow(SW_RESTORE):minimized MDI child", TRUE
);
2925 ok(GetActiveWindow() == mdi_frame
, "wrong active window %p\n", GetActiveWindow());
2926 ok(GetFocus() == mdi_child2
, "wrong focus window %p\n", GetFocus());
2928 active_child
= (HWND
)SendMessageA(mdi_client
, WM_MDIGETACTIVE
, 0, (LPARAM
)&zoomed
);
2929 ok(active_child
== mdi_child2
, "wrong active MDI child %p\n", active_child
);
2930 ok(!zoomed
, "wrong zoomed state %d\n", zoomed
);
2936 ShowWindow(mdi_child2
, SW_HIDE
);
2937 ok_sequence(WmHideChildSeq
, "ShowWindow(SW_HIDE):MDI child", FALSE
);
2939 ok(GetActiveWindow() == mdi_frame
, "wrong active window %p\n", GetActiveWindow());
2940 ok(GetFocus() == 0, "wrong focus window %p\n", GetFocus());
2942 DestroyWindow(mdi_child2
);
2943 ok_sequence(WmDestroyMDIchildInvisibleSeq
, "Destroy invisible MDI child window", FALSE
);
2945 ok(GetActiveWindow() == mdi_frame
, "wrong active window %p\n", GetActiveWindow());
2946 ok(GetFocus() == 0, "wrong focus window %p\n", GetFocus());
2948 /* test for maximized MDI children */
2949 trace("creating maximized visible MDI child window 1\n");
2950 mdi_child
= CreateWindowExA(WS_EX_MDICHILD
, "MDI_child_class", "MDI child",
2951 WS_CHILD
| WS_VISIBLE
| WS_MAXIMIZEBOX
| WS_MAXIMIZE
,
2952 0, 0, CW_USEDEFAULT
, CW_USEDEFAULT
,
2953 mdi_client
, 0, GetModuleHandleA(0), NULL
);
2955 ok_sequence(WmCreateMDIchildVisibleMaxSeq1
, "Create maximized visible 1st MDI child window", TRUE
);
2956 ok(IsZoomed(mdi_child
), "1st MDI child should be maximized\n");
2958 ok(GetActiveWindow() == mdi_frame
, "wrong active window %p\n", GetActiveWindow());
2959 ok(GetFocus() == mdi_child
|| /* win2k */
2960 GetFocus() == 0, /* win9x */
2961 "wrong focus window %p\n", GetFocus());
2963 active_child
= (HWND
)SendMessageA(mdi_client
, WM_MDIGETACTIVE
, 0, (LPARAM
)&zoomed
);
2964 ok(active_child
== mdi_child
, "wrong active MDI child %p\n", active_child
);
2965 ok(zoomed
, "wrong zoomed state %d\n", zoomed
);
2968 trace("creating maximized visible MDI child window 2\n");
2969 mdi_child2
= CreateWindowExA(WS_EX_MDICHILD
, "MDI_child_class", "MDI child",
2970 WS_CHILD
| WS_VISIBLE
| WS_MAXIMIZEBOX
| WS_MAXIMIZE
,
2971 0, 0, CW_USEDEFAULT
, CW_USEDEFAULT
,
2972 mdi_client
, 0, GetModuleHandleA(0), NULL
);
2974 ok_sequence(WmCreateMDIchildVisibleMaxSeq2
, "Create maximized visible 2nd MDI child 2 window", TRUE
);
2975 ok(IsZoomed(mdi_child2
), "2nd MDI child should be maximized\n");
2976 ok(!IsZoomed(mdi_child
), "1st MDI child should NOT be maximized\n");
2978 ok(GetActiveWindow() == mdi_frame
, "wrong active window %p\n", GetActiveWindow());
2979 ok(GetFocus() == mdi_child2
, "wrong focus window %p\n", GetFocus());
2981 active_child
= (HWND
)SendMessageA(mdi_client
, WM_MDIGETACTIVE
, 0, (LPARAM
)&zoomed
);
2982 ok(active_child
== mdi_child2
, "wrong active MDI child %p\n", active_child
);
2983 ok(zoomed
, "wrong zoomed state %d\n", zoomed
);
2986 trace("destroying maximized visible MDI child window 2\n");
2987 DestroyWindow(mdi_child2
);
2988 ok_sequence(WmDestroyMDIchildVisibleSeq
, "Destroy visible MDI child window", TRUE
);
2990 ok(!IsZoomed(mdi_child
), "1st MDI child should NOT be maximized\n");
2992 ok(GetActiveWindow() == mdi_frame
, "wrong active window %p\n", GetActiveWindow());
2993 ok(GetFocus() == 0, "wrong focus window %p\n", GetFocus());
2995 /* Win2k: MDI client still returns a just destroyed child as active
2996 * Win9x: MDI client returns 0
2998 active_child
= (HWND
)SendMessageA(mdi_client
, WM_MDIGETACTIVE
, 0, (LPARAM
)&zoomed
);
2999 ok(active_child
== mdi_child2
|| /* win2k */
3000 !active_child
, /* win9x */
3001 "wrong active MDI child %p\n", active_child
);
3004 ShowWindow(mdi_child
, SW_MAXIMIZE
);
3005 ok(IsZoomed(mdi_child
), "1st MDI child should be maximized\n");
3008 ok(GetActiveWindow() == mdi_frame
, "wrong active window %p\n", GetActiveWindow());
3009 ok(GetFocus() == mdi_child
, "wrong focus window %p\n", GetFocus());
3011 trace("re-creating maximized visible MDI child window 2\n");
3012 mdi_child2
= CreateWindowExA(WS_EX_MDICHILD
, "MDI_child_class", "MDI child",
3013 WS_CHILD
| WS_VISIBLE
| WS_MAXIMIZEBOX
| WS_MAXIMIZE
,
3014 0, 0, CW_USEDEFAULT
, CW_USEDEFAULT
,
3015 mdi_client
, 0, GetModuleHandleA(0), NULL
);
3017 ok_sequence(WmCreateMDIchildVisibleMaxSeq2
, "Create maximized visible 2nd MDI child 2 window", TRUE
);
3018 ok(IsZoomed(mdi_child2
), "2nd MDI child should be maximized\n");
3019 ok(!IsZoomed(mdi_child
), "1st MDI child should NOT be maximized\n");
3021 ok(GetActiveWindow() == mdi_frame
, "wrong active window %p\n", GetActiveWindow());
3022 ok(GetFocus() == mdi_child2
, "wrong focus window %p\n", GetFocus());
3024 active_child
= (HWND
)SendMessageA(mdi_client
, WM_MDIGETACTIVE
, 0, (LPARAM
)&zoomed
);
3025 ok(active_child
== mdi_child2
, "wrong active MDI child %p\n", active_child
);
3026 ok(zoomed
, "wrong zoomed state %d\n", zoomed
);
3029 SendMessageA(mdi_child2
, WM_SYSCOMMAND
, SC_CLOSE
, 0);
3030 ok_sequence(WmDestroyMDIchildVisibleMaxSeq2
, "WM_SYSCOMMAND/SC_CLOSE on a visible maximized MDI child window", TRUE
);
3031 ok(!IsWindow(mdi_child2
), "MDI child 2 should be destroyed\n");
3033 ok(IsZoomed(mdi_child
), "1st MDI child should be maximized\n");
3034 ok(GetActiveWindow() == mdi_frame
, "wrong active window %p\n", GetActiveWindow());
3035 ok(GetFocus() == mdi_child
, "wrong focus window %p\n", GetFocus());
3037 active_child
= (HWND
)SendMessageA(mdi_client
, WM_MDIGETACTIVE
, 0, (LPARAM
)&zoomed
);
3038 ok(active_child
== mdi_child
, "wrong active MDI child %p\n", active_child
);
3039 ok(zoomed
, "wrong zoomed state %d\n", zoomed
);
3042 DestroyWindow(mdi_child
);
3043 ok_sequence(WmDestroyMDIchildVisibleSeq
, "Destroy visible MDI child window", TRUE
);
3045 ok(GetActiveWindow() == mdi_frame
, "wrong active window %p\n", GetActiveWindow());
3046 ok(GetFocus() == 0, "wrong focus window %p\n", GetFocus());
3048 /* Win2k: MDI client still returns a just destroyed child as active
3049 * Win9x: MDI client returns 0
3051 active_child
= (HWND
)SendMessageA(mdi_client
, WM_MDIGETACTIVE
, 0, (LPARAM
)&zoomed
);
3052 ok(active_child
== mdi_child
|| /* win2k */
3053 !active_child
, /* win9x */
3054 "wrong active MDI child %p\n", active_child
);
3057 trace("creating maximized invisible MDI child window\n");
3058 mdi_child2
= CreateWindowExA(WS_EX_MDICHILD
, "MDI_child_class", "MDI child",
3059 WS_CHILD
| WS_MAXIMIZE
| WS_CAPTION
| WS_THICKFRAME
,
3060 0, 0, CW_USEDEFAULT
, CW_USEDEFAULT
,
3061 mdi_client
, 0, GetModuleHandleA(0), NULL
);
3063 ok_sequence(WmCreateMDIchildInvisibleMaxSeq4
, "Create maximized invisible MDI child window", TRUE
);
3064 ok(IsZoomed(mdi_child2
), "MDI child should be maximized\n");
3065 ok(!(GetWindowLongA(mdi_child2
, GWL_STYLE
) & WS_VISIBLE
), "MDI child should be not visible\n");
3066 ok(!IsWindowVisible(mdi_child2
), "MDI child should be not visible\n");
3068 /* Win2k: MDI client still returns a just destroyed child as active
3069 * Win9x: MDI client returns 0
3071 active_child
= (HWND
)SendMessageA(mdi_client
, WM_MDIGETACTIVE
, 0, (LPARAM
)&zoomed
);
3072 ok(active_child
== mdi_child
|| /* win2k */
3073 !active_child
, /* win9x */
3074 "wrong active MDI child %p\n", active_child
);
3077 trace("call ShowWindow(mdi_child, SW_MAXIMIZE)\n");
3078 ShowWindow(mdi_child2
, SW_MAXIMIZE
);
3079 ok_sequence(WmMaximizeMDIchildInvisibleSeq2
, "ShowWindow(SW_MAXIMIZE):invisible maximized MDI child", FALSE
);
3080 ok(IsZoomed(mdi_child2
), "MDI child should be maximized\n");
3081 ok(GetWindowLongA(mdi_child2
, GWL_STYLE
) & WS_VISIBLE
, "MDI child should be visible\n");
3082 ok(IsWindowVisible(mdi_child2
), "MDI child should be visible\n");
3084 active_child
= (HWND
)SendMessageA(mdi_client
, WM_MDIGETACTIVE
, 0, (LPARAM
)&zoomed
);
3085 ok(active_child
== mdi_child2
, "wrong active MDI child %p\n", active_child
);
3086 ok(zoomed
, "wrong zoomed state %d\n", zoomed
);
3089 SendMessageA(mdi_client
, WM_MDIDESTROY
, (WPARAM
)mdi_child2
, 0);
3092 /* end of test for maximized MDI children */
3094 mdi_cs
.szClass
= "MDI_child_Class";
3095 mdi_cs
.szTitle
= "MDI child";
3096 mdi_cs
.hOwner
= GetModuleHandleA(0);
3099 mdi_cs
.cx
= CW_USEDEFAULT
;
3100 mdi_cs
.cy
= CW_USEDEFAULT
;
3101 mdi_cs
.style
= WS_CHILD
| WS_SYSMENU
| WS_VISIBLE
| WS_MAXIMIZEBOX
| WS_MAXIMIZE
;
3103 mdi_child
= (HWND
)SendMessageA(mdi_client
, WM_MDICREATE
, 0, (LPARAM
)&mdi_cs
);
3104 ok(mdi_child
!= 0, "MDI child creation failed\n");
3105 ok_sequence(WmCreateMDIchildVisibleMaxSeq3
, "WM_MDICREATE for maximized visible MDI child window", TRUE
);
3107 ok(GetMenuItemID(hMenu
, GetMenuItemCount(hMenu
) - 1) == SC_CLOSE
, "SC_CLOSE menu item not found\n");
3109 active_child
= (HWND
)SendMessageA(mdi_client
, WM_MDIGETACTIVE
, 0, (LPARAM
)&zoomed
);
3110 ok(active_child
== mdi_child
, "wrong active MDI child %p\n", active_child
);
3112 ok(IsZoomed(mdi_child
), "MDI child should be maximized\n");
3113 ok(GetActiveWindow() == mdi_frame
, "wrong active window %p\n", GetActiveWindow());
3114 ok(GetFocus() == mdi_child
, "wrong focus window %p\n", GetFocus());
3116 active_child
= (HWND
)SendMessageA(mdi_client
, WM_MDIGETACTIVE
, 0, (LPARAM
)&zoomed
);
3117 ok(active_child
== mdi_child
, "wrong active MDI child %p\n", active_child
);
3118 ok(zoomed
, "wrong zoomed state %d\n", zoomed
);
3121 SendMessageA(mdi_client
, WM_MDIDESTROY
, (WPARAM
)mdi_child
, 0);
3122 ok_sequence(WmDestroyMDIchildVisibleMaxSeq1
, "Destroy visible maximized MDI child window", TRUE
);
3124 ok(!IsWindow(mdi_child
), "MDI child should be destroyed\n");
3125 active_child
= (HWND
)SendMessageA(mdi_client
, WM_MDIGETACTIVE
, 0, (LPARAM
)&zoomed
);
3126 ok(!active_child
, "wrong active MDI child %p\n", active_child
);
3131 DestroyWindow(mdi_client
);
3132 ok_sequence(WmDestroyMDIclientSeq
, "Destroy MDI client window", FALSE
);
3134 /* test maximization of MDI child with invisible parent */
3135 client_cs
.hWindowMenu
= 0;
3136 mdi_client
= CreateWindow("MDI_client_class",
3138 WS_CHILD
| WS_CLIPCHILDREN
| WS_VSCROLL
| WS_HSCROLL
| WS_VISIBLE
,
3140 mdi_frame
, 0, GetModuleHandleA(0), &client_cs
);
3141 ok_sequence(WmCreateMDIclientSeq
, "Create MDI client window", FALSE
);
3143 ShowWindow(mdi_client
, SW_HIDE
);
3144 ok_sequence(WmHideMDIclientSeq
, "Hide MDI client window", FALSE
);
3146 mdi_child
= CreateWindowExA(WS_EX_MDICHILD
, "MDI_child_class", "MDI child",
3147 WS_CHILD
| WS_CLIPCHILDREN
| WS_VSCROLL
| WS_HSCROLL
,
3149 mdi_client
, 0, GetModuleHandleA(0), NULL
);
3150 ok_sequence(WmCreateMDIchildInvisibleParentSeq
, "Create MDI child window with invisible parent", FALSE
);
3152 SendMessage(mdi_client
, WM_MDIMAXIMIZE
, (WPARAM
) mdi_child
, 0);
3153 ok_sequence(WmMaximizeMDIchildInvisibleParentSeq
, "Maximize MDI child window with invisible parent", TRUE
);
3154 zoomed
= IsZoomed(mdi_child
);
3155 ok(zoomed
, "wrong zoomed state %d\n", zoomed
);
3157 ShowWindow(mdi_client
, SW_SHOW
);
3158 ok_sequence(WmShowMDIclientSeq
, "Show MDI client window", FALSE
);
3160 DestroyWindow(mdi_child
);
3161 ok_sequence(WmDestroyMDIchildVisibleSeq
, "Destroy visible maximized MDI child window", TRUE
);
3163 DestroyWindow(mdi_client
);
3164 ok_sequence(WmDestroyMDIclientSeq
, "Destroy MDI client window", FALSE
);
3165 /* end of test for maximization of MDI child with invisible parent */
3167 DestroyWindow(mdi_frame
);
3168 ok_sequence(WmDestroyMDIframeSeq
, "Destroy MDI frame window", FALSE
);
3170 /************************* End of MDI test **********************************/
3172 static void test_WM_SETREDRAW(HWND hwnd
)
3174 DWORD style
= GetWindowLongA(hwnd
, GWL_STYLE
);
3178 SendMessageA(hwnd
, WM_SETREDRAW
, FALSE
, 0);
3179 ok_sequence(WmSetRedrawFalseSeq
, "SetRedraw:FALSE", FALSE
);
3181 ok(!(GetWindowLongA(hwnd
, GWL_STYLE
) & WS_VISIBLE
), "WS_VISIBLE should NOT be set\n");
3182 ok(!IsWindowVisible(hwnd
), "IsWindowVisible() should return FALSE\n");
3185 SendMessageA(hwnd
, WM_SETREDRAW
, TRUE
, 0);
3186 ok_sequence(WmSetRedrawTrueSeq
, "SetRedraw:TRUE", FALSE
);
3188 ok(GetWindowLongA(hwnd
, GWL_STYLE
) & WS_VISIBLE
, "WS_VISIBLE should be set\n");
3189 ok(IsWindowVisible(hwnd
), "IsWindowVisible() should return TRUE\n");
3191 /* restore original WS_VISIBLE state */
3192 SetWindowLongA(hwnd
, GWL_STYLE
, style
);
3197 static INT_PTR CALLBACK
TestModalDlgProcA(HWND hwnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
3201 trace("dialog: %p, %04x, %08lx, %08lx\n", hwnd
, message
, wParam
, lParam
);
3203 /* explicitly ignore WM_GETICON message */
3204 if (message
== WM_GETICON
) return 0;
3211 case WM_DEVICECHANGE
:
3216 case WM_WINDOWPOSCHANGING
:
3217 case WM_WINDOWPOSCHANGED
:
3219 WINDOWPOS
*winpos
= (WINDOWPOS
*)lParam
;
3221 trace("%s\n", (message
== WM_WINDOWPOSCHANGING
) ? "WM_WINDOWPOSCHANGING" : "WM_WINDOWPOSCHANGED");
3222 trace("%p after %p, x %d, y %d, cx %d, cy %d flags %08x\n",
3223 winpos
->hwnd
, winpos
->hwndInsertAfter
,
3224 winpos
->x
, winpos
->y
, winpos
->cx
, winpos
->cy
, winpos
->flags
);
3225 dump_winpos_flags(winpos
->flags
);
3227 /* Log only documented flags, win2k uses 0x1000 and 0x2000
3228 * in the high word for internal purposes
3230 wParam
= winpos
->flags
& 0xffff;
3231 /* We are not interested in the flags that don't match under XP and Win9x */
3232 wParam
&= ~(SWP_NOZORDER
);
3237 msg
.message
= message
;
3238 msg
.flags
= sent
|wparam
|lparam
;
3239 msg
.wParam
= wParam
;
3240 msg
.lParam
= lParam
;
3243 if (message
== WM_INITDIALOG
) SetTimer( hwnd
, 1, 100, NULL
);
3244 if (message
== WM_TIMER
) EndDialog( hwnd
, 0 );
3248 static void test_hv_scroll_1(HWND hwnd
, INT ctl
, DWORD clear
, DWORD set
, INT min
, INT max
)
3250 DWORD style
, exstyle
;
3254 exstyle
= GetWindowLongA(hwnd
, GWL_EXSTYLE
);
3255 style
= GetWindowLongA(hwnd
, GWL_STYLE
);
3256 /* do not be confused by WS_DLGFRAME set */
3257 if ((style
& WS_CAPTION
) == WS_CAPTION
) style
&= ~WS_CAPTION
;
3259 if (clear
) ok(style
& clear
, "style %08x should be set\n", clear
);
3260 if (set
) ok(!(style
& set
), "style %08x should not be set\n", set
);
3262 ret
= SetScrollRange(hwnd
, ctl
, min
, max
, FALSE
);
3263 ok( ret
, "SetScrollRange(%d) error %d\n", ctl
, GetLastError());
3264 if ((style
& (WS_DLGFRAME
| WS_BORDER
| WS_THICKFRAME
)) || (exstyle
& WS_EX_DLGMODALFRAME
))
3265 ok_sequence(WmSetScrollRangeHV_NC_Seq
, "SetScrollRange(SB_HORZ/SB_VERT) NC", FALSE
);
3267 ok_sequence(WmSetScrollRangeHVSeq
, "SetScrollRange(SB_HORZ/SB_VERT)", FALSE
);
3269 style
= GetWindowLongA(hwnd
, GWL_STYLE
);
3270 if (set
) ok(style
& set
, "style %08x should be set\n", set
);
3271 if (clear
) ok(!(style
& clear
), "style %08x should not be set\n", clear
);
3273 /* a subsequent call should do nothing */
3274 ret
= SetScrollRange(hwnd
, ctl
, min
, max
, FALSE
);
3275 ok( ret
, "SetScrollRange(%d) error %d\n", ctl
, GetLastError());
3276 ok_sequence(WmEmptySeq
, "SetScrollRange(SB_HORZ/SB_VERT) empty sequence", FALSE
);
3280 trace("Ignore GetScrollRange error below if you are on Win9x\n");
3281 ret
= GetScrollRange(hwnd
, ctl
, &xmin
, &xmax
);
3282 ok( ret
, "GetScrollRange(%d) error %d\n", ctl
, GetLastError());
3283 ok_sequence(WmEmptySeq
, "GetScrollRange(SB_HORZ/SB_VERT) empty sequence", FALSE
);
3284 ok(xmin
== min
, "unexpected min scroll value %d\n", xmin
);
3285 ok(xmax
== max
, "unexpected max scroll value %d\n", xmax
);
3288 static void test_hv_scroll_2(HWND hwnd
, INT ctl
, DWORD clear
, DWORD set
, INT min
, INT max
)
3290 DWORD style
, exstyle
;
3294 exstyle
= GetWindowLongA(hwnd
, GWL_EXSTYLE
);
3295 style
= GetWindowLongA(hwnd
, GWL_STYLE
);
3296 /* do not be confused by WS_DLGFRAME set */
3297 if ((style
& WS_CAPTION
) == WS_CAPTION
) style
&= ~WS_CAPTION
;
3299 if (clear
) ok(style
& clear
, "style %08x should be set\n", clear
);
3300 if (set
) ok(!(style
& set
), "style %08x should not be set\n", set
);
3302 si
.cbSize
= sizeof(si
);
3303 si
.fMask
= SIF_RANGE
;
3306 SetScrollInfo(hwnd
, ctl
, &si
, TRUE
);
3307 if ((style
& (WS_DLGFRAME
| WS_BORDER
| WS_THICKFRAME
)) || (exstyle
& WS_EX_DLGMODALFRAME
))
3308 ok_sequence(WmSetScrollRangeHV_NC_Seq
, "SetScrollInfo(SB_HORZ/SB_VERT) NC", FALSE
);
3310 ok_sequence(WmSetScrollRangeHVSeq
, "SetScrollInfo(SB_HORZ/SB_VERT)", FALSE
);
3312 style
= GetWindowLongA(hwnd
, GWL_STYLE
);
3313 if (set
) ok(style
& set
, "style %08x should be set\n", set
);
3314 if (clear
) ok(!(style
& clear
), "style %08x should not be set\n", clear
);
3316 /* a subsequent call should do nothing */
3317 SetScrollInfo(hwnd
, ctl
, &si
, TRUE
);
3318 if (style
& WS_HSCROLL
)
3319 ok_sequence(WmSetScrollRangeHSeq_empty
, "SetScrollInfo(SB_HORZ/SB_VERT) empty sequence", FALSE
);
3320 else if (style
& WS_VSCROLL
)
3321 ok_sequence(WmSetScrollRangeVSeq_empty
, "SetScrollInfo(SB_HORZ/SB_VERT) empty sequence", FALSE
);
3323 ok_sequence(WmEmptySeq
, "SetScrollInfo(SB_HORZ/SB_VERT) empty sequence", FALSE
);
3325 si
.fMask
= SIF_PAGE
;
3327 SetScrollInfo(hwnd
, ctl
, &si
, FALSE
);
3328 ok_sequence(WmEmptySeq
, "SetScrollInfo(SB_HORZ/SB_VERT) empty sequence", FALSE
);
3332 SetScrollInfo(hwnd
, ctl
, &si
, FALSE
);
3333 ok_sequence(WmEmptySeq
, "SetScrollInfo(SB_HORZ/SB_VERT) empty sequence", FALSE
);
3335 si
.fMask
= SIF_RANGE
;
3336 si
.nMin
= 0xdeadbeef;
3337 si
.nMax
= 0xdeadbeef;
3338 ret
= GetScrollInfo(hwnd
, ctl
, &si
);
3339 ok( ret
, "GetScrollInfo error %d\n", GetLastError());
3340 ok_sequence(WmEmptySeq
, "GetScrollRange(SB_HORZ/SB_VERT) empty sequence", FALSE
);
3341 ok(si
.nMin
== min
, "unexpected min scroll value %d\n", si
.nMin
);
3342 ok(si
.nMax
== max
, "unexpected max scroll value %d\n", si
.nMax
);
3345 /* Win9x sends WM_USER+xxx while and NT versions send SBM_xxx messages */
3346 static void test_scroll_messages(HWND hwnd
)
3354 ret
= GetScrollRange(hwnd
, SB_CTL
, &min
, &max
);
3355 ok( ret
, "GetScrollRange error %d\n", GetLastError());
3356 if (sequence
->message
!= WmGetScrollRangeSeq
[0].message
)
3357 trace("GetScrollRange(SB_CTL) generated unknown message %04x\n", sequence
->message
);
3358 /* values of min and max are undefined */
3361 ret
= SetScrollRange(hwnd
, SB_CTL
, 10, 150, FALSE
);
3362 ok( ret
, "SetScrollRange error %d\n", GetLastError());
3363 if (sequence
->message
!= WmSetScrollRangeSeq
[0].message
)
3364 trace("SetScrollRange(SB_CTL) generated unknown message %04x\n", sequence
->message
);
3369 ret
= GetScrollRange(hwnd
, SB_CTL
, &min
, &max
);
3370 ok( ret
, "GetScrollRange error %d\n", GetLastError());
3371 if (sequence
->message
!= WmGetScrollRangeSeq
[0].message
)
3372 trace("GetScrollRange(SB_CTL) generated unknown message %04x\n", sequence
->message
);
3373 /* values of min and max are undefined */
3376 si
.cbSize
= sizeof(si
);
3377 si
.fMask
= SIF_RANGE
;
3380 SetScrollInfo(hwnd
, SB_CTL
, &si
, FALSE
);
3381 if (sequence
->message
!= WmSetScrollRangeSeq
[0].message
)
3382 trace("SetScrollInfo(SB_CTL) generated unknown message %04x\n", sequence
->message
);
3385 si
.fMask
= SIF_PAGE
;
3387 SetScrollInfo(hwnd
, SB_CTL
, &si
, FALSE
);
3388 if (sequence
->message
!= WmSetScrollRangeSeq
[0].message
)
3389 trace("SetScrollInfo(SB_CTL) generated unknown message %04x\n", sequence
->message
);
3394 SetScrollInfo(hwnd
, SB_CTL
, &si
, FALSE
);
3395 if (sequence
->message
!= WmSetScrollRangeSeq
[0].message
)
3396 trace("SetScrollInfo(SB_CTL) generated unknown message %04x\n", sequence
->message
);
3399 si
.fMask
= SIF_RANGE
;
3400 si
.nMin
= 0xdeadbeef;
3401 si
.nMax
= 0xdeadbeef;
3402 ret
= GetScrollInfo(hwnd
, SB_CTL
, &si
);
3403 ok( ret
, "GetScrollInfo error %d\n", GetLastError());
3404 if (sequence
->message
!= WmGetScrollInfoSeq
[0].message
)
3405 trace("GetScrollInfo(SB_CTL) generated unknown message %04x\n", sequence
->message
);
3406 /* values of min and max are undefined */
3409 /* set WS_HSCROLL */
3410 test_hv_scroll_1(hwnd
, SB_HORZ
, 0, WS_HSCROLL
, 10, 150);
3411 /* clear WS_HSCROLL */
3412 test_hv_scroll_1(hwnd
, SB_HORZ
, WS_HSCROLL
, 0, 0, 0);
3414 /* set WS_HSCROLL */
3415 test_hv_scroll_2(hwnd
, SB_HORZ
, 0, WS_HSCROLL
, 10, 150);
3416 /* clear WS_HSCROLL */
3417 test_hv_scroll_2(hwnd
, SB_HORZ
, WS_HSCROLL
, 0, 0, 0);
3419 /* set WS_VSCROLL */
3420 test_hv_scroll_1(hwnd
, SB_VERT
, 0, WS_VSCROLL
, 10, 150);
3421 /* clear WS_VSCROLL */
3422 test_hv_scroll_1(hwnd
, SB_VERT
, WS_VSCROLL
, 0, 0, 0);
3424 /* set WS_VSCROLL */
3425 test_hv_scroll_2(hwnd
, SB_VERT
, 0, WS_VSCROLL
, 10, 150);
3426 /* clear WS_VSCROLL */
3427 test_hv_scroll_2(hwnd
, SB_VERT
, WS_VSCROLL
, 0, 0, 0);
3430 static void test_showwindow(void)
3435 hwnd
= CreateWindowExA(0, "TestWindowClass", "Test overlapped", WS_OVERLAPPEDWINDOW
,
3436 100, 100, 200, 200, 0, 0, 0, NULL
);
3437 ok (hwnd
!= 0, "Failed to create overlapped window\n");
3438 hchild
= CreateWindowExA(0, "TestWindowClass", "Test child", WS_CHILD
,
3439 0, 0, 10, 10, hwnd
, 0, 0, NULL
);
3440 ok (hchild
!= 0, "Failed to create child\n");
3443 /* ShowWindow( SW_SHOWNA) for invisible top level window */
3444 trace("calling ShowWindow( SW_SHOWNA) for invisible top level window\n");
3445 ok( ShowWindow(hwnd
, SW_SHOWNA
) == FALSE
, "ShowWindow: window was visible\n" );
3446 ok_sequence(WmSHOWNATopInvisible
, "ShowWindow(SW_SHOWNA) on invisible top level window", TRUE
);
3449 /* ShowWindow( SW_SHOWNA) for now visible top level window */
3450 trace("calling ShowWindow( SW_SHOWNA) for now visible top level window\n");
3451 ok( ShowWindow(hwnd
, SW_SHOWNA
) != FALSE
, "ShowWindow: window was invisible\n" );
3452 ok_sequence(WmSHOWNATopVisible
, "ShowWindow(SW_SHOWNA) on visible top level window", FALSE
);
3454 /* back to invisible */
3455 ShowWindow(hchild
, SW_HIDE
);
3456 ShowWindow(hwnd
, SW_HIDE
);
3458 /* ShowWindow(SW_SHOWNA) with child and parent invisible */
3459 trace("calling ShowWindow( SW_SHOWNA) for invisible child with invisible parent\n");
3460 ok( ShowWindow(hchild
, SW_SHOWNA
) == FALSE
, "ShowWindow: window was visible\n" );
3461 ok_sequence(WmSHOWNAChildInvisParInvis
, "ShowWindow(SW_SHOWNA) invisible child and parent", FALSE
);
3463 /* ShowWindow(SW_SHOWNA) with child visible and parent invisible */
3464 ok( ShowWindow(hchild
, SW_SHOW
) != FALSE
, "ShowWindow: window was invisible\n" );
3466 trace("calling ShowWindow( SW_SHOWNA) for the visible child and invisible parent\n");
3467 ok( ShowWindow(hchild
, SW_SHOWNA
) != FALSE
, "ShowWindow: window was invisible\n" );
3468 ok_sequence(WmSHOWNAChildVisParInvis
, "ShowWindow(SW_SHOWNA) visible child and invisible parent", FALSE
);
3470 /* ShowWindow(SW_SHOWNA) with child visible and parent visible */
3471 ShowWindow( hwnd
, SW_SHOW
);
3473 trace("calling ShowWindow( SW_SHOWNA) for the visible child and parent\n");
3474 ok( ShowWindow(hchild
, SW_SHOWNA
) != FALSE
, "ShowWindow: window was invisible\n" );
3475 ok_sequence(WmSHOWNAChildVisParVis
, "ShowWindow(SW_SHOWNA) for the visible child and parent", FALSE
);
3478 /* ShowWindow(SW_SHOWNA) with child invisible and parent visible */
3479 ShowWindow( hchild
, SW_HIDE
);
3481 trace("calling ShowWindow( SW_SHOWNA) for the invisible child and visible parent\n");
3482 ok( ShowWindow(hchild
, SW_SHOWNA
) == FALSE
, "ShowWindow: window was visible\n" );
3483 ok_sequence(WmSHOWNAChildInvisParVis
, "ShowWindow(SW_SHOWNA) for the invisible child and visible parent", FALSE
);
3487 ok(GetCapture() == hchild
, "wrong capture window %p\n", GetCapture());
3488 DestroyWindow(hchild
);
3489 ok(!GetCapture(), "wrong capture window %p\n", GetCapture());
3491 DestroyWindow(hwnd
);
3496 * 1. Create invisible maximized popup window.
3497 * 2. Move and resize it.
3498 * 3. Show it maximized.
3500 trace("calling CreateWindowExA( WS_MAXIMIZE ) for invisible maximized popup window\n");
3501 hwnd
= CreateWindowExA(0, "TestWindowClass", "Test popup", WS_POPUP
| WS_MAXIMIZE
,
3502 100, 100, 200, 200, 0, 0, 0, NULL
);
3503 ok (hwnd
!= 0, "Failed to create popup window\n");
3504 ok(IsZoomed(hwnd
), "window should be maximized\n");
3505 ok_sequence(WmCreateInvisibleMaxPopupSeq
, "CreateWindow(WS_MAXIMIZED):popup", FALSE
);
3508 GetWindowRect(hwnd
, &rc
);
3509 ok( rc
.right
-rc
.left
== GetSystemMetrics(SM_CXSCREEN
) &&
3510 rc
.bottom
-rc
.top
== GetSystemMetrics(SM_CYSCREEN
),
3511 "Invalid maximized size before ShowWindow (%d,%d)-(%d,%d)\n",
3512 rc
.left
, rc
.top
, rc
.right
, rc
.bottom
);
3513 /* Reset window's size & position */
3514 SetWindowPos(hwnd
, 0, 10, 10, 200, 200, SWP_NOZORDER
| SWP_NOACTIVATE
);
3515 ok(IsZoomed(hwnd
), "window should be maximized\n");
3518 trace("calling ShowWindow( SW_SHOWMAXIMIZE ) for invisible maximized popup window\n");
3519 ShowWindow(hwnd
, SW_SHOWMAXIMIZED
);
3520 ok(IsZoomed(hwnd
), "window should be maximized\n");
3521 ok_sequence(WmShowMaxPopupResizedSeq
, "ShowWindow(SW_SHOWMAXIMIZED):invisible maximized and resized popup", FALSE
);
3524 GetWindowRect(hwnd
, &rc
);
3525 ok( rc
.right
-rc
.left
== GetSystemMetrics(SM_CXSCREEN
) &&
3526 rc
.bottom
-rc
.top
== GetSystemMetrics(SM_CYSCREEN
),
3527 "Invalid maximized size after ShowWindow (%d,%d)-(%d,%d)\n",
3528 rc
.left
, rc
.top
, rc
.right
, rc
.bottom
);
3529 DestroyWindow(hwnd
);
3533 * 1. Create invisible maximized popup window.
3534 * 2. Show it maximized.
3536 trace("calling CreateWindowExA( WS_MAXIMIZE ) for invisible maximized popup window\n");
3537 hwnd
= CreateWindowExA(0, "TestWindowClass", "Test popup", WS_POPUP
| WS_MAXIMIZE
,
3538 100, 100, 200, 200, 0, 0, 0, NULL
);
3539 ok (hwnd
!= 0, "Failed to create popup window\n");
3540 ok(IsZoomed(hwnd
), "window should be maximized\n");
3541 ok_sequence(WmCreateInvisibleMaxPopupSeq
, "CreateWindow(WS_MAXIMIZED):popup", FALSE
);
3544 trace("calling ShowWindow( SW_SHOWMAXIMIZE ) for invisible maximized popup window\n");
3545 ShowWindow(hwnd
, SW_SHOWMAXIMIZED
);
3546 ok(IsZoomed(hwnd
), "window should be maximized\n");
3547 ok_sequence(WmShowMaxPopupSeq
, "ShowWindow(SW_SHOWMAXIMIZED):invisible maximized popup", FALSE
);
3549 DestroyWindow(hwnd
);
3553 * 1. Create visible maximized popup window.
3555 trace("calling CreateWindowExA( WS_MAXIMIZE ) for maximized popup window\n");
3556 hwnd
= CreateWindowExA(0, "TestWindowClass", "Test popup", WS_POPUP
| WS_MAXIMIZE
| WS_VISIBLE
,
3557 100, 100, 200, 200, 0, 0, 0, NULL
);
3558 ok (hwnd
!= 0, "Failed to create popup window\n");
3559 ok(IsZoomed(hwnd
), "window should be maximized\n");
3560 ok_sequence(WmCreateMaxPopupSeq
, "CreateWindow(WS_MAXIMIZED):popup", FALSE
);
3562 DestroyWindow(hwnd
);
3566 * 1. Create visible popup window.
3569 trace("calling CreateWindowExA( WS_VISIBLE ) for popup window\n");
3570 hwnd
= CreateWindowExA(0, "TestWindowClass", "Test popup", WS_POPUP
| WS_VISIBLE
,
3571 100, 100, 200, 200, 0, 0, 0, NULL
);
3572 ok (hwnd
!= 0, "Failed to create popup window\n");
3573 ok(!IsZoomed(hwnd
), "window should NOT be maximized\n");
3574 ok_sequence(WmCreatePopupSeq
, "CreateWindow(WS_VISIBLE):popup", TRUE
);
3577 trace("calling ShowWindow( SW_SHOWMAXIMIZE ) for visible popup window\n");
3578 ShowWindow(hwnd
, SW_SHOWMAXIMIZED
);
3579 ok(IsZoomed(hwnd
), "window should be maximized\n");
3580 ok_sequence(WmShowVisMaxPopupSeq
, "ShowWindow(SW_SHOWMAXIMIZED):popup", FALSE
);
3582 DestroyWindow(hwnd
);
3586 static void test_sys_menu(void)
3592 hwnd
= CreateWindowExA(0, "TestWindowClass", NULL
, WS_OVERLAPPEDWINDOW
,
3593 100, 100, 200, 200, 0, 0, 0, NULL
);
3594 ok (hwnd
!= 0, "Failed to create overlapped window\n");
3598 /* test existing window without CS_NOCLOSE style */
3599 hmenu
= GetSystemMenu(hwnd
, FALSE
);
3600 ok(hmenu
!= 0, "GetSystemMenu error %d\n", GetLastError());
3602 state
= GetMenuState(hmenu
, SC_CLOSE
, MF_BYCOMMAND
);
3603 ok(state
!= 0xffffffff, "wrong SC_CLOSE state %x\n", state
);
3604 ok(!(state
& (MF_DISABLED
| MF_GRAYED
)), "wrong SC_CLOSE state %x\n", state
);
3606 EnableMenuItem(hmenu
, SC_CLOSE
, MF_BYCOMMAND
| MF_GRAYED
);
3607 ok_sequence(WmEmptySeq
, "WmEnableMenuItem", FALSE
);
3609 state
= GetMenuState(hmenu
, SC_CLOSE
, MF_BYCOMMAND
);
3610 ok(state
!= 0xffffffff, "wrong SC_CLOSE state %x\n", state
);
3611 ok((state
& (MF_DISABLED
| MF_GRAYED
)) == MF_GRAYED
, "wrong SC_CLOSE state %x\n", state
);
3613 EnableMenuItem(hmenu
, SC_CLOSE
, 0);
3614 ok_sequence(WmEmptySeq
, "WmEnableMenuItem", FALSE
);
3616 state
= GetMenuState(hmenu
, SC_CLOSE
, MF_BYCOMMAND
);
3617 ok(state
!= 0xffffffff, "wrong SC_CLOSE state %x\n", state
);
3618 ok(!(state
& (MF_DISABLED
| MF_GRAYED
)), "wrong SC_CLOSE state %x\n", state
);
3620 /* test whether removing WS_SYSMENU destroys a system menu */
3621 SetWindowLongW(hwnd
, GWL_STYLE
, WS_POPUP
);
3622 SetWindowPos(hwnd
, 0, 0, 0, 0, 0, SWP_NOZORDER
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_FRAMECHANGED
);
3624 hmenu
= GetSystemMenu(hwnd
, FALSE
);
3625 ok(hmenu
!= 0, "GetSystemMenu error %d\n", GetLastError());
3627 DestroyWindow(hwnd
);
3629 /* test new window with CS_NOCLOSE style */
3630 hwnd
= CreateWindowExA(0, "NoCloseWindowClass", NULL
, WS_OVERLAPPEDWINDOW
,
3631 100, 100, 200, 200, 0, 0, 0, NULL
);
3632 ok (hwnd
!= 0, "Failed to create overlapped window\n");
3634 hmenu
= GetSystemMenu(hwnd
, FALSE
);
3635 ok(hmenu
!= 0, "GetSystemMenu error %d\n", GetLastError());
3637 state
= GetMenuState(hmenu
, SC_CLOSE
, MF_BYCOMMAND
);
3638 ok(state
== 0xffffffff, "wrong SC_CLOSE state %x\n", state
);
3640 DestroyWindow(hwnd
);
3642 /* test new window without WS_SYSMENU style */
3643 hwnd
= CreateWindowExA(0, "NoCloseWindowClass", NULL
, WS_OVERLAPPEDWINDOW
& ~WS_SYSMENU
,
3644 100, 100, 200, 200, 0, 0, 0, NULL
);
3645 ok(hwnd
!= 0, "Failed to create overlapped window\n");
3647 hmenu
= GetSystemMenu(hwnd
, FALSE
);
3648 ok(!hmenu
, "GetSystemMenu error %d\n", GetLastError());
3650 DestroyWindow(hwnd
);
3653 /* For shown WS_OVERLAPPEDWINDOW */
3654 static const struct message WmSetIcon_1
[] = {
3655 { WM_SETICON
, sent
},
3656 { 0x00AE, sent
|defwinproc
|optional
}, /* XP */
3657 { WM_GETTEXT
, sent
|defwinproc
|optional
},
3658 { WM_GETTEXT
, sent
|defwinproc
|optional
}, /* XP sends a duplicate */
3662 /* For WS_POPUP and hidden WS_OVERLAPPEDWINDOW */
3663 static const struct message WmSetIcon_2
[] = {
3664 { WM_SETICON
, sent
},
3668 static void test_MsgWaitForMultipleObjects(HWND hwnd
)
3673 ret
= MsgWaitForMultipleObjects(0, NULL
, FALSE
, 0, QS_POSTMESSAGE
);
3674 ok(ret
== WAIT_TIMEOUT
, "MsgWaitForMultipleObjects returned %x\n", ret
);
3676 PostMessageA(hwnd
, WM_USER
, 0, 0);
3678 ret
= MsgWaitForMultipleObjects(0, NULL
, FALSE
, 0, QS_POSTMESSAGE
);
3679 ok(ret
== WAIT_OBJECT_0
, "MsgWaitForMultipleObjects returned %x\n", ret
);
3681 ok(PeekMessageW( &msg
, 0, 0, 0, PM_REMOVE
), "PeekMessage should succeed\n");
3682 ok(msg
.message
== WM_USER
, "got %04x instead of WM_USER\n", msg
.message
);
3684 ret
= MsgWaitForMultipleObjects(0, NULL
, FALSE
, 0, QS_POSTMESSAGE
);
3685 ok(ret
== WAIT_TIMEOUT
, "MsgWaitForMultipleObjects returned %x\n", ret
);
3687 PostMessageA(hwnd
, WM_USER
, 0, 0);
3689 ret
= MsgWaitForMultipleObjects(0, NULL
, FALSE
, 0, QS_POSTMESSAGE
);
3690 ok(ret
== WAIT_OBJECT_0
, "MsgWaitForMultipleObjects returned %x\n", ret
);
3692 ok(PeekMessageW( &msg
, 0, 0, 0, PM_NOREMOVE
), "PeekMessage should succeed\n");
3693 ok(msg
.message
== WM_USER
, "got %04x instead of WM_USER\n", msg
.message
);
3695 /* shows QS_POSTMESSAGE flag is cleared in the PeekMessage call */
3696 ret
= MsgWaitForMultipleObjects(0, NULL
, FALSE
, 0, QS_POSTMESSAGE
);
3697 ok(ret
== WAIT_TIMEOUT
, "MsgWaitForMultipleObjects returned %x\n", ret
);
3699 PostMessageA(hwnd
, WM_USER
, 0, 0);
3701 /* new incoming message causes it to become signaled again */
3702 ret
= MsgWaitForMultipleObjects(0, NULL
, FALSE
, 0, QS_POSTMESSAGE
);
3703 ok(ret
== WAIT_OBJECT_0
, "MsgWaitForMultipleObjects returned %x\n", ret
);
3705 ok(PeekMessageW( &msg
, 0, 0, 0, PM_REMOVE
), "PeekMessage should succeed\n");
3706 ok(msg
.message
== WM_USER
, "got %04x instead of WM_USER\n", msg
.message
);
3707 ok(PeekMessageW( &msg
, 0, 0, 0, PM_REMOVE
), "PeekMessage should succeed\n");
3708 ok(msg
.message
== WM_USER
, "got %04x instead of WM_USER\n", msg
.message
);
3711 /* test if we receive the right sequence of messages */
3712 static void test_messages(void)
3714 HWND hwnd
, hparent
, hchild
;
3715 HWND hchild2
, hbutton
;
3721 hwnd
= CreateWindowExA(0, "TestWindowClass", "Test overlapped", WS_OVERLAPPEDWINDOW
,
3722 100, 100, 200, 200, 0, 0, 0, NULL
);
3723 ok (hwnd
!= 0, "Failed to create overlapped window\n");
3724 ok_sequence(WmCreateOverlappedSeq
, "CreateWindow:overlapped", FALSE
);
3726 /* test ShowWindow(SW_HIDE) on a newly created invisible window */
3727 ok( ShowWindow(hwnd
, SW_HIDE
) == FALSE
, "ShowWindow: window was visible\n" );
3728 ok_sequence(WmEmptySeq
, "ShowWindow(SW_HIDE):overlapped, invisible", FALSE
);
3730 /* test WM_SETREDRAW on a not visible top level window */
3731 test_WM_SETREDRAW(hwnd
);
3733 SetWindowPos(hwnd
, 0,0,0,0,0, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
);
3734 ok_sequence(WmSWP_ShowOverlappedSeq
, "SetWindowPos:SWP_SHOWWINDOW:overlapped", FALSE
);
3735 ok(IsWindowVisible(hwnd
), "window should be visible at this point\n");
3737 ok(GetActiveWindow() == hwnd
, "window should be active\n");
3738 ok(GetFocus() == hwnd
, "window should have input focus\n");
3739 ShowWindow(hwnd
, SW_HIDE
);
3740 ok_sequence(WmHideOverlappedSeq
, "ShowWindow(SW_HIDE):overlapped", TRUE
);
3742 ShowWindow(hwnd
, SW_SHOW
);
3743 ok_sequence(WmShowOverlappedSeq
, "ShowWindow(SW_SHOW):overlapped", TRUE
);
3745 ShowWindow(hwnd
, SW_HIDE
);
3746 ok_sequence(WmHideOverlappedSeq
, "ShowWindow(SW_HIDE):overlapped", FALSE
);
3748 ShowWindow(hwnd
, SW_SHOWMAXIMIZED
);
3749 ok_sequence(WmShowMaxOverlappedSeq
, "ShowWindow(SW_SHOWMAXIMIZED):overlapped", TRUE
);
3751 ShowWindow(hwnd
, SW_RESTORE
);
3752 /* FIXME: add ok_sequence() here */
3755 ShowWindow(hwnd
, SW_MINIMIZE
);
3756 ok_sequence(WmShowMinOverlappedSeq
, "ShowWindow(SW_SHOWMINIMIZED):overlapped", TRUE
);
3759 ShowWindow(hwnd
, SW_RESTORE
);
3760 /* FIXME: add ok_sequence() here */
3763 ShowWindow(hwnd
, SW_SHOW
);
3764 ok_sequence(WmEmptySeq
, "ShowWindow(SW_SHOW):overlapped already visible", FALSE
);
3766 ok(GetActiveWindow() == hwnd
, "window should be active\n");
3767 ok(GetFocus() == hwnd
, "window should have input focus\n");
3768 SetWindowPos(hwnd
, 0,0,0,0,0, SWP_HIDEWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
);
3769 ok_sequence(WmSWP_HideOverlappedSeq
, "SetWindowPos:SWP_HIDEWINDOW:overlapped", FALSE
);
3770 ok(!IsWindowVisible(hwnd
), "window should not be visible at this point\n");
3771 ok(GetActiveWindow() == hwnd
, "window should still be active\n");
3773 /* test WM_SETREDRAW on a visible top level window */
3774 ShowWindow(hwnd
, SW_SHOW
);
3775 test_WM_SETREDRAW(hwnd
);
3777 trace("testing scroll APIs on a visible top level window %p\n", hwnd
);
3778 test_scroll_messages(hwnd
);
3780 /* test resizing and moving */
3781 SetWindowPos( hwnd
, 0, 0, 0, 300, 300, SWP_NOMOVE
|SWP_NOACTIVATE
);
3782 ok_sequence(WmSWP_ResizeSeq
, "SetWindowPos:Resize", FALSE
);
3785 SetWindowPos( hwnd
, 0, 200, 200, 0, 0, SWP_NOSIZE
|SWP_NOACTIVATE
);
3786 ok_sequence(WmSWP_MoveSeq
, "SetWindowPos:Move", FALSE
);
3789 SetWindowPos( hwnd
, 0, 200, 200, 250, 250, SWP_NOZORDER
);
3790 ok_sequence(WmSWP_ResizeNoZOrder
, "SetWindowPos:WmSWP_ResizeNoZOrder", FALSE
);
3794 /* popups don't get WM_GETMINMAXINFO */
3795 SetWindowLongW( hwnd
, GWL_STYLE
, WS_VISIBLE
|WS_POPUP
);
3796 SetWindowPos( hwnd
, 0, 0, 0, 0, 0, SWP_NOZORDER
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_FRAMECHANGED
);
3798 SetWindowPos( hwnd
, 0, 0, 0, 200, 200, SWP_NOMOVE
|SWP_NOACTIVATE
);
3799 ok_sequence(WmSWP_ResizePopupSeq
, "SetWindowPos:ResizePopup", FALSE
);
3801 DestroyWindow(hwnd
);
3802 ok_sequence(WmDestroyOverlappedSeq
, "DestroyWindow:overlapped", FALSE
);
3804 hparent
= CreateWindowExA(0, "TestParentClass", "Test parent", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
3805 100, 100, 200, 200, 0, 0, 0, NULL
);
3806 ok (hparent
!= 0, "Failed to create parent window\n");
3809 hchild
= CreateWindowExA(0, "TestWindowClass", "Test child", WS_CHILD
| WS_MAXIMIZE
,
3810 0, 0, 10, 10, hparent
, 0, 0, NULL
);
3811 ok (hchild
!= 0, "Failed to create child window\n");
3812 ok_sequence(WmCreateMaximizedChildSeq
, "CreateWindow:maximized child", FALSE
);
3813 DestroyWindow(hchild
);
3816 /* visible child window with a caption */
3817 hchild
= CreateWindowExA(0, "TestWindowClass", "Test child",
3818 WS_CHILD
| WS_VISIBLE
| WS_CAPTION
,
3819 0, 0, 10, 10, hparent
, 0, 0, NULL
);
3820 ok (hchild
!= 0, "Failed to create child window\n");
3821 ok_sequence(WmCreateVisibleChildSeq
, "CreateWindow:visible child", FALSE
);
3823 trace("testing scroll APIs on a visible child window %p\n", hchild
);
3824 test_scroll_messages(hchild
);
3826 SetWindowPos(hchild
, 0,0,0,0,0, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
);
3827 ok_sequence(WmShowChildSeq_4
, "SetWindowPos(SWP_SHOWWINDOW):child with a caption", FALSE
);
3829 DestroyWindow(hchild
);
3832 hchild
= CreateWindowExA(0, "TestWindowClass", "Test child", WS_CHILD
,
3833 0, 0, 10, 10, hparent
, 0, 0, NULL
);
3834 ok (hchild
!= 0, "Failed to create child window\n");
3835 ok_sequence(WmCreateChildSeq
, "CreateWindow:child", FALSE
);
3837 hchild2
= CreateWindowExA(0, "SimpleWindowClass", "Test child2", WS_CHILD
,
3838 100, 100, 50, 50, hparent
, 0, 0, NULL
);
3839 ok (hchild2
!= 0, "Failed to create child2 window\n");
3842 hbutton
= CreateWindowExA(0, "TestWindowClass", "Test button", WS_CHILD
,
3843 0, 100, 50, 50, hchild
, 0, 0, NULL
);
3844 ok (hbutton
!= 0, "Failed to create button window\n");
3846 /* test WM_SETREDRAW on a not visible child window */
3847 test_WM_SETREDRAW(hchild
);
3849 ShowWindow(hchild
, SW_SHOW
);
3850 ok_sequence(WmShowChildSeq
, "ShowWindow(SW_SHOW):child", FALSE
);
3852 ShowWindow(hchild
, SW_HIDE
);
3853 ok_sequence(WmHideChildSeq
, "ShowWindow(SW_HIDE):child", FALSE
);
3855 ShowWindow(hchild
, SW_SHOW
);
3856 ok_sequence(WmShowChildSeq
, "ShowWindow(SW_SHOW):child", FALSE
);
3858 /* test WM_SETREDRAW on a visible child window */
3859 test_WM_SETREDRAW(hchild
);
3861 MoveWindow(hchild
, 10, 10, 20, 20, TRUE
);
3862 ok_sequence(WmResizingChildWithMoveWindowSeq
, "MoveWindow:child", FALSE
);
3864 ShowWindow(hchild
, SW_HIDE
);
3866 SetWindowPos(hchild
, 0,0,0,0,0, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
);
3867 ok_sequence(WmShowChildSeq_2
, "SetWindowPos:show_child_2", FALSE
);
3869 ShowWindow(hchild
, SW_HIDE
);
3871 SetWindowPos(hchild
, 0,0,0,0,0, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOACTIVATE
);
3872 ok_sequence(WmShowChildSeq_3
, "SetWindowPos:show_child_3", FALSE
);
3874 /* DestroyWindow sequence below expects that a child has focus */
3878 DestroyWindow(hchild
);
3879 ok_sequence(WmDestroyChildSeq
, "DestroyWindow:child", FALSE
);
3880 DestroyWindow(hchild2
);
3881 DestroyWindow(hbutton
);
3884 hchild
= CreateWindowExA(0, "TestWindowClass", "Test Child Popup", WS_CHILD
| WS_POPUP
,
3885 0, 0, 100, 100, hparent
, 0, 0, NULL
);
3886 ok (hchild
!= 0, "Failed to create child popup window\n");
3887 ok_sequence(WmCreateChildPopupSeq
, "CreateWindow:child_popup", FALSE
);
3888 DestroyWindow(hchild
);
3890 /* test what happens to a window which sets WS_VISIBLE in WM_CREATE */
3892 hchild
= CreateWindowExA(0, "TestPopupClass", "Test Popup", WS_POPUP
,
3893 0, 0, 100, 100, hparent
, 0, 0, NULL
);
3894 ok (hchild
!= 0, "Failed to create popup window\n");
3895 ok_sequence(WmCreateInvisiblePopupSeq
, "CreateWindow:invisible_popup", FALSE
);
3896 ok(GetWindowLongA(hchild
, GWL_STYLE
) & WS_VISIBLE
, "WS_VISIBLE should be set\n");
3897 ok(IsWindowVisible(hchild
), "IsWindowVisible() should return TRUE\n");
3899 ShowWindow(hchild
, SW_SHOW
);
3900 ok_sequence(WmEmptySeq
, "ShowWindow:show_visible_popup", FALSE
);
3902 SetWindowPos(hchild
, 0,0,0,0,0, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOACTIVATE
|SWP_NOZORDER
);
3903 ok_sequence(WmShowVisiblePopupSeq_2
, "SetWindowPos:show_visible_popup_2", FALSE
);
3905 SetWindowPos(hchild
, 0,0,0,0,0, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
);
3906 ok_sequence(WmShowVisiblePopupSeq_3
, "SetWindowPos:show_visible_popup_3", FALSE
);
3907 DestroyWindow(hchild
);
3909 /* this time add WS_VISIBLE for CreateWindowEx, but this fact actually
3910 * changes nothing in message sequences.
3913 hchild
= CreateWindowExA(0, "TestPopupClass", "Test Popup", WS_POPUP
| WS_VISIBLE
,
3914 0, 0, 100, 100, hparent
, 0, 0, NULL
);
3915 ok (hchild
!= 0, "Failed to create popup window\n");
3916 ok_sequence(WmCreateInvisiblePopupSeq
, "CreateWindow:invisible_popup", FALSE
);
3917 ok(GetWindowLongA(hchild
, GWL_STYLE
) & WS_VISIBLE
, "WS_VISIBLE should be set\n");
3918 ok(IsWindowVisible(hchild
), "IsWindowVisible() should return TRUE\n");
3920 ShowWindow(hchild
, SW_SHOW
);
3921 ok_sequence(WmEmptySeq
, "ShowWindow:show_visible_popup", FALSE
);
3923 SetWindowPos(hchild
, 0,0,0,0,0, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOACTIVATE
|SWP_NOZORDER
);
3924 ok_sequence(WmShowVisiblePopupSeq_2
, "SetWindowPos:show_visible_popup_2", FALSE
);
3925 DestroyWindow(hchild
);
3928 hwnd
= CreateWindowExA(WS_EX_DLGMODALFRAME
, "TestDialogClass", NULL
, WS_VISIBLE
|WS_CAPTION
|WS_SYSMENU
|WS_DLGFRAME
,
3929 0, 0, 100, 100, hparent
, 0, 0, NULL
);
3930 ok(hwnd
!= 0, "Failed to create custom dialog window\n");
3931 ok_sequence(WmCreateCustomDialogSeq
, "CreateCustomDialog", TRUE
);
3934 trace("testing scroll APIs on a visible dialog %p\n", hwnd);
3935 test_scroll_messages(hwnd);
3941 SendMessage(hwnd
, WM_NULL
, 0, 0);
3944 after_end_dialog
= 1;
3945 EndDialog( hwnd
, 0 );
3946 ok_sequence(WmEndCustomDialogSeq
, "EndCustomDialog", FALSE
);
3948 DestroyWindow(hwnd
);
3949 after_end_dialog
= 0;
3952 hwnd
= CreateWindowExA(0, "TestDialogClass", NULL
, WS_POPUP
,
3953 0, 0, 100, 100, 0, 0, GetModuleHandleA(0), NULL
);
3954 ok(hwnd
!= 0, "Failed to create custom dialog window\n");
3956 trace("call ShowWindow(%p, SW_SHOW)\n", hwnd
);
3957 ShowWindow(hwnd
, SW_SHOW
);
3958 ok_sequence(WmShowCustomDialogSeq
, "ShowCustomDialog", TRUE
);
3959 DestroyWindow(hwnd
);
3962 DialogBoxA( 0, "TEST_DIALOG", hparent
, TestModalDlgProcA
);
3963 ok_sequence(WmModalDialogSeq
, "ModalDialog", TRUE
);
3965 DestroyWindow(hparent
);
3968 /* Message sequence for SetMenu */
3969 ok(!DrawMenuBar(hwnd
), "DrawMenuBar should return FALSE for a window without a menu\n");
3970 ok_sequence(WmEmptySeq
, "DrawMenuBar for a window without a menu", FALSE
);
3972 hmenu
= CreateMenu();
3973 ok (hmenu
!= 0, "Failed to create menu\n");
3974 ok (InsertMenuA(hmenu
, -1, MF_BYPOSITION
, 0x1000, "foo"), "InsertMenu failed\n");
3975 hwnd
= CreateWindowExA(0, "TestWindowClass", "Test overlapped", WS_OVERLAPPEDWINDOW
,
3976 100, 100, 200, 200, 0, hmenu
, 0, NULL
);
3977 ok_sequence(WmCreateOverlappedSeq
, "CreateWindow:overlapped", FALSE
);
3978 ok (SetMenu(hwnd
, 0), "SetMenu\n");
3979 ok_sequence(WmSetMenuNonVisibleSizeChangeSeq
, "SetMenu:NonVisibleSizeChange", FALSE
);
3980 ok (SetMenu(hwnd
, 0), "SetMenu\n");
3981 ok_sequence(WmSetMenuNonVisibleNoSizeChangeSeq
, "SetMenu:NonVisibleNoSizeChange", FALSE
);
3982 ShowWindow(hwnd
, SW_SHOW
);
3983 UpdateWindow( hwnd
);
3984 while (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
3986 ok (SetMenu(hwnd
, 0), "SetMenu\n");
3987 ok_sequence(WmSetMenuVisibleNoSizeChangeSeq
, "SetMenu:VisibleNoSizeChange", FALSE
);
3988 ok (SetMenu(hwnd
, hmenu
), "SetMenu\n");
3989 ok_sequence(WmSetMenuVisibleSizeChangeSeq
, "SetMenu:VisibleSizeChange", FALSE
);
3991 UpdateWindow( hwnd
);
3992 while (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
3994 ok(DrawMenuBar(hwnd
), "DrawMenuBar\n");
3995 while (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
3996 ok_sequence(WmDrawMenuBarSeq
, "DrawMenuBar", FALSE
);
3998 DestroyWindow(hwnd
);
4001 /* Message sequence for EnableWindow */
4002 hparent
= CreateWindowExA(0, "TestWindowClass", "Test parent", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
4003 100, 100, 200, 200, 0, 0, 0, NULL
);
4004 ok (hparent
!= 0, "Failed to create parent window\n");
4005 hchild
= CreateWindowExA(0, "TestWindowClass", "Test child", WS_CHILD
| WS_VISIBLE
,
4006 0, 0, 10, 10, hparent
, 0, 0, NULL
);
4007 ok (hchild
!= 0, "Failed to create child window\n");
4013 EnableWindow(hparent
, FALSE
);
4014 ok_sequence(WmEnableWindowSeq_1
, "EnableWindow(FALSE)", FALSE
);
4016 EnableWindow(hparent
, TRUE
);
4017 ok_sequence(WmEnableWindowSeq_2
, "EnableWindow(TRUE)", FALSE
);
4019 while (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
4022 test_MsgWaitForMultipleObjects(hparent
);
4024 /* the following test causes an exception in user.exe under win9x */
4025 if (!PostMessageW( hparent
, WM_USER
, 0, 0 ))
4027 DestroyWindow(hparent
);
4031 PostMessageW( hparent
, WM_USER
+1, 0, 0 );
4032 /* PeekMessage(NULL) fails, but still removes the message */
4033 SetLastError(0xdeadbeef);
4034 ok( !PeekMessageW( NULL
, 0, 0, 0, PM_REMOVE
), "PeekMessage(NULL) should fail\n" );
4035 ok( GetLastError() == ERROR_NOACCESS
|| /* Win2k */
4036 GetLastError() == 0xdeadbeef, /* NT4 */
4037 "last error is %d\n", GetLastError() );
4038 ok( PeekMessageW( &msg
, 0, 0, 0, PM_REMOVE
), "PeekMessage should succeed\n" );
4039 ok( msg
.message
== WM_USER
+1, "got %x instead of WM_USER+1\n", msg
.message
);
4041 DestroyWindow(hchild
);
4042 DestroyWindow(hparent
);
4045 /* Message sequences for WM_SETICON */
4046 trace("testing WM_SETICON\n");
4047 hwnd
= CreateWindowExA(0, "TestWindowClass", NULL
, WS_OVERLAPPEDWINDOW
,
4048 CW_USEDEFAULT
, CW_USEDEFAULT
, 300, 300, 0,
4050 ShowWindow(hwnd
, SW_SHOW
);
4052 while (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
4054 SendMessage(hwnd
, WM_SETICON
, ICON_SMALL
, (LPARAM
)LoadIcon(0, IDI_APPLICATION
));
4055 ok_sequence(WmSetIcon_1
, "WM_SETICON for shown window with caption", FALSE
);
4057 ShowWindow(hwnd
, SW_HIDE
);
4058 while (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
4060 SendMessage(hwnd
, WM_SETICON
, ICON_SMALL
, (LPARAM
)LoadIcon(0, IDI_APPLICATION
));
4061 ok_sequence(WmSetIcon_2
, "WM_SETICON for hidden window with caption", FALSE
);
4062 DestroyWindow(hwnd
);
4065 hwnd
= CreateWindowExA(0, "TestPopupClass", NULL
, WS_POPUP
,
4066 CW_USEDEFAULT
, CW_USEDEFAULT
, 300, 300, 0,
4068 ShowWindow(hwnd
, SW_SHOW
);
4070 while (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
4072 SendMessage(hwnd
, WM_SETICON
, ICON_SMALL
, (LPARAM
)LoadIcon(0, IDI_APPLICATION
));
4073 ok_sequence(WmSetIcon_2
, "WM_SETICON for shown window without caption", FALSE
);
4075 ShowWindow(hwnd
, SW_HIDE
);
4076 while (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
4078 SendMessage(hwnd
, WM_SETICON
, ICON_SMALL
, (LPARAM
)LoadIcon(0, IDI_APPLICATION
));
4079 ok_sequence(WmSetIcon_2
, "WM_SETICON for hidden window without caption", FALSE
);
4080 DestroyWindow(hwnd
);
4084 static void invisible_parent_tests(void)
4086 HWND hparent
, hchild
;
4088 hparent
= CreateWindowExA(0, "TestParentClass", "Test parent", WS_OVERLAPPEDWINDOW
,
4089 100, 100, 200, 200, 0, 0, 0, NULL
);
4090 ok (hparent
!= 0, "Failed to create parent window\n");
4093 /* test showing child with hidden parent */
4095 hchild
= CreateWindowExA(0, "TestWindowClass", "Test child", WS_CHILD
,
4096 0, 0, 10, 10, hparent
, 0, 0, NULL
);
4097 ok (hchild
!= 0, "Failed to create child window\n");
4098 ok_sequence(WmCreateChildSeq
, "CreateWindow:child", FALSE
);
4100 ShowWindow( hchild
, SW_MINIMIZE
);
4101 ok_sequence(WmShowChildInvisibleParentSeq_1
, "ShowWindow(SW_MINIMIZE) child with invisible parent", FALSE
);
4102 ok(GetWindowLongA(hchild
, GWL_STYLE
) & WS_VISIBLE
, "WS_VISIBLE should be set\n");
4103 ok(!IsWindowVisible(hchild
), "IsWindowVisible() should return FALSE\n");
4108 ShowWindow( hchild
, SW_MINIMIZE
);
4109 ok_sequence(WmShowChildInvisibleParentSeq_1r
, "ShowWindow(SW_MINIMIZE) child with invisible parent", FALSE
);
4111 DestroyWindow(hchild
);
4112 hchild
= CreateWindowExA(0, "TestWindowClass", "Test child", WS_CHILD
,
4113 0, 0, 10, 10, hparent
, 0, 0, NULL
);
4116 ShowWindow( hchild
, SW_MAXIMIZE
);
4117 ok_sequence(WmShowChildInvisibleParentSeq_2
, "ShowWindow(SW_MAXIMIZE) child with invisible parent", FALSE
);
4118 ok(GetWindowLongA(hchild
, GWL_STYLE
) & WS_VISIBLE
, "WS_VISIBLE should be set\n");
4119 ok(!IsWindowVisible(hchild
), "IsWindowVisible() should return FALSE\n");
4124 ShowWindow( hchild
, SW_MAXIMIZE
);
4125 ok_sequence(WmShowChildInvisibleParentSeq_2r
, "ShowWindow(SW_MAXIMIZE) child with invisible parent", FALSE
);
4127 DestroyWindow(hchild
);
4128 hchild
= CreateWindowExA(0, "TestWindowClass", "Test child", WS_CHILD
,
4129 0, 0, 10, 10, hparent
, 0, 0, NULL
);
4132 ShowWindow( hchild
, SW_RESTORE
);
4133 ok_sequence(WmShowChildInvisibleParentSeq_5
, "ShowWindow(SW_RESTORE) child with invisible parent", FALSE
);
4134 ok(GetWindowLongA(hchild
, GWL_STYLE
) & WS_VISIBLE
, "WS_VISIBLE should be set\n");
4135 ok(!IsWindowVisible(hchild
), "IsWindowVisible() should return FALSE\n");
4137 DestroyWindow(hchild
);
4138 hchild
= CreateWindowExA(0, "TestWindowClass", "Test child", WS_CHILD
,
4139 0, 0, 10, 10, hparent
, 0, 0, NULL
);
4142 ShowWindow( hchild
, SW_SHOWMINIMIZED
);
4143 ok_sequence(WmShowChildInvisibleParentSeq_3
, "ShowWindow(SW_SHOWMINIMIZED) child with invisible parent", FALSE
);
4144 ok(GetWindowLongA(hchild
, GWL_STYLE
) & WS_VISIBLE
, "WS_VISIBLE should be set\n");
4145 ok(!IsWindowVisible(hchild
), "IsWindowVisible() should return FALSE\n");
4150 ShowWindow( hchild
, SW_SHOWMINIMIZED
);
4151 ok_sequence(WmShowChildInvisibleParentSeq_3r
, "ShowWindow(SW_SHOWMINIMIZED) child with invisible parent", FALSE
);
4153 DestroyWindow(hchild
);
4154 hchild
= CreateWindowExA(0, "TestWindowClass", "Test child", WS_CHILD
,
4155 0, 0, 10, 10, hparent
, 0, 0, NULL
);
4158 /* same as ShowWindow( hchild, SW_MAXIMIZE ); */
4159 ShowWindow( hchild
, SW_SHOWMAXIMIZED
);
4160 ok_sequence(WmShowChildInvisibleParentSeq_2
, "ShowWindow(SW_SHOWMAXIMIZED) child with invisible parent", FALSE
);
4161 ok(GetWindowLongA(hchild
, GWL_STYLE
) & WS_VISIBLE
, "WS_VISIBLE should be set\n");
4162 ok(!IsWindowVisible(hchild
), "IsWindowVisible() should return FALSE\n");
4164 DestroyWindow(hchild
);
4165 hchild
= CreateWindowExA(0, "TestWindowClass", "Test child", WS_CHILD
,
4166 0, 0, 10, 10, hparent
, 0, 0, NULL
);
4169 ShowWindow( hchild
, SW_SHOWMINNOACTIVE
);
4170 ok_sequence(WmShowChildInvisibleParentSeq_4
, "ShowWindow(SW_SHOWMINNOACTIVE) child with invisible parent", FALSE
);
4171 ok(GetWindowLongA(hchild
, GWL_STYLE
) & WS_VISIBLE
, "WS_VISIBLE should be set\n");
4172 ok(!IsWindowVisible(hchild
), "IsWindowVisible() should return FALSE\n");
4177 ShowWindow( hchild
, SW_SHOWMINNOACTIVE
);
4178 ok_sequence(WmShowChildInvisibleParentSeq_4r
, "ShowWindow(SW_SHOWMINNOACTIVE) child with invisible parent", FALSE
);
4180 DestroyWindow(hchild
);
4181 hchild
= CreateWindowExA(0, "TestWindowClass", "Test child", WS_CHILD
,
4182 0, 0, 10, 10, hparent
, 0, 0, NULL
);
4185 /* FIXME: looks like XP SP2 doesn't know about SW_FORCEMINIMIZE at all */
4186 ShowWindow( hchild
, SW_FORCEMINIMIZE
);
4187 ok_sequence(WmEmptySeq
, "ShowWindow(SW_FORCEMINIMIZE) child with invisible parent", TRUE
);
4189 ok(!(GetWindowLongA(hchild
, GWL_STYLE
) & WS_VISIBLE
), "WS_VISIBLE should be not set\n");
4191 ok(!IsWindowVisible(hchild
), "IsWindowVisible() should return FALSE\n");
4193 DestroyWindow(hchild
);
4194 hchild
= CreateWindowExA(0, "TestWindowClass", "Test child", WS_CHILD
,
4195 0, 0, 10, 10, hparent
, 0, 0, NULL
);
4198 ShowWindow( hchild
, SW_SHOWNA
);
4199 ok_sequence(WmShowChildInvisibleParentSeq_5
, "ShowWindow(SW_SHOWNA) child with invisible parent", FALSE
);
4200 ok(GetWindowLongA(hchild
, GWL_STYLE
) & WS_VISIBLE
, "WS_VISIBLE should be set\n");
4201 ok(!IsWindowVisible(hchild
), "IsWindowVisible() should return FALSE\n");
4206 ShowWindow( hchild
, SW_SHOWNA
);
4207 ok_sequence(WmShowChildInvisibleParentSeq_5
, "ShowWindow(SW_SHOWNA) child with invisible parent", FALSE
);
4209 DestroyWindow(hchild
);
4210 hchild
= CreateWindowExA(0, "TestWindowClass", "Test child", WS_CHILD
,
4211 0, 0, 10, 10, hparent
, 0, 0, NULL
);
4214 ShowWindow( hchild
, SW_SHOW
);
4215 ok_sequence(WmShowChildInvisibleParentSeq_5
, "ShowWindow(SW_SHOW) child with invisible parent", FALSE
);
4216 ok(GetWindowLongA(hchild
, GWL_STYLE
) & WS_VISIBLE
, "WS_VISIBLE should be set\n");
4217 ok(!IsWindowVisible(hchild
), "IsWindowVisible() should return FALSE\n");
4222 ShowWindow( hchild
, SW_SHOW
);
4223 ok_sequence(WmEmptySeq
, "ShowWindow(SW_SHOW) child with invisible parent", FALSE
);
4225 ShowWindow( hchild
, SW_HIDE
);
4226 ok_sequence(WmHideChildInvisibleParentSeq
, "ShowWindow:hide child with invisible parent", FALSE
);
4227 ok(!(GetWindowLongA(hchild
, GWL_STYLE
) & WS_VISIBLE
), "WS_VISIBLE should be not set\n");
4228 ok(!IsWindowVisible(hchild
), "IsWindowVisible() should return FALSE\n");
4230 SetWindowPos(hchild
, 0,0,0,0,0, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOACTIVATE
|SWP_NOZORDER
);
4231 ok_sequence(WmShowChildInvisibleParentSeq_6
, "SetWindowPos:show child with invisible parent", FALSE
);
4232 ok(GetWindowLongA(hchild
, GWL_STYLE
) & WS_VISIBLE
, "WS_VISIBLE should be set\n");
4233 ok(!IsWindowVisible(hchild
), "IsWindowVisible() should return FALSE\n");
4235 SetWindowPos(hchild
, 0,0,0,0,0, SWP_HIDEWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOACTIVATE
|SWP_NOZORDER
);
4236 ok_sequence(WmHideChildInvisibleParentSeq_2
, "SetWindowPos:hide child with invisible parent", FALSE
);
4237 ok(!(GetWindowLongA(hchild
, GWL_STYLE
) & WS_VISIBLE
), "WS_VISIBLE should not be set\n");
4238 ok(!IsWindowVisible(hchild
), "IsWindowVisible() should return FALSE\n");
4240 SetWindowPos(hchild
, 0,0,0,0,0, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOACTIVATE
|SWP_NOZORDER
);
4242 DestroyWindow(hchild
);
4243 ok_sequence(WmDestroyInvisibleChildSeq
, "DestroyInvisibleChildSeq", FALSE
);
4245 DestroyWindow(hparent
);
4249 /****************** button message test *************************/
4250 static const struct message WmSetFocusButtonSeq
[] =
4252 { HCBT_SETFOCUS
, hook
},
4253 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 1 },
4254 { WM_IME_NOTIFY
, sent
|wparam
|defwinproc
|optional
, 2 },
4255 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
4256 { WM_SETFOCUS
, sent
|wparam
, 0 },
4257 { WM_CTLCOLORBTN
, sent
|defwinproc
},
4260 static const struct message WmKillFocusButtonSeq
[] =
4262 { HCBT_SETFOCUS
, hook
},
4263 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
4264 { WM_KILLFOCUS
, sent
|wparam
, 0 },
4265 { WM_CTLCOLORBTN
, sent
|defwinproc
},
4266 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 0 },
4267 { WM_IME_NOTIFY
, sent
|wparam
|defwinproc
|optional
, 1 },
4270 static const struct message WmSetFocusStaticSeq
[] =
4272 { HCBT_SETFOCUS
, hook
},
4273 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 1 },
4274 { WM_IME_NOTIFY
, sent
|wparam
|defwinproc
|optional
, 2 },
4275 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
4276 { WM_SETFOCUS
, sent
|wparam
, 0 },
4277 { WM_CTLCOLORSTATIC
, sent
|defwinproc
},
4280 static const struct message WmKillFocusStaticSeq
[] =
4282 { HCBT_SETFOCUS
, hook
},
4283 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
4284 { WM_KILLFOCUS
, sent
|wparam
, 0 },
4285 { WM_CTLCOLORSTATIC
, sent
|defwinproc
},
4286 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 0 },
4287 { WM_IME_NOTIFY
, sent
|wparam
|defwinproc
|optional
, 1 },
4290 static const struct message WmLButtonDownSeq
[] =
4292 { WM_LBUTTONDOWN
, sent
|wparam
|lparam
, 0, 0 },
4293 { EVENT_SYSTEM_CAPTURESTART
, winevent_hook
|wparam
|lparam
, 0, 0 },
4294 { HCBT_SETFOCUS
, hook
},
4295 { WM_IME_SETCONTEXT
, sent
|wparam
|defwinproc
|optional
, 1 },
4296 { WM_IME_NOTIFY
, sent
|wparam
|defwinproc
|optional
, 2 },
4297 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
4298 { WM_SETFOCUS
, sent
|wparam
|defwinproc
, 0 },
4299 { WM_CTLCOLORBTN
, sent
|defwinproc
},
4300 { BM_SETSTATE
, sent
|wparam
|defwinproc
, TRUE
},
4301 { WM_CTLCOLORBTN
, sent
|defwinproc
},
4302 { EVENT_OBJECT_STATECHANGE
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
4305 static const struct message WmLButtonUpSeq
[] =
4307 { WM_LBUTTONUP
, sent
|wparam
|lparam
, 0, 0 },
4308 { BM_SETSTATE
, sent
|wparam
|defwinproc
, FALSE
},
4309 { WM_CTLCOLORBTN
, sent
|defwinproc
},
4310 { EVENT_OBJECT_STATECHANGE
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
4311 { EVENT_SYSTEM_CAPTUREEND
, winevent_hook
|wparam
|lparam
, 0, 0 },
4312 { WM_CAPTURECHANGED
, sent
|wparam
|defwinproc
, 0 },
4315 static const struct message WmSetFontButtonSeq
[] =
4317 { WM_SETFONT
, sent
},
4319 { WM_ERASEBKGND
, sent
|defwinproc
|optional
},
4320 { WM_CTLCOLORBTN
, sent
|defwinproc
},
4324 static WNDPROC old_button_proc
;
4326 static LRESULT CALLBACK
button_hook_proc(HWND hwnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
4328 static long defwndproc_counter
= 0;
4332 trace("button: %p, %04x, %08lx, %08lx\n", hwnd
, message
, wParam
, lParam
);
4334 /* explicitly ignore WM_GETICON message */
4335 if (message
== WM_GETICON
) return 0;
4337 msg
.message
= message
;
4338 msg
.flags
= sent
|wparam
|lparam
;
4339 if (defwndproc_counter
) msg
.flags
|= defwinproc
;
4340 msg
.wParam
= wParam
;
4341 msg
.lParam
= lParam
;
4344 if (message
== BM_SETSTATE
)
4345 ok(GetCapture() == hwnd
, "GetCapture() = %p\n", GetCapture());
4347 defwndproc_counter
++;
4348 ret
= CallWindowProcA(old_button_proc
, hwnd
, message
, wParam
, lParam
);
4349 defwndproc_counter
--;
4354 static void subclass_button(void)
4358 if (!GetClassInfoA(0, "button", &cls
)) assert(0);
4360 old_button_proc
= cls
.lpfnWndProc
;
4362 cls
.hInstance
= GetModuleHandle(0);
4363 cls
.lpfnWndProc
= button_hook_proc
;
4364 cls
.lpszClassName
= "my_button_class";
4365 UnregisterClass(cls
.lpszClassName
, cls
.hInstance
);
4366 if (!RegisterClassA(&cls
)) assert(0);
4369 static void test_button_messages(void)
4375 const struct message
*setfocus
;
4376 const struct message
*killfocus
;
4378 { BS_PUSHBUTTON
, DLGC_BUTTON
| DLGC_UNDEFPUSHBUTTON
,
4379 WmSetFocusButtonSeq
, WmKillFocusButtonSeq
},
4380 { BS_DEFPUSHBUTTON
, DLGC_BUTTON
| DLGC_DEFPUSHBUTTON
,
4381 WmSetFocusButtonSeq
, WmKillFocusButtonSeq
},
4382 { BS_CHECKBOX
, DLGC_BUTTON
,
4383 WmSetFocusStaticSeq
, WmKillFocusStaticSeq
},
4384 { BS_AUTOCHECKBOX
, DLGC_BUTTON
,
4385 WmSetFocusStaticSeq
, WmKillFocusStaticSeq
},
4386 { BS_RADIOBUTTON
, DLGC_BUTTON
| DLGC_RADIOBUTTON
,
4387 WmSetFocusStaticSeq
, WmKillFocusStaticSeq
},
4388 { BS_3STATE
, DLGC_BUTTON
,
4389 WmSetFocusStaticSeq
, WmKillFocusStaticSeq
},
4390 { BS_AUTO3STATE
, DLGC_BUTTON
,
4391 WmSetFocusStaticSeq
, WmKillFocusStaticSeq
},
4392 { BS_GROUPBOX
, DLGC_STATIC
,
4393 WmSetFocusStaticSeq
, WmKillFocusStaticSeq
},
4394 { BS_USERBUTTON
, DLGC_BUTTON
| DLGC_UNDEFPUSHBUTTON
,
4395 WmSetFocusButtonSeq
, WmKillFocusButtonSeq
},
4396 { BS_AUTORADIOBUTTON
, DLGC_BUTTON
| DLGC_RADIOBUTTON
,
4397 WmSetFocusStaticSeq
, WmKillFocusStaticSeq
},
4398 { BS_OWNERDRAW
, DLGC_BUTTON
,
4399 WmSetFocusButtonSeq
, WmKillFocusButtonSeq
}
4408 for (i
= 0; i
< sizeof(button
)/sizeof(button
[0]); i
++)
4410 hwnd
= CreateWindowExA(0, "my_button_class", "test", button
[i
].style
| WS_POPUP
,
4411 0, 0, 50, 14, 0, 0, 0, NULL
);
4412 ok(hwnd
!= 0, "Failed to create button window\n");
4414 dlg_code
= SendMessageA(hwnd
, WM_GETDLGCODE
, 0, 0);
4415 ok(dlg_code
== button
[i
].dlg_code
, "%u: wrong dlg_code %08x\n", i
, dlg_code
);
4417 ShowWindow(hwnd
, SW_SHOW
);
4422 trace("button style %08x\n", button
[i
].style
);
4424 ok_sequence(button
[i
].setfocus
, "SetFocus(hwnd) on a button", FALSE
);
4427 ok_sequence(button
[i
].killfocus
, "SetFocus(0) on a button", FALSE
);
4429 DestroyWindow(hwnd
);
4432 hwnd
= CreateWindowExA(0, "my_button_class", "test", BS_PUSHBUTTON
| WS_POPUP
| WS_VISIBLE
,
4433 0, 0, 50, 14, 0, 0, 0, NULL
);
4434 ok(hwnd
!= 0, "Failed to create button window\n");
4439 SendMessageA(hwnd
, WM_LBUTTONDOWN
, 0, 0);
4440 ok_sequence(WmLButtonDownSeq
, "WM_LBUTTONDOWN on a button", FALSE
);
4442 SendMessageA(hwnd
, WM_LBUTTONUP
, 0, 0);
4443 ok_sequence(WmLButtonUpSeq
, "WM_LBUTTONUP on a button", FALSE
);
4446 zfont
= (HFONT
)GetStockObject(SYSTEM_FONT
);
4447 SendMessageA(hwnd
, WM_SETFONT
, (WPARAM
)zfont
, TRUE
);
4449 ok_sequence(WmSetFontButtonSeq
, "WM_SETFONT on a button", FALSE
);
4451 DestroyWindow(hwnd
);
4454 /****************** static message test *************************/
4455 static const struct message WmSetFontStaticSeq
[] =
4457 { WM_SETFONT
, sent
},
4458 { WM_PAINT
, sent
|defwinproc
},
4459 { WM_ERASEBKGND
, sent
|defwinproc
|optional
},
4460 { WM_CTLCOLORSTATIC
, sent
|defwinproc
},
4464 static WNDPROC old_static_proc
;
4466 static LRESULT CALLBACK
static_hook_proc(HWND hwnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
4468 static long defwndproc_counter
= 0;
4472 trace("static: %p, %04x, %08lx, %08lx\n", hwnd
, message
, wParam
, lParam
);
4474 /* explicitly ignore WM_GETICON message */
4475 if (message
== WM_GETICON
) return 0;
4477 msg
.message
= message
;
4478 msg
.flags
= sent
|wparam
|lparam
;
4479 if (defwndproc_counter
) msg
.flags
|= defwinproc
;
4480 msg
.wParam
= wParam
;
4481 msg
.lParam
= lParam
;
4485 defwndproc_counter
++;
4486 ret
= CallWindowProcA(old_static_proc
, hwnd
, message
, wParam
, lParam
);
4487 defwndproc_counter
--;
4492 static void subclass_static(void)
4496 if (!GetClassInfoA(0, "static", &cls
)) assert(0);
4498 old_static_proc
= cls
.lpfnWndProc
;
4500 cls
.hInstance
= GetModuleHandle(0);
4501 cls
.lpfnWndProc
= static_hook_proc
;
4502 cls
.lpszClassName
= "my_static_class";
4503 UnregisterClass(cls
.lpszClassName
, cls
.hInstance
);
4504 if (!RegisterClassA(&cls
)) assert(0);
4507 static void test_static_messages(void)
4509 /* FIXME: make as comprehensive as the button message test */
4514 const struct message
*setfont
;
4516 { SS_LEFT
, DLGC_STATIC
,
4517 WmSetFontStaticSeq
}
4525 for (i
= 0; i
< sizeof(static_ctrl
)/sizeof(static_ctrl
[0]); i
++)
4527 hwnd
= CreateWindowExA(0, "my_static_class", "test", static_ctrl
[i
].style
| WS_POPUP
,
4528 0, 0, 50, 14, 0, 0, 0, NULL
);
4529 ok(hwnd
!= 0, "Failed to create static window\n");
4531 dlg_code
= SendMessageA(hwnd
, WM_GETDLGCODE
, 0, 0);
4532 ok(dlg_code
== static_ctrl
[i
].dlg_code
, "%u: wrong dlg_code %08x\n", i
, dlg_code
);
4534 ShowWindow(hwnd
, SW_SHOW
);
4539 trace("static style %08x\n", static_ctrl
[i
].style
);
4540 SendMessage(hwnd
, WM_SETFONT
, (WPARAM
)GetStockObject(DEFAULT_GUI_FONT
), TRUE
);
4541 ok_sequence(static_ctrl
[i
].setfont
, "WM_SETFONT on a static", FALSE
);
4543 DestroyWindow(hwnd
);
4547 /************* painting message test ********************/
4549 void dump_region(HRGN hrgn
)
4552 RGNDATA
*data
= NULL
;
4557 printf( "null region\n" );
4560 if (!(size
= GetRegionData( hrgn
, 0, NULL
))) return;
4561 if (!(data
= HeapAlloc( GetProcessHeap(), 0, size
))) return;
4562 GetRegionData( hrgn
, size
, data
);
4563 printf("%d rects:", data
->rdh
.nCount
);
4564 for (i
= 0, rect
= (RECT
*)data
->Buffer
; i
< data
->rdh
.nCount
; i
++, rect
++)
4565 printf( " (%d,%d)-(%d,%d)", rect
->left
, rect
->top
, rect
->right
, rect
->bottom
);
4567 HeapFree( GetProcessHeap(), 0, data
);
4570 static void check_update_rgn( HWND hwnd
, HRGN hrgn
)
4574 HRGN tmp
= CreateRectRgn( 0, 0, 0, 0 );
4575 HRGN update
= CreateRectRgn( 0, 0, 0, 0 );
4577 ret
= GetUpdateRgn( hwnd
, update
, FALSE
);
4578 ok( ret
!= ERROR
, "GetUpdateRgn failed\n" );
4579 if (ret
== NULLREGION
)
4581 ok( !hrgn
, "Update region shouldn't be empty\n" );
4585 if (CombineRgn( tmp
, hrgn
, update
, RGN_XOR
) != NULLREGION
)
4587 ok( 0, "Regions are different\n" );
4588 if (winetest_debug
> 0)
4590 printf( "Update region: " );
4591 dump_region( update
);
4592 printf( "Wanted region: " );
4593 dump_region( hrgn
);
4597 GetRgnBox( update
, &r1
);
4598 GetUpdateRect( hwnd
, &r2
, FALSE
);
4599 ok( r1
.left
== r2
.left
&& r1
.top
== r2
.top
&& r1
.right
== r2
.right
&& r1
.bottom
== r2
.bottom
,
4600 "Rectangles are different: %d,%d-%d,%d / %d,%d-%d,%d\n",
4601 r1
.left
, r1
.top
, r1
.right
, r1
.bottom
, r2
.left
, r2
.top
, r2
.right
, r2
.bottom
);
4603 DeleteObject( tmp
);
4604 DeleteObject( update
);
4607 static const struct message WmInvalidateRgn
[] = {
4608 { WM_NCPAINT
, sent
},
4609 { WM_GETTEXT
, sent
|defwinproc
|optional
},
4613 static const struct message WmGetUpdateRect
[] = {
4614 { WM_NCPAINT
, sent
},
4615 { WM_GETTEXT
, sent
|defwinproc
|optional
},
4620 static const struct message WmInvalidateFull
[] = {
4621 { WM_NCPAINT
, sent
|wparam
, 1 },
4622 { WM_GETTEXT
, sent
|defwinproc
|optional
},
4626 static const struct message WmInvalidateErase
[] = {
4627 { WM_NCPAINT
, sent
|wparam
, 1 },
4628 { WM_GETTEXT
, sent
|defwinproc
|optional
},
4629 { WM_ERASEBKGND
, sent
},
4633 static const struct message WmInvalidatePaint
[] = {
4635 { WM_NCPAINT
, sent
|wparam
|beginpaint
, 1 },
4636 { WM_GETTEXT
, sent
|beginpaint
|defwinproc
|optional
},
4640 static const struct message WmInvalidateErasePaint
[] = {
4642 { WM_NCPAINT
, sent
|wparam
|beginpaint
, 1 },
4643 { WM_GETTEXT
, sent
|beginpaint
|defwinproc
|optional
},
4644 { WM_ERASEBKGND
, sent
|beginpaint
},
4648 static const struct message WmInvalidateErasePaint2
[] = {
4650 { WM_NCPAINT
, sent
|beginpaint
},
4651 { WM_GETTEXT
, sent
|beginpaint
|defwinproc
|optional
},
4652 { WM_ERASEBKGND
, sent
|beginpaint
},
4656 static const struct message WmErase
[] = {
4657 { WM_ERASEBKGND
, sent
},
4661 static const struct message WmPaint
[] = {
4666 static const struct message WmParentOnlyPaint
[] = {
4667 { WM_PAINT
, sent
|parent
},
4671 static const struct message WmInvalidateParent
[] = {
4672 { WM_NCPAINT
, sent
|parent
},
4673 { WM_GETTEXT
, sent
|defwinproc
|parent
|optional
},
4674 { WM_ERASEBKGND
, sent
|parent
},
4678 static const struct message WmInvalidateParentChild
[] = {
4679 { WM_NCPAINT
, sent
|parent
},
4680 { WM_GETTEXT
, sent
|defwinproc
|parent
|optional
},
4681 { WM_ERASEBKGND
, sent
|parent
},
4682 { WM_NCPAINT
, sent
},
4683 { WM_GETTEXT
, sent
|defwinproc
|optional
},
4684 { WM_ERASEBKGND
, sent
},
4688 static const struct message WmInvalidateParentChild2
[] = {
4689 { WM_ERASEBKGND
, sent
|parent
},
4690 { WM_NCPAINT
, sent
},
4691 { WM_GETTEXT
, sent
|defwinproc
|optional
},
4692 { WM_ERASEBKGND
, sent
},
4696 static const struct message WmParentPaint
[] = {
4697 { WM_PAINT
, sent
|parent
},
4702 static const struct message WmParentPaintNc
[] = {
4703 { WM_PAINT
, sent
|parent
},
4705 { WM_NCPAINT
, sent
|beginpaint
},
4706 { WM_GETTEXT
, sent
|beginpaint
|defwinproc
|optional
},
4707 { WM_ERASEBKGND
, sent
|beginpaint
},
4711 static const struct message WmChildPaintNc
[] = {
4713 { WM_NCPAINT
, sent
|beginpaint
},
4714 { WM_GETTEXT
, sent
|beginpaint
|defwinproc
|optional
},
4715 { WM_ERASEBKGND
, sent
|beginpaint
},
4719 static const struct message WmParentErasePaint
[] = {
4720 { WM_PAINT
, sent
|parent
},
4721 { WM_NCPAINT
, sent
|parent
|beginpaint
},
4722 { WM_GETTEXT
, sent
|parent
|beginpaint
|defwinproc
|optional
},
4723 { WM_ERASEBKGND
, sent
|parent
|beginpaint
},
4725 { WM_NCPAINT
, sent
|beginpaint
},
4726 { WM_GETTEXT
, sent
|beginpaint
|defwinproc
|optional
},
4727 { WM_ERASEBKGND
, sent
|beginpaint
},
4731 static const struct message WmParentOnlyNcPaint
[] = {
4732 { WM_PAINT
, sent
|parent
},
4733 { WM_NCPAINT
, sent
|parent
|beginpaint
},
4734 { WM_GETTEXT
, sent
|parent
|beginpaint
|defwinproc
|optional
},
4738 static const struct message WmSetParentStyle
[] = {
4739 { WM_STYLECHANGING
, sent
|parent
},
4740 { WM_STYLECHANGED
, sent
|parent
},
4744 static void test_paint_messages(void)
4750 HWND hparent
, hchild
;
4751 HRGN hrgn
= CreateRectRgn( 0, 0, 0, 0 );
4752 HRGN hrgn2
= CreateRectRgn( 0, 0, 0, 0 );
4753 HWND hwnd
= CreateWindowExA(0, "TestWindowClass", "Test overlapped", WS_OVERLAPPEDWINDOW
,
4754 100, 100, 200, 200, 0, 0, 0, NULL
);
4755 ok (hwnd
!= 0, "Failed to create overlapped window\n");
4757 ShowWindow( hwnd
, SW_SHOW
);
4758 UpdateWindow( hwnd
);
4762 check_update_rgn( hwnd
, 0 );
4763 SetRectRgn( hrgn
, 10, 10, 20, 20 );
4764 ret
= RedrawWindow( hwnd
, NULL
, hrgn
, RDW_INVALIDATE
);
4765 ok(ret
, "RedrawWindow returned %d instead of TRUE\n", ret
);
4766 check_update_rgn( hwnd
, hrgn
);
4767 SetRectRgn( hrgn2
, 20, 20, 30, 30 );
4768 ret
= RedrawWindow( hwnd
, NULL
, hrgn2
, RDW_INVALIDATE
);
4769 ok(ret
, "RedrawWindow returned %d instead of TRUE\n", ret
);
4770 CombineRgn( hrgn
, hrgn
, hrgn2
, RGN_OR
);
4771 check_update_rgn( hwnd
, hrgn
);
4772 /* validate everything */
4773 ret
= RedrawWindow( hwnd
, NULL
, NULL
, RDW_VALIDATE
);
4774 ok(ret
, "RedrawWindow returned %d instead of TRUE\n", ret
);
4775 check_update_rgn( hwnd
, 0 );
4777 /* test empty region */
4778 SetRectRgn( hrgn
, 10, 10, 10, 15 );
4779 ret
= RedrawWindow( hwnd
, NULL
, hrgn
, RDW_INVALIDATE
);
4780 ok(ret
, "RedrawWindow returned %d instead of TRUE\n", ret
);
4781 check_update_rgn( hwnd
, 0 );
4782 /* test empty rect */
4783 SetRect( &rect
, 10, 10, 10, 15 );
4784 ret
= RedrawWindow( hwnd
, &rect
, NULL
, RDW_INVALIDATE
);
4785 ok(ret
, "RedrawWindow returned %d instead of TRUE\n", ret
);
4786 check_update_rgn( hwnd
, 0 );
4788 /* flush pending messages */
4789 while (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
4792 GetClientRect( hwnd
, &rect
);
4793 SetRectRgn( hrgn
, 0, 0, rect
.right
- rect
.left
, rect
.bottom
- rect
.top
);
4794 /* MSDN: if hwnd parameter is NULL, InvalidateRect invalidates and redraws
4795 * all windows and sends WM_ERASEBKGND and WM_NCPAINT.
4797 trace("testing InvalidateRect(0, NULL, FALSE)\n");
4798 SetRectEmpty( &rect
);
4799 ok(InvalidateRect(0, &rect
, FALSE
), "InvalidateRect(0, &rc, FALSE) should fail\n");
4800 check_update_rgn( hwnd
, hrgn
);
4801 ok_sequence( WmInvalidateErase
, "InvalidateErase", FALSE
);
4802 while (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
4803 ok_sequence( WmPaint
, "Paint", FALSE
);
4804 RedrawWindow( hwnd
, NULL
, NULL
, RDW_VALIDATE
);
4805 check_update_rgn( hwnd
, 0 );
4807 /* MSDN: if hwnd parameter is NULL, ValidateRect invalidates and redraws
4808 * all windows and sends WM_ERASEBKGND and WM_NCPAINT.
4810 trace("testing ValidateRect(0, NULL)\n");
4811 SetRectEmpty( &rect
);
4812 ok(ValidateRect(0, &rect
), "ValidateRect(0, &rc) should not fail\n");
4813 check_update_rgn( hwnd
, hrgn
);
4814 ok_sequence( WmInvalidateErase
, "InvalidateErase", FALSE
);
4815 while (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
4816 ok_sequence( WmPaint
, "Paint", FALSE
);
4817 RedrawWindow( hwnd
, NULL
, NULL
, RDW_VALIDATE
);
4818 check_update_rgn( hwnd
, 0 );
4820 trace("testing InvalidateRgn(0, NULL, FALSE)\n");
4821 SetLastError(0xdeadbeef);
4822 ok(!InvalidateRgn(0, NULL
, FALSE
), "InvalidateRgn(0, NULL, FALSE) should fail\n");
4823 ok(GetLastError() == ERROR_INVALID_WINDOW_HANDLE
, "wrong error code %d\n", GetLastError());
4824 check_update_rgn( hwnd
, 0 );
4825 while (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
4826 ok_sequence( WmEmptySeq
, "WmEmptySeq", FALSE
);
4828 trace("testing ValidateRgn(0, NULL)\n");
4829 SetLastError(0xdeadbeef);
4830 ok(!ValidateRgn(0, NULL
), "ValidateRgn(0, NULL) should fail\n");
4831 ok(GetLastError() == ERROR_INVALID_WINDOW_HANDLE
, "wrong error code %d\n", GetLastError());
4832 check_update_rgn( hwnd
, 0 );
4833 while (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
4834 ok_sequence( WmEmptySeq
, "WmEmptySeq", FALSE
);
4836 /* now with frame */
4837 SetRectRgn( hrgn
, -5, -5, 20, 20 );
4839 /* flush pending messages */
4840 while (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
4843 RedrawWindow( hwnd
, NULL
, hrgn
, RDW_INVALIDATE
| RDW_FRAME
);
4844 ok_sequence( WmEmptySeq
, "EmptySeq", FALSE
);
4846 SetRectRgn( hrgn
, 0, 0, 20, 20 ); /* GetUpdateRgn clips to client area */
4847 check_update_rgn( hwnd
, hrgn
);
4850 RedrawWindow( hwnd
, NULL
, hrgn
, RDW_INVALIDATE
| RDW_FRAME
| RDW_ERASENOW
);
4851 ok_sequence( WmInvalidateRgn
, "InvalidateRgn", FALSE
);
4854 RedrawWindow( hwnd
, NULL
, NULL
, RDW_INVALIDATE
| RDW_FRAME
| RDW_ERASENOW
);
4855 ok_sequence( WmInvalidateFull
, "InvalidateFull", FALSE
);
4857 GetClientRect( hwnd
, &rect
);
4858 SetRectRgn( hrgn
, rect
.left
, rect
.top
, rect
.right
, rect
.bottom
);
4859 check_update_rgn( hwnd
, hrgn
);
4862 RedrawWindow( hwnd
, NULL
, NULL
, RDW_INVALIDATE
| RDW_FRAME
| RDW_ERASE
| RDW_ERASENOW
);
4863 ok_sequence( WmInvalidateErase
, "InvalidateErase", FALSE
);
4866 RedrawWindow( hwnd
, NULL
, NULL
, RDW_INVALIDATE
| RDW_FRAME
| RDW_ERASENOW
| RDW_UPDATENOW
);
4867 ok_sequence( WmInvalidatePaint
, "InvalidatePaint", FALSE
);
4868 check_update_rgn( hwnd
, 0 );
4871 RedrawWindow( hwnd
, NULL
, NULL
, RDW_INVALIDATE
| RDW_FRAME
| RDW_ERASE
| RDW_UPDATENOW
);
4872 ok_sequence( WmInvalidateErasePaint
, "InvalidateErasePaint", FALSE
);
4873 check_update_rgn( hwnd
, 0 );
4876 SetRectRgn( hrgn
, 0, 0, 100, 100 );
4877 RedrawWindow( hwnd
, NULL
, hrgn
, RDW_INVALIDATE
);
4878 SetRectRgn( hrgn
, 0, 0, 50, 100 );
4879 RedrawWindow( hwnd
, NULL
, hrgn
, RDW_VALIDATE
);
4880 SetRectRgn( hrgn
, 50, 0, 100, 100 );
4881 check_update_rgn( hwnd
, hrgn
);
4882 RedrawWindow( hwnd
, NULL
, hrgn
, RDW_VALIDATE
| RDW_ERASENOW
);
4883 ok_sequence( WmEmptySeq
, "EmptySeq", FALSE
); /* must not generate messages, everything is valid */
4884 check_update_rgn( hwnd
, 0 );
4887 SetRectRgn( hrgn
, 0, 0, 100, 100 );
4888 RedrawWindow( hwnd
, NULL
, hrgn
, RDW_INVALIDATE
| RDW_ERASE
);
4889 SetRectRgn( hrgn
, 0, 0, 100, 50 );
4890 RedrawWindow( hwnd
, NULL
, hrgn
, RDW_VALIDATE
| RDW_ERASENOW
);
4891 ok_sequence( WmErase
, "Erase", FALSE
);
4892 SetRectRgn( hrgn
, 0, 50, 100, 100 );
4893 check_update_rgn( hwnd
, hrgn
);
4896 SetRectRgn( hrgn
, 0, 0, 100, 100 );
4897 RedrawWindow( hwnd
, NULL
, hrgn
, RDW_INVALIDATE
| RDW_ERASE
);
4898 SetRectRgn( hrgn
, 0, 0, 50, 50 );
4899 RedrawWindow( hwnd
, NULL
, hrgn
, RDW_VALIDATE
| RDW_NOERASE
| RDW_UPDATENOW
);
4900 ok_sequence( WmPaint
, "Paint", FALSE
);
4903 SetRectRgn( hrgn
, -4, -4, -2, -2 );
4904 RedrawWindow( hwnd
, NULL
, hrgn
, RDW_INVALIDATE
| RDW_FRAME
);
4905 SetRectRgn( hrgn
, -200, -200, -198, -198 );
4906 RedrawWindow( hwnd
, NULL
, hrgn
, RDW_VALIDATE
| RDW_NOFRAME
| RDW_ERASENOW
);
4907 ok_sequence( WmEmptySeq
, "EmptySeq", FALSE
);
4910 SetRectRgn( hrgn
, -4, -4, -2, -2 );
4911 RedrawWindow( hwnd
, NULL
, hrgn
, RDW_INVALIDATE
| RDW_FRAME
);
4912 SetRectRgn( hrgn
, -4, -4, -3, -3 );
4913 RedrawWindow( hwnd
, NULL
, hrgn
, RDW_VALIDATE
| RDW_NOFRAME
);
4914 SetRectRgn( hrgn
, 0, 0, 1, 1 );
4915 RedrawWindow( hwnd
, NULL
, hrgn
, RDW_INVALIDATE
| RDW_UPDATENOW
);
4916 ok_sequence( WmPaint
, "Paint", FALSE
);
4919 SetRectRgn( hrgn
, -4, -4, -1, -1 );
4920 RedrawWindow( hwnd
, NULL
, hrgn
, RDW_INVALIDATE
| RDW_FRAME
);
4921 RedrawWindow( hwnd
, NULL
, 0, RDW_ERASENOW
);
4922 /* make sure no WM_PAINT was generated */
4923 while (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
4924 ok_sequence( WmInvalidateRgn
, "InvalidateRgn", FALSE
);
4927 SetRectRgn( hrgn
, -4, -4, -1, -1 );
4928 RedrawWindow( hwnd
, NULL
, hrgn
, RDW_INVALIDATE
| RDW_FRAME
);
4929 while (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
))
4931 if (msg
.hwnd
== hwnd
&& msg
.message
== WM_PAINT
)
4933 /* GetUpdateRgn must return empty region since only nonclient area is invalidated */
4934 INT ret
= GetUpdateRgn( hwnd
, hrgn
, FALSE
);
4935 ok( ret
== NULLREGION
, "Invalid GetUpdateRgn result %d\n", ret
);
4936 ret
= GetUpdateRect( hwnd
, &rect
, FALSE
);
4937 ok( ret
, "Invalid GetUpdateRect result %d\n", ret
);
4938 /* this will send WM_NCPAINT and validate the non client area */
4939 ret
= GetUpdateRect( hwnd
, &rect
, TRUE
);
4940 ok( !ret
, "Invalid GetUpdateRect result %d\n", ret
);
4942 DispatchMessage( &msg
);
4944 ok_sequence( WmGetUpdateRect
, "GetUpdateRect", FALSE
);
4946 DestroyWindow( hwnd
);
4948 /* now test with a child window */
4950 hparent
= CreateWindowExA(0, "TestParentClass", "Test parent", WS_OVERLAPPEDWINDOW
,
4951 100, 100, 200, 200, 0, 0, 0, NULL
);
4952 ok (hparent
!= 0, "Failed to create parent window\n");
4954 hchild
= CreateWindowExA(0, "TestWindowClass", "Test child", WS_CHILD
| WS_VISIBLE
| WS_BORDER
,
4955 10, 10, 100, 100, hparent
, 0, 0, NULL
);
4956 ok (hchild
!= 0, "Failed to create child window\n");
4958 ShowWindow( hparent
, SW_SHOW
);
4959 UpdateWindow( hparent
);
4960 UpdateWindow( hchild
);
4963 log_all_parent_messages
++;
4965 SetRect( &rect
, 0, 0, 50, 50 );
4966 RedrawWindow( hparent
, &rect
, 0, RDW_INVALIDATE
| RDW_ERASE
| RDW_FRAME
);
4967 RedrawWindow( hparent
, NULL
, 0, RDW_ERASENOW
| RDW_ALLCHILDREN
);
4968 ok_sequence( WmInvalidateParentChild
, "InvalidateParentChild", FALSE
);
4970 RedrawWindow( hparent
, &rect
, 0, RDW_INVALIDATE
| RDW_ERASE
| RDW_FRAME
);
4972 MapWindowPoints( hchild
, hparent
, &pt
, 1 );
4973 SetRectRgn( hrgn
, 0, 0, 50 - pt
.x
, 50 - pt
.y
);
4974 check_update_rgn( hchild
, hrgn
);
4975 SetRectRgn( hrgn
, 0, 0, 50, 50 );
4976 check_update_rgn( hparent
, hrgn
);
4977 RedrawWindow( hparent
, NULL
, 0, RDW_ERASENOW
);
4978 ok_sequence( WmInvalidateParent
, "InvalidateParent", FALSE
);
4979 RedrawWindow( hchild
, NULL
, 0, RDW_ERASENOW
);
4980 ok_sequence( WmEmptySeq
, "EraseNow child", FALSE
);
4982 while (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
4983 ok_sequence( WmParentPaintNc
, "WmParentPaintNc", FALSE
);
4985 RedrawWindow( hparent
, &rect
, 0, RDW_INVALIDATE
| RDW_ERASE
| RDW_FRAME
| RDW_ALLCHILDREN
);
4986 RedrawWindow( hparent
, NULL
, 0, RDW_ERASENOW
);
4987 ok_sequence( WmInvalidateParent
, "InvalidateParent2", FALSE
);
4988 RedrawWindow( hchild
, NULL
, 0, RDW_ERASENOW
);
4989 ok_sequence( WmEmptySeq
, "EraseNow child", FALSE
);
4991 RedrawWindow( hparent
, &rect
, 0, RDW_INVALIDATE
| RDW_ERASE
);
4992 RedrawWindow( hparent
, NULL
, 0, RDW_ERASENOW
| RDW_ALLCHILDREN
);
4993 ok_sequence( WmInvalidateParentChild2
, "InvalidateParentChild2", FALSE
);
4995 SetWindowLong( hparent
, GWL_STYLE
, GetWindowLong(hparent
,GWL_STYLE
) | WS_CLIPCHILDREN
);
4997 RedrawWindow( hparent
, &rect
, 0, RDW_INVALIDATE
| RDW_ERASE
| RDW_FRAME
| RDW_ALLCHILDREN
);
4998 RedrawWindow( hparent
, NULL
, 0, RDW_ERASENOW
);
4999 ok_sequence( WmInvalidateParentChild
, "InvalidateParentChild3", FALSE
);
5001 /* flush all paint messages */
5002 while (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
5005 /* RDW_UPDATENOW on child with WS_CLIPCHILDREN doesn't change corresponding parent area */
5006 RedrawWindow( hparent
, &rect
, 0, RDW_INVALIDATE
| RDW_ERASE
| RDW_FRAME
| RDW_ALLCHILDREN
);
5007 SetRectRgn( hrgn
, 0, 0, 50, 50 );
5008 check_update_rgn( hparent
, hrgn
);
5009 RedrawWindow( hchild
, NULL
, 0, RDW_UPDATENOW
);
5010 ok_sequence( WmInvalidateErasePaint2
, "WmInvalidateErasePaint2", FALSE
);
5011 SetRectRgn( hrgn
, 0, 0, 50, 50 );
5012 check_update_rgn( hparent
, hrgn
);
5014 /* flush all paint messages */
5015 while (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
5016 SetWindowLong( hparent
, GWL_STYLE
, GetWindowLong(hparent
,GWL_STYLE
) & ~WS_CLIPCHILDREN
);
5019 /* RDW_UPDATENOW on child without WS_CLIPCHILDREN will validate corresponding parent area */
5020 RedrawWindow( hparent
, &rect
, 0, RDW_INVALIDATE
| RDW_ERASE
| RDW_FRAME
);
5021 SetRectRgn( hrgn
, 0, 0, 50, 50 );
5022 check_update_rgn( hparent
, hrgn
);
5023 RedrawWindow( hchild
, NULL
, 0, RDW_UPDATENOW
);
5024 ok_sequence( WmInvalidateErasePaint2
, "WmInvalidateErasePaint2", FALSE
);
5025 SetRectRgn( hrgn2
, 10, 10, 50, 50 );
5026 CombineRgn( hrgn
, hrgn
, hrgn2
, RGN_DIFF
);
5027 check_update_rgn( hparent
, hrgn
);
5028 /* flush all paint messages */
5029 while (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
5032 /* same as above but parent gets completely validated */
5033 SetRect( &rect
, 20, 20, 30, 30 );
5034 RedrawWindow( hparent
, &rect
, 0, RDW_INVALIDATE
| RDW_ERASE
| RDW_FRAME
);
5035 SetRectRgn( hrgn
, 20, 20, 30, 30 );
5036 check_update_rgn( hparent
, hrgn
);
5037 RedrawWindow( hchild
, NULL
, 0, RDW_UPDATENOW
);
5038 ok_sequence( WmInvalidateErasePaint2
, "WmInvalidateErasePaint2", FALSE
);
5039 check_update_rgn( hparent
, 0 ); /* no update region */
5040 while (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
5041 ok_sequence( WmEmptySeq
, "WmEmpty", FALSE
); /* and no paint messages */
5043 /* make sure RDW_VALIDATE on child doesn't have the same effect */
5045 RedrawWindow( hparent
, &rect
, 0, RDW_INVALIDATE
| RDW_ERASE
| RDW_FRAME
);
5046 SetRectRgn( hrgn
, 20, 20, 30, 30 );
5047 check_update_rgn( hparent
, hrgn
);
5048 RedrawWindow( hchild
, NULL
, 0, RDW_VALIDATE
| RDW_NOERASE
);
5049 SetRectRgn( hrgn
, 20, 20, 30, 30 );
5050 check_update_rgn( hparent
, hrgn
);
5052 /* same as above but normal WM_PAINT doesn't validate parent */
5054 SetRect( &rect
, 20, 20, 30, 30 );
5055 RedrawWindow( hparent
, &rect
, 0, RDW_INVALIDATE
| RDW_ERASE
| RDW_FRAME
);
5056 SetRectRgn( hrgn
, 20, 20, 30, 30 );
5057 check_update_rgn( hparent
, hrgn
);
5058 /* no WM_PAINT in child while parent still pending */
5059 while (PeekMessage( &msg
, hchild
, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
5060 ok_sequence( WmEmptySeq
, "No WM_PAINT", FALSE
);
5061 while (PeekMessage( &msg
, hparent
, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
5062 ok_sequence( WmParentErasePaint
, "WmParentErasePaint", FALSE
);
5065 RedrawWindow( hparent
, &rect
, 0, RDW_INVALIDATE
| RDW_ERASE
| RDW_FRAME
);
5066 /* no WM_PAINT in child while parent still pending */
5067 while (PeekMessage( &msg
, hchild
, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
5068 ok_sequence( WmEmptySeq
, "No WM_PAINT", FALSE
);
5069 RedrawWindow( hparent
, &rect
, 0, RDW_VALIDATE
| RDW_NOERASE
| RDW_NOCHILDREN
);
5070 /* now that parent is valid child should get WM_PAINT */
5071 while (PeekMessage( &msg
, hchild
, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
5072 ok_sequence( WmInvalidateErasePaint2
, "WmInvalidateErasePaint2", FALSE
);
5073 while (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
5074 ok_sequence( WmEmptySeq
, "No other message", FALSE
);
5076 /* same thing with WS_CLIPCHILDREN in parent */
5078 SetWindowLong( hparent
, GWL_STYLE
, GetWindowLong(hparent
,GWL_STYLE
) | WS_CLIPCHILDREN
);
5079 ok_sequence( WmSetParentStyle
, "WmSetParentStyle", FALSE
);
5080 /* changing style invalidates non client area, but we need to invalidate something else to see it */
5081 RedrawWindow( hparent
, &rect
, 0, RDW_UPDATENOW
);
5082 ok_sequence( WmEmptySeq
, "No message", FALSE
);
5083 RedrawWindow( hparent
, &rect
, 0, RDW_INVALIDATE
| RDW_UPDATENOW
);
5084 ok_sequence( WmParentOnlyNcPaint
, "WmParentOnlyNcPaint", FALSE
);
5087 RedrawWindow( hparent
, &rect
, 0, RDW_INVALIDATE
| RDW_ERASE
| RDW_ALLCHILDREN
);
5088 SetRectRgn( hrgn
, 20, 20, 30, 30 );
5089 check_update_rgn( hparent
, hrgn
);
5090 /* no WM_PAINT in child while parent still pending */
5091 while (PeekMessage( &msg
, hchild
, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
5092 ok_sequence( WmEmptySeq
, "No WM_PAINT", FALSE
);
5093 /* WM_PAINT in parent first */
5094 while (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
5095 ok_sequence( WmParentPaintNc
, "WmParentPaintNc2", FALSE
);
5097 /* no RDW_ERASE in parent still causes RDW_ERASE and RDW_FRAME in child */
5099 SetRect( &rect
, 0, 0, 30, 30 );
5100 RedrawWindow( hparent
, &rect
, 0, RDW_INVALIDATE
| RDW_ALLCHILDREN
);
5101 SetRectRgn( hrgn
, 0, 0, 30, 30 );
5102 check_update_rgn( hparent
, hrgn
);
5103 while (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
5104 ok_sequence( WmParentPaintNc
, "WmParentPaintNc3", FALSE
);
5106 /* validate doesn't cause RDW_NOERASE or RDW_NOFRAME in child */
5108 SetRect( &rect
, -10, 0, 30, 30 );
5109 RedrawWindow( hchild
, &rect
, 0, RDW_INVALIDATE
| RDW_FRAME
| RDW_ERASE
);
5110 SetRect( &rect
, 0, 0, 20, 20 );
5111 RedrawWindow( hparent
, &rect
, 0, RDW_VALIDATE
| RDW_ALLCHILDREN
);
5112 RedrawWindow( hparent
, NULL
, 0, RDW_UPDATENOW
);
5113 ok_sequence( WmChildPaintNc
, "WmChildPaintNc", FALSE
);
5115 /* validate doesn't cause RDW_NOERASE or RDW_NOFRAME in child */
5117 SetRect( &rect
, -10, 0, 30, 30 );
5118 RedrawWindow( hchild
, &rect
, 0, RDW_INVALIDATE
| RDW_FRAME
| RDW_ERASE
);
5119 SetRect( &rect
, 0, 0, 100, 100 );
5120 RedrawWindow( hparent
, &rect
, 0, RDW_VALIDATE
| RDW_ALLCHILDREN
);
5121 RedrawWindow( hparent
, NULL
, 0, RDW_UPDATENOW
);
5122 ok_sequence( WmEmptySeq
, "WmChildPaintNc2", FALSE
);
5123 RedrawWindow( hparent
, NULL
, 0, RDW_ERASENOW
);
5124 ok_sequence( WmEmptySeq
, "WmChildPaintNc3", FALSE
);
5126 /* test RDW_INTERNALPAINT behavior */
5129 RedrawWindow( hparent
, NULL
, 0, RDW_INTERNALPAINT
| RDW_NOCHILDREN
);
5130 while (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
5131 ok_sequence( WmParentOnlyPaint
, "WmParentOnlyPaint", FALSE
);
5133 RedrawWindow( hparent
, NULL
, 0, RDW_INTERNALPAINT
| RDW_ALLCHILDREN
);
5134 while (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
5135 ok_sequence( WmParentPaint
, "WmParentPaint", FALSE
);
5137 RedrawWindow( hparent
, NULL
, 0, RDW_INTERNALPAINT
);
5138 while (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
5139 ok_sequence( WmParentOnlyPaint
, "WmParentOnlyPaint", FALSE
);
5141 assert( GetWindowLong(hparent
, GWL_STYLE
) & WS_CLIPCHILDREN
);
5142 UpdateWindow( hparent
);
5143 while (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
5145 trace("testing SWP_FRAMECHANGED on parent with WS_CLIPCHILDREN\n");
5146 RedrawWindow( hchild
, NULL
, 0, RDW_INVALIDATE
| RDW_ERASE
| RDW_FRAME
);
5147 SetWindowPos( hparent
, 0, 0, 0, 0, 0, SWP_NOSIZE
| SWP_NOMOVE
|
5148 SWP_NOACTIVATE
| SWP_NOZORDER
| SWP_FRAMECHANGED
);
5149 while (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
5150 ok_sequence(WmSWP_FrameChanged_clip
, "SetWindowPos:FrameChanged_clip", FALSE
);
5152 UpdateWindow( hparent
);
5153 while (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
5155 trace("testing SWP_FRAMECHANGED|SWP_DEFERERASE on parent with WS_CLIPCHILDREN\n");
5156 RedrawWindow( hchild
, NULL
, 0, RDW_INVALIDATE
| RDW_ERASE
| RDW_FRAME
);
5157 SetWindowPos( hparent
, 0, 0, 0, 0, 0, SWP_NOSIZE
| SWP_NOMOVE
| SWP_DEFERERASE
|
5158 SWP_NOACTIVATE
| SWP_NOZORDER
| SWP_FRAMECHANGED
);
5159 while (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
5160 ok_sequence(WmSWP_FrameChangedDeferErase
, "SetWindowPos:FrameChangedDeferErase", FALSE
);
5162 SetWindowLong( hparent
, GWL_STYLE
, GetWindowLong(hparent
,GWL_STYLE
) & ~WS_CLIPCHILDREN
);
5163 ok_sequence( WmSetParentStyle
, "WmSetParentStyle", FALSE
);
5164 RedrawWindow( hparent
, NULL
, 0, RDW_INTERNALPAINT
);
5165 while (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
5166 ok_sequence( WmParentPaint
, "WmParentPaint", FALSE
);
5168 assert( !(GetWindowLong(hparent
, GWL_STYLE
) & WS_CLIPCHILDREN
) );
5169 UpdateWindow( hparent
);
5170 while (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
5172 trace("testing SWP_FRAMECHANGED on parent without WS_CLIPCHILDREN\n");
5173 RedrawWindow( hchild
, NULL
, 0, RDW_INVALIDATE
| RDW_ERASE
| RDW_FRAME
);
5174 SetWindowPos( hparent
, 0, 0, 0, 0, 0, SWP_NOSIZE
| SWP_NOMOVE
|
5175 SWP_NOACTIVATE
| SWP_NOZORDER
| SWP_FRAMECHANGED
);
5176 while (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
5177 ok_sequence(WmSWP_FrameChanged_noclip
, "SetWindowPos:FrameChanged_noclip", FALSE
);
5179 UpdateWindow( hparent
);
5180 while (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
5182 trace("testing SWP_FRAMECHANGED|SWP_DEFERERASE on parent without WS_CLIPCHILDREN\n");
5183 RedrawWindow( hchild
, NULL
, 0, RDW_INVALIDATE
| RDW_ERASE
| RDW_FRAME
);
5184 SetWindowPos( hparent
, 0, 0, 0, 0, 0, SWP_NOSIZE
| SWP_NOMOVE
| SWP_DEFERERASE
|
5185 SWP_NOACTIVATE
| SWP_NOZORDER
| SWP_FRAMECHANGED
);
5186 while (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
5187 ok_sequence(WmSWP_FrameChangedDeferErase
, "SetWindowPos:FrameChangedDeferErase", FALSE
);
5189 log_all_parent_messages
--;
5190 DestroyWindow( hparent
);
5191 ok(!IsWindow(hchild
), "child must be destroyed with its parent\n");
5193 DeleteObject( hrgn
);
5194 DeleteObject( hrgn2
);
5203 static DWORD WINAPI
thread_proc(void *param
)
5206 struct wnd_event
*wnd_event
= (struct wnd_event
*)param
;
5208 wnd_event
->hwnd
= CreateWindowExA(0, "TestWindowClass", "window caption text", WS_OVERLAPPEDWINDOW
,
5209 100, 100, 200, 200, 0, 0, 0, NULL
);
5210 ok(wnd_event
->hwnd
!= 0, "Failed to create overlapped window\n");
5212 SetEvent(wnd_event
->event
);
5214 while (GetMessage(&msg
, 0, 0, 0))
5216 TranslateMessage(&msg
);
5217 DispatchMessage(&msg
);
5220 ok(IsWindow(wnd_event
->hwnd
), "window should still exist\n");
5225 static void test_interthread_messages(void)
5232 int len
, expected_len
;
5233 struct wnd_event wnd_event
;
5236 wnd_event
.event
= CreateEventW(NULL
, 0, 0, NULL
);
5237 if (!wnd_event
.event
)
5239 trace("skipping interthread message test under win9x\n");
5243 hThread
= CreateThread(NULL
, 0, thread_proc
, &wnd_event
, 0, &tid
);
5244 ok(hThread
!= NULL
, "CreateThread failed, error %d\n", GetLastError());
5246 ok(WaitForSingleObject(wnd_event
.event
, INFINITE
) == WAIT_OBJECT_0
, "WaitForSingleObject failed\n");
5248 CloseHandle(wnd_event
.event
);
5250 SetLastError(0xdeadbeef);
5251 ok(!DestroyWindow(wnd_event
.hwnd
), "DestroyWindow succeded\n");
5252 ok(GetLastError() == ERROR_ACCESS_DENIED
, "wrong error code %d\n", GetLastError());
5254 proc
= (WNDPROC
)GetWindowLongPtrA(wnd_event
.hwnd
, GWLP_WNDPROC
);
5255 ok(proc
!= NULL
, "GetWindowLongPtrA(GWLP_WNDPROC) error %d\n", GetLastError());
5257 expected_len
= lstrlenA("window caption text");
5258 memset(buf
, 0, sizeof(buf
));
5259 SetLastError(0xdeadbeef);
5260 len
= CallWindowProcA(proc
, wnd_event
.hwnd
, WM_GETTEXT
, sizeof(buf
), (LPARAM
)buf
);
5261 ok(len
== expected_len
, "CallWindowProcA(WM_GETTEXT) error %d, len %d, expected len %d\n", GetLastError(), len
, expected_len
);
5262 ok(!lstrcmpA(buf
, "window caption text"), "window text mismatch\n");
5264 msg
.hwnd
= wnd_event
.hwnd
;
5265 msg
.message
= WM_GETTEXT
;
5266 msg
.wParam
= sizeof(buf
);
5267 msg
.lParam
= (LPARAM
)buf
;
5268 memset(buf
, 0, sizeof(buf
));
5269 SetLastError(0xdeadbeef);
5270 len
= DispatchMessageA(&msg
);
5271 ok(!len
&& GetLastError() == ERROR_MESSAGE_SYNC_ONLY
,
5272 "DispatchMessageA(WM_GETTEXT) succeded on another thread window: ret %d, error %d\n", len
, GetLastError());
5274 /* the following test causes an exception in user.exe under win9x */
5275 msg
.hwnd
= wnd_event
.hwnd
;
5276 msg
.message
= WM_TIMER
;
5278 msg
.lParam
= GetWindowLongPtrA(wnd_event
.hwnd
, GWLP_WNDPROC
);
5279 SetLastError(0xdeadbeef);
5280 len
= DispatchMessageA(&msg
);
5281 ok(!len
&& GetLastError() == 0xdeadbeef,
5282 "DispatchMessageA(WM_TIMER) failed on another thread window: ret %d, error %d\n", len
, GetLastError());
5284 ret
= PostMessageA(wnd_event
.hwnd
, WM_QUIT
, 0, 0);
5285 ok( ret
, "PostMessageA(WM_QUIT) error %d\n", GetLastError());
5287 ok(WaitForSingleObject(hThread
, INFINITE
) == WAIT_OBJECT_0
, "WaitForSingleObject failed\n");
5288 CloseHandle(hThread
);
5290 ok(!IsWindow(wnd_event
.hwnd
), "window should be destroyed on thread exit\n");
5294 static const struct message WmVkN
[] = {
5295 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, 'N', 1 }, /* XP */
5296 { WM_KEYDOWN
, wparam
|lparam
, 'N', 1 },
5297 { WM_KEYDOWN
, sent
|wparam
|lparam
, 'N', 1 },
5298 { WM_CHAR
, wparam
|lparam
, 'n', 1 },
5299 { WM_COMMAND
, sent
|wparam
|lparam
, MAKEWPARAM(1002,1), 0 },
5300 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, 'N', 0xc0000001 }, /* XP */
5301 { WM_KEYUP
, wparam
|lparam
, 'N', 0xc0000001 },
5302 { WM_KEYUP
, sent
|wparam
|lparam
, 'N', 0xc0000001 },
5305 static const struct message WmShiftVkN
[] = {
5306 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_SHIFT
, 1 }, /* XP */
5307 { WM_KEYDOWN
, wparam
|lparam
, VK_SHIFT
, 1 },
5308 { WM_KEYDOWN
, sent
|wparam
|lparam
, VK_SHIFT
, 1 },
5309 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, 'N', 1 }, /* XP */
5310 { WM_KEYDOWN
, wparam
|lparam
, 'N', 1 },
5311 { WM_KEYDOWN
, sent
|wparam
|lparam
, 'N', 1 },
5312 { WM_CHAR
, wparam
|lparam
, 'N', 1 },
5313 { WM_COMMAND
, sent
|wparam
|lparam
, MAKEWPARAM(1001,1), 0 },
5314 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, 'N', 0xc0000001 }, /* XP */
5315 { WM_KEYUP
, wparam
|lparam
, 'N', 0xc0000001 },
5316 { WM_KEYUP
, sent
|wparam
|lparam
, 'N', 0xc0000001 },
5317 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_SHIFT
, 0xc0000001 }, /* XP */
5318 { WM_KEYUP
, wparam
|lparam
, VK_SHIFT
, 0xc0000001 },
5319 { WM_KEYUP
, sent
|wparam
|lparam
, VK_SHIFT
, 0xc0000001 },
5322 static const struct message WmCtrlVkN
[] = {
5323 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_CONTROL
, 1 }, /* XP */
5324 { WM_KEYDOWN
, wparam
|lparam
, VK_CONTROL
, 1 },
5325 { WM_KEYDOWN
, sent
|wparam
|lparam
, VK_CONTROL
, 1 },
5326 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, 'N', 1 }, /* XP */
5327 { WM_KEYDOWN
, wparam
|lparam
, 'N', 1 },
5328 { WM_KEYDOWN
, sent
|wparam
|lparam
, 'N', 1 },
5329 { WM_CHAR
, wparam
|lparam
, 0x000e, 1 },
5330 { WM_COMMAND
, sent
|wparam
|lparam
, MAKEWPARAM(1000,1), 0 },
5331 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, 'N', 0xc0000001 }, /* XP */
5332 { WM_KEYUP
, wparam
|lparam
, 'N', 0xc0000001 },
5333 { WM_KEYUP
, sent
|wparam
|lparam
, 'N', 0xc0000001 },
5334 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_CONTROL
, 0xc0000001 }, /* XP */
5335 { WM_KEYUP
, wparam
|lparam
, VK_CONTROL
, 0xc0000001 },
5336 { WM_KEYUP
, sent
|wparam
|lparam
, VK_CONTROL
, 0xc0000001 },
5339 static const struct message WmCtrlVkN_2
[] = {
5340 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_CONTROL
, 1 }, /* XP */
5341 { WM_KEYDOWN
, wparam
|lparam
, VK_CONTROL
, 1 },
5342 { WM_KEYDOWN
, sent
|wparam
|lparam
, VK_CONTROL
, 1 },
5343 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, 'N', 1 }, /* XP */
5344 { WM_KEYDOWN
, wparam
|lparam
, 'N', 1 },
5345 { WM_COMMAND
, sent
|wparam
|lparam
, MAKEWPARAM(1000,1), 0 },
5346 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, 'N', 0xc0000001 }, /* XP */
5347 { WM_KEYUP
, wparam
|lparam
, 'N', 0xc0000001 },
5348 { WM_KEYUP
, sent
|wparam
|lparam
, 'N', 0xc0000001 },
5349 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_CONTROL
, 0xc0000001 }, /* XP */
5350 { WM_KEYUP
, wparam
|lparam
, VK_CONTROL
, 0xc0000001 },
5351 { WM_KEYUP
, sent
|wparam
|lparam
, VK_CONTROL
, 0xc0000001 },
5354 static const struct message WmAltVkN
[] = {
5355 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_MENU
, 0x20000001 }, /* XP */
5356 { WM_SYSKEYDOWN
, wparam
|lparam
, VK_MENU
, 0x20000001 },
5357 { WM_SYSKEYDOWN
, sent
|wparam
|lparam
, VK_MENU
, 0x20000001 },
5358 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, 'N', 0x20000001 }, /* XP */
5359 { WM_SYSKEYDOWN
, wparam
|lparam
, 'N', 0x20000001 },
5360 { WM_SYSKEYDOWN
, sent
|wparam
|lparam
, 'N', 0x20000001 },
5361 { WM_SYSCHAR
, wparam
|lparam
, 'n', 0x20000001 },
5362 { WM_SYSCHAR
, sent
|wparam
|lparam
, 'n', 0x20000001 },
5363 { WM_SYSCOMMAND
, sent
|defwinproc
|wparam
|lparam
, SC_KEYMENU
, 'n' },
5364 { HCBT_SYSCOMMAND
, hook
},
5365 { WM_ENTERMENULOOP
, sent
|defwinproc
|wparam
|lparam
, 0, 0 },
5366 { EVENT_SYSTEM_CAPTURESTART
, winevent_hook
|wparam
|lparam
, 0, 0 },
5367 { 0x00AE, sent
|defwinproc
|optional
}, /* XP */
5368 { WM_GETTEXT
, sent
|defwinproc
|optional
}, /* XP */
5369 { WM_INITMENU
, sent
|defwinproc
},
5370 { EVENT_SYSTEM_MENUSTART
, winevent_hook
|wparam
|lparam
, OBJID_SYSMENU
, 0 },
5371 { WM_MENUCHAR
, sent
|defwinproc
|wparam
, MAKEWPARAM('n',MF_SYSMENU
) },
5372 { EVENT_SYSTEM_CAPTUREEND
, winevent_hook
|wparam
|lparam
, 0, 0 },
5373 { WM_CAPTURECHANGED
, sent
|defwinproc
},
5374 { WM_MENUSELECT
, sent
|defwinproc
|wparam
, MAKEWPARAM(0,0xffff) },
5375 { EVENT_SYSTEM_MENUEND
, winevent_hook
|wparam
|lparam
, OBJID_SYSMENU
, 0 },
5376 { WM_EXITMENULOOP
, sent
|defwinproc
},
5377 { WM_MENUSELECT
, sent
|defwinproc
|wparam
|optional
, MAKEWPARAM(0,0xffff) }, /* Win95 bug */
5378 { WM_EXITMENULOOP
, sent
|defwinproc
|optional
}, /* Win95 bug */
5379 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, 'N', 0xe0000001 }, /* XP */
5380 { WM_SYSKEYUP
, wparam
|lparam
, 'N', 0xe0000001 },
5381 { WM_SYSKEYUP
, sent
|wparam
|lparam
, 'N', 0xe0000001 },
5382 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_MENU
, 0xc0000001 }, /* XP */
5383 { WM_KEYUP
, wparam
|lparam
, VK_MENU
, 0xc0000001 },
5384 { WM_KEYUP
, sent
|wparam
|lparam
, VK_MENU
, 0xc0000001 },
5387 static const struct message WmAltVkN_2
[] = {
5388 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_MENU
, 0x20000001 }, /* XP */
5389 { WM_SYSKEYDOWN
, wparam
|lparam
, VK_MENU
, 0x20000001 },
5390 { WM_SYSKEYDOWN
, sent
|wparam
|lparam
, VK_MENU
, 0x20000001 },
5391 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, 'N', 0x20000001 }, /* XP */
5392 { WM_SYSKEYDOWN
, wparam
|lparam
, 'N', 0x20000001 },
5393 { WM_COMMAND
, sent
|wparam
|lparam
, MAKEWPARAM(1003,1), 0 },
5394 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, 'N', 0xe0000001 }, /* XP */
5395 { WM_SYSKEYUP
, wparam
|lparam
, 'N', 0xe0000001 },
5396 { WM_SYSKEYUP
, sent
|wparam
|lparam
, 'N', 0xe0000001 },
5397 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_MENU
, 0xc0000001 }, /* XP */
5398 { WM_KEYUP
, wparam
|lparam
, VK_MENU
, 0xc0000001 },
5399 { WM_KEYUP
, sent
|wparam
|lparam
, VK_MENU
, 0xc0000001 },
5402 static const struct message WmCtrlAltVkN
[] = {
5403 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_CONTROL
, 1 }, /* XP */
5404 { WM_KEYDOWN
, wparam
|lparam
, VK_CONTROL
, 1 },
5405 { WM_KEYDOWN
, sent
|wparam
|lparam
, VK_CONTROL
, 1 },
5406 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_MENU
, 0x20000001 }, /* XP */
5407 { WM_KEYDOWN
, wparam
|lparam
, VK_MENU
, 0x20000001 },
5408 { WM_KEYDOWN
, sent
|wparam
|lparam
, VK_MENU
, 0x20000001 },
5409 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, 'N', 0x20000001 }, /* XP */
5410 { WM_KEYDOWN
, wparam
|lparam
, 'N', 0x20000001 },
5411 { WM_KEYDOWN
, sent
|wparam
|lparam
, 'N', 0x20000001 },
5412 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, 'N', 0xe0000001 }, /* XP */
5413 { WM_KEYUP
, wparam
|lparam
, 'N', 0xe0000001 },
5414 { WM_KEYUP
, sent
|wparam
|lparam
, 'N', 0xe0000001 },
5415 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_MENU
, 0xc0000001 }, /* XP */
5416 { WM_KEYUP
, wparam
|lparam
, VK_MENU
, 0xc0000001 },
5417 { WM_KEYUP
, sent
|wparam
|lparam
, VK_MENU
, 0xc0000001 },
5418 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_CONTROL
, 0xc0000001 }, /* XP */
5419 { WM_KEYUP
, wparam
|lparam
, VK_CONTROL
, 0xc0000001 },
5420 { WM_KEYUP
, sent
|wparam
|lparam
, VK_CONTROL
, 0xc0000001 },
5423 static const struct message WmCtrlShiftVkN
[] = {
5424 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_CONTROL
, 1 }, /* XP */
5425 { WM_KEYDOWN
, wparam
|lparam
, VK_CONTROL
, 1 },
5426 { WM_KEYDOWN
, sent
|wparam
|lparam
, VK_CONTROL
, 1 },
5427 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_SHIFT
, 1 }, /* XP */
5428 { WM_KEYDOWN
, wparam
|lparam
, VK_SHIFT
, 1 },
5429 { WM_KEYDOWN
, sent
|wparam
|lparam
, VK_SHIFT
, 1 },
5430 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, 'N', 1 }, /* XP */
5431 { WM_KEYDOWN
, wparam
|lparam
, 'N', 1 },
5432 { WM_COMMAND
, sent
|wparam
|lparam
, MAKEWPARAM(1004,1), 0 },
5433 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, 'N', 0xc0000001 }, /* XP */
5434 { WM_KEYUP
, wparam
|lparam
, 'N', 0xc0000001 },
5435 { WM_KEYUP
, sent
|wparam
|lparam
, 'N', 0xc0000001 },
5436 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_SHIFT
, 0xc0000001 }, /* XP */
5437 { WM_KEYUP
, wparam
|lparam
, VK_SHIFT
, 0xc0000001 },
5438 { WM_KEYUP
, sent
|wparam
|lparam
, VK_SHIFT
, 0xc0000001 },
5439 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_CONTROL
, 0xc0000001 }, /* XP */
5440 { WM_KEYUP
, wparam
|lparam
, VK_CONTROL
, 0xc0000001 },
5441 { WM_KEYUP
, sent
|wparam
|lparam
, VK_CONTROL
, 0xc0000001 },
5444 static const struct message WmCtrlAltShiftVkN
[] = {
5445 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_CONTROL
, 1 }, /* XP */
5446 { WM_KEYDOWN
, wparam
|lparam
, VK_CONTROL
, 1 },
5447 { WM_KEYDOWN
, sent
|wparam
|lparam
, VK_CONTROL
, 1 },
5448 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_MENU
, 0x20000001 }, /* XP */
5449 { WM_KEYDOWN
, wparam
|lparam
, VK_MENU
, 0x20000001 },
5450 { WM_KEYDOWN
, sent
|wparam
|lparam
, VK_MENU
, 0x20000001 },
5451 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_SHIFT
, 0x20000001 }, /* XP */
5452 { WM_KEYDOWN
, wparam
|lparam
, VK_SHIFT
, 0x20000001 },
5453 { WM_KEYDOWN
, sent
|wparam
|lparam
, VK_SHIFT
, 0x20000001 },
5454 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, 'N', 0x20000001 }, /* XP */
5455 { WM_KEYDOWN
, wparam
|lparam
, 'N', 0x20000001 },
5456 { WM_COMMAND
, sent
|wparam
|lparam
, MAKEWPARAM(1005,1), 0 },
5457 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, 'N', 0xe0000001 }, /* XP */
5458 { WM_KEYUP
, wparam
|lparam
, 'N', 0xe0000001 },
5459 { WM_KEYUP
, sent
|wparam
|lparam
, 'N', 0xe0000001 },
5460 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_SHIFT
, 0xe0000001 }, /* XP */
5461 { WM_KEYUP
, wparam
|lparam
, VK_SHIFT
, 0xe0000001 },
5462 { WM_KEYUP
, sent
|wparam
|lparam
, VK_SHIFT
, 0xe0000001 },
5463 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_MENU
, 0xc0000001 }, /* XP */
5464 { WM_KEYUP
, wparam
|lparam
, VK_MENU
, 0xc0000001 },
5465 { WM_KEYUP
, sent
|wparam
|lparam
, VK_MENU
, 0xc0000001 },
5466 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_CONTROL
, 0xc0000001 }, /* XP */
5467 { WM_KEYUP
, wparam
|lparam
, VK_CONTROL
, 0xc0000001 },
5468 { WM_KEYUP
, sent
|wparam
|lparam
, VK_CONTROL
, 0xc0000001 },
5471 static const struct message WmAltPressRelease
[] = {
5472 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_MENU
, 0x20000001 }, /* XP */
5473 { WM_SYSKEYDOWN
, wparam
|lparam
, VK_MENU
, 0x20000001 },
5474 { WM_SYSKEYDOWN
, sent
|wparam
|lparam
, VK_MENU
, 0x20000001 },
5475 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_MENU
, 0xc0000001 }, /* XP */
5476 { WM_SYSKEYUP
, wparam
|lparam
, VK_MENU
, 0xc0000001 },
5477 { WM_SYSKEYUP
, sent
|wparam
|lparam
, VK_MENU
, 0xc0000001 },
5478 { WM_SYSCOMMAND
, sent
|defwinproc
|wparam
|lparam
, SC_KEYMENU
, 0 },
5479 { HCBT_SYSCOMMAND
, hook
},
5480 { WM_ENTERMENULOOP
, sent
|defwinproc
|wparam
|lparam
, 0, 0 },
5481 { EVENT_SYSTEM_CAPTURESTART
, winevent_hook
|wparam
|lparam
, 0, 0 },
5482 { WM_INITMENU
, sent
|defwinproc
},
5483 { EVENT_SYSTEM_MENUSTART
, winevent_hook
|wparam
|lparam
, OBJID_SYSMENU
, 0 },
5484 { WM_MENUSELECT
, sent
|defwinproc
|wparam
, MAKEWPARAM(0,MF_SYSMENU
|MF_POPUP
|MF_HILITE
) },
5485 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_SYSMENU
, 1 },
5487 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_MENU
, 0x30000001 }, /* XP */
5489 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_SYSMENU
, 0 },
5490 { EVENT_SYSTEM_CAPTUREEND
, winevent_hook
|wparam
|lparam
, 0, 0, },
5491 { WM_CAPTURECHANGED
, sent
|defwinproc
},
5492 { WM_MENUSELECT
, sent
|defwinproc
|wparam
|optional
, MAKEWPARAM(0,0xffff) },
5493 { EVENT_SYSTEM_MENUEND
, winevent_hook
|wparam
|lparam
, OBJID_SYSMENU
, 0 },
5494 { WM_EXITMENULOOP
, sent
|defwinproc
},
5495 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_MENU
, 0xc0000001 }, /* XP */
5496 { WM_SYSKEYUP
, wparam
|lparam
, VK_MENU
, 0xc0000001 },
5497 { WM_SYSKEYUP
, sent
|wparam
|lparam
, VK_MENU
, 0xc0000001 },
5500 static const struct message WmAltMouseButton
[] = {
5501 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_MENU
, 0x20000001 }, /* XP */
5502 { WM_SYSKEYDOWN
, wparam
|lparam
, VK_MENU
, 0x20000001 },
5503 { WM_SYSKEYDOWN
, sent
|wparam
|lparam
, VK_MENU
, 0x20000001 },
5504 { WM_MOUSEMOVE
, wparam
|optional
, 0, 0 },
5505 { WM_MOUSEMOVE
, sent
|wparam
|optional
, 0, 0 },
5506 { WM_LBUTTONDOWN
, wparam
, MK_LBUTTON
, 0 },
5507 { WM_LBUTTONDOWN
, sent
|wparam
, MK_LBUTTON
, 0 },
5508 { WM_LBUTTONUP
, wparam
, 0, 0 },
5509 { WM_LBUTTONUP
, sent
|wparam
, 0, 0 },
5510 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_MENU
, 0xc0000001 }, /* XP */
5511 { WM_SYSKEYUP
, wparam
|lparam
, VK_MENU
, 0xc0000001 },
5512 { WM_SYSKEYUP
, sent
|wparam
|lparam
, VK_MENU
, 0xc0000001 },
5515 static const struct message WmF1Seq
[] = {
5516 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_F1
, 1 }, /* XP */
5517 { WM_KEYDOWN
, wparam
|lparam
, VK_F1
, 1 },
5518 { WM_KEYDOWN
, sent
|wparam
|lparam
, VK_F1
, 0x00000001 },
5519 { 0x4d, wparam
|lparam
, 0, 0 },
5520 { 0x4d, sent
|wparam
|lparam
, 0, 0 },
5521 { WM_HELP
, sent
|defwinproc
},
5522 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_F1
, 0xc0000001 }, /* XP */
5523 { WM_KEYUP
, wparam
|lparam
, VK_F1
, 0xc0000001 },
5524 { WM_KEYUP
, sent
|wparam
|lparam
, VK_F1
, 0xc0000001 },
5527 static const struct message WmVkAppsSeq
[] = {
5528 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_APPS
, 1 }, /* XP */
5529 { WM_KEYDOWN
, wparam
|lparam
, VK_APPS
, 1 },
5530 { WM_KEYDOWN
, sent
|wparam
|lparam
, VK_APPS
, 0x00000001 },
5531 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_APPS
, 0xc0000001 }, /* XP */
5532 { WM_KEYUP
, wparam
|lparam
, VK_APPS
, 0xc0000001 },
5533 { WM_KEYUP
, sent
|wparam
|lparam
, VK_APPS
, 0xc0000001 },
5534 { WM_CONTEXTMENU
, lparam
, /*hwnd*/0, (LPARAM
)-1 },
5535 { WM_CONTEXTMENU
, sent
|lparam
, /*hwnd*/0, (LPARAM
)-1 },
5539 static void pump_msg_loop(HWND hwnd
, HACCEL hAccel
)
5543 while (PeekMessageA(&msg
, 0, 0, 0, PM_REMOVE
))
5545 struct message log_msg
;
5547 trace("accel: %p, %04x, %08lx, %08lx\n", msg
.hwnd
, msg
.message
, msg
.wParam
, msg
.lParam
);
5549 /* ignore some unwanted messages */
5550 if (msg
.message
== WM_MOUSEMOVE
||
5551 msg
.message
== WM_GETICON
||
5552 msg
.message
== WM_DEVICECHANGE
)
5555 log_msg
.message
= msg
.message
;
5556 log_msg
.flags
= wparam
|lparam
;
5557 log_msg
.wParam
= msg
.wParam
;
5558 log_msg
.lParam
= msg
.lParam
;
5559 add_message(&log_msg
);
5561 if (!hAccel
|| !TranslateAccelerator(hwnd
, hAccel
, &msg
))
5563 TranslateMessage(&msg
);
5564 DispatchMessage(&msg
);
5569 static void test_accelerators(void)
5574 HWND hwnd
= CreateWindowExA(0, "TestWindowClass", NULL
, WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
5575 100, 100, 200, 200, 0, 0, 0, NULL
);
5584 ok(GetFocus() == hwnd
, "wrong focus window %p\n", GetFocus());
5586 state
= GetKeyState(VK_SHIFT
);
5587 ok(!(state
& 0x8000), "wrong Shift state %04x\n", state
);
5588 state
= GetKeyState(VK_CAPITAL
);
5589 ok(state
== 0, "wrong CapsLock state %04x\n", state
);
5591 hAccel
= LoadAccelerators(GetModuleHandleA(0), MAKEINTRESOURCE(1));
5592 assert(hAccel
!= 0);
5594 pump_msg_loop(hwnd
, 0);
5597 trace("testing VK_N press/release\n");
5599 keybd_event('N', 0, 0, 0);
5600 keybd_event('N', 0, KEYEVENTF_KEYUP
, 0);
5601 pump_msg_loop(hwnd
, hAccel
);
5602 ok_sequence(WmVkN
, "VK_N press/release", FALSE
);
5604 trace("testing Shift+VK_N press/release\n");
5606 keybd_event(VK_SHIFT
, 0, 0, 0);
5607 keybd_event('N', 0, 0, 0);
5608 keybd_event('N', 0, KEYEVENTF_KEYUP
, 0);
5609 keybd_event(VK_SHIFT
, 0, KEYEVENTF_KEYUP
, 0);
5610 pump_msg_loop(hwnd
, hAccel
);
5611 ok_sequence(WmShiftVkN
, "Shift+VK_N press/release", FALSE
);
5613 trace("testing Ctrl+VK_N press/release\n");
5615 keybd_event(VK_CONTROL
, 0, 0, 0);
5616 keybd_event('N', 0, 0, 0);
5617 keybd_event('N', 0, KEYEVENTF_KEYUP
, 0);
5618 keybd_event(VK_CONTROL
, 0, KEYEVENTF_KEYUP
, 0);
5619 pump_msg_loop(hwnd
, hAccel
);
5620 ok_sequence(WmCtrlVkN
, "Ctrl+VK_N press/release", FALSE
);
5622 trace("testing Alt+VK_N press/release\n");
5624 keybd_event(VK_MENU
, 0, 0, 0);
5625 keybd_event('N', 0, 0, 0);
5626 keybd_event('N', 0, KEYEVENTF_KEYUP
, 0);
5627 keybd_event(VK_MENU
, 0, KEYEVENTF_KEYUP
, 0);
5628 pump_msg_loop(hwnd
, hAccel
);
5629 ok_sequence(WmAltVkN
, "Alt+VK_N press/release", FALSE
);
5631 trace("testing Ctrl+Alt+VK_N press/release 1\n");
5633 keybd_event(VK_CONTROL
, 0, 0, 0);
5634 keybd_event(VK_MENU
, 0, 0, 0);
5635 keybd_event('N', 0, 0, 0);
5636 keybd_event('N', 0, KEYEVENTF_KEYUP
, 0);
5637 keybd_event(VK_MENU
, 0, KEYEVENTF_KEYUP
, 0);
5638 keybd_event(VK_CONTROL
, 0, KEYEVENTF_KEYUP
, 0);
5639 pump_msg_loop(hwnd
, hAccel
);
5640 ok_sequence(WmCtrlAltVkN
, "Ctrl+Alt+VK_N press/release 1", FALSE
);
5642 ret
= DestroyAcceleratorTable(hAccel
);
5643 ok( ret
, "DestroyAcceleratorTable error %d\n", GetLastError());
5645 hAccel
= LoadAccelerators(GetModuleHandleA(0), MAKEINTRESOURCE(2));
5646 assert(hAccel
!= 0);
5648 trace("testing VK_N press/release\n");
5650 keybd_event('N', 0, 0, 0);
5651 keybd_event('N', 0, KEYEVENTF_KEYUP
, 0);
5652 pump_msg_loop(hwnd
, hAccel
);
5653 ok_sequence(WmVkN
, "VK_N press/release", FALSE
);
5655 trace("testing Shift+VK_N press/release\n");
5657 keybd_event(VK_SHIFT
, 0, 0, 0);
5658 keybd_event('N', 0, 0, 0);
5659 keybd_event('N', 0, KEYEVENTF_KEYUP
, 0);
5660 keybd_event(VK_SHIFT
, 0, KEYEVENTF_KEYUP
, 0);
5661 pump_msg_loop(hwnd
, hAccel
);
5662 ok_sequence(WmShiftVkN
, "Shift+VK_N press/release", FALSE
);
5664 trace("testing Ctrl+VK_N press/release 2\n");
5666 keybd_event(VK_CONTROL
, 0, 0, 0);
5667 keybd_event('N', 0, 0, 0);
5668 keybd_event('N', 0, KEYEVENTF_KEYUP
, 0);
5669 keybd_event(VK_CONTROL
, 0, KEYEVENTF_KEYUP
, 0);
5670 pump_msg_loop(hwnd
, hAccel
);
5671 ok_sequence(WmCtrlVkN_2
, "Ctrl+VK_N press/release 2", FALSE
);
5673 trace("testing Alt+VK_N press/release 2\n");
5675 keybd_event(VK_MENU
, 0, 0, 0);
5676 keybd_event('N', 0, 0, 0);
5677 keybd_event('N', 0, KEYEVENTF_KEYUP
, 0);
5678 keybd_event(VK_MENU
, 0, KEYEVENTF_KEYUP
, 0);
5679 pump_msg_loop(hwnd
, hAccel
);
5680 ok_sequence(WmAltVkN_2
, "Alt+VK_N press/release 2", FALSE
);
5682 trace("testing Ctrl+Alt+VK_N press/release 2\n");
5684 keybd_event(VK_CONTROL
, 0, 0, 0);
5685 keybd_event(VK_MENU
, 0, 0, 0);
5686 keybd_event('N', 0, 0, 0);
5687 keybd_event('N', 0, KEYEVENTF_KEYUP
, 0);
5688 keybd_event(VK_MENU
, 0, KEYEVENTF_KEYUP
, 0);
5689 keybd_event(VK_CONTROL
, 0, KEYEVENTF_KEYUP
, 0);
5690 pump_msg_loop(hwnd
, hAccel
);
5691 ok_sequence(WmCtrlAltVkN
, "Ctrl+Alt+VK_N press/release 2", FALSE
);
5693 trace("testing Ctrl+Shift+VK_N press/release\n");
5695 keybd_event(VK_CONTROL
, 0, 0, 0);
5696 keybd_event(VK_SHIFT
, 0, 0, 0);
5697 keybd_event('N', 0, 0, 0);
5698 keybd_event('N', 0, KEYEVENTF_KEYUP
, 0);
5699 keybd_event(VK_SHIFT
, 0, KEYEVENTF_KEYUP
, 0);
5700 keybd_event(VK_CONTROL
, 0, KEYEVENTF_KEYUP
, 0);
5701 pump_msg_loop(hwnd
, hAccel
);
5702 ok_sequence(WmCtrlShiftVkN
, "Ctrl+Shift+VK_N press/release", FALSE
);
5704 trace("testing Ctrl+Alt+Shift+VK_N press/release\n");
5706 keybd_event(VK_CONTROL
, 0, 0, 0);
5707 keybd_event(VK_MENU
, 0, 0, 0);
5708 keybd_event(VK_SHIFT
, 0, 0, 0);
5709 keybd_event('N', 0, 0, 0);
5710 keybd_event('N', 0, KEYEVENTF_KEYUP
, 0);
5711 keybd_event(VK_SHIFT
, 0, KEYEVENTF_KEYUP
, 0);
5712 keybd_event(VK_MENU
, 0, KEYEVENTF_KEYUP
, 0);
5713 keybd_event(VK_CONTROL
, 0, KEYEVENTF_KEYUP
, 0);
5714 pump_msg_loop(hwnd
, hAccel
);
5715 ok_sequence(WmCtrlAltShiftVkN
, "Ctrl+Alt+Shift+VK_N press/release", FALSE
);
5717 ret
= DestroyAcceleratorTable(hAccel
);
5718 ok( ret
, "DestroyAcceleratorTable error %d\n", GetLastError());
5720 trace("testing Alt press/release\n");
5722 keybd_event(VK_MENU
, 0, 0, 0);
5723 keybd_event(VK_MENU
, 0, KEYEVENTF_KEYUP
, 0);
5724 keybd_event(VK_MENU
, 0, 0, 0);
5725 keybd_event(VK_MENU
, 0, KEYEVENTF_KEYUP
, 0);
5726 pump_msg_loop(hwnd
, 0);
5727 /* this test doesn't pass in Wine for managed windows */
5728 ok_sequence(WmAltPressRelease
, "Alt press/release", TRUE
);
5730 trace("testing Alt+MouseButton press/release\n");
5731 /* first, move mouse pointer inside of the window client area */
5732 GetClientRect(hwnd
, &rc
);
5733 MapWindowPoints(hwnd
, 0, (LPPOINT
)&rc
, 2);
5734 rc
.left
+= (rc
.right
- rc
.left
)/2;
5735 rc
.top
+= (rc
.bottom
- rc
.top
)/2;
5736 SetCursorPos(rc
.left
, rc
.top
);
5738 pump_msg_loop(hwnd
, 0);
5740 keybd_event(VK_MENU
, 0, 0, 0);
5741 mouse_event(MOUSEEVENTF_LEFTDOWN
, 0, 0, 0, 0);
5742 mouse_event(MOUSEEVENTF_LEFTUP
, 0, 0, 0, 0);
5743 keybd_event(VK_MENU
, 0, KEYEVENTF_KEYUP
, 0);
5744 pump_msg_loop(hwnd
, 0);
5745 ok_sequence(WmAltMouseButton
, "Alt+MouseButton press/release", FALSE
);
5747 trace("testing VK_F1 press/release\n");
5748 keybd_event(VK_F1
, 0, 0, 0);
5749 keybd_event(VK_F1
, 0, KEYEVENTF_KEYUP
, 0);
5750 pump_msg_loop(hwnd
, 0);
5751 ok_sequence(WmF1Seq
, "F1 press/release", TRUE
);
5753 trace("testing VK_APPS press/release\n");
5754 keybd_event(VK_APPS
, 0, 0, 0);
5755 keybd_event(VK_APPS
, 0, KEYEVENTF_KEYUP
, 0);
5756 pump_msg_loop(hwnd
, 0);
5757 ok_sequence(WmVkAppsSeq
, "VK_APPS press/release", FALSE
);
5759 DestroyWindow(hwnd
);
5762 /************* window procedures ********************/
5764 static LRESULT
MsgCheckProc (BOOL unicode
, HWND hwnd
, UINT message
,
5765 WPARAM wParam
, LPARAM lParam
)
5767 static long defwndproc_counter
= 0;
5768 static long beginpaint_counter
= 0;
5772 trace("%p, %04x, %08lx, %08lx\n", hwnd
, message
, wParam
, lParam
);
5774 /* explicitly ignore WM_GETICON message */
5775 if (message
== WM_GETICON
) return 0;
5781 LONG style
= GetWindowLongA(hwnd
, GWL_STYLE
);
5782 ok((BOOL
)wParam
== !(style
& WS_DISABLED
),
5783 "wrong WS_DISABLED state: %ld != %d\n", wParam
, !(style
& WS_DISABLED
));
5787 case WM_CAPTURECHANGED
:
5788 if (test_DestroyWindow_flag
)
5790 DWORD style
= GetWindowLongA(hwnd
, GWL_STYLE
);
5791 if (style
& WS_CHILD
)
5792 lParam
= GetWindowLongPtrA(hwnd
, GWLP_ID
);
5793 else if (style
& WS_POPUP
)
5794 lParam
= WND_POPUP_ID
;
5796 lParam
= WND_PARENT_ID
;
5804 ok(!GetWindow(hwnd
, GW_CHILD
), "children should be unlinked at this point\n");
5805 capture
= GetCapture();
5808 ok(capture
== hwnd
, "capture should NOT be released at this point (capture %p)\n", capture
);
5809 trace("current capture %p, releasing...\n", capture
);
5816 ok(pGetAncestor(hwnd
, GA_PARENT
) != 0, "parent should NOT be unlinked at this point\n");
5817 if (test_DestroyWindow_flag
)
5819 DWORD style
= GetWindowLongA(hwnd
, GWL_STYLE
);
5820 if (style
& WS_CHILD
)
5821 lParam
= GetWindowLongPtrA(hwnd
, GWLP_ID
);
5822 else if (style
& WS_POPUP
)
5823 lParam
= WND_POPUP_ID
;
5825 lParam
= WND_PARENT_ID
;
5829 /* test_accelerators() depends on this */
5836 case WM_DEVICECHANGE
:
5839 case WM_WINDOWPOSCHANGING
:
5840 case WM_WINDOWPOSCHANGED
:
5842 WINDOWPOS
*winpos
= (WINDOWPOS
*)lParam
;
5844 trace("%s\n", (message
== WM_WINDOWPOSCHANGING
) ? "WM_WINDOWPOSCHANGING" : "WM_WINDOWPOSCHANGED");
5845 trace("%p after %p, x %d, y %d, cx %d, cy %d flags %08x\n",
5846 winpos
->hwnd
, winpos
->hwndInsertAfter
,
5847 winpos
->x
, winpos
->y
, winpos
->cx
, winpos
->cy
, winpos
->flags
);
5848 dump_winpos_flags(winpos
->flags
);
5850 /* Log only documented flags, win2k uses 0x1000 and 0x2000
5851 * in the high word for internal purposes
5853 wParam
= winpos
->flags
& 0xffff;
5854 /* We are not interested in the flags that don't match under XP and Win9x */
5855 wParam
&= ~(SWP_NOZORDER
);
5860 msg
.message
= message
;
5861 msg
.flags
= sent
|wparam
|lparam
;
5862 if (defwndproc_counter
) msg
.flags
|= defwinproc
;
5863 if (beginpaint_counter
) msg
.flags
|= beginpaint
;
5864 msg
.wParam
= wParam
;
5865 msg
.lParam
= lParam
;
5868 if (message
== WM_GETMINMAXINFO
&& (GetWindowLongA(hwnd
, GWL_STYLE
) & WS_CHILD
))
5870 HWND parent
= GetParent(hwnd
);
5872 MINMAXINFO
*minmax
= (MINMAXINFO
*)lParam
;
5874 GetClientRect(parent
, &rc
);
5875 trace("parent %p client size = (%d x %d)\n", parent
, rc
.right
, rc
.bottom
);
5877 trace("ptReserved = (%d,%d)\n"
5878 "ptMaxSize = (%d,%d)\n"
5879 "ptMaxPosition = (%d,%d)\n"
5880 "ptMinTrackSize = (%d,%d)\n"
5881 "ptMaxTrackSize = (%d,%d)\n",
5882 minmax
->ptReserved
.x
, minmax
->ptReserved
.y
,
5883 minmax
->ptMaxSize
.x
, minmax
->ptMaxSize
.y
,
5884 minmax
->ptMaxPosition
.x
, minmax
->ptMaxPosition
.y
,
5885 minmax
->ptMinTrackSize
.x
, minmax
->ptMinTrackSize
.y
,
5886 minmax
->ptMaxTrackSize
.x
, minmax
->ptMaxTrackSize
.y
);
5888 ok(minmax
->ptMaxSize
.x
== rc
.right
, "default width of maximized child %d != %d\n",
5889 minmax
->ptMaxSize
.x
, rc
.right
);
5890 ok(minmax
->ptMaxSize
.y
== rc
.bottom
, "default height of maximized child %d != %d\n",
5891 minmax
->ptMaxSize
.y
, rc
.bottom
);
5894 if (message
== WM_PAINT
)
5897 beginpaint_counter
++;
5898 BeginPaint( hwnd
, &ps
);
5899 beginpaint_counter
--;
5900 EndPaint( hwnd
, &ps
);
5904 defwndproc_counter
++;
5905 ret
= unicode
? DefWindowProcW(hwnd
, message
, wParam
, lParam
)
5906 : DefWindowProcA(hwnd
, message
, wParam
, lParam
);
5907 defwndproc_counter
--;
5912 static LRESULT WINAPI
MsgCheckProcA(HWND hwnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
5914 return MsgCheckProc (FALSE
, hwnd
, message
, wParam
, lParam
);
5917 static LRESULT WINAPI
MsgCheckProcW(HWND hwnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
5919 return MsgCheckProc (TRUE
, hwnd
, message
, wParam
, lParam
);
5922 static LRESULT WINAPI
PopupMsgCheckProcA(HWND hwnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
5924 static long defwndproc_counter
= 0;
5928 trace("popup: %p, %04x, %08lx, %08lx\n", hwnd
, message
, wParam
, lParam
);
5930 /* explicitly ignore WM_GETICON message */
5931 if (message
== WM_GETICON
) return 0;
5933 msg
.message
= message
;
5934 msg
.flags
= sent
|wparam
|lparam
;
5935 if (defwndproc_counter
) msg
.flags
|= defwinproc
;
5936 msg
.wParam
= wParam
;
5937 msg
.lParam
= lParam
;
5940 if (message
== WM_CREATE
)
5942 DWORD style
= GetWindowLongA(hwnd
, GWL_STYLE
) | WS_VISIBLE
;
5943 SetWindowLongA(hwnd
, GWL_STYLE
, style
);
5946 defwndproc_counter
++;
5947 ret
= DefWindowProcA(hwnd
, message
, wParam
, lParam
);
5948 defwndproc_counter
--;
5953 static LRESULT WINAPI
ParentMsgCheckProcA(HWND hwnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
5955 static long defwndproc_counter
= 0;
5956 static long beginpaint_counter
= 0;
5960 trace("parent: %p, %04x, %08lx, %08lx\n", hwnd
, message
, wParam
, lParam
);
5962 /* explicitly ignore WM_GETICON message */
5963 if (message
== WM_GETICON
) return 0;
5965 if (log_all_parent_messages
||
5966 message
== WM_PARENTNOTIFY
|| message
== WM_CANCELMODE
||
5967 message
== WM_SETFOCUS
|| message
== WM_KILLFOCUS
||
5968 message
== WM_ENABLE
|| message
== WM_ENTERIDLE
||
5969 message
== WM_IME_SETCONTEXT
)
5983 INT ret
= GetClipBox((HDC
)wParam
, &rc
);
5985 trace("WM_ERASEBKGND: GetClipBox()=%d, (%d,%d-%d,%d)\n",
5986 ret
, rc
.left
, rc
.top
, rc
.right
, rc
.bottom
);
5990 case WM_WINDOWPOSCHANGING
:
5991 case WM_WINDOWPOSCHANGED
:
5993 WINDOWPOS
*winpos
= (WINDOWPOS
*)lParam
;
5995 trace("%s\n", (message
== WM_WINDOWPOSCHANGING
) ? "WM_WINDOWPOSCHANGING" : "WM_WINDOWPOSCHANGED");
5996 trace("%p after %p, x %d, y %d, cx %d, cy %d flags %08x\n",
5997 winpos
->hwnd
, winpos
->hwndInsertAfter
,
5998 winpos
->x
, winpos
->y
, winpos
->cx
, winpos
->cy
, winpos
->flags
);
5999 dump_winpos_flags(winpos
->flags
);
6001 /* Log only documented flags, win2k uses 0x1000 and 0x2000
6002 * in the high word for internal purposes
6004 wParam
= winpos
->flags
& 0xffff;
6005 /* We are not interested in the flags that don't match under XP and Win9x */
6006 wParam
&= ~(SWP_NOZORDER
);
6011 msg
.message
= message
;
6012 msg
.flags
= sent
|parent
|wparam
|lparam
;
6013 if (defwndproc_counter
) msg
.flags
|= defwinproc
;
6014 if (beginpaint_counter
) msg
.flags
|= beginpaint
;
6015 msg
.wParam
= wParam
;
6016 msg
.lParam
= lParam
;
6020 if (message
== WM_PAINT
)
6023 beginpaint_counter
++;
6024 BeginPaint( hwnd
, &ps
);
6025 beginpaint_counter
--;
6026 EndPaint( hwnd
, &ps
);
6030 defwndproc_counter
++;
6031 ret
= DefWindowProcA(hwnd
, message
, wParam
, lParam
);
6032 defwndproc_counter
--;
6037 static LRESULT WINAPI
TestDlgProcA(HWND hwnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
6039 static long defwndproc_counter
= 0;
6043 trace("dialog: %p, %04x, %08lx, %08lx\n", hwnd
, message
, wParam
, lParam
);
6045 /* explicitly ignore WM_GETICON message */
6046 if (message
== WM_GETICON
) return 0;
6050 DefDlgProcA(hwnd
, DM_SETDEFID
, 1, 0);
6051 ret
= DefDlgProcA(hwnd
, DM_GETDEFID
, 0, 0);
6052 if (after_end_dialog
)
6053 ok( ret
== 0, "DM_GETDEFID should return 0 after EndDialog, got %lx\n", ret
);
6055 ok(HIWORD(ret
) == DC_HASDEFID
, "DM_GETDEFID should return DC_HASDEFID, got %lx\n", ret
);
6060 case WM_WINDOWPOSCHANGING
:
6061 case WM_WINDOWPOSCHANGED
:
6063 WINDOWPOS
*winpos
= (WINDOWPOS
*)lParam
;
6065 trace("%s\n", (message
== WM_WINDOWPOSCHANGING
) ? "WM_WINDOWPOSCHANGING" : "WM_WINDOWPOSCHANGED");
6066 trace("%p after %p, x %d, y %d, cx %d, cy %d flags %08x\n",
6067 winpos
->hwnd
, winpos
->hwndInsertAfter
,
6068 winpos
->x
, winpos
->y
, winpos
->cx
, winpos
->cy
, winpos
->flags
);
6069 dump_winpos_flags(winpos
->flags
);
6071 /* Log only documented flags, win2k uses 0x1000 and 0x2000
6072 * in the high word for internal purposes
6074 wParam
= winpos
->flags
& 0xffff;
6075 /* We are not interested in the flags that don't match under XP and Win9x */
6076 wParam
&= ~(SWP_NOZORDER
);
6081 msg
.message
= message
;
6082 msg
.flags
= sent
|wparam
|lparam
;
6083 if (defwndproc_counter
) msg
.flags
|= defwinproc
;
6084 msg
.wParam
= wParam
;
6085 msg
.lParam
= lParam
;
6088 defwndproc_counter
++;
6089 ret
= DefDlgProcA(hwnd
, message
, wParam
, lParam
);
6090 defwndproc_counter
--;
6095 static void dump_winpos_flags(UINT flags
)
6097 if (!winetest_debug
) return;
6099 if (flags
& SWP_SHOWWINDOW
) printf("|SWP_SHOWWINDOW");
6100 if (flags
& SWP_HIDEWINDOW
) printf("|SWP_HIDEWINDOW");
6101 if (flags
& SWP_NOACTIVATE
) printf("|SWP_NOACTIVATE");
6102 if (flags
& SWP_FRAMECHANGED
) printf("|SWP_FRAMECHANGED");
6103 if (flags
& SWP_NOCOPYBITS
) printf("|SWP_NOCOPYBITS");
6104 if (flags
& SWP_NOOWNERZORDER
) printf("|SWP_NOOWNERZORDER");
6105 if (flags
& SWP_NOSENDCHANGING
) printf("|SWP_NOSENDCHANGING");
6106 if (flags
& SWP_DEFERERASE
) printf("|SWP_DEFERERASE");
6107 if (flags
& SWP_ASYNCWINDOWPOS
) printf("|SWP_ASYNCWINDOWPOS");
6108 if (flags
& SWP_NOZORDER
) printf("|SWP_NOZORDER");
6109 if (flags
& SWP_NOREDRAW
) printf("|SWP_NOREDRAW");
6110 if (flags
& SWP_NOSIZE
) printf("|SWP_NOSIZE");
6111 if (flags
& SWP_NOMOVE
) printf("|SWP_NOMOVE");
6112 if (flags
& SWP_NOCLIENTSIZE
) printf("|SWP_NOCLIENTSIZE");
6113 if (flags
& SWP_NOCLIENTMOVE
) printf("|SWP_NOCLIENTMOVE");
6115 #define DUMPED_FLAGS \
6121 SWP_FRAMECHANGED | \
6125 SWP_NOOWNERZORDER | \
6126 SWP_NOSENDCHANGING | \
6128 SWP_ASYNCWINDOWPOS | \
6129 SWP_NOCLIENTSIZE | \
6132 if(flags
& ~DUMPED_FLAGS
) printf("|0x%04x", flags
& ~DUMPED_FLAGS
);
6137 static LRESULT WINAPI
ShowWindowProcA(HWND hwnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
6139 static long defwndproc_counter
= 0;
6143 /* log only specific messages we are interested in */
6146 #if 0 /* probably log these as well */
6152 trace("WM_SHOWWINDOW %ld\n", wParam
);
6155 trace("WM_SIZE %ld\n", wParam
);
6160 case WM_GETMINMAXINFO
:
6161 trace("WM_GETMINMAXINFO\n");
6164 case WM_WINDOWPOSCHANGING
:
6165 case WM_WINDOWPOSCHANGED
:
6167 WINDOWPOS
*winpos
= (WINDOWPOS
*)lParam
;
6169 trace("%s\n", (message
== WM_WINDOWPOSCHANGING
) ? "WM_WINDOWPOSCHANGING" : "WM_WINDOWPOSCHANGED");
6170 trace("%p after %p, x %d, y %d, cx %d, cy %d flags %08x\n",
6171 winpos
->hwnd
, winpos
->hwndInsertAfter
,
6172 winpos
->x
, winpos
->y
, winpos
->cx
, winpos
->cy
, winpos
->flags
);
6174 dump_winpos_flags(winpos
->flags
);
6176 /* Log only documented flags, win2k uses 0x1000 and 0x2000
6177 * in the high word for internal purposes
6179 wParam
= winpos
->flags
& 0xffff;
6180 /* We are not interested in the flags that don't match under XP and Win9x */
6181 wParam
&= ~(SWP_NOZORDER
);
6185 default: /* ignore */
6186 /*trace("showwindow: %p, %04x, %08x, %08lx\n", hwnd, message, wParam, lParam);*/
6187 return DefWindowProcA(hwnd
, message
, wParam
, lParam
);
6190 msg
.message
= message
;
6191 msg
.flags
= sent
|wparam
|lparam
;
6192 if (defwndproc_counter
) msg
.flags
|= defwinproc
;
6193 msg
.wParam
= wParam
;
6194 msg
.lParam
= lParam
;
6197 defwndproc_counter
++;
6198 ret
= DefWindowProcA(hwnd
, message
, wParam
, lParam
);
6199 defwndproc_counter
--;
6204 static BOOL
RegisterWindowClasses(void)
6209 cls
.lpfnWndProc
= MsgCheckProcA
;
6212 cls
.hInstance
= GetModuleHandleA(0);
6214 cls
.hCursor
= LoadCursorA(0, (LPSTR
)IDC_ARROW
);
6215 cls
.hbrBackground
= GetStockObject(WHITE_BRUSH
);
6216 cls
.lpszMenuName
= NULL
;
6217 cls
.lpszClassName
= "TestWindowClass";
6218 if(!RegisterClassA(&cls
)) return FALSE
;
6220 cls
.lpfnWndProc
= ShowWindowProcA
;
6221 cls
.lpszClassName
= "ShowWindowClass";
6222 if(!RegisterClassA(&cls
)) return FALSE
;
6224 cls
.lpfnWndProc
= PopupMsgCheckProcA
;
6225 cls
.lpszClassName
= "TestPopupClass";
6226 if(!RegisterClassA(&cls
)) return FALSE
;
6228 cls
.lpfnWndProc
= ParentMsgCheckProcA
;
6229 cls
.lpszClassName
= "TestParentClass";
6230 if(!RegisterClassA(&cls
)) return FALSE
;
6232 cls
.lpfnWndProc
= DefWindowProcA
;
6233 cls
.lpszClassName
= "SimpleWindowClass";
6234 if(!RegisterClassA(&cls
)) return FALSE
;
6236 cls
.style
= CS_NOCLOSE
;
6237 cls
.lpszClassName
= "NoCloseWindowClass";
6238 if(!RegisterClassA(&cls
)) return FALSE
;
6240 ok(GetClassInfoA(0, "#32770", &cls
), "GetClassInfo failed\n");
6242 cls
.hInstance
= GetModuleHandleA(0);
6243 cls
.hbrBackground
= 0;
6244 cls
.lpfnWndProc
= TestDlgProcA
;
6245 cls
.lpszClassName
= "TestDialogClass";
6246 if(!RegisterClassA(&cls
)) return FALSE
;
6251 static HHOOK hCBT_hook
;
6252 static DWORD cbt_hook_thread_id
;
6254 static LRESULT CALLBACK
cbt_hook_proc(int nCode
, WPARAM wParam
, LPARAM lParam
)
6256 static const char * const CBT_code_name
[10] = {
6263 "HCBT_CLICKSKIPPED",
6267 const char *code_name
= (nCode
>= 0 && nCode
<= HCBT_SETFOCUS
) ? CBT_code_name
[nCode
] : "Unknown";
6271 trace("CBT: %d (%s), %08lx, %08lx\n", nCode
, code_name
, wParam
, lParam
);
6273 ok(cbt_hook_thread_id
== GetCurrentThreadId(), "we didn't ask for events from other threads\n");
6275 if (nCode
== HCBT_CLICKSKIPPED
)
6277 /* ignore this event, XP sends it a lot when switching focus between windows */
6278 return CallNextHookEx(hCBT_hook
, nCode
, wParam
, lParam
);
6281 if (nCode
== HCBT_SYSCOMMAND
|| nCode
== HCBT_KEYSKIPPED
)
6285 msg
.message
= nCode
;
6286 msg
.flags
= hook
|wparam
|lparam
;
6287 msg
.wParam
= wParam
;
6288 msg
.lParam
= lParam
;
6291 return CallNextHookEx(hCBT_hook
, nCode
, wParam
, lParam
);
6294 if (nCode
== HCBT_DESTROYWND
)
6296 if (test_DestroyWindow_flag
)
6298 DWORD style
= GetWindowLongA((HWND
)wParam
, GWL_STYLE
);
6299 if (style
& WS_CHILD
)
6300 lParam
= GetWindowLongPtrA((HWND
)wParam
, GWLP_ID
);
6301 else if (style
& WS_POPUP
)
6302 lParam
= WND_POPUP_ID
;
6304 lParam
= WND_PARENT_ID
;
6308 /* Log also SetFocus(0) calls */
6309 hwnd
= wParam
? (HWND
)wParam
: (HWND
)lParam
;
6311 if (GetClassNameA(hwnd
, buf
, sizeof(buf
)))
6313 if (!lstrcmpiA(buf
, "TestWindowClass") ||
6314 !lstrcmpiA(buf
, "ShowWindowClass") ||
6315 !lstrcmpiA(buf
, "TestParentClass") ||
6316 !lstrcmpiA(buf
, "TestPopupClass") ||
6317 !lstrcmpiA(buf
, "SimpleWindowClass") ||
6318 !lstrcmpiA(buf
, "TestDialogClass") ||
6319 !lstrcmpiA(buf
, "MDI_frame_class") ||
6320 !lstrcmpiA(buf
, "MDI_client_class") ||
6321 !lstrcmpiA(buf
, "MDI_child_class") ||
6322 !lstrcmpiA(buf
, "my_button_class") ||
6323 !lstrcmpiA(buf
, "my_edit_class") ||
6324 !lstrcmpiA(buf
, "static") ||
6325 !lstrcmpiA(buf
, "MyDialogClass") ||
6326 !lstrcmpiA(buf
, "#32770"))
6330 msg
.message
= nCode
;
6331 msg
.flags
= hook
|wparam
|lparam
;
6332 msg
.wParam
= wParam
;
6333 msg
.lParam
= lParam
;
6337 return CallNextHookEx(hCBT_hook
, nCode
, wParam
, lParam
);
6340 static void CALLBACK
win_event_proc(HWINEVENTHOOK hevent
,
6350 trace("WEH:%p,event %08x,hwnd %p,obj %08x,id %08x,thread %08x,time %08x\n",
6351 hevent
, event
, hwnd
, object_id
, child_id
, thread_id
, event_time
);
6353 ok(thread_id
== GetCurrentThreadId(), "we didn't ask for events from other threads\n");
6355 /* ignore mouse cursor events */
6356 if (object_id
== OBJID_CURSOR
) return;
6358 if (!hwnd
|| GetClassNameA(hwnd
, buf
, sizeof(buf
)))
6361 !lstrcmpiA(buf
, "TestWindowClass") ||
6362 !lstrcmpiA(buf
, "TestParentClass") ||
6363 !lstrcmpiA(buf
, "TestPopupClass") ||
6364 !lstrcmpiA(buf
, "SimpleWindowClass") ||
6365 !lstrcmpiA(buf
, "TestDialogClass") ||
6366 !lstrcmpiA(buf
, "MDI_frame_class") ||
6367 !lstrcmpiA(buf
, "MDI_client_class") ||
6368 !lstrcmpiA(buf
, "MDI_child_class") ||
6369 !lstrcmpiA(buf
, "my_button_class") ||
6370 !lstrcmpiA(buf
, "my_edit_class") ||
6371 !lstrcmpiA(buf
, "static") ||
6372 !lstrcmpiA(buf
, "MyDialogClass") ||
6373 !lstrcmpiA(buf
, "#32770"))
6377 msg
.message
= event
;
6378 msg
.flags
= winevent_hook
|wparam
|lparam
;
6379 msg
.wParam
= object_id
;
6380 msg
.lParam
= child_id
;
6386 static const WCHAR wszUnicode
[] = {'U','n','i','c','o','d','e',0};
6387 static const WCHAR wszAnsi
[] = {'U',0};
6389 static LRESULT CALLBACK
MsgConversionProcW(HWND hwnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
6393 case CB_FINDSTRINGEXACT
:
6394 trace("String: %p\n", (LPCWSTR
)lParam
);
6395 if (!lstrcmpW((LPCWSTR
)lParam
, wszUnicode
))
6397 if (!lstrcmpW((LPCWSTR
)lParam
, wszAnsi
))
6401 return DefWindowProcW(hwnd
, uMsg
, wParam
, lParam
);
6404 static const struct message WmGetTextLengthAfromW
[] = {
6405 { WM_GETTEXTLENGTH
, sent
},
6406 { WM_GETTEXT
, sent
},
6410 static const WCHAR testWindowClassW
[] =
6411 { 'T','e','s','t','W','i','n','d','o','w','C','l','a','s','s','W',0 };
6413 static const WCHAR dummy_window_text
[] = {'d','u','m','m','y',' ','t','e','x','t',0};
6415 /* dummy window proc for WM_GETTEXTLENGTH test */
6416 static LRESULT CALLBACK
get_text_len_proc( HWND hwnd
, UINT msg
, WPARAM wp
, LPARAM lp
)
6420 case WM_GETTEXTLENGTH
:
6421 return lstrlenW(dummy_window_text
) + 37; /* some random length */
6423 lstrcpynW( (LPWSTR
)lp
, dummy_window_text
, wp
);
6424 return lstrlenW( (LPWSTR
)lp
);
6426 return DefWindowProcW( hwnd
, msg
, wp
, lp
);
6430 static void test_message_conversion(void)
6432 static const WCHAR wszMsgConversionClass
[] =
6433 {'M','s','g','C','o','n','v','e','r','s','i','o','n','C','l','a','s','s',0};
6437 WNDPROC wndproc
, newproc
;
6441 cls
.lpfnWndProc
= MsgConversionProcW
;
6444 cls
.hInstance
= GetModuleHandleW(NULL
);
6446 cls
.hCursor
= LoadCursorW(NULL
, (LPWSTR
)IDC_ARROW
);
6447 cls
.hbrBackground
= (HBRUSH
)(COLOR_BTNFACE
+1);
6448 cls
.lpszMenuName
= NULL
;
6449 cls
.lpszClassName
= wszMsgConversionClass
;
6450 /* this call will fail on Win9x, but that doesn't matter as this test is
6451 * meaningless on those platforms */
6452 if(!RegisterClassW(&cls
)) return;
6455 cls
.lpfnWndProc
= MsgCheckProcW
;
6458 cls
.hInstance
= GetModuleHandleW(0);
6460 cls
.hCursor
= LoadCursorW(0, (LPWSTR
)IDC_ARROW
);
6461 cls
.hbrBackground
= GetStockObject(WHITE_BRUSH
);
6462 cls
.lpszMenuName
= NULL
;
6463 cls
.lpszClassName
= testWindowClassW
;
6464 if(!RegisterClassW(&cls
)) return;
6466 hwnd
= CreateWindowExW(0, wszMsgConversionClass
, NULL
, WS_OVERLAPPED
,
6467 100, 100, 200, 200, 0, 0, 0, NULL
);
6468 ok(hwnd
!= NULL
, "Window creation failed\n");
6472 wndproc
= (WNDPROC
)GetWindowLongPtrA(hwnd
, GWLP_WNDPROC
);
6473 lRes
= CallWindowProcA(wndproc
, hwnd
, CB_FINDSTRINGEXACT
, 0, (LPARAM
)wszUnicode
);
6474 ok(lRes
== 0, "String should have been converted\n");
6475 lRes
= CallWindowProcW(wndproc
, hwnd
, CB_FINDSTRINGEXACT
, 0, (LPARAM
)wszUnicode
);
6476 ok(lRes
== 1, "String shouldn't have been converted\n");
6480 wndproc
= (WNDPROC
)GetWindowLongPtrW(hwnd
, GWLP_WNDPROC
);
6481 lRes
= CallWindowProcA(wndproc
, hwnd
, CB_FINDSTRINGEXACT
, 0, (LPARAM
)wszUnicode
);
6482 ok(lRes
== 1, "String shouldn't have been converted\n");
6483 lRes
= CallWindowProcW(wndproc
, hwnd
, CB_FINDSTRINGEXACT
, 0, (LPARAM
)wszUnicode
);
6484 ok(lRes
== 1, "String shouldn't have been converted\n");
6486 /* Synchronous messages */
6488 lRes
= SendMessageA(hwnd
, CB_FINDSTRINGEXACT
, 0, (LPARAM
)wszUnicode
);
6489 ok(lRes
== 0, "String should have been converted\n");
6490 lRes
= SendMessageW(hwnd
, CB_FINDSTRINGEXACT
, 0, (LPARAM
)wszUnicode
);
6491 ok(lRes
== 1, "String shouldn't have been converted\n");
6493 /* Asynchronous messages */
6496 lRes
= PostMessageA(hwnd
, CB_FINDSTRINGEXACT
, 0, (LPARAM
)wszUnicode
);
6497 ok(lRes
== 0 && (GetLastError() == ERROR_MESSAGE_SYNC_ONLY
|| GetLastError() == ERROR_INVALID_PARAMETER
),
6498 "PostMessage on sync only message returned %ld, last error %d\n", lRes
, GetLastError());
6500 lRes
= PostMessageW(hwnd
, CB_FINDSTRINGEXACT
, 0, (LPARAM
)wszUnicode
);
6501 ok(lRes
== 0 && (GetLastError() == ERROR_MESSAGE_SYNC_ONLY
|| GetLastError() == ERROR_INVALID_PARAMETER
),
6502 "PostMessage on sync only message returned %ld, last error %d\n", lRes
, GetLastError());
6504 lRes
= PostThreadMessageA(GetCurrentThreadId(), CB_FINDSTRINGEXACT
, 0, (LPARAM
)wszUnicode
);
6505 ok(lRes
== 0 && (GetLastError() == ERROR_MESSAGE_SYNC_ONLY
|| GetLastError() == ERROR_INVALID_PARAMETER
),
6506 "PosThreadtMessage on sync only message returned %ld, last error %d\n", lRes
, GetLastError());
6508 lRes
= PostThreadMessageW(GetCurrentThreadId(), CB_FINDSTRINGEXACT
, 0, (LPARAM
)wszUnicode
);
6509 ok(lRes
== 0 && (GetLastError() == ERROR_MESSAGE_SYNC_ONLY
|| GetLastError() == ERROR_INVALID_PARAMETER
),
6510 "PosThreadtMessage on sync only message returned %ld, last error %d\n", lRes
, GetLastError());
6512 lRes
= SendNotifyMessageA(hwnd
, CB_FINDSTRINGEXACT
, 0, (LPARAM
)wszUnicode
);
6513 ok(lRes
== 0 && (GetLastError() == ERROR_MESSAGE_SYNC_ONLY
|| GetLastError() == ERROR_INVALID_PARAMETER
),
6514 "SendNotifyMessage on sync only message returned %ld, last error %d\n", lRes
, GetLastError());
6516 lRes
= SendNotifyMessageW(hwnd
, CB_FINDSTRINGEXACT
, 0, (LPARAM
)wszUnicode
);
6517 ok(lRes
== 0 && (GetLastError() == ERROR_MESSAGE_SYNC_ONLY
|| GetLastError() == ERROR_INVALID_PARAMETER
),
6518 "SendNotifyMessage on sync only message returned %ld, last error %d\n", lRes
, GetLastError());
6520 lRes
= SendMessageCallbackA(hwnd
, CB_FINDSTRINGEXACT
, 0, (LPARAM
)wszUnicode
, NULL
, 0);
6521 ok(lRes
== 0 && (GetLastError() == ERROR_MESSAGE_SYNC_ONLY
|| GetLastError() == ERROR_INVALID_PARAMETER
),
6522 "SendMessageCallback on sync only message returned %ld, last error %d\n", lRes
, GetLastError());
6524 lRes
= SendMessageCallbackW(hwnd
, CB_FINDSTRINGEXACT
, 0, (LPARAM
)wszUnicode
, NULL
, 0);
6525 ok(lRes
== 0 && (GetLastError() == ERROR_MESSAGE_SYNC_ONLY
|| GetLastError() == ERROR_INVALID_PARAMETER
),
6526 "SendMessageCallback on sync only message returned %ld, last error %d\n", lRes
, GetLastError());
6528 /* Check WM_GETTEXTLENGTH A->W behaviour, whether WM_GETTEXT is also sent or not */
6530 hwnd
= CreateWindowW (testWindowClassW
, wszUnicode
,
6531 WS_OVERLAPPEDWINDOW
,
6532 100, 100, 200, 200, 0, 0, 0, NULL
);
6535 lRes
= SendMessageA (hwnd
, WM_GETTEXTLENGTH
, 0, 0);
6536 ok_sequence(WmGetTextLengthAfromW
, "ANSI WM_GETTEXTLENGTH to Unicode window", FALSE
);
6537 ok( lRes
== WideCharToMultiByte( CP_ACP
, 0, wszUnicode
, lstrlenW(wszUnicode
), NULL
, 0, NULL
, NULL
),
6538 "got bad length %ld\n", lRes
);
6541 lRes
= CallWindowProcA( (WNDPROC
)GetWindowLongPtrA( hwnd
, GWLP_WNDPROC
),
6542 hwnd
, WM_GETTEXTLENGTH
, 0, 0);
6543 ok_sequence(WmGetTextLengthAfromW
, "ANSI WM_GETTEXTLENGTH to Unicode window", FALSE
);
6544 ok( lRes
== WideCharToMultiByte( CP_ACP
, 0, wszUnicode
, lstrlenW(wszUnicode
), NULL
, 0, NULL
, NULL
),
6545 "got bad length %ld\n", lRes
);
6547 wndproc
= (WNDPROC
)SetWindowLongPtrW( hwnd
, GWLP_WNDPROC
, (LONG_PTR
)get_text_len_proc
);
6548 newproc
= (WNDPROC
)GetWindowLongPtrA( hwnd
, GWLP_WNDPROC
);
6549 lRes
= CallWindowProcA( newproc
, hwnd
, WM_GETTEXTLENGTH
, 0, 0 );
6550 ok( lRes
== WideCharToMultiByte( CP_ACP
, 0, dummy_window_text
, lstrlenW(dummy_window_text
),
6551 NULL
, 0, NULL
, NULL
),
6552 "got bad length %ld\n", lRes
);
6554 SetWindowLongPtrW( hwnd
, GWLP_WNDPROC
, (LONG_PTR
)wndproc
); /* restore old wnd proc */
6555 lRes
= CallWindowProcA( newproc
, hwnd
, WM_GETTEXTLENGTH
, 0, 0 );
6556 ok( lRes
== WideCharToMultiByte( CP_ACP
, 0, dummy_window_text
, lstrlenW(dummy_window_text
),
6557 NULL
, 0, NULL
, NULL
),
6558 "got bad length %ld\n", lRes
);
6560 ret
= DestroyWindow(hwnd
);
6561 ok( ret
, "DestroyWindow() error %d\n", GetLastError());
6571 static VOID CALLBACK
tfunc(HWND hwnd
, UINT uMsg
, UINT_PTR id
, DWORD dwTime
)
6575 #define TIMER_ID 0x19
6577 static DWORD WINAPI
timer_thread_proc(LPVOID x
)
6579 struct timer_info
*info
= x
;
6582 r
= KillTimer(info
->hWnd
, 0x19);
6583 ok(r
,"KillTimer failed in thread\n");
6584 r
= SetTimer(info
->hWnd
,TIMER_ID
,10000,tfunc
);
6585 ok(r
,"SetTimer failed in thread\n");
6586 ok(r
==TIMER_ID
,"SetTimer id different\n");
6587 r
= SetEvent(info
->handles
[0]);
6588 ok(r
,"SetEvent failed in thread\n");
6592 static void test_timers(void)
6594 struct timer_info info
;
6597 info
.hWnd
= CreateWindow ("TestWindowClass", NULL
,
6598 WS_OVERLAPPEDWINDOW
,
6599 CW_USEDEFAULT
, CW_USEDEFAULT
, 300, 300, 0,
6602 info
.id
= SetTimer(info
.hWnd
,TIMER_ID
,10000,tfunc
);
6603 ok(info
.id
, "SetTimer failed\n");
6604 ok(info
.id
==TIMER_ID
, "SetTimer timer ID different\n");
6605 info
.handles
[0] = CreateEvent(NULL
,0,0,NULL
);
6606 info
.handles
[1] = CreateThread(NULL
,0,timer_thread_proc
,&info
,0,&id
);
6608 WaitForMultipleObjects(2, info
.handles
, FALSE
, INFINITE
);
6610 WaitForSingleObject(info
.handles
[1], INFINITE
);
6612 CloseHandle(info
.handles
[0]);
6613 CloseHandle(info
.handles
[1]);
6615 ok( KillTimer(info
.hWnd
, TIMER_ID
), "KillTimer failed\n");
6617 ok(DestroyWindow(info
.hWnd
), "failed to destroy window\n");
6620 /* Various win events with arbitrary parameters */
6621 static const struct message WmWinEventsSeq
[] = {
6622 { EVENT_SYSTEM_SOUND
, winevent_hook
|wparam
|lparam
, OBJID_WINDOW
, 0 },
6623 { EVENT_SYSTEM_ALERT
, winevent_hook
|wparam
|lparam
, OBJID_SYSMENU
, 1 },
6624 { EVENT_SYSTEM_FOREGROUND
, winevent_hook
|wparam
|lparam
, OBJID_TITLEBAR
, 2 },
6625 { EVENT_SYSTEM_MENUSTART
, winevent_hook
|wparam
|lparam
, OBJID_MENU
, 3 },
6626 { EVENT_SYSTEM_MENUEND
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 4 },
6627 { EVENT_SYSTEM_MENUPOPUPSTART
, winevent_hook
|wparam
|lparam
, OBJID_VSCROLL
, 5 },
6628 { EVENT_SYSTEM_MENUPOPUPEND
, winevent_hook
|wparam
|lparam
, OBJID_HSCROLL
, 6 },
6629 { EVENT_SYSTEM_CAPTURESTART
, winevent_hook
|wparam
|lparam
, OBJID_SIZEGRIP
, 7 },
6630 { EVENT_SYSTEM_CAPTUREEND
, winevent_hook
|wparam
|lparam
, OBJID_CARET
, 8 },
6631 /* our win event hook ignores OBJID_CURSOR events */
6632 /*{ EVENT_SYSTEM_MOVESIZESTART, winevent_hook|wparam|lparam, OBJID_CURSOR, 9 },*/
6633 { EVENT_SYSTEM_MOVESIZEEND
, winevent_hook
|wparam
|lparam
, OBJID_ALERT
, 10 },
6634 { EVENT_SYSTEM_CONTEXTHELPSTART
, winevent_hook
|wparam
|lparam
, OBJID_SOUND
, 11 },
6635 { EVENT_SYSTEM_CONTEXTHELPEND
, winevent_hook
|wparam
|lparam
, OBJID_QUERYCLASSNAMEIDX
, 12 },
6636 { EVENT_SYSTEM_DRAGDROPSTART
, winevent_hook
|wparam
|lparam
, OBJID_NATIVEOM
, 13 },
6637 { EVENT_SYSTEM_DRAGDROPEND
, winevent_hook
|wparam
|lparam
, OBJID_WINDOW
, 0 },
6638 { EVENT_SYSTEM_DIALOGSTART
, winevent_hook
|wparam
|lparam
, OBJID_SYSMENU
, 1 },
6639 { EVENT_SYSTEM_DIALOGEND
, winevent_hook
|wparam
|lparam
, OBJID_TITLEBAR
, 2 },
6640 { EVENT_SYSTEM_SCROLLINGSTART
, winevent_hook
|wparam
|lparam
, OBJID_MENU
, 3 },
6641 { EVENT_SYSTEM_SCROLLINGEND
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 4 },
6642 { EVENT_SYSTEM_SWITCHSTART
, winevent_hook
|wparam
|lparam
, OBJID_VSCROLL
, 5 },
6643 { EVENT_SYSTEM_SWITCHEND
, winevent_hook
|wparam
|lparam
, OBJID_HSCROLL
, 6 },
6644 { EVENT_SYSTEM_MINIMIZESTART
, winevent_hook
|wparam
|lparam
, OBJID_SIZEGRIP
, 7 },
6645 { EVENT_SYSTEM_MINIMIZEEND
, winevent_hook
|wparam
|lparam
, OBJID_CARET
, 8 },
6648 static const struct message WmWinEventCaretSeq
[] = {
6649 { EVENT_OBJECT_CREATE
, winevent_hook
|wparam
|lparam
, OBJID_CARET
, 0 }, /* hook 1 */
6650 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, OBJID_CARET
, 0 }, /* hook 1 */
6651 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, OBJID_CARET
, 0 }, /* hook 2 */
6652 { EVENT_OBJECT_NAMECHANGE
, winevent_hook
|wparam
|lparam
, OBJID_CARET
, 0 }, /* hook 1 */
6655 static const struct message WmWinEventCaretSeq_2
[] = {
6656 { EVENT_OBJECT_CREATE
, winevent_hook
|wparam
|lparam
, OBJID_CARET
, 0 }, /* hook 1/2 */
6657 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, OBJID_CARET
, 0 }, /* hook 1/2 */
6658 { EVENT_OBJECT_NAMECHANGE
, winevent_hook
|wparam
|lparam
, OBJID_CARET
, 0 }, /* hook 1/2 */
6661 static const struct message WmWinEventAlertSeq
[] = {
6662 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, OBJID_ALERT
, 0 },
6665 static const struct message WmWinEventAlertSeq_2
[] = {
6666 /* create window in the thread proc */
6667 { EVENT_OBJECT_CREATE
, winevent_hook
|wparam
|lparam
, OBJID_WINDOW
, 2 },
6668 /* our test event */
6669 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, OBJID_ALERT
, 2 },
6672 static const struct message WmGlobalHookSeq_1
[] = {
6673 /* create window in the thread proc */
6674 { HCBT_CREATEWND
, hook
|lparam
, 0, 2 },
6675 /* our test events */
6676 { HCBT_SYSCOMMAND
, hook
|wparam
|lparam
, SC_PREVWINDOW
, 2 },
6677 { HCBT_SYSCOMMAND
, hook
|wparam
|lparam
, SC_NEXTWINDOW
, 2 },
6680 static const struct message WmGlobalHookSeq_2
[] = {
6681 { HCBT_SYSCOMMAND
, hook
|wparam
|lparam
, SC_NEXTWINDOW
, 0 }, /* old local hook */
6682 { HCBT_SYSCOMMAND
, hook
|wparam
|lparam
, SC_NEXTWINDOW
, 2 }, /* new global hook */
6683 { HCBT_SYSCOMMAND
, hook
|wparam
|lparam
, SC_PREVWINDOW
, 0 }, /* old local hook */
6684 { HCBT_SYSCOMMAND
, hook
|wparam
|lparam
, SC_PREVWINDOW
, 2 }, /* new global hook */
6688 static const struct message WmMouseLLHookSeq
[] = {
6689 { WM_MOUSEMOVE
, hook
},
6690 { WM_LBUTTONUP
, hook
},
6691 { WM_MOUSEMOVE
, hook
},
6695 static void CALLBACK
win_event_global_hook_proc(HWINEVENTHOOK hevent
,
6705 trace("WEH_2:%p,event %08x,hwnd %p,obj %08x,id %08x,thread %08x,time %08x\n",
6706 hevent
, event
, hwnd
, object_id
, child_id
, thread_id
, event_time
);
6708 if (GetClassNameA(hwnd
, buf
, sizeof(buf
)))
6710 if (!lstrcmpiA(buf
, "TestWindowClass") ||
6711 !lstrcmpiA(buf
, "static"))
6715 msg
.message
= event
;
6716 msg
.flags
= winevent_hook
|wparam
|lparam
;
6717 msg
.wParam
= object_id
;
6718 msg
.lParam
= (thread_id
== GetCurrentThreadId()) ? child_id
: (child_id
+ 2);
6724 static HHOOK hCBT_global_hook
;
6725 static DWORD cbt_global_hook_thread_id
;
6727 static LRESULT CALLBACK
cbt_global_hook_proc(int nCode
, WPARAM wParam
, LPARAM lParam
)
6732 trace("CBT_2: %d, %08lx, %08lx\n", nCode
, wParam
, lParam
);
6734 if (nCode
== HCBT_SYSCOMMAND
)
6738 msg
.message
= nCode
;
6739 msg
.flags
= hook
|wparam
|lparam
;
6740 msg
.wParam
= wParam
;
6741 msg
.lParam
= (cbt_global_hook_thread_id
== GetCurrentThreadId()) ? 1 : 2;
6744 return CallNextHookEx(hCBT_global_hook
, nCode
, wParam
, lParam
);
6746 /* WH_MOUSE_LL hook */
6747 if (nCode
== HC_ACTION
)
6750 MSLLHOOKSTRUCT
*mhll
= (MSLLHOOKSTRUCT
*)lParam
;
6752 /* we can't test for real mouse events */
6753 if (mhll
->flags
& LLMHF_INJECTED
)
6755 msg
.message
= wParam
;
6759 return CallNextHookEx(hCBT_global_hook
, nCode
, wParam
, lParam
);
6762 /* Log also SetFocus(0) calls */
6763 hwnd
= wParam
? (HWND
)wParam
: (HWND
)lParam
;
6765 if (GetClassNameA(hwnd
, buf
, sizeof(buf
)))
6767 if (!lstrcmpiA(buf
, "TestWindowClass") ||
6768 !lstrcmpiA(buf
, "static"))
6772 msg
.message
= nCode
;
6773 msg
.flags
= hook
|wparam
|lparam
;
6774 msg
.wParam
= wParam
;
6775 msg
.lParam
= (cbt_global_hook_thread_id
== GetCurrentThreadId()) ? 1 : 2;
6779 return CallNextHookEx(hCBT_global_hook
, nCode
, wParam
, lParam
);
6782 static DWORD WINAPI
win_event_global_thread_proc(void *param
)
6786 HANDLE hevent
= *(HANDLE
*)param
;
6787 HMODULE user32
= GetModuleHandleA("user32.dll");
6788 FARPROC pNotifyWinEvent
= GetProcAddress(user32
, "NotifyWinEvent");
6790 assert(pNotifyWinEvent
);
6792 hwnd
= CreateWindowExA(0, "static", NULL
, WS_POPUP
, 0,0,0,0,0,0,0, NULL
);
6794 trace("created thread window %p\n", hwnd
);
6796 *(HWND
*)param
= hwnd
;
6799 /* this event should be received only by our new hook proc,
6800 * an old one does not expect an event from another thread.
6802 pNotifyWinEvent(EVENT_OBJECT_LOCATIONCHANGE
, hwnd
, OBJID_ALERT
, 0);
6805 while (GetMessage(&msg
, 0, 0, 0))
6807 TranslateMessage(&msg
);
6808 DispatchMessage(&msg
);
6813 static DWORD WINAPI
cbt_global_hook_thread_proc(void *param
)
6817 HANDLE hevent
= *(HANDLE
*)param
;
6820 /* these events should be received only by our new hook proc,
6821 * an old one does not expect an event from another thread.
6824 hwnd
= CreateWindowExA(0, "static", NULL
, WS_POPUP
, 0,0,0,0,0,0,0, NULL
);
6826 trace("created thread window %p\n", hwnd
);
6828 *(HWND
*)param
= hwnd
;
6830 /* Windows doesn't like when a thread plays games with the focus,
6831 that leads to all kinds of misbehaviours and failures to activate
6832 a window. So, better keep next lines commented out.
6836 DefWindowProcA(hwnd
, WM_SYSCOMMAND
, SC_PREVWINDOW
, 0);
6837 DefWindowProcA(hwnd
, WM_SYSCOMMAND
, SC_NEXTWINDOW
, 0);
6841 while (GetMessage(&msg
, 0, 0, 0))
6843 TranslateMessage(&msg
);
6844 DispatchMessage(&msg
);
6849 static DWORD WINAPI
mouse_ll_global_thread_proc(void *param
)
6853 HANDLE hevent
= *(HANDLE
*)param
;
6855 hwnd
= CreateWindowExA(0, "static", NULL
, WS_POPUP
, 0,0,0,0,0,0,0, NULL
);
6857 trace("created thread window %p\n", hwnd
);
6859 *(HWND
*)param
= hwnd
;
6863 /* Windows doesn't like when a thread plays games with the focus,
6864 * that leads to all kinds of misbehaviours and failures to activate
6865 * a window. So, better don't generate a mouse click message below.
6867 mouse_event(MOUSEEVENTF_MOVE
, -1, 0, 0, 0);
6868 mouse_event(MOUSEEVENTF_LEFTUP
, 0, 0, 0, 0);
6869 mouse_event(MOUSEEVENTF_MOVE
, 1, 0, 0, 0);
6872 while (GetMessage(&msg
, 0, 0, 0))
6874 TranslateMessage(&msg
);
6875 DispatchMessage(&msg
);
6880 static void test_winevents(void)
6886 HANDLE hthread
, hevent
;
6888 HWINEVENTHOOK hhook
;
6889 const struct message
*events
= WmWinEventsSeq
;
6890 HMODULE user32
= GetModuleHandleA("user32.dll");
6891 FARPROC pSetWinEventHook
= GetProcAddress(user32
, "SetWinEventHook");
6892 FARPROC pUnhookWinEvent
= GetProcAddress(user32
, "UnhookWinEvent");
6893 FARPROC pNotifyWinEvent
= GetProcAddress(user32
, "NotifyWinEvent");
6895 hwnd
= CreateWindowExA(0, "TestWindowClass", NULL
,
6896 WS_OVERLAPPEDWINDOW
,
6897 CW_USEDEFAULT
, CW_USEDEFAULT
, 300, 300, 0,
6901 /****** start of global hook test *************/
6902 hCBT_global_hook
= SetWindowsHookExA(WH_CBT
, cbt_global_hook_proc
, GetModuleHandleA(0), 0);
6903 assert(hCBT_global_hook
);
6905 hevent
= CreateEventA(NULL
, 0, 0, NULL
);
6907 hwnd2
= (HWND
)hevent
;
6909 hthread
= CreateThread(NULL
, 0, cbt_global_hook_thread_proc
, &hwnd2
, 0, &tid
);
6910 ok(hthread
!= NULL
, "CreateThread failed, error %d\n", GetLastError());
6912 ok(WaitForSingleObject(hevent
, INFINITE
) == WAIT_OBJECT_0
, "WaitForSingleObject failed\n");
6914 ok_sequence(WmGlobalHookSeq_1
, "global hook 1", FALSE
);
6917 /* this one should be received only by old hook proc */
6918 DefWindowProcA(hwnd
, WM_SYSCOMMAND
, SC_NEXTWINDOW
, 0);
6919 /* this one should be received only by old hook proc */
6920 DefWindowProcA(hwnd
, WM_SYSCOMMAND
, SC_PREVWINDOW
, 0);
6922 ok_sequence(WmGlobalHookSeq_2
, "global hook 2", FALSE
);
6924 ret
= UnhookWindowsHookEx(hCBT_global_hook
);
6925 ok( ret
, "UnhookWindowsHookEx error %d\n", GetLastError());
6927 PostThreadMessageA(tid
, WM_QUIT
, 0, 0);
6928 ok(WaitForSingleObject(hthread
, INFINITE
) == WAIT_OBJECT_0
, "WaitForSingleObject failed\n");
6929 CloseHandle(hthread
);
6930 CloseHandle(hevent
);
6931 ok(!IsWindow(hwnd2
), "window should be destroyed on thread exit\n");
6932 /****** end of global hook test *************/
6934 if (!pSetWinEventHook
|| !pNotifyWinEvent
|| !pUnhookWinEvent
)
6936 ok(DestroyWindow(hwnd
), "failed to destroy window\n");
6944 /* this test doesn't pass under Win9x */
6945 /* win2k ignores events with hwnd == 0 */
6946 SetLastError(0xdeadbeef);
6947 pNotifyWinEvent(events
[0].message
, 0, events
[0].wParam
, events
[0].lParam
);
6948 ok(GetLastError() == ERROR_INVALID_WINDOW_HANDLE
|| /* Win2k */
6949 GetLastError() == 0xdeadbeef, /* Win9x */
6950 "unexpected error %d\n", GetLastError());
6951 ok_sequence(WmEmptySeq
, "empty notify winevents", FALSE
);
6954 for (i
= 0; i
< sizeof(WmWinEventsSeq
)/sizeof(WmWinEventsSeq
[0]); i
++)
6955 pNotifyWinEvent(events
[i
].message
, hwnd
, events
[i
].wParam
, events
[i
].lParam
);
6957 ok_sequence(WmWinEventsSeq
, "notify winevents", FALSE
);
6959 /****** start of event filtering test *************/
6960 hhook
= (HWINEVENTHOOK
)pSetWinEventHook(
6961 EVENT_OBJECT_SHOW
, /* 0x8002 */
6962 EVENT_OBJECT_LOCATIONCHANGE
, /* 0x800B */
6963 GetModuleHandleA(0), win_event_global_hook_proc
,
6964 GetCurrentProcessId(), 0,
6965 WINEVENT_INCONTEXT
);
6966 ok(hhook
!= 0, "SetWinEventHook error %d\n", GetLastError());
6968 hevent
= CreateEventA(NULL
, 0, 0, NULL
);
6970 hwnd2
= (HWND
)hevent
;
6972 hthread
= CreateThread(NULL
, 0, win_event_global_thread_proc
, &hwnd2
, 0, &tid
);
6973 ok(hthread
!= NULL
, "CreateThread failed, error %d\n", GetLastError());
6975 ok(WaitForSingleObject(hevent
, INFINITE
) == WAIT_OBJECT_0
, "WaitForSingleObject failed\n");
6977 ok_sequence(WmWinEventAlertSeq
, "alert winevent", FALSE
);
6980 /* this one should be received only by old hook proc */
6981 pNotifyWinEvent(EVENT_OBJECT_CREATE
, hwnd
, OBJID_CARET
, 0); /* 0x8000 */
6982 pNotifyWinEvent(EVENT_OBJECT_SHOW
, hwnd
, OBJID_CARET
, 0); /* 0x8002 */
6983 /* this one should be received only by old hook proc */
6984 pNotifyWinEvent(EVENT_OBJECT_NAMECHANGE
, hwnd
, OBJID_CARET
, 0); /* 0x800C */
6986 ok_sequence(WmWinEventCaretSeq
, "caret winevent", FALSE
);
6988 ret
= pUnhookWinEvent(hhook
);
6989 ok( ret
, "UnhookWinEvent error %d\n", GetLastError());
6991 PostThreadMessageA(tid
, WM_QUIT
, 0, 0);
6992 ok(WaitForSingleObject(hthread
, INFINITE
) == WAIT_OBJECT_0
, "WaitForSingleObject failed\n");
6993 CloseHandle(hthread
);
6994 CloseHandle(hevent
);
6995 ok(!IsWindow(hwnd2
), "window should be destroyed on thread exit\n");
6996 /****** end of event filtering test *************/
6998 /****** start of out of context event test *************/
6999 hhook
= (HWINEVENTHOOK
)pSetWinEventHook(
7000 EVENT_MIN
, EVENT_MAX
,
7001 0, win_event_global_hook_proc
,
7002 GetCurrentProcessId(), 0,
7003 WINEVENT_OUTOFCONTEXT
);
7004 ok(hhook
!= 0, "SetWinEventHook error %d\n", GetLastError());
7006 hevent
= CreateEventA(NULL
, 0, 0, NULL
);
7008 hwnd2
= (HWND
)hevent
;
7012 hthread
= CreateThread(NULL
, 0, win_event_global_thread_proc
, &hwnd2
, 0, &tid
);
7013 ok(hthread
!= NULL
, "CreateThread failed, error %d\n", GetLastError());
7015 ok(WaitForSingleObject(hevent
, INFINITE
) == WAIT_OBJECT_0
, "WaitForSingleObject failed\n");
7017 ok_sequence(WmEmptySeq
, "empty notify winevents", FALSE
);
7018 /* process pending winevent messages */
7019 ok(!PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
), "msg queue should be empty\n");
7020 ok_sequence(WmWinEventAlertSeq_2
, "alert winevent for out of context proc", FALSE
);
7023 /* this one should be received only by old hook proc */
7024 pNotifyWinEvent(EVENT_OBJECT_CREATE
, hwnd
, OBJID_CARET
, 0); /* 0x8000 */
7025 pNotifyWinEvent(EVENT_OBJECT_SHOW
, hwnd
, OBJID_CARET
, 0); /* 0x8002 */
7026 /* this one should be received only by old hook proc */
7027 pNotifyWinEvent(EVENT_OBJECT_NAMECHANGE
, hwnd
, OBJID_CARET
, 0); /* 0x800C */
7029 ok_sequence(WmWinEventCaretSeq_2
, "caret winevent for incontext proc", FALSE
);
7030 /* process pending winevent messages */
7031 ok(!PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
), "msg queue should be empty\n");
7032 ok_sequence(WmWinEventCaretSeq_2
, "caret winevent for out of context proc", FALSE
);
7034 ret
= pUnhookWinEvent(hhook
);
7035 ok( ret
, "UnhookWinEvent error %d\n", GetLastError());
7037 PostThreadMessageA(tid
, WM_QUIT
, 0, 0);
7038 ok(WaitForSingleObject(hthread
, INFINITE
) == WAIT_OBJECT_0
, "WaitForSingleObject failed\n");
7039 CloseHandle(hthread
);
7040 CloseHandle(hevent
);
7041 ok(!IsWindow(hwnd2
), "window should be destroyed on thread exit\n");
7042 /****** end of out of context event test *************/
7044 /****** start of MOUSE_LL hook test *************/
7045 hCBT_global_hook
= SetWindowsHookExA(WH_MOUSE_LL
, cbt_global_hook_proc
, GetModuleHandleA(0), 0);
7046 /* WH_MOUSE_LL is not supported on Win9x platforms */
7047 if (!hCBT_global_hook
)
7049 trace("Skipping WH_MOUSE_LL test on this platform\n");
7050 goto skip_mouse_ll_hook_test
;
7053 hevent
= CreateEventA(NULL
, 0, 0, NULL
);
7055 hwnd2
= (HWND
)hevent
;
7057 hthread
= CreateThread(NULL
, 0, mouse_ll_global_thread_proc
, &hwnd2
, 0, &tid
);
7058 ok(hthread
!= NULL
, "CreateThread failed, error %d\n", GetLastError());
7060 while (WaitForSingleObject(hevent
, 100) == WAIT_TIMEOUT
)
7061 while (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
7063 ok_sequence(WmMouseLLHookSeq
, "MOUSE_LL hook other thread", FALSE
);
7066 mouse_event(MOUSEEVENTF_MOVE
, -1, 0, 0, 0);
7067 mouse_event(MOUSEEVENTF_LEFTUP
, 0, 0, 0, 0);
7068 mouse_event(MOUSEEVENTF_MOVE
, 1, 0, 0, 0);
7070 ok_sequence(WmMouseLLHookSeq
, "MOUSE_LL hook same thread", FALSE
);
7072 ret
= UnhookWindowsHookEx(hCBT_global_hook
);
7073 ok( ret
, "UnhookWindowsHookEx error %d\n", GetLastError());
7075 PostThreadMessageA(tid
, WM_QUIT
, 0, 0);
7076 ok(WaitForSingleObject(hthread
, INFINITE
) == WAIT_OBJECT_0
, "WaitForSingleObject failed\n");
7077 CloseHandle(hthread
);
7078 CloseHandle(hevent
);
7079 ok(!IsWindow(hwnd2
), "window should be destroyed on thread exit\n");
7080 /****** end of MOUSE_LL hook test *************/
7081 skip_mouse_ll_hook_test
:
7083 ok(DestroyWindow(hwnd
), "failed to destroy window\n");
7086 static void test_set_hook(void)
7090 HWINEVENTHOOK hwinevent_hook
;
7091 HMODULE user32
= GetModuleHandleA("user32.dll");
7092 FARPROC pSetWinEventHook
= GetProcAddress(user32
, "SetWinEventHook");
7093 FARPROC pUnhookWinEvent
= GetProcAddress(user32
, "UnhookWinEvent");
7095 hhook
= SetWindowsHookExA(WH_CBT
, cbt_hook_proc
, GetModuleHandleA(0), GetCurrentThreadId());
7096 ok(hhook
!= 0, "local hook does not require hModule set to 0\n");
7097 UnhookWindowsHookEx(hhook
);
7101 /* this test doesn't pass under Win9x: BUG! */
7102 SetLastError(0xdeadbeef);
7103 hhook
= SetWindowsHookExA(WH_CBT
, cbt_hook_proc
, 0, 0);
7104 ok(!hhook
, "global hook requires hModule != 0\n");
7105 ok(GetLastError() == ERROR_HOOK_NEEDS_HMOD
, "unexpected error %d\n", GetLastError());
7108 SetLastError(0xdeadbeef);
7109 hhook
= SetWindowsHookExA(WH_CBT
, 0, GetModuleHandleA(0), GetCurrentThreadId());
7110 ok(!hhook
, "SetWinEventHook with invalid proc should fail\n");
7111 ok(GetLastError() == ERROR_INVALID_FILTER_PROC
|| /* Win2k */
7112 GetLastError() == 0xdeadbeef, /* Win9x */
7113 "unexpected error %d\n", GetLastError());
7115 SetLastError(0xdeadbeef);
7116 ok(!UnhookWindowsHookEx((HHOOK
)0xdeadbeef), "UnhookWindowsHookEx succeeded\n");
7117 ok(GetLastError() == ERROR_INVALID_HOOK_HANDLE
|| /* Win2k */
7118 GetLastError() == 0xdeadbeef, /* Win9x */
7119 "unexpected error %d\n", GetLastError());
7121 if (!pSetWinEventHook
|| !pUnhookWinEvent
) return;
7123 /* even process local incontext hooks require hmodule */
7124 SetLastError(0xdeadbeef);
7125 hwinevent_hook
= (HWINEVENTHOOK
)pSetWinEventHook(EVENT_MIN
, EVENT_MAX
,
7126 0, win_event_proc
, GetCurrentProcessId(), 0, WINEVENT_INCONTEXT
);
7127 ok(!hwinevent_hook
, "WINEVENT_INCONTEXT requires hModule != 0\n");
7128 ok(GetLastError() == ERROR_HOOK_NEEDS_HMOD
|| /* Win2k */
7129 GetLastError() == 0xdeadbeef, /* Win9x */
7130 "unexpected error %d\n", GetLastError());
7132 /* even thread local incontext hooks require hmodule */
7133 SetLastError(0xdeadbeef);
7134 hwinevent_hook
= (HWINEVENTHOOK
)pSetWinEventHook(EVENT_MIN
, EVENT_MAX
,
7135 0, win_event_proc
, GetCurrentProcessId(), GetCurrentThreadId(), WINEVENT_INCONTEXT
);
7136 ok(!hwinevent_hook
, "WINEVENT_INCONTEXT requires hModule != 0\n");
7137 ok(GetLastError() == ERROR_HOOK_NEEDS_HMOD
|| /* Win2k */
7138 GetLastError() == 0xdeadbeef, /* Win9x */
7139 "unexpected error %d\n", GetLastError());
7143 /* these 3 tests don't pass under Win9x */
7144 SetLastError(0xdeadbeef);
7145 hwinevent_hook
= (HWINEVENTHOOK
)pSetWinEventHook(1, 0,
7146 0, win_event_proc
, GetCurrentProcessId(), 0, WINEVENT_OUTOFCONTEXT
);
7147 ok(!hwinevent_hook
, "SetWinEventHook with invalid event range should fail\n");
7148 ok(GetLastError() == ERROR_INVALID_HOOK_FILTER
, "unexpected error %d\n", GetLastError());
7150 SetLastError(0xdeadbeef);
7151 hwinevent_hook
= (HWINEVENTHOOK
)pSetWinEventHook(-1, 1,
7152 0, win_event_proc
, GetCurrentProcessId(), 0, WINEVENT_OUTOFCONTEXT
);
7153 ok(!hwinevent_hook
, "SetWinEventHook with invalid event range should fail\n");
7154 ok(GetLastError() == ERROR_INVALID_HOOK_FILTER
, "unexpected error %d\n", GetLastError());
7156 SetLastError(0xdeadbeef);
7157 hwinevent_hook
= (HWINEVENTHOOK
)pSetWinEventHook(EVENT_MIN
, EVENT_MAX
,
7158 0, win_event_proc
, 0, 0xdeadbeef, WINEVENT_OUTOFCONTEXT
);
7159 ok(!hwinevent_hook
, "SetWinEventHook with invalid tid should fail\n");
7160 ok(GetLastError() == ERROR_INVALID_THREAD_ID
, "unexpected error %d\n", GetLastError());
7163 SetLastError(0xdeadbeef);
7164 hwinevent_hook
= (HWINEVENTHOOK
)pSetWinEventHook(0, 0,
7165 0, win_event_proc
, GetCurrentProcessId(), 0, WINEVENT_OUTOFCONTEXT
);
7166 ok(hwinevent_hook
!= 0, "SetWinEventHook error %d\n", GetLastError());
7167 ok(GetLastError() == 0xdeadbeef, "unexpected error %d\n", GetLastError());
7168 ret
= pUnhookWinEvent(hwinevent_hook
);
7169 ok( ret
, "UnhookWinEvent error %d\n", GetLastError());
7172 /* This call succeeds under win2k SP4, but fails under Wine.
7173 Does win2k test/use passed process id? */
7174 SetLastError(0xdeadbeef);
7175 hwinevent_hook
= (HWINEVENTHOOK
)pSetWinEventHook(EVENT_MIN
, EVENT_MAX
,
7176 0, win_event_proc
, 0xdeadbeef, 0, WINEVENT_OUTOFCONTEXT
);
7177 ok(hwinevent_hook
!= 0, "SetWinEventHook error %d\n", GetLastError());
7178 ok(GetLastError() == 0xdeadbeef, "unexpected error %d\n", GetLastError());
7179 ret
= pUnhookWinEvent(hwinevent_hook
);
7180 ok( ret
, "UnhookWinEvent error %d\n", GetLastError());
7183 SetLastError(0xdeadbeef);
7184 ok(!pUnhookWinEvent((HWINEVENTHOOK
)0xdeadbeef), "UnhookWinEvent succeeded\n");
7185 ok(GetLastError() == ERROR_INVALID_HANDLE
|| /* Win2k */
7186 GetLastError() == 0xdeadbeef, /* Win9x */
7187 "unexpected error %d\n", GetLastError());
7190 static const struct message ScrollWindowPaint1
[] = {
7192 { WM_ERASEBKGND
, sent
|beginpaint
},
7196 static const struct message ScrollWindowPaint2
[] = {
7201 static void test_scrollwindowex(void)
7204 RECT rect
={0,0,130,130};
7207 hwnd
= CreateWindowExA(0, "TestWindowClass", "Test Scroll",
7208 WS_VISIBLE
|WS_OVERLAPPEDWINDOW
,
7209 100, 100, 200, 200, 0, 0, 0, NULL
);
7210 ok (hwnd
!= 0, "Failed to create overlapped window\n");
7211 hchild
= CreateWindowExA(0, "TestWindowClass", "Test child",
7212 WS_VISIBLE
|WS_CAPTION
|WS_CHILD
,
7213 10, 10, 150, 150, hwnd
, 0, 0, NULL
);
7214 ok (hchild
!= 0, "Failed to create child\n");
7219 /* scroll without the child window */
7220 trace("start scroll\n");
7221 ScrollWindowEx( hwnd
, 10, 10, &rect
, NULL
, NULL
, NULL
,
7222 SW_ERASE
|SW_INVALIDATE
);
7223 ok_sequence(WmEmptySeq
, "ScrollWindowEx", 0);
7224 trace("end scroll\n");
7226 while (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
7227 ok_sequence(ScrollWindowPaint1
, "ScrollWindowEx", 0);
7231 /* Now without the SW_ERASE flag */
7232 trace("start scroll\n");
7233 ScrollWindowEx( hwnd
, 10, 10, &rect
, NULL
, NULL
, NULL
, SW_INVALIDATE
);
7234 ok_sequence(WmEmptySeq
, "ScrollWindowEx", 0);
7235 trace("end scroll\n");
7237 while (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
7238 ok_sequence(ScrollWindowPaint2
, "ScrollWindowEx", 0);
7242 /* now scroll the child window as well */
7243 trace("start scroll\n");
7244 ScrollWindowEx( hwnd
, 10, 10, &rect
, NULL
, NULL
, NULL
,
7245 SW_SCROLLCHILDREN
|SW_ERASE
|SW_INVALIDATE
);
7246 todo_wine
{ /* wine sends WM_POSCHANGING, WM_POSCHANGED messages */
7247 /* windows sometimes a WM_MOVE */
7248 ok_sequence(WmEmptySeq
, "ScrollWindowEx", 0);
7250 trace("end scroll\n");
7252 while (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
7253 ok_sequence(ScrollWindowPaint1
, "ScrollWindowEx", 0);
7257 /* now scroll with ScrollWindow() */
7258 trace("start scroll with ScrollWindow\n");
7259 ScrollWindow( hwnd
, 5, 5, NULL
, NULL
);
7260 trace("end scroll\n");
7262 while (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
7263 ok_sequence(ScrollWindowPaint1
, "ScrollWindow", 0);
7265 ok(DestroyWindow(hchild
), "failed to destroy window\n");
7266 ok(DestroyWindow(hwnd
), "failed to destroy window\n");
7270 static const struct message destroy_window_with_children
[] = {
7271 { EVENT_SYSTEM_CAPTURESTART
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* popup */
7272 { HCBT_DESTROYWND
, hook
|lparam
, 0, WND_PARENT_ID
}, /* parent */
7273 { HCBT_DESTROYWND
, hook
|lparam
, 0, WND_POPUP_ID
}, /* popup */
7274 { EVENT_OBJECT_DESTROY
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* popup */
7275 { WM_DESTROY
, sent
|wparam
|lparam
, 0, WND_POPUP_ID
}, /* popup */
7276 { WM_CAPTURECHANGED
, sent
|wparam
|lparam
, 0, WND_POPUP_ID
}, /* popup */
7277 { WM_NCDESTROY
, sent
|wparam
|lparam
, 0, WND_POPUP_ID
}, /* popup */
7278 { EVENT_OBJECT_DESTROY
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* parent */
7279 { WM_DESTROY
, sent
|wparam
|lparam
, 0, WND_PARENT_ID
}, /* parent */
7280 { WM_DESTROY
, sent
|wparam
|lparam
, 0, WND_CHILD_ID
+ 2 }, /* child2 */
7281 { WM_DESTROY
, sent
|wparam
|lparam
, 0, WND_CHILD_ID
+ 1 }, /* child1 */
7282 { WM_DESTROY
, sent
|wparam
|lparam
, 0, WND_CHILD_ID
+ 3 }, /* child3 */
7283 { WM_NCDESTROY
, sent
|wparam
|lparam
, 0, WND_CHILD_ID
+ 2 }, /* child2 */
7284 { WM_NCDESTROY
, sent
|wparam
|lparam
, 0, WND_CHILD_ID
+ 3 }, /* child3 */
7285 { WM_NCDESTROY
, sent
|wparam
|lparam
, 0, WND_CHILD_ID
+ 1 }, /* child1 */
7286 { WM_NCDESTROY
, sent
|wparam
|lparam
, 0, WND_PARENT_ID
}, /* parent */
7290 static void test_DestroyWindow(void)
7293 HWND parent
, child1
, child2
, child3
, child4
, test
;
7294 UINT child_id
= WND_CHILD_ID
+ 1;
7296 parent
= CreateWindowExA(0, "TestWindowClass", NULL
, WS_OVERLAPPEDWINDOW
,
7297 100, 100, 200, 200, 0, 0, 0, NULL
);
7298 assert(parent
!= 0);
7299 child1
= CreateWindowExA(0, "TestWindowClass", NULL
, WS_CHILD
,
7300 0, 0, 50, 50, parent
, (HMENU
)child_id
++, 0, NULL
);
7301 assert(child1
!= 0);
7302 child2
= CreateWindowExA(0, "TestWindowClass", NULL
, WS_CHILD
,
7303 0, 0, 50, 50, GetDesktopWindow(), (HMENU
)child_id
++, 0, NULL
);
7304 assert(child2
!= 0);
7305 child3
= CreateWindowExA(0, "TestWindowClass", NULL
, WS_CHILD
,
7306 0, 0, 50, 50, child1
, (HMENU
)child_id
++, 0, NULL
);
7307 assert(child3
!= 0);
7308 child4
= CreateWindowExA(0, "TestWindowClass", NULL
, WS_POPUP
,
7309 0, 0, 50, 50, parent
, 0, 0, NULL
);
7310 assert(child4
!= 0);
7312 /* test owner/parent of child2 */
7313 test
= GetParent(child2
);
7314 ok(test
== GetDesktopWindow(), "wrong parent %p\n", test
);
7315 ok(!IsChild(parent
, child2
), "wrong parent/child %p/%p\n", parent
, child2
);
7317 test
= pGetAncestor(child2
, GA_PARENT
);
7318 ok(test
== GetDesktopWindow(), "wrong parent %p\n", test
);
7320 test
= GetWindow(child2
, GW_OWNER
);
7321 ok(!test
, "wrong owner %p\n", test
);
7323 test
= SetParent(child2
, parent
);
7324 ok(test
== GetDesktopWindow(), "wrong old parent %p\n", test
);
7326 /* test owner/parent of the parent */
7327 test
= GetParent(parent
);
7328 ok(!test
, "wrong parent %p\n", test
);
7330 ok(!IsChild(GetDesktopWindow(), parent
), "wrong parent/child %p/%p\n", GetDesktopWindow(), parent
);
7333 test
= pGetAncestor(parent
, GA_PARENT
);
7334 ok(test
== GetDesktopWindow(), "wrong parent %p\n", test
);
7336 test
= GetWindow(parent
, GW_OWNER
);
7337 ok(!test
, "wrong owner %p\n", test
);
7339 /* test owner/parent of child1 */
7340 test
= GetParent(child1
);
7341 ok(test
== parent
, "wrong parent %p\n", test
);
7342 ok(IsChild(parent
, child1
), "wrong parent/child %p/%p\n", parent
, child1
);
7344 test
= pGetAncestor(child1
, GA_PARENT
);
7345 ok(test
== parent
, "wrong parent %p\n", test
);
7347 test
= GetWindow(child1
, GW_OWNER
);
7348 ok(!test
, "wrong owner %p\n", test
);
7350 /* test owner/parent of child2 */
7351 test
= GetParent(child2
);
7352 ok(test
== parent
, "wrong parent %p\n", test
);
7353 ok(IsChild(parent
, child2
), "wrong parent/child %p/%p\n", parent
, child2
);
7355 test
= pGetAncestor(child2
, GA_PARENT
);
7356 ok(test
== parent
, "wrong parent %p\n", test
);
7358 test
= GetWindow(child2
, GW_OWNER
);
7359 ok(!test
, "wrong owner %p\n", test
);
7361 /* test owner/parent of child3 */
7362 test
= GetParent(child3
);
7363 ok(test
== child1
, "wrong parent %p\n", test
);
7364 ok(IsChild(parent
, child3
), "wrong parent/child %p/%p\n", parent
, child3
);
7366 test
= pGetAncestor(child3
, GA_PARENT
);
7367 ok(test
== child1
, "wrong parent %p\n", test
);
7369 test
= GetWindow(child3
, GW_OWNER
);
7370 ok(!test
, "wrong owner %p\n", test
);
7372 /* test owner/parent of child4 */
7373 test
= GetParent(child4
);
7374 ok(test
== parent
, "wrong parent %p\n", test
);
7375 ok(!IsChild(parent
, child4
), "wrong parent/child %p/%p\n", parent
, child4
);
7377 test
= pGetAncestor(child4
, GA_PARENT
);
7378 ok(test
== GetDesktopWindow(), "wrong parent %p\n", test
);
7380 test
= GetWindow(child4
, GW_OWNER
);
7381 ok(test
== parent
, "wrong owner %p\n", test
);
7385 trace("parent %p, child1 %p, child2 %p, child3 %p, child4 %p\n",
7386 parent
, child1
, child2
, child3
, child4
);
7389 test
= GetCapture();
7390 ok(test
== child4
, "wrong capture window %p\n", test
);
7392 test_DestroyWindow_flag
= TRUE
;
7393 ret
= DestroyWindow(parent
);
7394 ok( ret
, "DestroyWindow() error %d\n", GetLastError());
7395 test_DestroyWindow_flag
= FALSE
;
7396 ok_sequence(destroy_window_with_children
, "destroy window with children", 0);
7398 ok(!IsWindow(parent
), "parent still exists\n");
7399 ok(!IsWindow(child1
), "child1 still exists\n");
7400 ok(!IsWindow(child2
), "child2 still exists\n");
7401 ok(!IsWindow(child3
), "child3 still exists\n");
7402 ok(!IsWindow(child4
), "child4 still exists\n");
7404 test
= GetCapture();
7405 ok(!test
, "wrong capture window %p\n", test
);
7409 static const struct message WmDispatchPaint
[] = {
7410 { WM_NCPAINT
, sent
},
7411 { WM_GETTEXT
, sent
|defwinproc
|optional
},
7412 { WM_GETTEXT
, sent
|defwinproc
|optional
},
7413 { WM_ERASEBKGND
, sent
},
7417 static LRESULT WINAPI
DispatchMessageCheckProc(HWND hwnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
7419 if (message
== WM_PAINT
) return 0;
7420 return MsgCheckProcA( hwnd
, message
, wParam
, lParam
);
7423 static void test_DispatchMessage(void)
7428 HWND hwnd
= CreateWindowA( "TestWindowClass", NULL
, WS_OVERLAPPEDWINDOW
,
7429 100, 100, 200, 200, 0, 0, 0, NULL
);
7430 ShowWindow( hwnd
, SW_SHOW
);
7431 UpdateWindow( hwnd
);
7432 while (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
7434 SetWindowLongPtrA( hwnd
, GWLP_WNDPROC
, (LONG_PTR
)DispatchMessageCheckProc
);
7436 SetRect( &rect
, -5, -5, 5, 5 );
7437 RedrawWindow( hwnd
, &rect
, 0, RDW_INVALIDATE
|RDW_ERASE
|RDW_FRAME
);
7439 while (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
))
7441 if (msg
.message
!= WM_PAINT
) DispatchMessage( &msg
);
7445 DispatchMessage( &msg
);
7446 /* DispatchMessage will send WM_NCPAINT if non client area is still invalid after WM_PAINT */
7447 if (!count
) ok_sequence( WmDispatchPaint
, "WmDispatchPaint", FALSE
);
7448 else ok_sequence( WmEmptySeq
, "WmEmpty", FALSE
);
7449 if (++count
> 10) break;
7452 ok( msg
.message
== WM_PAINT
&& count
> 10, "WM_PAINT messages stopped\n" );
7454 trace("now without DispatchMessage\n");
7456 RedrawWindow( hwnd
, &rect
, 0, RDW_INVALIDATE
|RDW_ERASE
|RDW_FRAME
);
7458 while (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
))
7460 if (msg
.message
!= WM_PAINT
) DispatchMessage( &msg
);
7463 HRGN hrgn
= CreateRectRgn( 0, 0, 0, 0 );
7465 /* this will send WM_NCCPAINT just like DispatchMessage does */
7466 GetUpdateRgn( hwnd
, hrgn
, TRUE
);
7467 ok_sequence( WmDispatchPaint
, "WmDispatchPaint", FALSE
);
7468 DeleteObject( hrgn
);
7469 GetClientRect( hwnd
, &rect
);
7470 ValidateRect( hwnd
, &rect
); /* this will stop WM_PAINTs */
7471 ok( !count
, "Got multiple WM_PAINTs\n" );
7472 if (++count
> 10) break;
7475 DestroyWindow(hwnd
);
7479 static const struct message WmUser
[] = {
7491 static DWORD CALLBACK
send_msg_thread( LPVOID arg
)
7493 struct sendmsg_info
*info
= arg
;
7494 info
->ret
= SendMessageTimeoutA( info
->hwnd
, WM_USER
, 0, 0, 0, info
->timeout
, NULL
);
7495 if (!info
->ret
) ok( GetLastError() == ERROR_TIMEOUT
, "unexpected error %d\n", GetLastError());
7499 static void wait_for_thread( HANDLE thread
)
7501 while (MsgWaitForMultipleObjects(1, &thread
, FALSE
, INFINITE
, QS_SENDMESSAGE
) != WAIT_OBJECT_0
)
7504 while (PeekMessageA( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage(&msg
);
7508 static LRESULT WINAPI
send_msg_delay_proc(HWND hwnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
7510 if (message
== WM_USER
) Sleep(200);
7511 return MsgCheckProcA( hwnd
, message
, wParam
, lParam
);
7514 static void test_SendMessageTimeout(void)
7518 struct sendmsg_info info
;
7521 info
.hwnd
= CreateWindowA( "TestWindowClass", NULL
, WS_OVERLAPPEDWINDOW
,
7522 100, 100, 200, 200, 0, 0, 0, NULL
);
7523 while (PeekMessageA( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
7526 info
.timeout
= 1000;
7527 info
.ret
= 0xdeadbeef;
7528 thread
= CreateThread( NULL
, 0, send_msg_thread
, &info
, 0, &tid
);
7529 wait_for_thread( thread
);
7530 CloseHandle( thread
);
7531 ok( info
.ret
== 1, "SendMessageTimeout failed\n" );
7532 ok_sequence( WmUser
, "WmUser", FALSE
);
7535 info
.ret
= 0xdeadbeef;
7536 thread
= CreateThread( NULL
, 0, send_msg_thread
, &info
, 0, &tid
);
7537 Sleep(100); /* SendMessageTimeout should timeout here */
7538 wait_for_thread( thread
);
7539 CloseHandle( thread
);
7540 ok( info
.ret
== 0, "SendMessageTimeout succeeded\n" );
7541 ok_sequence( WmEmptySeq
, "WmEmptySeq", FALSE
);
7543 /* 0 means infinite timeout */
7545 info
.ret
= 0xdeadbeef;
7546 thread
= CreateThread( NULL
, 0, send_msg_thread
, &info
, 0, &tid
);
7548 wait_for_thread( thread
);
7549 CloseHandle( thread
);
7550 ok( info
.ret
== 1, "SendMessageTimeout failed\n" );
7551 ok_sequence( WmUser
, "WmUser", FALSE
);
7553 /* timeout is treated as signed despite the prototype */
7554 info
.timeout
= 0x7fffffff;
7555 info
.ret
= 0xdeadbeef;
7556 thread
= CreateThread( NULL
, 0, send_msg_thread
, &info
, 0, &tid
);
7558 wait_for_thread( thread
);
7559 CloseHandle( thread
);
7560 ok( info
.ret
== 1, "SendMessageTimeout failed\n" );
7561 ok_sequence( WmUser
, "WmUser", FALSE
);
7563 info
.timeout
= 0x80000000;
7564 info
.ret
= 0xdeadbeef;
7565 thread
= CreateThread( NULL
, 0, send_msg_thread
, &info
, 0, &tid
);
7567 wait_for_thread( thread
);
7568 CloseHandle( thread
);
7569 ok( info
.ret
== 0, "SendMessageTimeout succeeded\n" );
7570 ok_sequence( WmEmptySeq
, "WmEmptySeq", FALSE
);
7572 /* now check for timeout during message processing */
7573 SetWindowLongPtrA( info
.hwnd
, GWLP_WNDPROC
, (LONG_PTR
)send_msg_delay_proc
);
7575 info
.ret
= 0xdeadbeef;
7576 thread
= CreateThread( NULL
, 0, send_msg_thread
, &info
, 0, &tid
);
7577 wait_for_thread( thread
);
7578 CloseHandle( thread
);
7579 /* we should timeout but still get the message */
7580 ok( info
.ret
== 0, "SendMessageTimeout failed\n" );
7581 ok_sequence( WmUser
, "WmUser", FALSE
);
7583 DestroyWindow( info
.hwnd
);
7587 /****************** edit message test *************************/
7588 #define ID_EDIT 0x1234
7589 static const struct message sl_edit_setfocus
[] =
7591 { HCBT_SETFOCUS
, hook
},
7592 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 1 },
7593 { WM_IME_NOTIFY
, sent
|wparam
|defwinproc
|optional
, 2 },
7594 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
7595 { WM_SETFOCUS
, sent
|wparam
, 0 },
7596 { WM_CTLCOLOREDIT
, sent
|parent
},
7597 { EVENT_OBJECT_CREATE
, winevent_hook
|wparam
|lparam
, OBJID_CARET
, 0 },
7598 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, OBJID_CARET
, 0 },
7599 { WM_COMMAND
, sent
|parent
|wparam
, MAKEWPARAM(ID_EDIT
, EN_SETFOCUS
) },
7602 static const struct message ml_edit_setfocus
[] =
7604 { HCBT_SETFOCUS
, hook
},
7605 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 1 },
7606 { WM_IME_NOTIFY
, sent
|wparam
|defwinproc
|optional
, 2 },
7607 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
7608 { WM_SETFOCUS
, sent
|wparam
, 0 },
7609 { EVENT_OBJECT_CREATE
, winevent_hook
|wparam
|lparam
, OBJID_CARET
, 0 },
7610 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, OBJID_CARET
, 0 },
7611 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, OBJID_CARET
, 0 },
7612 { WM_COMMAND
, sent
|parent
|wparam
, MAKEWPARAM(ID_EDIT
, EN_SETFOCUS
) },
7615 static const struct message sl_edit_killfocus
[] =
7617 { HCBT_SETFOCUS
, hook
},
7618 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
7619 { WM_KILLFOCUS
, sent
|wparam
, 0 },
7620 { EVENT_OBJECT_HIDE
, winevent_hook
|wparam
|lparam
, OBJID_CARET
, 0 },
7621 { EVENT_OBJECT_DESTROY
, winevent_hook
|wparam
|lparam
, OBJID_CARET
, 0 },
7622 { WM_COMMAND
, sent
|parent
|wparam
, MAKEWPARAM(ID_EDIT
, EN_KILLFOCUS
) },
7623 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 0 },
7624 { WM_IME_NOTIFY
, sent
|wparam
|defwinproc
|optional
, 1 },
7627 static const struct message sl_edit_lbutton_dblclk
[] =
7629 { WM_LBUTTONDBLCLK
, sent
},
7630 { EVENT_SYSTEM_CAPTURESTART
, winevent_hook
|wparam
|lparam
, 0, 0 },
7633 static const struct message sl_edit_lbutton_down
[] =
7635 { WM_LBUTTONDOWN
, sent
|wparam
|lparam
, 0, 0 },
7636 { HCBT_SETFOCUS
, hook
},
7637 { WM_IME_SETCONTEXT
, sent
|wparam
|defwinproc
|optional
, 1 },
7638 { WM_IME_NOTIFY
, sent
|wparam
|defwinproc
|optional
, 2 },
7639 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
7640 { WM_SETFOCUS
, sent
|wparam
|defwinproc
, 0 },
7641 { WM_CTLCOLOREDIT
, sent
|parent
},
7642 { EVENT_OBJECT_CREATE
, winevent_hook
|wparam
|lparam
, OBJID_CARET
, 0 },
7643 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, OBJID_CARET
, 0 },
7644 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, OBJID_CARET
, 0 },
7645 { WM_COMMAND
, sent
|parent
|wparam
, MAKEWPARAM(ID_EDIT
, EN_SETFOCUS
) },
7646 { EVENT_SYSTEM_CAPTURESTART
, winevent_hook
|wparam
|lparam
, 0, 0 },
7647 { EVENT_OBJECT_HIDE
, winevent_hook
|wparam
|lparam
, OBJID_CARET
, 0 },
7648 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, OBJID_CARET
, 0 },
7649 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, OBJID_CARET
, 0 },
7652 static const struct message ml_edit_lbutton_down
[] =
7654 { WM_LBUTTONDOWN
, sent
|wparam
|lparam
, 0, 0 },
7655 { EVENT_SYSTEM_CAPTURESTART
, winevent_hook
|wparam
|lparam
, 0, 0 },
7656 { HCBT_SETFOCUS
, hook
},
7657 { WM_IME_SETCONTEXT
, sent
|wparam
|defwinproc
|optional
, 1 },
7658 { WM_IME_NOTIFY
, sent
|wparam
|defwinproc
|optional
, 2 },
7659 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
7660 { WM_SETFOCUS
, sent
|wparam
|defwinproc
, 0 },
7661 { EVENT_OBJECT_CREATE
, winevent_hook
|wparam
|lparam
, OBJID_CARET
, 0 },
7662 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, OBJID_CARET
, 0 },
7663 { WM_COMMAND
, sent
|parent
|wparam
, MAKEWPARAM(ID_EDIT
, EN_SETFOCUS
) },
7666 static const struct message sl_edit_lbutton_up
[] =
7668 { WM_LBUTTONUP
, sent
|wparam
|lparam
, 0, 0 },
7669 { EVENT_OBJECT_HIDE
, winevent_hook
|wparam
|lparam
, OBJID_CARET
, 0 },
7670 { EVENT_SYSTEM_CAPTUREEND
, winevent_hook
|wparam
|lparam
, 0, 0 },
7671 { WM_CAPTURECHANGED
, sent
|defwinproc
},
7672 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, OBJID_CARET
, 0 },
7675 static const struct message ml_edit_lbutton_up
[] =
7677 { WM_LBUTTONUP
, sent
|wparam
|lparam
, 0, 0 },
7678 { EVENT_SYSTEM_CAPTUREEND
, winevent_hook
|wparam
|lparam
, 0, 0 },
7679 { WM_CAPTURECHANGED
, sent
|defwinproc
},
7683 static WNDPROC old_edit_proc
;
7685 static LRESULT CALLBACK
edit_hook_proc(HWND hwnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
7687 static long defwndproc_counter
= 0;
7691 trace("edit: %p, %04x, %08lx, %08lx\n", hwnd
, message
, wParam
, lParam
);
7693 /* explicitly ignore WM_GETICON message */
7694 if (message
== WM_GETICON
) return 0;
7696 msg
.message
= message
;
7697 msg
.flags
= sent
|wparam
|lparam
;
7698 if (defwndproc_counter
) msg
.flags
|= defwinproc
;
7699 msg
.wParam
= wParam
;
7700 msg
.lParam
= lParam
;
7703 defwndproc_counter
++;
7704 ret
= CallWindowProcA(old_edit_proc
, hwnd
, message
, wParam
, lParam
);
7705 defwndproc_counter
--;
7710 static void subclass_edit(void)
7714 if (!GetClassInfoA(0, "edit", &cls
)) assert(0);
7716 old_edit_proc
= cls
.lpfnWndProc
;
7718 cls
.hInstance
= GetModuleHandle(0);
7719 cls
.lpfnWndProc
= edit_hook_proc
;
7720 cls
.lpszClassName
= "my_edit_class";
7721 UnregisterClass(cls
.lpszClassName
, cls
.hInstance
);
7722 if (!RegisterClassA(&cls
)) assert(0);
7725 static void test_edit_messages(void)
7731 log_all_parent_messages
++;
7733 parent
= CreateWindowExA(0, "TestParentClass", "Test parent", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
7734 100, 100, 200, 200, 0, 0, 0, NULL
);
7735 ok (parent
!= 0, "Failed to create parent window\n");
7737 /* test single line edit */
7738 hwnd
= CreateWindowExA(0, "my_edit_class", "test", WS_CHILD
,
7739 0, 0, 80, 20, parent
, (HMENU
)ID_EDIT
, 0, NULL
);
7740 ok(hwnd
!= 0, "Failed to create edit window\n");
7742 dlg_code
= SendMessageA(hwnd
, WM_GETDLGCODE
, 0, 0);
7743 ok(dlg_code
== (DLGC_WANTCHARS
|DLGC_HASSETSEL
|DLGC_WANTARROWS
), "wrong dlg_code %08x\n", dlg_code
);
7745 ShowWindow(hwnd
, SW_SHOW
);
7751 ok_sequence(sl_edit_setfocus
, "SetFocus(hwnd) on an edit", FALSE
);
7754 ok_sequence(sl_edit_killfocus
, "SetFocus(0) on an edit", FALSE
);
7760 SendMessageA(hwnd
, WM_LBUTTONDBLCLK
, 0, 0);
7761 ok_sequence(sl_edit_lbutton_dblclk
, "WM_LBUTTONDBLCLK on an edit", FALSE
);
7767 SendMessageA(hwnd
, WM_LBUTTONDOWN
, 0, 0);
7768 ok_sequence(sl_edit_lbutton_down
, "WM_LBUTTONDOWN on an edit", FALSE
);
7770 SendMessageA(hwnd
, WM_LBUTTONUP
, 0, 0);
7771 ok_sequence(sl_edit_lbutton_up
, "WM_LBUTTONUP on an edit", FALSE
);
7773 DestroyWindow(hwnd
);
7775 /* test multiline edit */
7776 hwnd
= CreateWindowExA(0, "my_edit_class", "test", WS_CHILD
| ES_MULTILINE
,
7777 0, 0, 80, 20, parent
, (HMENU
)ID_EDIT
, 0, NULL
);
7778 ok(hwnd
!= 0, "Failed to create edit window\n");
7780 dlg_code
= SendMessageA(hwnd
, WM_GETDLGCODE
, 0, 0);
7781 ok(dlg_code
== (DLGC_WANTCHARS
|DLGC_HASSETSEL
|DLGC_WANTARROWS
|DLGC_WANTALLKEYS
),
7782 "wrong dlg_code %08x\n", dlg_code
);
7784 ShowWindow(hwnd
, SW_SHOW
);
7790 ok_sequence(ml_edit_setfocus
, "SetFocus(hwnd) on multiline edit", FALSE
);
7793 ok_sequence(sl_edit_killfocus
, "SetFocus(0) on multiline edit", FALSE
);
7799 SendMessageA(hwnd
, WM_LBUTTONDBLCLK
, 0, 0);
7800 ok_sequence(sl_edit_lbutton_dblclk
, "WM_LBUTTONDBLCLK on multiline edit", FALSE
);
7806 SendMessageA(hwnd
, WM_LBUTTONDOWN
, 0, 0);
7807 ok_sequence(ml_edit_lbutton_down
, "WM_LBUTTONDOWN on multiline edit", FALSE
);
7809 SendMessageA(hwnd
, WM_LBUTTONUP
, 0, 0);
7810 ok_sequence(ml_edit_lbutton_up
, "WM_LBUTTONUP on multiline edit", FALSE
);
7812 DestroyWindow(hwnd
);
7813 DestroyWindow(parent
);
7815 log_all_parent_messages
--;
7818 /**************************** End of Edit test ******************************/
7820 static const struct message WmKeyDownSkippedSeq
[] =
7822 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, 'N', 1 }, /* XP */
7825 static const struct message WmKeyUpSkippedSeq
[] =
7827 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, 'N', 0xc0000001 }, /* XP */
7831 #define EV_START_STOP 0
7832 #define EV_SENDMSG 1
7838 HANDLE hevent
[3]; /* 0 - start/stop, 1 - SendMessage, 2 - ack */
7841 static DWORD CALLBACK
send_msg_thread_2(void *param
)
7844 struct peekmsg_info
*info
= param
;
7846 trace("thread: waiting for start\n");
7847 WaitForSingleObject(info
->hevent
[EV_START_STOP
], INFINITE
);
7848 trace("thread: looping\n");
7852 ret
= WaitForMultipleObjects(2, info
->hevent
, FALSE
, INFINITE
);
7856 case WAIT_OBJECT_0
+ EV_START_STOP
:
7857 trace("thread: exiting\n");
7860 case WAIT_OBJECT_0
+ EV_SENDMSG
:
7861 trace("thread: sending message\n");
7862 SendNotifyMessageA(info
->hwnd
, WM_USER
, 0, 0);
7863 SetEvent(info
->hevent
[EV_ACK
]);
7867 trace("unexpected return: %04x\n", ret
);
7875 static void test_PeekMessage(void)
7880 UINT qs_all_input
= QS_ALLINPUT
;
7881 UINT qs_input
= QS_INPUT
;
7883 struct peekmsg_info info
;
7885 info
.hwnd
= CreateWindowA("TestWindowClass", NULL
, WS_OVERLAPPEDWINDOW
,
7886 100, 100, 200, 200, 0, 0, 0, NULL
);
7888 ShowWindow(info
.hwnd
, SW_SHOW
);
7889 UpdateWindow(info
.hwnd
);
7890 SetFocus(info
.hwnd
);
7892 info
.hevent
[EV_START_STOP
] = CreateEventA(NULL
, 0, 0, NULL
);
7893 info
.hevent
[EV_SENDMSG
] = CreateEventA(NULL
, 0, 0, NULL
);
7894 info
.hevent
[EV_ACK
] = CreateEventA(NULL
, 0, 0, NULL
);
7896 hthread
= CreateThread(NULL
, 0, send_msg_thread_2
, &info
, 0, &tid
);
7899 trace("signalling to start looping\n");
7900 SetEvent(info
.hevent
[EV_START_STOP
]);
7902 while (PeekMessageA(&msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessageA(&msg
);
7905 SetLastError(0xdeadbeef);
7906 qstatus
= GetQueueStatus(qs_all_input
);
7907 if (GetLastError() == ERROR_INVALID_FLAGS
)
7909 trace("QS_RAWINPUT not supported on this platform\n");
7910 qs_all_input
&= ~QS_RAWINPUT
;
7911 qs_input
&= ~QS_RAWINPUT
;
7913 ok(qstatus
== 0, "wrong qstatus %08x\n", qstatus
);
7915 trace("signalling to send message\n");
7916 SetEvent(info
.hevent
[EV_SENDMSG
]);
7917 WaitForSingleObject(info
.hevent
[EV_ACK
], INFINITE
);
7919 /* pass invalid QS_xxxx flags */
7920 SetLastError(0xdeadbeef);
7921 qstatus
= GetQueueStatus(0xffffffff);
7922 ok(qstatus
== 0, "GetQueueStatus should fail: %08x\n", qstatus
);
7923 ok(GetLastError() == ERROR_INVALID_FLAGS
, "wrong error %d\n", GetLastError());
7925 qstatus
= GetQueueStatus(qs_all_input
);
7926 ok(qstatus
== MAKELONG(QS_SENDMESSAGE
, QS_SENDMESSAGE
),
7927 "wrong qstatus %08x\n", qstatus
);
7930 ret
= PeekMessageA(&msg
, 0, 0, 0, PM_REMOVE
);
7932 "PeekMessageA should have returned FALSE instead of msg %04x\n",
7934 ok_sequence(WmUser
, "WmUser", FALSE
);
7936 qstatus
= GetQueueStatus(qs_all_input
);
7937 ok(qstatus
== 0, "wrong qstatus %08x\n", qstatus
);
7939 keybd_event('N', 0, 0, 0);
7940 keybd_event('N', 0, KEYEVENTF_KEYUP
, 0);
7941 qstatus
= GetQueueStatus(qs_all_input
);
7942 ok(qstatus
== MAKELONG(QS_KEY
, QS_KEY
),
7943 "wrong qstatus %08x\n", qstatus
);
7945 PostMessageA(info
.hwnd
, WM_CHAR
, 'z', 0);
7946 qstatus
= GetQueueStatus(qs_all_input
);
7947 ok(qstatus
== MAKELONG(QS_POSTMESSAGE
, QS_POSTMESSAGE
|QS_KEY
),
7948 "wrong qstatus %08x\n", qstatus
);
7950 InvalidateRect(info
.hwnd
, NULL
, FALSE
);
7951 qstatus
= GetQueueStatus(qs_all_input
);
7952 ok(qstatus
== MAKELONG(QS_PAINT
, QS_PAINT
|QS_POSTMESSAGE
|QS_KEY
),
7953 "wrong qstatus %08x\n", qstatus
);
7955 trace("signalling to send message\n");
7956 SetEvent(info
.hevent
[EV_SENDMSG
]);
7957 WaitForSingleObject(info
.hevent
[EV_ACK
], INFINITE
);
7959 qstatus
= GetQueueStatus(qs_all_input
);
7960 ok(qstatus
== MAKELONG(QS_SENDMESSAGE
, QS_SENDMESSAGE
|QS_PAINT
|QS_POSTMESSAGE
|QS_KEY
),
7961 "wrong qstatus %08x\n", qstatus
);
7964 ret
= PeekMessageA(&msg
, 0, 0, 0, PM_REMOVE
| (qs_input
<< 16));
7966 "PeekMessageA should have returned FALSE instead of msg %04x\n",
7968 ok_sequence(WmUser
, "WmUser", FALSE
);
7970 qstatus
= GetQueueStatus(qs_all_input
);
7971 ok(qstatus
== MAKELONG(0, QS_PAINT
|QS_POSTMESSAGE
|QS_KEY
),
7972 "wrong qstatus %08x\n", qstatus
);
7974 trace("signalling to send message\n");
7975 SetEvent(info
.hevent
[EV_SENDMSG
]);
7976 WaitForSingleObject(info
.hevent
[EV_ACK
], INFINITE
);
7978 qstatus
= GetQueueStatus(qs_all_input
);
7979 ok(qstatus
== MAKELONG(QS_SENDMESSAGE
, QS_SENDMESSAGE
|QS_PAINT
|QS_POSTMESSAGE
|QS_KEY
),
7980 "wrong qstatus %08x\n", qstatus
);
7983 ret
= PeekMessageA(&msg
, 0, 0, 0, PM_REMOVE
| PM_QS_POSTMESSAGE
);
7985 "PeekMessageA should have returned FALSE instead of msg %04x\n",
7987 ok_sequence(WmUser
, "WmUser", FALSE
);
7989 qstatus
= GetQueueStatus(qs_all_input
);
7990 ok(qstatus
== MAKELONG(0, QS_PAINT
|QS_POSTMESSAGE
|QS_KEY
),
7991 "wrong qstatus %08x\n", qstatus
);
7994 ret
= PeekMessageA(&msg
, 0, 0, 0, PM_REMOVE
| PM_QS_POSTMESSAGE
);
7995 ok(ret
&& msg
.message
== WM_CHAR
&& msg
.wParam
== 'z',
7996 "got %d and %04x wParam %08lx instead of TRUE and WM_CHAR wParam 'z'\n",
7997 ret
, msg
.message
, msg
.wParam
);
7998 ok_sequence(WmEmptySeq
, "WmEmptySeq", FALSE
);
8000 qstatus
= GetQueueStatus(qs_all_input
);
8001 ok(qstatus
== MAKELONG(0, QS_PAINT
|QS_KEY
),
8002 "wrong qstatus %08x\n", qstatus
);
8005 ret
= PeekMessageA(&msg
, 0, 0, 0, PM_REMOVE
| PM_QS_POSTMESSAGE
);
8007 "PeekMessageA should have returned FALSE instead of msg %04x\n",
8009 ok_sequence(WmEmptySeq
, "WmEmptySeq", FALSE
);
8011 qstatus
= GetQueueStatus(qs_all_input
);
8012 ok(qstatus
== MAKELONG(0, QS_PAINT
|QS_KEY
),
8013 "wrong qstatus %08x\n", qstatus
);
8016 ret
= PeekMessageA(&msg
, 0, 0, 0, PM_REMOVE
| PM_QS_PAINT
);
8017 ok(ret
&& msg
.message
== WM_PAINT
,
8018 "got %d and %04x instead of TRUE and WM_PAINT\n", ret
, msg
.message
);
8019 DispatchMessageA(&msg
);
8020 ok_sequence(WmPaint
, "WmPaint", FALSE
);
8022 qstatus
= GetQueueStatus(qs_all_input
);
8023 ok(qstatus
== MAKELONG(0, QS_KEY
),
8024 "wrong qstatus %08x\n", qstatus
);
8027 ret
= PeekMessageA(&msg
, 0, 0, 0, PM_REMOVE
| PM_QS_PAINT
);
8029 "PeekMessageA should have returned FALSE instead of msg %04x\n",
8031 ok_sequence(WmEmptySeq
, "WmEmptySeq", FALSE
);
8033 qstatus
= GetQueueStatus(qs_all_input
);
8034 ok(qstatus
== MAKELONG(0, QS_KEY
),
8035 "wrong qstatus %08x\n", qstatus
);
8037 trace("signalling to send message\n");
8038 SetEvent(info
.hevent
[EV_SENDMSG
]);
8039 WaitForSingleObject(info
.hevent
[EV_ACK
], INFINITE
);
8041 qstatus
= GetQueueStatus(qs_all_input
);
8042 ok(qstatus
== MAKELONG(QS_SENDMESSAGE
, QS_SENDMESSAGE
|QS_KEY
),
8043 "wrong qstatus %08x\n", qstatus
);
8045 PostMessageA(info
.hwnd
, WM_CHAR
, 'z', 0);
8047 qstatus
= GetQueueStatus(qs_all_input
);
8048 ok(qstatus
== MAKELONG(QS_POSTMESSAGE
, QS_SENDMESSAGE
|QS_POSTMESSAGE
|QS_KEY
),
8049 "wrong qstatus %08x\n", qstatus
);
8052 ret
= PeekMessageA(&msg
, 0, WM_CHAR
, WM_CHAR
, PM_REMOVE
);
8053 ok(ret
&& msg
.message
== WM_CHAR
&& msg
.wParam
== 'z',
8054 "got %d and %04x wParam %08lx instead of TRUE and WM_CHAR wParam 'z'\n",
8055 ret
, msg
.message
, msg
.wParam
);
8056 ok_sequence(WmUser
, "WmUser", FALSE
);
8058 qstatus
= GetQueueStatus(qs_all_input
);
8059 ok(qstatus
== MAKELONG(0, QS_KEY
),
8060 "wrong qstatus %08x\n", qstatus
);
8063 ret
= PeekMessageA(&msg
, 0, WM_CHAR
, WM_CHAR
, PM_REMOVE
);
8065 "PeekMessageA should have returned FALSE instead of msg %04x\n",
8067 ok_sequence(WmEmptySeq
, "WmEmptySeq", FALSE
);
8069 qstatus
= GetQueueStatus(qs_all_input
);
8070 ok(qstatus
== MAKELONG(0, QS_KEY
),
8071 "wrong qstatus %08x\n", qstatus
);
8073 PostMessageA(info
.hwnd
, WM_CHAR
, 'z', 0);
8075 qstatus
= GetQueueStatus(qs_all_input
);
8076 ok(qstatus
== MAKELONG(QS_POSTMESSAGE
, QS_POSTMESSAGE
|QS_KEY
),
8077 "wrong qstatus %08x\n", qstatus
);
8079 trace("signalling to send message\n");
8080 SetEvent(info
.hevent
[EV_SENDMSG
]);
8081 WaitForSingleObject(info
.hevent
[EV_ACK
], INFINITE
);
8083 qstatus
= GetQueueStatus(qs_all_input
);
8084 ok(qstatus
== MAKELONG(QS_SENDMESSAGE
, QS_SENDMESSAGE
|QS_POSTMESSAGE
|QS_KEY
),
8085 "wrong qstatus %08x\n", qstatus
);
8088 ret
= PeekMessageA(&msg
, 0, 0, 0, PM_REMOVE
| (QS_KEY
<< 16));
8090 "PeekMessageA should have returned FALSE instead of msg %04x\n",
8092 ok_sequence(WmUser
, "WmUser", FALSE
);
8094 qstatus
= GetQueueStatus(qs_all_input
);
8095 ok(qstatus
== MAKELONG(0, QS_POSTMESSAGE
|QS_KEY
),
8096 "wrong qstatus %08x\n", qstatus
);
8099 if (qs_all_input
& QS_RAWINPUT
) /* use QS_RAWINPUT only if supported */
8100 ret
= PeekMessageA(&msg
, 0, 0, 0, PM_REMOVE
| (QS_RAWINPUT
<< 16));
8101 else /* workaround for a missing QS_RAWINPUT support */
8102 ret
= PeekMessageA(&msg
, 0, WM_KEYDOWN
, WM_KEYDOWN
, PM_REMOVE
);
8103 ok(ret
&& msg
.message
== WM_KEYDOWN
&& msg
.wParam
== 'N',
8104 "got %d and %04x wParam %08lx instead of TRUE and WM_KEYDOWN wParam 'N'\n",
8105 ret
, msg
.message
, msg
.wParam
);
8106 ok_sequence(WmKeyDownSkippedSeq
, "WmKeyDownSkippedSeq", FALSE
);
8108 qstatus
= GetQueueStatus(qs_all_input
);
8109 ok(qstatus
== MAKELONG(0, QS_POSTMESSAGE
|QS_KEY
),
8110 "wrong qstatus %08x\n", qstatus
);
8113 if (qs_all_input
& QS_RAWINPUT
) /* use QS_RAWINPUT only if supported */
8114 ret
= PeekMessageA(&msg
, 0, 0, 0, PM_REMOVE
| (QS_RAWINPUT
<< 16));
8115 else /* workaround for a missing QS_RAWINPUT support */
8116 ret
= PeekMessageA(&msg
, 0, WM_KEYUP
, WM_KEYUP
, PM_REMOVE
);
8117 ok(ret
&& msg
.message
== WM_KEYUP
&& msg
.wParam
== 'N',
8118 "got %d and %04x wParam %08lx instead of TRUE and WM_KEYUP wParam 'N'\n",
8119 ret
, msg
.message
, msg
.wParam
);
8120 ok_sequence(WmKeyUpSkippedSeq
, "WmKeyUpSkippedSeq", FALSE
);
8122 qstatus
= GetQueueStatus(qs_all_input
);
8123 ok(qstatus
== MAKELONG(0, QS_POSTMESSAGE
),
8124 "wrong qstatus %08x\n", qstatus
);
8127 ret
= PeekMessageA(&msg
, 0, 0, 0, PM_REMOVE
| PM_QS_SENDMESSAGE
);
8129 "PeekMessageA should have returned FALSE instead of msg %04x\n",
8131 ok_sequence(WmEmptySeq
, "WmEmptySeq", FALSE
);
8133 qstatus
= GetQueueStatus(qs_all_input
);
8134 ok(qstatus
== MAKELONG(0, QS_POSTMESSAGE
),
8135 "wrong qstatus %08x\n", qstatus
);
8138 ret
= PeekMessageA(&msg
, 0, 0, 0, PM_REMOVE
);
8139 ok(ret
&& msg
.message
== WM_CHAR
&& msg
.wParam
== 'z',
8140 "got %d and %04x wParam %08lx instead of TRUE and WM_CHAR wParam 'z'\n",
8141 ret
, msg
.message
, msg
.wParam
);
8142 ok_sequence(WmEmptySeq
, "WmEmptySeq", FALSE
);
8144 qstatus
= GetQueueStatus(qs_all_input
);
8146 "wrong qstatus %08x\n", qstatus
);
8149 ret
= PeekMessageA(&msg
, 0, 0, 0, PM_REMOVE
);
8151 "PeekMessageA should have returned FALSE instead of msg %04x\n",
8153 ok_sequence(WmEmptySeq
, "WmEmptySeq", FALSE
);
8155 qstatus
= GetQueueStatus(qs_all_input
);
8157 "wrong qstatus %08x\n", qstatus
);
8159 /* test whether presence of the quit flag in the queue affects
8162 PostQuitMessage(0x1234abcd);
8164 qstatus
= GetQueueStatus(qs_all_input
);
8165 ok(qstatus
== MAKELONG(QS_POSTMESSAGE
, QS_POSTMESSAGE
),
8166 "wrong qstatus %08x\n", qstatus
);
8168 PostMessageA(info
.hwnd
, WM_USER
, 0, 0);
8170 qstatus
= GetQueueStatus(qs_all_input
);
8171 ok(qstatus
== MAKELONG(QS_POSTMESSAGE
, QS_POSTMESSAGE
),
8172 "wrong qstatus %08x\n", qstatus
);
8175 ret
= PeekMessageA(&msg
, 0, 0, 0, PM_REMOVE
);
8176 ok(ret
&& msg
.message
== WM_USER
,
8177 "got %d and %04x instead of TRUE and WM_USER\n", ret
, msg
.message
);
8178 ok_sequence(WmEmptySeq
, "WmEmptySeq", FALSE
);
8180 qstatus
= GetQueueStatus(qs_all_input
);
8181 ok(qstatus
== MAKELONG(0, QS_POSTMESSAGE
),
8182 "wrong qstatus %08x\n", qstatus
);
8185 ret
= PeekMessageA(&msg
, 0, 0, 0, PM_REMOVE
);
8186 ok(ret
&& msg
.message
== WM_QUIT
,
8187 "got %d and %04x instead of TRUE and WM_QUIT\n", ret
, msg
.message
);
8188 ok(msg
.wParam
== 0x1234abcd, "got wParam %08lx instead of 0x1234abcd\n", msg
.wParam
);
8189 ok(msg
.lParam
== 0, "got lParam %08lx instead of 0\n", msg
.lParam
);
8190 ok_sequence(WmEmptySeq
, "WmEmptySeq", FALSE
);
8192 qstatus
= GetQueueStatus(qs_all_input
);
8194 ok(qstatus
== MAKELONG(0, QS_POSTMESSAGE
),
8195 "wrong qstatus %08x\n", qstatus
);
8199 ret
= PeekMessageA(&msg
, 0, 0, 0, PM_REMOVE
);
8201 "PeekMessageA should have returned FALSE instead of msg %04x\n",
8203 ok_sequence(WmEmptySeq
, "WmEmptySeq", FALSE
);
8205 qstatus
= GetQueueStatus(qs_all_input
);
8207 "wrong qstatus %08x\n", qstatus
);
8209 trace("signalling to exit\n");
8210 SetEvent(info
.hevent
[EV_START_STOP
]);
8212 WaitForSingleObject(hthread
, INFINITE
);
8214 CloseHandle(hthread
);
8215 CloseHandle(info
.hevent
[0]);
8216 CloseHandle(info
.hevent
[1]);
8217 CloseHandle(info
.hevent
[2]);
8219 DestroyWindow(info
.hwnd
);
8223 static void test_quit_message(void)
8228 /* test using PostQuitMessage */
8229 PostQuitMessage(0xbeef);
8231 ret
= PeekMessage(&msg
, NULL
, 0, 0, PM_NOREMOVE
);
8232 ok(ret
, "PeekMessage failed with error %d\n", GetLastError());
8233 ok(msg
.message
== WM_QUIT
, "Received message 0x%04x instead of WM_QUIT\n", msg
.message
);
8234 ok(msg
.wParam
== 0xbeef, "wParam was 0x%lx instead of 0xbeef\n", msg
.wParam
);
8236 ret
= PostThreadMessage(GetCurrentThreadId(), WM_USER
, 0, 0);
8237 ok(ret
, "PostMessage failed with error %d\n", GetLastError());
8239 ret
= GetMessage(&msg
, NULL
, 0, 0);
8240 ok(ret
> 0, "GetMessage failed with error %d\n", GetLastError());
8241 ok(msg
.message
== WM_USER
, "Received message 0x%04x instead of WM_USER\n", msg
.message
);
8243 /* note: WM_QUIT message received after WM_USER message */
8244 ret
= GetMessage(&msg
, NULL
, 0, 0);
8245 ok(!ret
, "GetMessage return %d with error %d instead of FALSE\n", ret
, GetLastError());
8246 ok(msg
.message
== WM_QUIT
, "Received message 0x%04x instead of WM_QUIT\n", msg
.message
);
8247 ok(msg
.wParam
== 0xbeef, "wParam was 0x%lx instead of 0xbeef\n", msg
.wParam
);
8249 ret
= PeekMessage(&msg
, NULL
, 0, 0, PM_REMOVE
);
8250 ok( !ret
|| msg
.message
!= WM_QUIT
, "Received WM_QUIT again\n" );
8252 /* now test with PostThreadMessage - different behaviour! */
8253 PostThreadMessage(GetCurrentThreadId(), WM_QUIT
, 0xdead, 0);
8255 ret
= PeekMessage(&msg
, NULL
, 0, 0, PM_NOREMOVE
);
8256 ok(ret
, "PeekMessage failed with error %d\n", GetLastError());
8257 ok(msg
.message
== WM_QUIT
, "Received message 0x%04x instead of WM_QUIT\n", msg
.message
);
8258 ok(msg
.wParam
== 0xdead, "wParam was 0x%lx instead of 0xdead\n", msg
.wParam
);
8260 ret
= PostThreadMessage(GetCurrentThreadId(), WM_USER
, 0, 0);
8261 ok(ret
, "PostMessage failed with error %d\n", GetLastError());
8263 /* note: we receive the WM_QUIT message first this time */
8264 ret
= GetMessage(&msg
, NULL
, 0, 0);
8265 ok(!ret
, "GetMessage return %d with error %d instead of FALSE\n", ret
, GetLastError());
8266 ok(msg
.message
== WM_QUIT
, "Received message 0x%04x instead of WM_QUIT\n", msg
.message
);
8267 ok(msg
.wParam
== 0xdead, "wParam was 0x%lx instead of 0xdead\n", msg
.wParam
);
8269 ret
= GetMessage(&msg
, NULL
, 0, 0);
8270 ok(ret
> 0, "GetMessage failed with error %d\n", GetLastError());
8271 ok(msg
.message
== WM_USER
, "Received message 0x%04x instead of WM_USER\n", msg
.message
);
8274 static const struct message WmMouseHoverSeq
[] = {
8275 { WM_TIMER
, sent
|optional
}, /* XP sends it */
8276 { WM_SYSTIMER
, sent
},
8277 { WM_MOUSEHOVER
, sent
|wparam
, 0 },
8281 static void pump_msg_loop_timeout(DWORD timeout
, BOOL inject_mouse_move
)
8284 DWORD start_ticks
, end_ticks
;
8286 start_ticks
= GetTickCount();
8287 /* add some deviation (5%) to cover not expected delays */
8288 start_ticks
+= timeout
/ 20;
8292 while (PeekMessage(&msg
, 0, 0, 0, PM_REMOVE
))
8294 /* Timer proc messages are not dispatched to the window proc,
8295 * and therefore not logged.
8297 if (msg
.message
== WM_TIMER
|| msg
.message
== WM_SYSTIMER
)
8299 struct message s_msg
;
8301 s_msg
.message
= msg
.message
;
8302 s_msg
.flags
= sent
|wparam
|lparam
;
8303 s_msg
.wParam
= msg
.wParam
;
8304 s_msg
.lParam
= msg
.lParam
;
8305 add_message(&s_msg
);
8307 DispatchMessage(&msg
);
8310 end_ticks
= GetTickCount();
8312 /* inject WM_MOUSEMOVE to see how it changes tracking */
8313 if (inject_mouse_move
&& start_ticks
+ timeout
/ 2 >= end_ticks
)
8315 mouse_event(MOUSEEVENTF_MOVE
, -1, 0, 0, 0);
8316 mouse_event(MOUSEEVENTF_MOVE
, 1, 0, 0, 0);
8318 inject_mouse_move
= FALSE
;
8320 } while (start_ticks
+ timeout
>= end_ticks
);
8323 static void test_TrackMouseEvent(void)
8326 TRACKMOUSEEVENT tme
;
8329 RECT rc_parent
, rc_child
;
8330 UINT default_hover_time
, hover_width
= 0, hover_height
= 0;
8332 #define track_hover(track_hwnd, track_hover_time) \
8333 tme.cbSize = sizeof(tme); \
8334 tme.dwFlags = TME_HOVER; \
8335 tme.hwndTrack = track_hwnd; \
8336 tme.dwHoverTime = track_hover_time; \
8337 SetLastError(0xdeadbeef); \
8338 ret = TrackMouseEvent(&tme); \
8339 ok(ret, "TrackMouseEvent(TME_HOVER) error %d\n", GetLastError())
8341 #define track_query(expected_track_flags, expected_track_hwnd, expected_hover_time) \
8342 tme.cbSize = sizeof(tme); \
8343 tme.dwFlags = TME_QUERY; \
8344 tme.hwndTrack = (HWND)0xdeadbeef; \
8345 tme.dwHoverTime = 0xdeadbeef; \
8346 SetLastError(0xdeadbeef); \
8347 ret = TrackMouseEvent(&tme); \
8348 ok(ret, "TrackMouseEvent(TME_QUERY) error %d\n", GetLastError());\
8349 ok(tme.cbSize == sizeof(tme), "wrong tme.cbSize %u\n", tme.cbSize); \
8350 ok(tme.dwFlags == (expected_track_flags), \
8351 "wrong tme.dwFlags %08x, expected %08x\n", tme.dwFlags, (expected_track_flags)); \
8352 ok(tme.hwndTrack == (expected_track_hwnd), \
8353 "wrong tme.hwndTrack %p, expected %p\n", tme.hwndTrack, (expected_track_hwnd)); \
8354 ok(tme.dwHoverTime == (expected_hover_time), \
8355 "wrong tme.dwHoverTime %u, expected %u\n", tme.dwHoverTime, (expected_hover_time))
8357 #define track_hover_cancel(track_hwnd) \
8358 tme.cbSize = sizeof(tme); \
8359 tme.dwFlags = TME_HOVER | TME_CANCEL; \
8360 tme.hwndTrack = track_hwnd; \
8361 tme.dwHoverTime = 0xdeadbeef; \
8362 SetLastError(0xdeadbeef); \
8363 ret = TrackMouseEvent(&tme); \
8364 ok(ret, "TrackMouseEvent(TME_HOVER | TME_CANCEL) error %d\n", GetLastError())
8366 default_hover_time
= 0xdeadbeef;
8367 SetLastError(0xdeadbeef);
8368 ret
= SystemParametersInfo(SPI_GETMOUSEHOVERTIME
, 0, &default_hover_time
, 0);
8369 ok(ret
, "SystemParametersInfo(SPI_GETMOUSEHOVERTIME) error %u\n", GetLastError());
8370 if (!ret
) default_hover_time
= 400;
8371 trace("SPI_GETMOUSEHOVERTIME returned %u ms\n", default_hover_time
);
8373 SetLastError(0xdeadbeef);
8374 ret
= SystemParametersInfo(SPI_GETMOUSEHOVERWIDTH
, 0, &hover_width
, 0);
8375 ok(ret
, "SystemParametersInfo(SPI_GETMOUSEHOVERWIDTH) error %u\n", GetLastError());
8376 if (!ret
) hover_width
= 4;
8377 SetLastError(0xdeadbeef);
8378 ret
= SystemParametersInfo(SPI_GETMOUSEHOVERHEIGHT
, 0, &hover_height
, 0);
8379 ok(ret
, "SystemParametersInfo(SPI_GETMOUSEHOVERHEIGHT) error %u\n", GetLastError());
8380 if (!ret
) hover_height
= 4;
8381 trace("hover rect is %u x %d\n", hover_width
, hover_height
);
8383 hwnd
= CreateWindowEx(0, "TestWindowClass", NULL
,
8384 WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
8385 CW_USEDEFAULT
, CW_USEDEFAULT
, 300, 300, 0,
8389 hchild
= CreateWindowEx(0, "TestWindowClass", NULL
,
8390 WS_CHILD
| WS_BORDER
| WS_VISIBLE
,
8391 50, 50, 200, 200, hwnd
,
8399 tme
.dwFlags
= TME_QUERY
;
8400 tme
.hwndTrack
= (HWND
)0xdeadbeef;
8401 tme
.dwHoverTime
= 0xdeadbeef;
8402 SetLastError(0xdeadbeef);
8403 ret
= TrackMouseEvent(&tme
);
8404 ok(!ret
, "TrackMouseEvent should fail\n");
8405 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "not expected error %d\n", GetLastError());
8407 tme
.cbSize
= sizeof(tme
);
8408 tme
.dwFlags
= TME_HOVER
;
8409 tme
.hwndTrack
= (HWND
)0xdeadbeef;
8410 tme
.dwHoverTime
= 0xdeadbeef;
8411 SetLastError(0xdeadbeef);
8412 ret
= TrackMouseEvent(&tme
);
8413 ok(!ret
, "TrackMouseEvent should fail\n");
8414 ok(GetLastError() == ERROR_INVALID_WINDOW_HANDLE
, "not expected error %d\n", GetLastError());
8416 tme
.cbSize
= sizeof(tme
);
8417 tme
.dwFlags
= TME_HOVER
| TME_CANCEL
;
8418 tme
.hwndTrack
= (HWND
)0xdeadbeef;
8419 tme
.dwHoverTime
= 0xdeadbeef;
8420 SetLastError(0xdeadbeef);
8421 ret
= TrackMouseEvent(&tme
);
8422 ok(!ret
, "TrackMouseEvent should fail\n");
8423 ok(GetLastError() == ERROR_INVALID_WINDOW_HANDLE
, "not expected error %d\n", GetLastError());
8425 GetWindowRect(hwnd
, &rc_parent
);
8426 GetWindowRect(hchild
, &rc_child
);
8427 SetCursorPos(rc_child
.left
- 10, rc_child
.top
- 10);
8429 /* Process messages so that the system updates its internal current
8430 * window and hittest, otherwise TrackMouseEvent calls don't have any
8433 while (PeekMessage(&msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage(&msg
);
8436 track_query(0, NULL
, 0);
8437 track_hover(hchild
, 0);
8438 track_query(0, NULL
, 0);
8440 while (PeekMessage(&msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage(&msg
);
8443 track_hover(hwnd
, 0);
8444 track_query(TME_HOVER
, hwnd
, default_hover_time
);
8446 pump_msg_loop_timeout(default_hover_time
, FALSE
);
8447 ok_sequence(WmMouseHoverSeq
, "WmMouseHoverSeq", FALSE
);
8449 track_query(0, NULL
, 0);
8451 track_hover(hwnd
, HOVER_DEFAULT
);
8452 track_query(TME_HOVER
, hwnd
, default_hover_time
);
8454 Sleep(default_hover_time
/ 2);
8455 mouse_event(MOUSEEVENTF_MOVE
, -1, 0, 0, 0);
8456 mouse_event(MOUSEEVENTF_MOVE
, 1, 0, 0, 0);
8458 track_query(TME_HOVER
, hwnd
, default_hover_time
);
8460 pump_msg_loop_timeout(default_hover_time
/ 2, FALSE
);
8461 ok_sequence(WmMouseHoverSeq
, "WmMouseHoverSeq", FALSE
);
8463 track_query(0, NULL
, 0);
8465 track_hover(hwnd
, HOVER_DEFAULT
);
8466 track_query(TME_HOVER
, hwnd
, default_hover_time
);
8468 pump_msg_loop_timeout(default_hover_time
, TRUE
);
8469 ok_sequence(WmMouseHoverSeq
, "WmMouseHoverSeq", FALSE
);
8471 track_query(0, NULL
, 0);
8473 track_hover(hwnd
, HOVER_DEFAULT
);
8474 track_query(TME_HOVER
, hwnd
, default_hover_time
);
8475 track_hover_cancel(hwnd
);
8477 DestroyWindow(hwnd
);
8481 #undef track_hover_cancel
8485 static const struct message WmSetWindowRgn
[] = {
8486 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
|SWP_NOACTIVATE
|SWP_FRAMECHANGED
|SWP_NOSIZE
|SWP_NOMOVE
},
8487 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
8488 { WM_NCPAINT
, sent
}, /* wparam != 1 */
8489 { WM_GETTEXT
, sent
|defwinproc
|optional
},
8490 { WM_ERASEBKGND
, sent
|optional
}, /* FIXME: remove optional once Wine is fixed */
8491 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
|SWP_NOACTIVATE
|SWP_FRAMECHANGED
|SWP_NOSIZE
|SWP_NOMOVE
},
8492 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
8496 static const struct message WmSetWindowRgn_no_redraw
[] = {
8497 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
|SWP_NOACTIVATE
|SWP_FRAMECHANGED
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOREDRAW
},
8498 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
8499 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
|SWP_NOACTIVATE
|SWP_FRAMECHANGED
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOREDRAW
},
8500 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
8504 static const struct message WmSetWindowRgn_clear
[] = {
8505 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_NOACTIVATE
|SWP_FRAMECHANGED
|SWP_NOSIZE
|SWP_NOMOVE
}, /* some versions of 2000/XP also has SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE in wparam */
8506 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
8507 { WM_NCPAINT
, sent
}, /* wparam != 1 */
8508 { WM_GETTEXT
, sent
|defwinproc
|optional
},
8509 { WM_ERASEBKGND
, sent
|optional
}, /* FIXME: remove optional once Wine is fixed */
8510 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
|SWP_NOACTIVATE
|SWP_FRAMECHANGED
|SWP_NOSIZE
|SWP_NOMOVE
},
8511 { WM_NCCALCSIZE
, sent
|wparam
|optional
, 1 },
8512 { WM_NCPAINT
, sent
|optional
}, /* wparam != 1 */
8513 { WM_GETTEXT
, sent
|defwinproc
|optional
},
8514 { WM_ERASEBKGND
, sent
|optional
},
8515 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
8516 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
8520 static void test_SetWindowRgn(void)
8523 HWND hwnd
= CreateWindowExA(0, "TestWindowClass", "Test overlapped", WS_OVERLAPPEDWINDOW
,
8524 100, 100, 200, 200, 0, 0, 0, NULL
);
8525 ok( hwnd
!= 0, "Failed to create overlapped window\n" );
8527 ShowWindow( hwnd
, SW_SHOW
);
8528 UpdateWindow( hwnd
);
8532 trace("testing SetWindowRgn\n");
8533 hrgn
= CreateRectRgn( 0, 0, 150, 150 );
8534 SetWindowRgn( hwnd
, hrgn
, TRUE
);
8535 ok_sequence( WmSetWindowRgn
, "WmSetWindowRgn", FALSE
);
8537 hrgn
= CreateRectRgn( 30, 30, 160, 160 );
8538 SetWindowRgn( hwnd
, hrgn
, FALSE
);
8539 ok_sequence( WmSetWindowRgn_no_redraw
, "WmSetWindowRgn_no_redraw", FALSE
);
8541 hrgn
= CreateRectRgn( 0, 0, 180, 180 );
8542 SetWindowRgn( hwnd
, hrgn
, TRUE
);
8543 ok_sequence( WmSetWindowRgn
, "WmSetWindowRgn2", FALSE
);
8545 SetWindowRgn( hwnd
, 0, TRUE
);
8546 ok_sequence( WmSetWindowRgn_clear
, "WmSetWindowRgn_clear", FALSE
);
8548 DestroyWindow( hwnd
);
8551 /*************************** ShowWindow() test ******************************/
8552 static const struct message WmShowNormal
[] = {
8553 { WM_SHOWWINDOW
, sent
|wparam
, 1 },
8554 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
},
8555 { HCBT_ACTIVATE
, hook
},
8556 { WM_WINDOWPOSCHANGING
, sent
|wparam
|optional
, SWP_NOSIZE
|SWP_NOMOVE
}, /* win2003 doesn't send it */
8557 { HCBT_SETFOCUS
, hook
},
8558 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
8561 static const struct message WmShow
[] = {
8562 { WM_SHOWWINDOW
, sent
|wparam
, 1 },
8563 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
},
8564 { HCBT_ACTIVATE
, hook
|optional
}, /* win2000 doesn't send it */
8565 { WM_WINDOWPOSCHANGING
, sent
|wparam
|optional
, SWP_NOSIZE
|SWP_NOMOVE
}, /* win2000 doesn't send it */
8566 { HCBT_SETFOCUS
, hook
|optional
}, /* win2000 doesn't send it */
8567 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
8570 static const struct message WmShowNoActivate_1
[] = {
8571 { HCBT_MINMAX
, hook
|lparam
, 0, SW_SHOWNOACTIVATE
},
8572 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOACTIVATE
|SWP_FRAMECHANGED
|0x8000 },
8573 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOACTIVATE
|SWP_FRAMECHANGED
|0x8000 },
8574 { WM_MOVE
, sent
|defwinproc
},
8575 { WM_SIZE
, sent
|wparam
|defwinproc
, SIZE_RESTORED
},
8578 static const struct message WmShowNoActivate_2
[] = {
8579 { HCBT_MINMAX
, hook
|lparam
, 0, SW_SHOWNOACTIVATE
},
8580 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOACTIVATE
|SWP_FRAMECHANGED
|SWP_NOCOPYBITS
|0x8000 },
8581 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOACTIVATE
|SWP_FRAMECHANGED
|SWP_NOCOPYBITS
|0x8000 },
8582 { WM_MOVE
, sent
|defwinproc
},
8583 { WM_SIZE
, sent
|wparam
|defwinproc
, SIZE_RESTORED
},
8584 { HCBT_SETFOCUS
, hook
},
8585 { HCBT_ACTIVATE
, hook
|optional
}, /* win2003 doesn't send it */
8586 { WM_WINDOWPOSCHANGING
, sent
|wparam
|optional
, SWP_NOSIZE
|SWP_NOMOVE
}, /* win2003 doesn't send it */
8587 { HCBT_SETFOCUS
, hook
|optional
}, /* win2003 doesn't send it */
8590 static const struct message WmShowNA_1
[] = {
8591 { WM_SHOWWINDOW
, sent
|wparam
, 1 },
8592 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
8593 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
8596 static const struct message WmShowNA_2
[] = {
8597 { WM_SHOWWINDOW
, sent
|wparam
, 1 },
8598 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
8601 static const struct message WmRestore_1
[] = {
8602 { HCBT_MINMAX
, hook
|lparam
, 0, SW_RESTORE
},
8603 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_FRAMECHANGED
|SWP_NOCOPYBITS
|0x8000 },
8604 { HCBT_ACTIVATE
, hook
|optional
}, /* win2000 doesn't send it */
8605 { WM_WINDOWPOSCHANGING
, sent
|wparam
|optional
, SWP_NOSIZE
|SWP_NOMOVE
}, /* win2000 doesn't send it */
8606 { HCBT_SETFOCUS
, hook
|optional
}, /* win2000 doesn't send it */
8607 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_FRAMECHANGED
|SWP_NOCOPYBITS
|0x8000 },
8608 { WM_MOVE
, sent
|defwinproc
},
8609 { WM_SIZE
, sent
|wparam
|defwinproc
, SIZE_RESTORED
},
8610 { HCBT_SETFOCUS
, hook
|optional
}, /* win2000 sends it */
8613 static const struct message WmRestore_2
[] = {
8614 { WM_SHOWWINDOW
, sent
|wparam
, 1 },
8615 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
},
8616 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
8619 static const struct message WmRestore_3
[] = {
8620 { HCBT_MINMAX
, hook
|lparam
, 0, SW_RESTORE
},
8621 { WM_GETMINMAXINFO
, sent
},
8622 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOCOPYBITS
|0x8000 },
8623 { HCBT_ACTIVATE
, hook
|optional
}, /* win2003 doesn't send it */
8624 { WM_WINDOWPOSCHANGING
, sent
|wparam
|optional
, SWP_NOSIZE
|SWP_NOMOVE
}, /* win2003 doesn't send it */
8625 { HCBT_SETFOCUS
, hook
|optional
}, /* win2003 doesn't send it */
8626 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOCOPYBITS
|0x8000 },
8627 { WM_MOVE
, sent
|defwinproc
},
8628 { WM_SIZE
, sent
|wparam
|defwinproc
, SIZE_MAXIMIZED
},
8629 { HCBT_SETFOCUS
, hook
|optional
}, /* win2003 sends it */
8632 static const struct message WmRestore_4
[] = {
8633 { HCBT_MINMAX
, hook
|lparam
, 0, SW_RESTORE
},
8634 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|0x8000 },
8635 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|0x8000 },
8636 { WM_MOVE
, sent
|defwinproc
},
8637 { WM_SIZE
, sent
|wparam
|defwinproc
, SIZE_RESTORED
},
8640 static const struct message WmRestore_5
[] = {
8641 { HCBT_MINMAX
, hook
|lparam
, 0, SW_SHOWNORMAL
},
8642 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|0x8000 },
8643 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|0x8000 },
8644 { WM_MOVE
, sent
|defwinproc
},
8645 { WM_SIZE
, sent
|wparam
|defwinproc
, SIZE_RESTORED
},
8648 static const struct message WmHide_1
[] = {
8649 { WM_SHOWWINDOW
, sent
|wparam
, 0 },
8650 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_HIDEWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
},
8651 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_HIDEWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
8652 { HCBT_SETFOCUS
, hook
|optional
}, /* win2000 sends it */
8655 static const struct message WmHide_2
[] = {
8656 { WM_SHOWWINDOW
, sent
|wparam
, 0 },
8657 { WM_WINDOWPOSCHANGING
, sent
/*|wparam, SWP_HIDEWINDOW|SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOMOVE*/ }, /* win2000 doesn't add SWP_NOACTIVATE */
8658 { WM_WINDOWPOSCHANGED
, sent
/*|wparam, SWP_HIDEWINDOW|SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOMOVE|SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE*/ }, /* win2000 doesn't add SWP_NOACTIVATE */
8661 static const struct message WmHide_3
[] = {
8662 { WM_SHOWWINDOW
, sent
|wparam
, 0 },
8663 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_HIDEWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
},
8664 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_HIDEWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
8665 { HCBT_SETFOCUS
, hook
},
8668 static const struct message WmShowMinimized_1
[] = {
8669 { HCBT_MINMAX
, hook
|lparam
, 0, SW_SHOWMINIMIZED
},
8670 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_FRAMECHANGED
|SWP_NOCOPYBITS
|0x8000 },
8671 { HCBT_ACTIVATE
, hook
|optional
}, /* win2000 doesn't send it */
8672 { WM_WINDOWPOSCHANGING
, sent
|wparam
|optional
, SWP_NOSIZE
|SWP_NOMOVE
}, /* win2000 doesn't send it */
8673 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_FRAMECHANGED
|SWP_NOCOPYBITS
|0x8000 },
8674 { WM_MOVE
, sent
|defwinproc
},
8675 { WM_SIZE
, sent
|wparam
|defwinproc
, SIZE_MINIMIZED
},
8678 static const struct message WmMinimize_1
[] = {
8679 { HCBT_MINMAX
, hook
|lparam
, 0, SW_MINIMIZE
},
8680 { HCBT_SETFOCUS
, hook
|optional
}, /* win2000 doesn't send it */
8681 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOACTIVATE
|SWP_FRAMECHANGED
|SWP_NOCOPYBITS
|0x8000 },
8682 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_NOACTIVATE
|SWP_FRAMECHANGED
|SWP_NOCOPYBITS
|0x8000 },
8683 { WM_MOVE
, sent
|defwinproc
},
8684 { WM_SIZE
, sent
|wparam
|defwinproc
, SIZE_MINIMIZED
},
8687 static const struct message WmMinimize_2
[] = {
8688 { HCBT_MINMAX
, hook
|lparam
, 0, SW_MINIMIZE
},
8689 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOACTIVATE
|SWP_FRAMECHANGED
|SWP_NOCOPYBITS
|0x8000 },
8690 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_NOACTIVATE
|SWP_FRAMECHANGED
|SWP_NOCOPYBITS
|0x8000 },
8691 { WM_MOVE
, sent
|defwinproc
},
8692 { WM_SIZE
, sent
|wparam
|defwinproc
, SIZE_MINIMIZED
},
8695 static const struct message WmMinimize_3
[] = {
8696 { HCBT_MINMAX
, hook
|lparam
, 0, SW_MINIMIZE
},
8697 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOACTIVATE
|SWP_FRAMECHANGED
|SWP_NOCOPYBITS
|0x8000 },
8698 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOACTIVATE
|SWP_FRAMECHANGED
|SWP_NOCOPYBITS
|0x8000 },
8699 { WM_MOVE
, sent
|defwinproc
},
8700 { WM_SIZE
, sent
|wparam
|defwinproc
, SIZE_MINIMIZED
},
8703 static const struct message WmShowMinNoActivate
[] = {
8704 { HCBT_MINMAX
, hook
|lparam
, 0, SW_SHOWMINNOACTIVE
},
8705 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
8706 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
8709 static const struct message WmMinMax_1
[] = {
8710 { HCBT_MINMAX
, hook
|lparam
, 0, SW_SHOWMINIMIZED
},
8713 static const struct message WmMinMax_2
[] = {
8714 { HCBT_MINMAX
, hook
|lparam
, 0, SW_SHOWMAXIMIZED
},
8717 static const struct message WmMinMax_3
[] = {
8718 { HCBT_MINMAX
, hook
|lparam
, 0, SW_MINIMIZE
},
8721 static const struct message WmMinMax_4
[] = {
8722 { HCBT_MINMAX
, hook
|lparam
, 0, SW_SHOWMINNOACTIVE
},
8725 static const struct message WmShowMaximized_1
[] = {
8726 { HCBT_MINMAX
, hook
|lparam
, 0, SW_SHOWMAXIMIZED
},
8727 { WM_GETMINMAXINFO
, sent
},
8728 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_FRAMECHANGED
|SWP_NOCOPYBITS
|0x8000 },
8729 { HCBT_ACTIVATE
, hook
|optional
}, /* win2000 doesn't send it */
8730 { WM_WINDOWPOSCHANGING
, sent
|wparam
|optional
, SWP_NOSIZE
|SWP_NOMOVE
}, /* win2000 doesn't send it */
8731 { HCBT_SETFOCUS
, hook
|optional
}, /* win2000 doesn't send it */
8732 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_FRAMECHANGED
|SWP_NOCOPYBITS
|0x8000 },
8733 { WM_MOVE
, sent
|defwinproc
},
8734 { WM_SIZE
, sent
|wparam
|defwinproc
, SIZE_MAXIMIZED
},
8735 { HCBT_SETFOCUS
, hook
|optional
}, /* win2003 sends it */
8738 static const struct message WmShowMaximized_2
[] = {
8739 { HCBT_MINMAX
, hook
|lparam
, 0, SW_SHOWMAXIMIZED
},
8740 { WM_GETMINMAXINFO
, sent
},
8741 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_NOSIZE
|SWP_NOMOVE
},
8742 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
8743 { WM_MOVE
, sent
|optional
}, /* Win9x doesn't send it */
8744 { WM_SIZE
, sent
|wparam
|optional
, SIZE_MAXIMIZED
}, /* Win9x doesn't send it */
8745 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOCOPYBITS
|0x8000 },
8746 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOCOPYBITS
|0x8000 },
8747 { WM_MOVE
, sent
|defwinproc
},
8748 { WM_SIZE
, sent
|wparam
|defwinproc
, SIZE_MAXIMIZED
},
8749 { HCBT_SETFOCUS
, hook
},
8752 static const struct message WmShowMaximized_3
[] = {
8753 { HCBT_MINMAX
, hook
|lparam
, 0, SW_SHOWMAXIMIZED
},
8754 { WM_GETMINMAXINFO
, sent
},
8755 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|0x8000 },
8756 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|0x8000 },
8757 { WM_MOVE
, sent
|defwinproc
},
8758 { WM_SIZE
, sent
|wparam
|defwinproc
, SIZE_MAXIMIZED
},
8762 static void test_ShowWindow(void)
8764 /* ShowWindow commands in random order */
8767 INT cmd
; /* ShowWindow command */
8768 LPARAM ret
; /* ShowWindow return value */
8769 DWORD style
; /* window style after the command */
8770 const struct message
*msg
; /* message sequence the command produces */
8771 BOOL todo_msg
; /* message sequence doesn't match what Wine does */
8774 /* 1 */ { SW_SHOWNORMAL
, FALSE
, WS_VISIBLE
, WmShowNormal
, FALSE
},
8775 /* 2 */ { SW_SHOWNORMAL
, TRUE
, WS_VISIBLE
, WmEmptySeq
, FALSE
},
8776 /* 3 */ { SW_HIDE
, TRUE
, 0, WmHide_1
, FALSE
},
8777 /* 4 */ { SW_HIDE
, FALSE
, 0, WmEmptySeq
, FALSE
},
8778 /* 5 */ { SW_SHOWMINIMIZED
, FALSE
, WS_VISIBLE
|WS_MINIMIZE
, WmShowMinimized_1
, FALSE
},
8779 /* 6 */ { SW_SHOWMINIMIZED
, TRUE
, WS_VISIBLE
|WS_MINIMIZE
, WmMinMax_1
, FALSE
},
8780 /* 7 */ { SW_HIDE
, TRUE
, WS_MINIMIZE
, WmHide_1
, FALSE
},
8781 /* 8 */ { SW_HIDE
, FALSE
, WS_MINIMIZE
, WmEmptySeq
, FALSE
},
8782 /* 9 */ { SW_SHOWMAXIMIZED
, FALSE
, WS_VISIBLE
|WS_MAXIMIZE
, WmShowMaximized_1
, FALSE
},
8783 /* 10 */ { SW_SHOWMAXIMIZED
, TRUE
, WS_VISIBLE
|WS_MAXIMIZE
, WmMinMax_2
, FALSE
},
8784 /* 11 */ { SW_HIDE
, TRUE
, WS_MAXIMIZE
, WmHide_1
, FALSE
},
8785 /* 12 */ { SW_HIDE
, FALSE
, WS_MAXIMIZE
, WmEmptySeq
, FALSE
},
8786 /* 13 */ { SW_SHOWNOACTIVATE
, FALSE
, WS_VISIBLE
, WmShowNoActivate_1
, FALSE
},
8787 /* 14 */ { SW_SHOWNOACTIVATE
, TRUE
, WS_VISIBLE
, WmEmptySeq
, FALSE
},
8788 /* 15 */ { SW_HIDE
, TRUE
, 0, WmHide_2
, FALSE
},
8789 /* 16 */ { SW_HIDE
, FALSE
, 0, WmEmptySeq
, FALSE
},
8790 /* 17 */ { SW_SHOW
, FALSE
, WS_VISIBLE
, WmShow
, FALSE
},
8791 /* 18 */ { SW_SHOW
, TRUE
, WS_VISIBLE
, WmEmptySeq
, FALSE
},
8792 /* 19 */ { SW_MINIMIZE
, TRUE
, WS_VISIBLE
|WS_MINIMIZE
, WmMinimize_1
, TRUE
},
8793 /* 20 */ { SW_MINIMIZE
, TRUE
, WS_VISIBLE
|WS_MINIMIZE
, WmMinMax_3
, FALSE
},
8794 /* 21 */ { SW_HIDE
, TRUE
, WS_MINIMIZE
, WmHide_2
, FALSE
},
8795 /* 22 */ { SW_SHOWMINNOACTIVE
, FALSE
, WS_VISIBLE
|WS_MINIMIZE
, WmShowMinNoActivate
, TRUE
},
8796 /* 23 */ { SW_SHOWMINNOACTIVE
, TRUE
, WS_VISIBLE
|WS_MINIMIZE
, WmMinMax_4
, FALSE
},
8797 /* 24 */ { SW_HIDE
, TRUE
, WS_MINIMIZE
, WmHide_2
, FALSE
},
8798 /* 25 */ { SW_HIDE
, FALSE
, WS_MINIMIZE
, WmEmptySeq
, FALSE
},
8799 /* 26 */ { SW_SHOWNA
, FALSE
, WS_VISIBLE
|WS_MINIMIZE
, WmShowNA_1
, FALSE
},
8800 /* 27 */ { SW_SHOWNA
, TRUE
, WS_VISIBLE
|WS_MINIMIZE
, WmShowNA_2
, FALSE
},
8801 /* 28 */ { SW_HIDE
, TRUE
, WS_MINIMIZE
, WmHide_2
, FALSE
},
8802 /* 29 */ { SW_HIDE
, FALSE
, WS_MINIMIZE
, WmEmptySeq
, FALSE
},
8803 /* 30 */ { SW_RESTORE
, FALSE
, WS_VISIBLE
, WmRestore_1
, FALSE
},
8804 /* 31 */ { SW_RESTORE
, TRUE
, WS_VISIBLE
, WmEmptySeq
, FALSE
},
8805 /* 32 */ { SW_HIDE
, TRUE
, 0, WmHide_3
, TRUE
},
8806 /* 33 */ { SW_HIDE
, FALSE
, 0, WmEmptySeq
, FALSE
},
8807 /* 34 */ { SW_NORMALNA
, FALSE
, 0, WmEmptySeq
, TRUE
}, /* what does this mean?! */
8808 /* 35 */ { SW_NORMALNA
, FALSE
, 0, WmEmptySeq
, TRUE
},
8809 /* 36 */ { SW_HIDE
, FALSE
, 0, WmEmptySeq
, FALSE
},
8810 /* 37 */ { SW_RESTORE
, FALSE
, WS_VISIBLE
, WmRestore_2
, FALSE
},
8811 /* 38 */ { SW_RESTORE
, TRUE
, WS_VISIBLE
, WmEmptySeq
, FALSE
},
8812 /* 39 */ { SW_SHOWNOACTIVATE
, TRUE
, WS_VISIBLE
, WmEmptySeq
, FALSE
},
8813 /* 40 */ { SW_MINIMIZE
, TRUE
, WS_VISIBLE
|WS_MINIMIZE
, WmMinimize_2
, TRUE
},
8814 /* 41 */ { SW_MINIMIZE
, TRUE
, WS_VISIBLE
|WS_MINIMIZE
, WmMinMax_3
, FALSE
},
8815 /* 42 */ { SW_SHOWMAXIMIZED
, TRUE
, WS_VISIBLE
|WS_MAXIMIZE
, WmShowMaximized_2
, TRUE
},
8816 /* 43 */ { SW_SHOWMAXIMIZED
, TRUE
, WS_VISIBLE
|WS_MAXIMIZE
, WmMinMax_2
, FALSE
},
8817 /* 44 */ { SW_MINIMIZE
, TRUE
, WS_VISIBLE
|WS_MINIMIZE
, WmMinimize_1
, TRUE
},
8818 /* 45 */ { SW_MINIMIZE
, TRUE
, WS_VISIBLE
|WS_MINIMIZE
, WmMinMax_3
, FALSE
},
8819 /* 46 */ { SW_RESTORE
, TRUE
, WS_VISIBLE
|WS_MAXIMIZE
, WmRestore_3
, FALSE
},
8820 /* 47 */ { SW_RESTORE
, TRUE
, WS_VISIBLE
, WmRestore_4
, FALSE
},
8821 /* 48 */ { SW_SHOWMAXIMIZED
, TRUE
, WS_VISIBLE
|WS_MAXIMIZE
, WmShowMaximized_3
, FALSE
},
8822 /* 49 */ { SW_SHOW
, TRUE
, WS_VISIBLE
|WS_MAXIMIZE
, WmEmptySeq
, FALSE
},
8823 /* 50 */ { SW_SHOWNORMAL
, TRUE
, WS_VISIBLE
, WmRestore_5
, FALSE
},
8824 /* 51 */ { SW_SHOWNORMAL
, TRUE
, WS_VISIBLE
, WmEmptySeq
, FALSE
},
8825 /* 52 */ { SW_HIDE
, TRUE
, 0, WmHide_1
, FALSE
},
8826 /* 53 */ { SW_HIDE
, FALSE
, 0, WmEmptySeq
, FALSE
},
8827 /* 54 */ { SW_MINIMIZE
, FALSE
, WS_VISIBLE
|WS_MINIMIZE
, WmMinimize_3
, TRUE
},
8828 /* 55 */ { SW_HIDE
, TRUE
, WS_MINIMIZE
, WmHide_2
, FALSE
},
8829 /* 56 */ { SW_SHOWNOACTIVATE
, FALSE
, WS_VISIBLE
, WmShowNoActivate_2
, FALSE
},
8830 /* 57 */ { SW_SHOW
, TRUE
, WS_VISIBLE
, WmEmptySeq
, FALSE
}
8837 #define WS_BASE (WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX|WS_MAXIMIZEBOX|WS_POPUP|WS_CLIPSIBLINGS)
8838 hwnd
= CreateWindowEx(0, "ShowWindowClass", NULL
, WS_BASE
,
8843 style
= GetWindowLong(hwnd
, GWL_STYLE
) & ~WS_BASE
;
8844 ok(style
== 0, "expected style 0, got %08x\n", style
);
8849 for (i
= 0; i
< sizeof(sw
)/sizeof(sw
[0]); i
++)
8851 static const char * const sw_cmd_name
[13] =
8853 "SW_HIDE", "SW_SHOWNORMAL", "SW_SHOWMINIMIZED", "SW_SHOWMAXIMIZED",
8854 "SW_SHOWNOACTIVATE", "SW_SHOW", "SW_MINIMIZE", "SW_SHOWMINNOACTIVE",
8855 "SW_SHOWNA", "SW_RESTORE", "SW_SHOWDEFAULT", "SW_FORCEMINIMIZE",
8856 "SW_NORMALNA" /* 0xCC */
8859 INT idx
; /* index into the above array of names */
8861 idx
= (sw
[i
].cmd
== SW_NORMALNA
) ? 12 : sw
[i
].cmd
;
8863 style
= GetWindowLong(hwnd
, GWL_STYLE
);
8864 trace("%d: sending %s, current window style %08x\n", i
+1, sw_cmd_name
[idx
], style
);
8865 ret
= ShowWindow(hwnd
, sw
[i
].cmd
);
8866 ok(!ret
== !sw
[i
].ret
, "%d: cmd %s: expected ret %lu, got %lu\n", i
+1, sw_cmd_name
[idx
], sw
[i
].ret
, ret
);
8867 style
= GetWindowLong(hwnd
, GWL_STYLE
) & ~WS_BASE
;
8868 ok(style
== sw
[i
].style
, "%d: expected style %08x, got %08x\n", i
+1, sw
[i
].style
, style
);
8870 sprintf(comment
, "%d: ShowWindow(%s)", i
+1, sw_cmd_name
[idx
]);
8871 ok_sequence(sw
[i
].msg
, comment
, sw
[i
].todo_msg
);
8877 DestroyWindow(hwnd
);
8880 static INT_PTR WINAPI
test_dlg_proc(HWND hwnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
8884 trace("dialog: %p, %04x, %08lx, %08lx\n", hwnd
, message
, wParam
, lParam
);
8888 case WM_WINDOWPOSCHANGING
:
8889 case WM_WINDOWPOSCHANGED
:
8891 WINDOWPOS
*winpos
= (WINDOWPOS
*)lParam
;
8893 trace("%s\n", (message
== WM_WINDOWPOSCHANGING
) ? "WM_WINDOWPOSCHANGING" : "WM_WINDOWPOSCHANGED");
8894 trace("%p after %p, x %d, y %d, cx %d, cy %d flags %08x\n",
8895 winpos
->hwnd
, winpos
->hwndInsertAfter
,
8896 winpos
->x
, winpos
->y
, winpos
->cx
, winpos
->cy
, winpos
->flags
);
8897 dump_winpos_flags(winpos
->flags
);
8899 /* Log only documented flags, win2k uses 0x1000 and 0x2000
8900 * in the high word for internal purposes
8902 wParam
= winpos
->flags
& 0xffff;
8903 /* We are not interested in the flags that don't match under XP and Win9x */
8904 wParam
&= ~(SWP_NOZORDER
);
8908 /* explicitly ignore WM_GETICON message */
8913 msg
.message
= message
;
8914 msg
.flags
= sent
|wparam
|lparam
;
8915 msg
.wParam
= wParam
;
8916 msg
.lParam
= lParam
;
8919 /* calling DefDlgProc leads to a recursion under XP */
8930 static const struct message WmDefDlgSetFocus_1
[] = {
8931 { WM_GETDLGCODE
, sent
|wparam
|lparam
, 0, 0 },
8932 { WM_GETTEXTLENGTH
, sent
|wparam
|lparam
|optional
, 0, 0 }, /* XP */
8933 { WM_GETTEXT
, sent
|wparam
|optional
, 6 }, /* XP */
8934 { WM_GETTEXT
, sent
|wparam
|optional
, 12 }, /* XP */
8935 { EM_SETSEL
, sent
|wparam
, 0 }, /* XP sets lparam to text length, Win9x to -2 */
8936 { HCBT_SETFOCUS
, hook
},
8937 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 1 },
8938 { WM_IME_NOTIFY
, sent
|wparam
|defwinproc
|optional
, 2 },
8939 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
8940 { WM_SETFOCUS
, sent
|wparam
, 0 },
8941 { WM_CTLCOLOREDIT
, sent
},
8942 { EVENT_OBJECT_CREATE
, winevent_hook
|wparam
|lparam
, OBJID_CARET
, 0 },
8943 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, OBJID_CARET
, 0 },
8944 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, OBJID_CARET
, 0 },
8945 { WM_COMMAND
, sent
|wparam
, MAKEWPARAM(1, EN_SETFOCUS
) },
8948 static const struct message WmDefDlgSetFocus_2
[] = {
8949 { WM_GETDLGCODE
, sent
|wparam
|lparam
, 0, 0 },
8950 { WM_GETTEXTLENGTH
, sent
|wparam
|lparam
|optional
, 0, 0 }, /* XP */
8951 { WM_GETTEXT
, sent
|wparam
|optional
, 6 }, /* XP */
8952 { WM_GETTEXT
, sent
|wparam
|optional
, 12 }, /* XP */
8953 { EM_SETSEL
, sent
|wparam
, 0 }, /* XP sets lparam to text length, Win9x to -2 */
8954 { WM_CTLCOLOREDIT
, sent
|optional
}, /* XP */
8957 /* Creation of a dialog */
8958 static const struct message WmCreateDialogParamSeq_1
[] = {
8959 { HCBT_CREATEWND
, hook
},
8960 { WM_NCCREATE
, sent
},
8961 { WM_NCCALCSIZE
, sent
|wparam
, 0 },
8962 { WM_CREATE
, sent
},
8963 { EVENT_OBJECT_CREATE
, winevent_hook
|wparam
|lparam
, 0, 0 },
8964 { WM_SIZE
, sent
|wparam
, SIZE_RESTORED
},
8966 { WM_SETFONT
, sent
},
8967 { WM_INITDIALOG
, sent
},
8968 { WM_CHANGEUISTATE
, sent
|optional
},
8971 /* Creation of a dialog */
8972 static const struct message WmCreateDialogParamSeq_2
[] = {
8973 { HCBT_CREATEWND
, hook
},
8974 { WM_NCCREATE
, sent
},
8975 { WM_NCCALCSIZE
, sent
|wparam
, 0 },
8976 { WM_CREATE
, sent
},
8977 { EVENT_OBJECT_CREATE
, winevent_hook
|wparam
|lparam
, 0, 0 },
8978 { WM_SIZE
, sent
|wparam
, SIZE_RESTORED
},
8980 { WM_CHANGEUISTATE
, sent
|optional
},
8984 static void test_dialog_messages(void)
8987 HWND hdlg
, hedit1
, hedit2
, hfocus
;
8990 #define set_selection(hctl, start, end) \
8991 ret = SendMessage(hctl, EM_SETSEL, start, end); \
8992 ok(ret == 1, "EM_SETSEL returned %ld\n", ret);
8994 #define check_selection(hctl, start, end) \
8995 ret = SendMessage(hctl, EM_GETSEL, 0, 0); \
8996 ok(ret == MAKELRESULT(start, end), "wrong selection (%d - %d)\n", LOWORD(ret), HIWORD(ret));
9000 hdlg
= CreateWindowEx(WS_EX_DLGMODALFRAME
, "TestDialogClass", NULL
,
9001 WS_VISIBLE
|WS_CAPTION
|WS_SYSMENU
|WS_DLGFRAME
,
9002 0, 0, 100, 100, 0, 0, 0, NULL
);
9003 ok(hdlg
!= 0, "Failed to create custom dialog window\n");
9005 hedit1
= CreateWindowEx(0, "my_edit_class", NULL
,
9006 WS_CHILD
|WS_BORDER
|WS_VISIBLE
|WS_TABSTOP
,
9007 0, 0, 80, 20, hdlg
, (HMENU
)1, 0, NULL
);
9008 ok(hedit1
!= 0, "Failed to create edit control\n");
9009 hedit2
= CreateWindowEx(0, "my_edit_class", NULL
,
9010 WS_CHILD
|WS_BORDER
|WS_VISIBLE
|WS_TABSTOP
,
9011 0, 40, 80, 20, hdlg
, (HMENU
)2, 0, NULL
);
9012 ok(hedit2
!= 0, "Failed to create edit control\n");
9014 SendMessage(hedit1
, WM_SETTEXT
, 0, (LPARAM
)"hello");
9015 SendMessage(hedit2
, WM_SETTEXT
, 0, (LPARAM
)"bye");
9017 hfocus
= GetFocus();
9018 ok(hfocus
== hdlg
, "wrong focus %p\n", hfocus
);
9021 hfocus
= GetFocus();
9022 ok(hfocus
== hedit2
, "wrong focus %p\n", hfocus
);
9024 check_selection(hedit1
, 0, 0);
9025 check_selection(hedit2
, 0, 0);
9027 set_selection(hedit2
, 0, -1);
9028 check_selection(hedit2
, 0, 3);
9031 hfocus
= GetFocus();
9032 ok(hfocus
== 0, "wrong focus %p\n", hfocus
);
9035 ret
= DefDlgProc(hdlg
, WM_SETFOCUS
, 0, 0);
9036 ok(ret
== 0, "WM_SETFOCUS returned %ld\n", ret
);
9037 ok_sequence(WmDefDlgSetFocus_1
, "DefDlgProc(WM_SETFOCUS) 1", FALSE
);
9039 hfocus
= GetFocus();
9040 ok(hfocus
== hedit1
, "wrong focus %p\n", hfocus
);
9042 check_selection(hedit1
, 0, 5);
9043 check_selection(hedit2
, 0, 3);
9046 ret
= DefDlgProc(hdlg
, WM_SETFOCUS
, 0, 0);
9047 ok(ret
== 0, "WM_SETFOCUS returned %ld\n", ret
);
9048 ok_sequence(WmDefDlgSetFocus_2
, "DefDlgProc(WM_SETFOCUS) 2", FALSE
);
9050 hfocus
= GetFocus();
9051 ok(hfocus
== hedit1
, "wrong focus %p\n", hfocus
);
9053 check_selection(hedit1
, 0, 5);
9054 check_selection(hedit2
, 0, 3);
9059 #undef set_selection
9060 #undef check_selection
9062 ok(GetClassInfo(0, "#32770", &cls
), "GetClassInfo failed\n");
9063 cls
.lpszClassName
= "MyDialogClass";
9064 cls
.hInstance
= GetModuleHandle(0);
9065 /* need a cast since a dlgproc is used as a wndproc */
9066 cls
.lpfnWndProc
= (WNDPROC
)test_dlg_proc
;
9067 if (!RegisterClass(&cls
)) assert(0);
9069 hdlg
= CreateDialogParam(0, "CLASS_TEST_DIALOG_2", 0, test_dlg_proc
, 0);
9070 ok(IsWindow(hdlg
), "CreateDialogParam failed\n");
9071 ok_sequence(WmCreateDialogParamSeq_1
, "CreateDialogParam_1", FALSE
);
9075 hdlg
= CreateDialogParam(0, "CLASS_TEST_DIALOG_2", 0, NULL
, 0);
9076 ok(IsWindow(hdlg
), "CreateDialogParam failed\n");
9077 ok_sequence(WmCreateDialogParamSeq_2
, "CreateDialogParam_2", FALSE
);
9081 UnregisterClass(cls
.lpszClassName
, cls
.hInstance
);
9084 static void test_nullCallback(void)
9089 hwnd
= CreateWindowExA(0, "TestWindowClass", "Test overlapped", WS_OVERLAPPEDWINDOW
,
9090 100, 100, 200, 200, 0, 0, 0, NULL
);
9091 ok (hwnd
!= 0, "Failed to create overlapped window\n");
9093 SendMessageCallbackA(hwnd
,WM_NULL
,0,0,NULL
,0);
9094 while (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
9095 DestroyWindow(hwnd
);
9101 HMODULE user32
= GetModuleHandleA("user32.dll");
9102 FARPROC pSetWinEventHook
= GetProcAddress(user32
, "SetWinEventHook");
9103 FARPROC pUnhookWinEvent
= GetProcAddress(user32
, "UnhookWinEvent");
9104 FARPROC pIsWinEventHookInstalled
= 0;/*GetProcAddress(user32, "IsWinEventHookInstalled");*/
9105 pGetAncestor
= (void*) GetProcAddress(user32
, "GetAncestor");
9107 if (!RegisterWindowClasses()) assert(0);
9109 if (pSetWinEventHook
)
9111 hEvent_hook
= (HWINEVENTHOOK
)pSetWinEventHook(EVENT_MIN
, EVENT_MAX
,
9112 GetModuleHandleA(0),
9115 GetCurrentThreadId(),
9116 WINEVENT_INCONTEXT
);
9117 assert(hEvent_hook
);
9119 if (pIsWinEventHookInstalled
)
9122 for (event
= EVENT_MIN
; event
<= EVENT_MAX
; event
++)
9123 ok(pIsWinEventHookInstalled(event
), "IsWinEventHookInstalled(%u) failed\n", event
);
9127 cbt_hook_thread_id
= GetCurrentThreadId();
9128 hCBT_hook
= SetWindowsHookExA(WH_CBT
, cbt_hook_proc
, 0, GetCurrentThreadId());
9133 /* Fix message sequences before removing 4 lines below */
9135 if (pUnhookWinEvent
&& hEvent_hook
)
9137 ret
= pUnhookWinEvent(hEvent_hook
);
9138 ok( ret
, "UnhookWinEvent error %d\n", GetLastError());
9139 pUnhookWinEvent
= 0;
9146 test_scrollwindowex();
9149 invisible_parent_tests();
9150 test_mdi_messages();
9151 test_button_messages();
9152 test_static_messages();
9153 test_paint_messages();
9154 test_interthread_messages();
9155 test_message_conversion();
9156 test_accelerators();
9159 test_DestroyWindow();
9160 test_DispatchMessage();
9161 test_SendMessageTimeout();
9162 test_edit_messages();
9163 test_quit_message();
9164 test_TrackMouseEvent();
9165 test_SetWindowRgn();
9167 test_dialog_messages();
9168 test_nullCallback();
9170 UnhookWindowsHookEx(hCBT_hook
);
9171 if (pUnhookWinEvent
)
9173 ret
= pUnhookWinEvent(hEvent_hook
);
9174 ok( ret
, "UnhookWinEvent error %d\n", GetLastError());
9175 SetLastError(0xdeadbeef);
9176 ok(!pUnhookWinEvent(hEvent_hook
), "UnhookWinEvent succeeded\n");
9177 ok(GetLastError() == ERROR_INVALID_HANDLE
|| /* Win2k */
9178 GetLastError() == 0xdeadbeef, /* Win9x */
9179 "unexpected error %d\n", GetLastError());