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
43 #define SW_NORMALNA 0xCC /* undoc. flag in MinMaximize */
46 #define WM_SYSTIMER 0x0118
49 #define WND_PARENT_ID 1
50 #define WND_POPUP_ID 2
51 #define WND_CHILD_ID 3
53 static BOOL test_DestroyWindow_flag
;
54 static HWINEVENTHOOK hEvent_hook
;
56 static HWND (WINAPI
*pGetAncestor
)(HWND
,UINT
);
58 static void dump_winpos_flags(UINT flags
);
61 FIXME: add tests for these
62 Window Edge Styles (Win31/Win95/98 look), in order of precedence:
63 WS_EX_DLGMODALFRAME: double border, WS_CAPTION allowed
64 WS_THICKFRAME: thick border
65 WS_DLGFRAME: double border, WS_CAPTION not allowed (but possibly shown anyway)
66 WS_BORDER (default for overlapped windows): single black border
67 none (default for child (and popup?) windows): no border
84 UINT message
; /* the WM_* code */
85 msg_flags_t flags
; /* message props */
86 WPARAM wParam
; /* expected value of wParam */
87 LPARAM lParam
; /* expected value of lParam */
90 /* Empty message sequence */
91 static const struct message WmEmptySeq
[] =
95 /* CreateWindow (for overlapped window, not initially visible) (16/32) */
96 static const struct message WmCreateOverlappedSeq
[] = {
97 { HCBT_CREATEWND
, hook
},
98 { WM_GETMINMAXINFO
, sent
},
99 { WM_NCCREATE
, sent
},
100 { WM_NCCALCSIZE
, sent
|wparam
, 0 },
101 { EVENT_OBJECT_REORDER
, winevent_hook
|wparam
|lparam
, 0, 0 },
103 { EVENT_OBJECT_CREATE
, winevent_hook
|wparam
|lparam
, 0, 0 },
106 /* SetWindowPos(SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE)
107 * for a not visible overlapped window.
109 static const struct message WmSWP_ShowOverlappedSeq
[] = {
110 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
},
111 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, 0, 0 },
112 { WM_NCPAINT
, sent
|wparam
|optional
, 1 },
113 { WM_GETTEXT
, sent
|defwinproc
|optional
},
114 { WM_ERASEBKGND
, sent
|optional
},
115 { HCBT_ACTIVATE
, hook
},
116 { EVENT_SYSTEM_FOREGROUND
, winevent_hook
|wparam
|lparam
, 0, 0 },
117 { WM_QUERYNEWPALETTE
, sent
|wparam
|lparam
|optional
, 0, 0 },
118 { WM_WINDOWPOSCHANGING
, sent
|wparam
|optional
, SWP_NOSIZE
|SWP_NOMOVE
}, /* Win9x: SWP_NOSENDCHANGING */
119 { WM_ACTIVATEAPP
, sent
|wparam
, 1 },
120 { WM_NCACTIVATE
, sent
|wparam
, 1 },
121 { WM_GETTEXT
, sent
|defwinproc
|optional
},
122 { WM_ACTIVATE
, sent
|wparam
, 1 },
123 { HCBT_SETFOCUS
, hook
},
124 { WM_IME_SETCONTEXT
, sent
|wparam
|defwinproc
|optional
, 1 },
125 { WM_IME_NOTIFY
, sent
|wparam
|defwinproc
|optional
, 2 },
126 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
127 { WM_SETFOCUS
, sent
|wparam
|defwinproc
, 0 },
128 { WM_NCPAINT
, sent
|wparam
|optional
, 1 },
129 { WM_GETTEXT
, sent
|defwinproc
|optional
},
130 { WM_ERASEBKGND
, sent
|optional
},
131 /* Win9x adds SWP_NOZORDER below */
132 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
133 { WM_NCCALCSIZE
, sent
|wparam
|optional
, 1 },
134 { WM_NCPAINT
, sent
|wparam
|optional
, 1 },
135 { WM_ERASEBKGND
, sent
|optional
},
136 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
139 /* SetWindowPos(SWP_HIDEWINDOW|SWP_NOSIZE|SWP_NOMOVE)
140 * for a visible overlapped window.
142 static const struct message WmSWP_HideOverlappedSeq
[] = {
143 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_HIDEWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
},
144 { EVENT_OBJECT_HIDE
, winevent_hook
|wparam
|lparam
, 0, 0 },
145 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_HIDEWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
149 /* SetWindowPos(SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOMOVE)
150 * for a visible overlapped window.
152 static const struct message WmSWP_ResizeSeq
[] = {
153 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_NOACTIVATE
|SWP_NOMOVE
},
154 { WM_GETMINMAXINFO
, sent
|defwinproc
},
155 { WM_NCCALCSIZE
, sent
|wparam
, TRUE
},
156 { WM_NCPAINT
, sent
|optional
},
157 { WM_GETTEXT
, sent
|defwinproc
|optional
},
158 { WM_ERASEBKGND
, sent
|optional
},
159 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_NOACTIVATE
|SWP_NOMOVE
|SWP_NOCLIENTMOVE
},
160 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_RESTORED
},
161 { WM_NCCALCSIZE
, sent
|wparam
|optional
, TRUE
},
162 { WM_NCPAINT
, sent
|optional
},
163 { WM_GETTEXT
, sent
|defwinproc
|optional
},
164 { WM_ERASEBKGND
, sent
|optional
},
165 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
166 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
|optional
, 0, 0 }, /* XP sends a duplicate */
170 /* SetWindowPos(SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOMOVE)
171 * for a visible popup window.
173 static const struct message WmSWP_ResizePopupSeq
[] = {
174 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_NOACTIVATE
|SWP_NOMOVE
},
175 { WM_GETMINMAXINFO
, sent
|defwinproc
|optional
}, /* Win9x */
176 { WM_NCCALCSIZE
, sent
|wparam
, TRUE
},
177 { WM_NCPAINT
, sent
|optional
},
178 { WM_GETTEXT
, sent
|defwinproc
|optional
},
179 { WM_ERASEBKGND
, sent
|optional
},
180 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_NOACTIVATE
|SWP_NOMOVE
|SWP_NOCLIENTMOVE
},
181 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_RESTORED
},
182 { WM_NCCALCSIZE
, sent
|wparam
|optional
, TRUE
},
183 { WM_NCPAINT
, sent
|optional
},
184 { WM_GETTEXT
, sent
|defwinproc
|optional
},
185 { WM_ERASEBKGND
, sent
|optional
},
186 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
190 /* SetWindowPos(SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOSIZE)
191 * for a visible overlapped window.
193 static const struct message WmSWP_MoveSeq
[] = {
194 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_NOACTIVATE
|SWP_NOSIZE
},
195 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOCLIENTSIZE
},
196 { WM_MOVE
, sent
|defwinproc
|wparam
, 0 },
197 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
200 /* Resize with SetWindowPos(SWP_NOZORDER)
201 * for a visible overlapped window
202 * SWP_NOZORDER is stripped by the logging code
204 static const struct message WmSWP_ResizeNoZOrder
[] = {
205 { WM_WINDOWPOSCHANGING
, sent
|wparam
, 0/*SWP_NOZORDER*/ },
206 { WM_GETMINMAXINFO
, sent
|defwinproc
},
207 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
208 { WM_NCPAINT
, sent
},
209 { WM_GETTEXT
, sent
|defwinproc
|optional
},
210 { WM_ERASEBKGND
, sent
|optional
}, /* FIXME: remove optional once Wine is fixed */
211 { WM_WINDOWPOSCHANGED
, sent
|wparam
, /*SWP_NOZORDER|*/SWP_NOMOVE
|SWP_NOCLIENTMOVE
},
212 { WM_SIZE
, sent
|defwinproc
|wparam
, 0 },
213 { WM_NCCALCSIZE
, sent
|wparam
|optional
, 1 }, /* Win9x doesn't send it */
214 { WM_NCPAINT
, sent
|optional
}, /* Win9x doesn't send it */
215 { WM_GETTEXT
, sent
|defwinproc
|optional
}, /* Win9x doesn't send it */
216 { WM_ERASEBKGND
, sent
|optional
}, /* Win9x doesn't send it */
220 /* SetWindowPos(SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE|
221 SWP_NOZORDER|SWP_FRAMECHANGED)
222 * for a visible overlapped window with WS_CLIPCHILDREN style set.
224 static const struct message WmSWP_FrameChanged_clip
[] = {
225 { WM_WINDOWPOSCHANGING
, sent
|wparam
|parent
, SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOACTIVATE
|SWP_FRAMECHANGED
},
226 { WM_NCCALCSIZE
, sent
|wparam
|parent
, 1 },
227 { WM_NCPAINT
, sent
|parent
}, /* wparam != 1 */
228 { WM_GETTEXT
, sent
|parent
|defwinproc
|optional
},
229 { WM_ERASEBKGND
, sent
|parent
|optional
}, /* FIXME: remove optional once Wine is fixed */
230 { WM_NCPAINT
, sent
}, /* wparam != 1 */
231 { WM_ERASEBKGND
, sent
},
232 { WM_WINDOWPOSCHANGED
, sent
|wparam
|parent
, SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOACTIVATE
|SWP_FRAMECHANGED
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
233 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
237 /* SetWindowPos(SWP_NOSIZE|SWP_NOMOVE|SWP_DEFERERASE|SWP_NOACTIVATE|
238 SWP_NOZORDER|SWP_FRAMECHANGED)
239 * for a visible overlapped window.
241 static const struct message WmSWP_FrameChangedDeferErase
[] = {
242 { WM_WINDOWPOSCHANGING
, sent
|wparam
|parent
, SWP_NOSIZE
|SWP_NOMOVE
|SWP_DEFERERASE
|SWP_NOACTIVATE
|SWP_FRAMECHANGED
},
243 { WM_NCCALCSIZE
, sent
|wparam
|parent
, 1 },
244 { WM_WINDOWPOSCHANGED
, sent
|wparam
|parent
, SWP_NOSIZE
|SWP_NOMOVE
|SWP_DEFERERASE
|SWP_NOACTIVATE
|SWP_FRAMECHANGED
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
245 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
246 { WM_PAINT
, sent
|parent
},
247 { WM_NCPAINT
, sent
|beginpaint
|parent
}, /* wparam != 1 */
248 { WM_GETTEXT
, sent
|beginpaint
|parent
|defwinproc
|optional
},
250 { WM_NCPAINT
, sent
|beginpaint
}, /* wparam != 1 */
251 { WM_ERASEBKGND
, sent
|beginpaint
},
255 /* SetWindowPos(SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE|
256 SWP_NOZORDER|SWP_FRAMECHANGED)
257 * for a visible overlapped window without WS_CLIPCHILDREN style set.
259 static const struct message WmSWP_FrameChanged_noclip
[] = {
260 { WM_WINDOWPOSCHANGING
, sent
|wparam
|parent
, SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOACTIVATE
|SWP_FRAMECHANGED
},
261 { WM_NCCALCSIZE
, sent
|wparam
|parent
, 1 },
262 { WM_NCPAINT
, sent
|parent
}, /* wparam != 1 */
263 { WM_GETTEXT
, sent
|parent
|defwinproc
|optional
},
264 { WM_ERASEBKGND
, sent
|parent
|optional
}, /* FIXME: remove optional once Wine is fixed */
265 { WM_WINDOWPOSCHANGED
, sent
|wparam
|parent
, SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOACTIVATE
|SWP_FRAMECHANGED
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
266 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
268 { WM_NCPAINT
, sent
|beginpaint
}, /* wparam != 1 */
269 { WM_ERASEBKGND
, sent
|beginpaint
},
273 /* ShowWindow(SW_SHOW) for a not visible overlapped window */
274 static const struct message WmShowOverlappedSeq
[] = {
275 { WM_SHOWWINDOW
, sent
|wparam
, 1 },
276 { WM_NCPAINT
, sent
|wparam
|optional
, 1 },
277 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
},
278 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, 0, 0 },
279 { WM_NCPAINT
, sent
|wparam
|optional
, 1 },
280 { WM_GETTEXT
, sent
|defwinproc
|optional
},
281 { WM_ERASEBKGND
, sent
|optional
},
282 { HCBT_ACTIVATE
, hook
},
283 { EVENT_SYSTEM_FOREGROUND
, winevent_hook
|wparam
|lparam
, 0, 0 },
284 { WM_QUERYNEWPALETTE
, sent
|wparam
|lparam
|optional
, 0, 0 },
285 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_NOSIZE
|SWP_NOMOVE
},
286 { WM_NCPAINT
, sent
|wparam
|optional
, 1 },
287 { WM_ACTIVATEAPP
, sent
|wparam
, 1 },
288 { WM_NCACTIVATE
, sent
|wparam
, 1 },
289 { WM_GETTEXT
, sent
|defwinproc
|optional
},
290 { WM_ACTIVATE
, sent
|wparam
, 1 },
291 { HCBT_SETFOCUS
, hook
},
292 { WM_IME_SETCONTEXT
, sent
|wparam
|defwinproc
|optional
, 1 },
293 { WM_IME_NOTIFY
, sent
|wparam
|defwinproc
|optional
, 2 },
294 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
295 { WM_SETFOCUS
, sent
|wparam
|defwinproc
, 0 },
296 { WM_NCPAINT
, sent
|wparam
|optional
, 1 },
297 { WM_GETTEXT
, sent
|defwinproc
|optional
},
298 { WM_ERASEBKGND
, sent
|optional
},
299 /* Win9x adds SWP_NOZORDER below */
300 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
301 { WM_NCCALCSIZE
, sent
|optional
},
302 { WM_NCPAINT
, sent
|optional
},
303 { WM_ERASEBKGND
, sent
|optional
},
304 #if 0 /* CreateWindow/ShowWindow(SW_SHOW) also generates WM_SIZE/WM_MOVE
305 * messages. Does that mean that CreateWindow doesn't set initial
306 * window dimensions for overlapped windows?
313 /* ShowWindow(SW_SHOWMAXIMIZED) for a not visible overlapped window */
314 static const struct message WmShowMaxOverlappedSeq
[] = {
315 { HCBT_MINMAX
, hook
|lparam
, 0, SW_MAXIMIZE
},
316 { WM_GETMINMAXINFO
, sent
},
317 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_FRAMECHANGED
|0x8000 },
318 { WM_GETMINMAXINFO
, sent
|defwinproc
},
319 { WM_NCCALCSIZE
, sent
|wparam
, TRUE
},
320 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, 0, 0 },
321 { HCBT_ACTIVATE
, hook
},
322 { EVENT_SYSTEM_FOREGROUND
, winevent_hook
|wparam
|lparam
, 0, 0 },
323 { WM_QUERYNEWPALETTE
, sent
|wparam
|lparam
|optional
, 0, 0 },
324 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_NOSIZE
|SWP_NOMOVE
},
325 { WM_ACTIVATEAPP
, sent
|wparam
, 1 },
326 { WM_NCACTIVATE
, sent
|wparam
, 1 },
327 { WM_GETTEXT
, sent
|defwinproc
|optional
},
328 { WM_ACTIVATE
, sent
|wparam
, 1 },
329 { HCBT_SETFOCUS
, hook
},
330 { WM_IME_SETCONTEXT
, sent
|wparam
|defwinproc
|optional
, 1 },
331 { WM_IME_NOTIFY
, sent
|wparam
|defwinproc
|optional
, 2 },
332 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
333 { WM_SETFOCUS
, sent
|wparam
|defwinproc
, 0 },
334 { WM_NCPAINT
, sent
|wparam
|optional
, 1 },
335 { WM_GETTEXT
, sent
|defwinproc
|optional
},
336 { WM_ERASEBKGND
, sent
|optional
},
337 /* Win9x adds SWP_NOZORDER below */
338 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_FRAMECHANGED
|0x8000 },
339 { WM_MOVE
, sent
|defwinproc
},
340 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_MAXIMIZED
},
341 { WM_NCCALCSIZE
, sent
|optional
},
342 { WM_NCPAINT
, sent
|optional
},
343 { WM_ERASEBKGND
, sent
|optional
},
344 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
345 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
348 /* ShowWindow(SW_SHOWMINIMIZED) for a not visible overlapped window */
349 static const struct message WmShowMinOverlappedSeq
[] = {
350 { HCBT_MINMAX
, hook
|lparam
, 0, SW_MINIMIZE
},
351 { HCBT_SETFOCUS
, hook
},
352 { WM_KILLFOCUS
, sent
},
353 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 0 },
354 { WM_IME_NOTIFY
, sent
|wparam
|optional
|defwinproc
, 1 },
355 { WM_GETTEXT
, sent
|optional
},
356 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_NOCOPYBITS
|SWP_SHOWWINDOW
|SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_STATECHANGED
},
357 { WM_GETMINMAXINFO
, sent
|defwinproc
},
358 { WM_NCCALCSIZE
, sent
|wparam
, TRUE
},
359 { WM_NCPAINT
, sent
},
360 { WM_GETTEXT
, sent
|defwinproc
|optional
},
361 { WM_WINDOWPOSCHANGED
, sent
},
362 { WM_MOVE
, sent
|defwinproc
},
363 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_MINIMIZED
},
364 { WM_NCCALCSIZE
, sent
|optional
},
365 { WM_NCACTIVATE
, sent
|wparam
, 0 },
366 { WM_GETTEXT
, sent
|defwinproc
|optional
},
367 { WM_ACTIVATE
, sent
},
368 { WM_ACTIVATEAPP
, sent
|wparam
, 0 },
371 /* ShowWindow(SW_HIDE) for a visible overlapped window */
372 static const struct message WmHideOverlappedSeq
[] = {
373 { WM_SHOWWINDOW
, sent
|wparam
, 0 },
374 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_HIDEWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
},
375 { EVENT_OBJECT_HIDE
, winevent_hook
|wparam
|lparam
, 0, 0 },
376 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_HIDEWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
377 { WM_SIZE
, sent
|optional
}, /* XP doesn't send it */
378 { WM_MOVE
, sent
|optional
}, /* XP doesn't send it */
379 { WM_NCACTIVATE
, sent
|wparam
, 0 },
380 { WM_ACTIVATE
, sent
|wparam
, 0 },
381 { WM_ACTIVATEAPP
, sent
|wparam
, 0 },
382 { WM_KILLFOCUS
, sent
|wparam
, 0 },
383 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 0 },
384 { WM_IME_NOTIFY
, sent
|wparam
|optional
|defwinproc
, 1 },
387 /* DestroyWindow for a visible overlapped window */
388 static const struct message WmDestroyOverlappedSeq
[] = {
389 { HCBT_DESTROYWND
, hook
},
390 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_HIDEWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
391 { EVENT_OBJECT_HIDE
, winevent_hook
|wparam
|lparam
, 0, 0 },
392 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_HIDEWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
393 { WM_NCACTIVATE
, sent
|wparam
, 0 },
394 { WM_ACTIVATE
, sent
|wparam
, 0 },
395 { WM_ACTIVATEAPP
, sent
|wparam
, 0 },
396 { WM_KILLFOCUS
, sent
|wparam
, 0 },
397 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 0 },
398 { WM_IME_NOTIFY
, sent
|wparam
|optional
|defwinproc
, 1 },
399 { EVENT_OBJECT_DESTROY
, winevent_hook
|wparam
|lparam
, 0, 0 },
400 { WM_DESTROY
, sent
},
401 { WM_NCDESTROY
, sent
},
404 /* CreateWindow(WS_MAXIMIZE|WS_VISIBLE) for popup window */
405 static const struct message WmCreateMaxPopupSeq
[] = {
406 { HCBT_CREATEWND
, hook
},
407 { WM_NCCREATE
, sent
},
408 { WM_NCCALCSIZE
, sent
|wparam
, 0 },
410 { WM_SIZE
, sent
|wparam
, SIZE_RESTORED
},
412 { HCBT_MINMAX
, hook
|lparam
, 0, SW_MAXIMIZE
},
413 { WM_GETMINMAXINFO
, sent
},
414 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_NOACTIVATE
|SWP_FRAMECHANGED
|0x8000 },
415 { WM_NCCALCSIZE
, sent
|wparam
, TRUE
},
416 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_NOACTIVATE
|SWP_FRAMECHANGED
|SWP_NOREDRAW
|0x8000 },
417 { WM_MOVE
, sent
|defwinproc
},
418 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_MAXIMIZED
},
419 { WM_SHOWWINDOW
, sent
|wparam
, 1 },
420 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
},
421 { HCBT_ACTIVATE
, hook
},
422 { WM_QUERYNEWPALETTE
, sent
|wparam
|lparam
|optional
, 0, 0 },
423 { WM_WINDOWPOSCHANGING
, sent
|wparam
|optional
, SWP_NOSIZE
|SWP_NOMOVE
},
424 { WM_ACTIVATEAPP
, sent
|wparam
, 1 },
425 { WM_NCACTIVATE
, sent
|wparam
, 1 },
426 { WM_ACTIVATE
, sent
|wparam
, 1 },
427 { HCBT_SETFOCUS
, hook
},
428 { WM_IME_SETCONTEXT
, sent
|wparam
|defwinproc
|optional
, 1 },
429 { WM_IME_NOTIFY
, sent
|wparam
|defwinproc
|optional
, 2 },
430 { WM_SETFOCUS
, sent
|wparam
|defwinproc
, 0 },
431 { WM_SYNCPAINT
, sent
|wparam
|optional
, 4 },
432 { WM_NCPAINT
, sent
|wparam
|optional
, 1 },
433 { WM_ERASEBKGND
, sent
|optional
},
434 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_NOCLIENTMOVE
|SWP_NOCLIENTSIZE
|SWP_SHOWWINDOW
|SWP_NOMOVE
|SWP_NOSIZE
},
437 /* CreateWindow(WS_MAXIMIZE) for popup window, not initially visible */
438 static const struct message WmCreateInvisibleMaxPopupSeq
[] = {
439 { HCBT_CREATEWND
, hook
},
440 { WM_NCCREATE
, sent
},
441 { WM_NCCALCSIZE
, sent
|wparam
, 0 },
443 { WM_SIZE
, sent
|wparam
, SIZE_RESTORED
},
445 { HCBT_MINMAX
, hook
|lparam
, 0, SW_MAXIMIZE
},
446 { WM_GETMINMAXINFO
, sent
},
447 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_NOACTIVATE
|SWP_FRAMECHANGED
|0x8000 },
448 { WM_NCCALCSIZE
, sent
|wparam
, TRUE
},
449 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_NOACTIVATE
|SWP_FRAMECHANGED
|SWP_NOREDRAW
|0x8000 },
450 { WM_MOVE
, sent
|defwinproc
},
451 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_MAXIMIZED
},
454 /* ShowWindow(SW_SHOWMAXIMIZED) for a resized not visible popup window */
455 static const struct message WmShowMaxPopupResizedSeq
[] = {
456 { HCBT_MINMAX
, hook
|lparam
, 0, SW_MAXIMIZE
},
457 { WM_GETMINMAXINFO
, sent
},
458 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_FRAMECHANGED
},
459 { WM_NCCALCSIZE
, sent
|wparam
, TRUE
},
460 { HCBT_ACTIVATE
, hook
},
461 { WM_QUERYNEWPALETTE
, sent
|wparam
|lparam
|optional
, 0, 0 },
462 { WM_WINDOWPOSCHANGING
, sent
|wparam
|optional
, SWP_NOSIZE
|SWP_NOMOVE
},
463 { WM_ACTIVATEAPP
, sent
|wparam
, 1 },
464 { WM_NCACTIVATE
, sent
|wparam
, 1 },
465 { WM_ACTIVATE
, sent
|wparam
, 1 },
466 { HCBT_SETFOCUS
, hook
},
467 { WM_IME_SETCONTEXT
, sent
|wparam
|defwinproc
|optional
, 1 },
468 { WM_IME_NOTIFY
, sent
|wparam
|defwinproc
|optional
, 2 },
469 { WM_SETFOCUS
, sent
|wparam
|defwinproc
, 0 },
470 { WM_NCPAINT
, sent
|wparam
|optional
, 1 },
471 { WM_ERASEBKGND
, sent
|optional
},
472 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_NOCLIENTMOVE
|SWP_SHOWWINDOW
|SWP_FRAMECHANGED
|SWP_NOMOVE
},
473 /* WinNT4.0 sends WM_MOVE */
474 { WM_MOVE
, sent
|defwinproc
|optional
},
475 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_MAXIMIZED
},
478 /* ShowWindow(SW_SHOWMAXIMIZED) for a not visible popup window */
479 static const struct message WmShowMaxPopupSeq
[] = {
480 { HCBT_MINMAX
, hook
|lparam
, 0, SW_MAXIMIZE
},
481 { WM_GETMINMAXINFO
, sent
},
482 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_FRAMECHANGED
},
483 { WM_NCCALCSIZE
, sent
|wparam
, TRUE
},
484 { HCBT_ACTIVATE
, hook
},
485 { WM_QUERYNEWPALETTE
, sent
|wparam
|lparam
|optional
, 0, 0 },
486 { WM_WINDOWPOSCHANGING
, sent
|wparam
|optional
, SWP_NOSIZE
|SWP_NOMOVE
},
487 { WM_ACTIVATEAPP
, sent
|wparam
, 1 },
488 { WM_NCACTIVATE
, sent
|wparam
, 1 },
489 { WM_ACTIVATE
, sent
|wparam
, 1 },
490 { HCBT_SETFOCUS
, hook
},
491 { WM_IME_SETCONTEXT
, sent
|wparam
|defwinproc
|optional
, 1 },
492 { WM_IME_NOTIFY
, sent
|wparam
|defwinproc
|optional
, 2 },
493 { WM_SETFOCUS
, sent
|wparam
|defwinproc
, 0 },
494 { WM_SYNCPAINT
, sent
|wparam
|optional
, 4 },
495 { WM_NCPAINT
, sent
|wparam
|optional
, 1 },
496 { WM_ERASEBKGND
, sent
|optional
},
497 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
|SWP_SHOWWINDOW
|SWP_FRAMECHANGED
|SWP_NOMOVE
|SWP_NOSIZE
},
500 /* CreateWindow(WS_VISIBLE) for popup window */
501 static const struct message WmCreatePopupSeq
[] = {
502 { HCBT_CREATEWND
, hook
},
503 { WM_NCCREATE
, sent
},
504 { WM_NCCALCSIZE
, sent
|wparam
, 0 },
506 { WM_SIZE
, sent
|wparam
, SIZE_RESTORED
},
508 { WM_SHOWWINDOW
, sent
|wparam
, 1 },
509 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
},
510 { HCBT_ACTIVATE
, hook
},
511 { WM_QUERYNEWPALETTE
, sent
|wparam
|lparam
|optional
, 0, 0 },
512 { WM_WINDOWPOSCHANGING
, sent
|wparam
|optional
, SWP_NOSIZE
|SWP_NOMOVE
},
513 { WM_NCPAINT
, sent
|wparam
|optional
, 1 },
514 { WM_ERASEBKGND
, sent
|optional
},
515 { WM_ACTIVATEAPP
, sent
|wparam
, 1 },
516 { WM_NCACTIVATE
, sent
|wparam
, 1 },
517 { WM_ACTIVATE
, sent
|wparam
, 1 },
518 { HCBT_SETFOCUS
, hook
},
519 { WM_IME_SETCONTEXT
, sent
|wparam
|defwinproc
|optional
, 1 },
520 { WM_IME_NOTIFY
, sent
|wparam
|defwinproc
|optional
, 2 },
521 { WM_SETFOCUS
, sent
|wparam
|defwinproc
, 0 },
522 { WM_SYNCPAINT
, sent
|wparam
|optional
, 4 },
523 { WM_NCPAINT
, sent
|wparam
|optional
, 1 },
524 { WM_ERASEBKGND
, sent
|optional
},
525 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_NOCLIENTMOVE
|SWP_NOCLIENTSIZE
|SWP_SHOWWINDOW
|SWP_NOMOVE
|SWP_NOSIZE
},
528 /* ShowWindow(SW_SHOWMAXIMIZED) for a visible popup window */
529 static const struct message WmShowVisMaxPopupSeq
[] = {
530 { HCBT_MINMAX
, hook
|lparam
, 0, SW_MAXIMIZE
},
531 { WM_GETMINMAXINFO
, sent
},
532 { WM_GETTEXT
, sent
|optional
},
533 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|0x8000 },
534 { WM_NCCALCSIZE
, sent
|wparam
, TRUE
},
535 { WM_QUERYNEWPALETTE
, sent
|wparam
|lparam
|optional
, 0, 0 },
536 { WM_NCPAINT
, sent
|wparam
|optional
, 1 },
537 { WM_ERASEBKGND
, sent
|optional
},
538 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|0x8000 },
539 { WM_MOVE
, sent
|defwinproc
},
540 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_MAXIMIZED
},
543 /* CreateWindow (for a child popup window, not initially visible) */
544 static const struct message WmCreateChildPopupSeq
[] = {
545 { HCBT_CREATEWND
, hook
},
546 { WM_NCCREATE
, sent
},
547 { WM_NCCALCSIZE
, sent
|wparam
, 0 },
549 { EVENT_OBJECT_CREATE
, winevent_hook
|wparam
|lparam
, 0, 0 },
550 { WM_SIZE
, sent
|wparam
, SIZE_RESTORED
},
554 /* CreateWindow (for a popup window, not initially visible,
555 * which sets WS_VISIBLE in WM_CREATE handler)
557 static const struct message WmCreateInvisiblePopupSeq
[] = {
558 { HCBT_CREATEWND
, hook
},
559 { WM_NCCREATE
, sent
},
560 { WM_NCCALCSIZE
, sent
|wparam
, 0 },
562 { WM_STYLECHANGING
, sent
},
563 { WM_STYLECHANGED
, sent
},
564 { EVENT_OBJECT_CREATE
, winevent_hook
|wparam
|lparam
, 0, 0 },
565 { WM_SIZE
, sent
|wparam
, SIZE_RESTORED
},
569 /* SetWindowPos(SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE|SWP_NOZORDER)
570 * for a popup window with WS_VISIBLE style set
572 static const struct message WmShowVisiblePopupSeq_2
[] = {
573 { WM_WINDOWPOSCHANGING
, sent
|wparam
, 0 },
576 /* SetWindowPos(SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE)
577 * for a popup window with WS_VISIBLE style set
579 static const struct message WmShowVisiblePopupSeq_3
[] = {
580 { WM_WINDOWPOSCHANGING
, sent
|wparam
, 0 },
581 { HCBT_ACTIVATE
, hook
},
582 { EVENT_SYSTEM_FOREGROUND
, winevent_hook
|wparam
|lparam
, 0, 0 },
583 { WM_QUERYNEWPALETTE
, sent
|wparam
|lparam
|optional
, 0, 0 },
584 { WM_WINDOWPOSCHANGING
, sent
|wparam
, 0 },
585 { WM_NCACTIVATE
, sent
|wparam
, 1 },
586 { WM_ACTIVATE
, sent
|wparam
, 1 },
587 { HCBT_SETFOCUS
, hook
},
588 { WM_KILLFOCUS
, sent
|parent
},
589 { WM_IME_SETCONTEXT
, sent
|parent
|wparam
|optional
, 0 },
590 { WM_IME_SETCONTEXT
, sent
|wparam
|defwinproc
|optional
, 1 },
591 { WM_IME_NOTIFY
, sent
|wparam
|defwinproc
|optional
, 2 },
592 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
593 { WM_SETFOCUS
, sent
|defwinproc
},
596 /* CreateWindow (for child window, not initially visible) */
597 static const struct message WmCreateChildSeq
[] = {
598 { HCBT_CREATEWND
, hook
},
599 { WM_NCCREATE
, sent
},
600 /* child is inserted into parent's child list after WM_NCCREATE returns */
601 { WM_NCCALCSIZE
, sent
|wparam
, 0 },
603 { EVENT_OBJECT_CREATE
, winevent_hook
|wparam
|lparam
, 0, 0 },
604 { WM_SIZE
, sent
|wparam
, SIZE_RESTORED
},
606 { WM_PARENTNOTIFY
, sent
|parent
|wparam
, WM_CREATE
},
609 /* CreateWindow (for maximized child window, not initially visible) */
610 static const struct message WmCreateMaximizedChildSeq
[] = {
611 { HCBT_CREATEWND
, hook
},
612 { WM_NCCREATE
, sent
},
613 { WM_NCCALCSIZE
, sent
|wparam
, 0 },
615 { EVENT_OBJECT_CREATE
, winevent_hook
|wparam
|lparam
, 0, 0 },
616 { WM_SIZE
, sent
|wparam
, SIZE_RESTORED
},
618 { HCBT_MINMAX
, hook
|lparam
, 0, SW_MAXIMIZE
},
619 { WM_GETMINMAXINFO
, sent
},
620 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|0x8000 },
621 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
622 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOMOVE
|SWP_NOREDRAW
|SWP_NOCLIENTMOVE
|0x8000 },
623 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_MAXIMIZED
},
624 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
625 { WM_PARENTNOTIFY
, sent
|parent
|wparam
, WM_CREATE
},
628 /* CreateWindow (for a child window, initially visible) */
629 static const struct message WmCreateVisibleChildSeq
[] = {
630 { HCBT_CREATEWND
, hook
},
631 { WM_NCCREATE
, sent
},
632 /* child is inserted into parent's child list after WM_NCCREATE returns */
633 { WM_NCCALCSIZE
, sent
|wparam
, 0 },
634 { EVENT_OBJECT_REORDER
, winevent_hook
|wparam
|lparam
, 0, 0 },
636 { EVENT_OBJECT_CREATE
, winevent_hook
|wparam
|lparam
, 0, 0 },
637 { WM_SIZE
, sent
|wparam
, SIZE_RESTORED
},
639 { WM_PARENTNOTIFY
, sent
|parent
|wparam
, WM_CREATE
},
640 { WM_SHOWWINDOW
, sent
|wparam
, 1 },
641 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOACTIVATE
},
642 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, 0, 0 },
643 { WM_ERASEBKGND
, sent
|parent
|optional
},
644 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOACTIVATE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
645 { WM_NCCALCSIZE
, sent
|wparam
|optional
, 1 }, /* WinXP */
646 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
649 /* ShowWindow(SW_SHOW) for a not visible child window */
650 static const struct message WmShowChildSeq
[] = {
651 { WM_SHOWWINDOW
, sent
|wparam
, 1 },
652 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
653 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, 0, 0 },
654 { WM_ERASEBKGND
, sent
|parent
|optional
},
655 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
658 /* ShowWindow(SW_HIDE) for a visible child window */
659 static const struct message WmHideChildSeq
[] = {
660 { WM_SHOWWINDOW
, sent
|wparam
, 0 },
661 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_HIDEWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
662 { EVENT_OBJECT_HIDE
, winevent_hook
|wparam
|lparam
, 0, 0 },
663 { WM_ERASEBKGND
, sent
|parent
|optional
},
664 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_HIDEWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
667 /* SetWindowPos(SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE)
668 * for a not visible child window
670 static const struct message WmShowChildSeq_2
[] = {
671 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
},
672 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, 0, 0 },
673 { WM_CHILDACTIVATE
, sent
},
674 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
677 /* SetWindowPos(SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE)
678 * for a not visible child window
680 static const struct message WmShowChildSeq_3
[] = {
681 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOACTIVATE
},
682 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, 0, 0 },
683 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOACTIVATE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
686 /* SetWindowPos(SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE)
687 * for a visible child window with a caption
689 static const struct message WmShowChildSeq_4
[] = {
690 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
},
691 { WM_CHILDACTIVATE
, sent
},
694 /* ShowWindow(SW_MINIMIZE) for child with invisible parent */
695 static const struct message WmShowChildInvisibleParentSeq_1
[] = {
696 { HCBT_MINMAX
, hook
|lparam
, 0, SW_MINIMIZE
},
697 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOCOPYBITS
|0x8000 },
698 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
699 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOREDRAW
|SWP_NOCOPYBITS
|0x8000 },
700 { WM_MOVE
, sent
|defwinproc
},
701 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_MINIMIZED
},
702 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
703 /* FIXME: Wine creates an icon/title window while Windows doesn't */
704 { WM_PARENTNOTIFY
, sent
|parent
|wparam
|optional
, WM_CREATE
},
705 { WM_GETTEXT
, sent
|optional
},
708 /* repeated ShowWindow(SW_MINIMIZE) for child with invisible parent */
709 static const struct message WmShowChildInvisibleParentSeq_1r
[] = {
710 { HCBT_MINMAX
, hook
|lparam
, 0, SW_MINIMIZE
},
713 /* ShowWindow(SW_MAXIMIZE) for child with invisible parent */
714 static const struct message WmShowChildInvisibleParentSeq_2
[] = {
715 { HCBT_MINMAX
, hook
|lparam
, 0, SW_MAXIMIZE
},
716 { WM_GETMINMAXINFO
, sent
},
717 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_FRAMECHANGED
|0x8000 },
718 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
719 { WM_CHILDACTIVATE
, sent
},
720 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_FRAMECHANGED
|SWP_NOMOVE
|SWP_NOREDRAW
|SWP_NOCLIENTMOVE
|0x8000 },
721 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_MAXIMIZED
},
722 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
725 /* repeated ShowWindow(SW_MAXIMIZE) for child with invisible parent */
726 static const struct message WmShowChildInvisibleParentSeq_2r
[] = {
727 { HCBT_MINMAX
, hook
|lparam
, 0, SW_MAXIMIZE
},
730 /* ShowWindow(SW_SHOWMINIMIZED) for child with invisible parent */
731 static const struct message WmShowChildInvisibleParentSeq_3
[] = {
732 { HCBT_MINMAX
, hook
|lparam
, 0, SW_SHOWMINIMIZED
},
733 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_FRAMECHANGED
|SWP_NOCOPYBITS
|0x8000 },
734 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
735 { WM_CHILDACTIVATE
, sent
},
736 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_FRAMECHANGED
|SWP_NOREDRAW
|SWP_NOCOPYBITS
|0x8000 },
737 { WM_MOVE
, sent
|defwinproc
},
738 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_MINIMIZED
},
739 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
740 /* FIXME: Wine creates an icon/title window while Windows doesn't */
741 { WM_PARENTNOTIFY
, sent
|parent
|wparam
|optional
, WM_CREATE
},
742 { WM_GETTEXT
, sent
|optional
},
745 /* repeated ShowWindow(SW_SHOWMINIMIZED) for child with invisible parent */
746 static const struct message WmShowChildInvisibleParentSeq_3r
[] = {
747 { HCBT_MINMAX
, hook
|lparam
, 0, SW_SHOWMINIMIZED
},
750 /* ShowWindow(SW_SHOWMINNOACTIVE) for child with invisible parent */
751 static const struct message WmShowChildInvisibleParentSeq_4
[] = {
752 { HCBT_MINMAX
, hook
|lparam
, 0, SW_SHOWMINNOACTIVE
},
753 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOCOPYBITS
|0x8000 },
754 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
755 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOREDRAW
|SWP_NOCOPYBITS
|0x8000 },
756 { WM_MOVE
, sent
|defwinproc
},
757 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_MINIMIZED
},
758 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
759 /* FIXME: Wine creates an icon/title window while Windows doesn't */
760 { WM_PARENTNOTIFY
, sent
|parent
|wparam
|optional
, WM_CREATE
},
761 { WM_GETTEXT
, sent
|optional
},
764 /* repeated ShowWindow(SW_SHOWMINNOACTIVE) for child with invisible parent */
765 static const struct message WmShowChildInvisibleParentSeq_4r
[] = {
766 { HCBT_MINMAX
, hook
|lparam
, 0, SW_SHOWMINNOACTIVE
},
769 /* ShowWindow(SW_SHOW) for child with invisible parent */
770 static const struct message WmShowChildInvisibleParentSeq_5
[] = {
771 { WM_SHOWWINDOW
, sent
|wparam
, 1 },
774 /* ShowWindow(SW_HIDE) for child with invisible parent */
775 static const struct message WmHideChildInvisibleParentSeq
[] = {
776 { WM_SHOWWINDOW
, sent
|wparam
, 0 },
779 /* SetWindowPos(SWP_SHOWWINDOW) for child with invisible parent */
780 static const struct message WmShowChildInvisibleParentSeq_6
[] = {
781 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOACTIVATE
},
782 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, 0, 0 },
783 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOACTIVATE
|SWP_NOREDRAW
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
786 /* SetWindowPos(SWP_HIDEWINDOW) for child with invisible parent */
787 static const struct message WmHideChildInvisibleParentSeq_2
[] = {
788 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_HIDEWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
789 { EVENT_OBJECT_HIDE
, winevent_hook
|wparam
|lparam
, 0, 0 },
790 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_HIDEWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOREDRAW
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
793 /* DestroyWindow for a visible child window */
794 static const struct message WmDestroyChildSeq
[] = {
795 { HCBT_DESTROYWND
, hook
},
796 { WM_PARENTNOTIFY
, sent
|parent
|wparam
, WM_DESTROY
},
797 { WM_SHOWWINDOW
, sent
|wparam
, 0 },
798 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_HIDEWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
799 { EVENT_OBJECT_HIDE
, winevent_hook
|wparam
|lparam
, 0, 0 },
800 { WM_ERASEBKGND
, sent
|parent
|optional
},
801 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_HIDEWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
802 { HCBT_SETFOCUS
, hook
}, /* set focus to a parent */
803 { WM_KILLFOCUS
, sent
},
804 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 0 },
805 { WM_IME_SETCONTEXT
, sent
|wparam
|parent
|optional
, 1 },
806 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
807 { WM_SETFOCUS
, sent
|parent
},
808 { EVENT_OBJECT_DESTROY
, winevent_hook
|wparam
|lparam
, 0, 0 },
809 { WM_DESTROY
, sent
},
810 { WM_DESTROY
, sent
|optional
}, /* some other (IME?) window */
811 { WM_NCDESTROY
, sent
|optional
}, /* some other (IME?) window */
812 { WM_NCDESTROY
, sent
},
815 /* DestroyWindow for a visible child window with invisible parent */
816 static const struct message WmDestroyInvisibleChildSeq
[] = {
817 { HCBT_DESTROYWND
, hook
},
818 { WM_PARENTNOTIFY
, sent
|parent
|wparam
, WM_DESTROY
},
819 { WM_SHOWWINDOW
, sent
|wparam
, 0 },
820 { EVENT_OBJECT_DESTROY
, winevent_hook
|wparam
|lparam
, 0, 0 },
821 { WM_DESTROY
, sent
},
822 { WM_NCDESTROY
, sent
},
825 /* Moving the mouse in nonclient area */
826 static const struct message WmMouseMoveInNonClientAreaSeq
[] = { /* FIXME: add */
827 { WM_NCHITTEST
, sent
},
828 { WM_SETCURSOR
, sent
},
829 { WM_NCMOUSEMOVE
, posted
},
832 /* Moving the mouse in client area */
833 static const struct message WmMouseMoveInClientAreaSeq
[] = { /* FIXME: add */
834 { WM_NCHITTEST
, sent
},
835 { WM_SETCURSOR
, sent
},
836 { WM_MOUSEMOVE
, posted
},
839 /* Moving by dragging the title bar (after WM_NCHITTEST and WM_SETCURSOR) (outline move) */
840 static const struct message WmDragTitleBarSeq
[] = { /* FIXME: add */
841 { WM_NCLBUTTONDOWN
, sent
|wparam
, HTCAPTION
},
842 { WM_SYSCOMMAND
, sent
|defwinproc
|wparam
, SC_MOVE
+2 },
843 { WM_GETMINMAXINFO
, sent
|defwinproc
},
844 { WM_ENTERSIZEMOVE
, sent
|defwinproc
},
845 { WM_WINDOWPOSCHANGING
, sent
|wparam
|defwinproc
, 0 },
846 { WM_WINDOWPOSCHANGED
, sent
|wparam
|defwinproc
, 0 },
847 { WM_MOVE
, sent
|defwinproc
},
848 { WM_EXITSIZEMOVE
, sent
|defwinproc
},
851 /* Sizing by dragging the thick borders (after WM_NCHITTEST and WM_SETCURSOR) (outline move) */
852 static const struct message WmDragThickBordersBarSeq
[] = { /* FIXME: add */
853 { WM_NCLBUTTONDOWN
, sent
|wparam
, 0xd },
854 { WM_SYSCOMMAND
, sent
|defwinproc
|wparam
, 0xf004 },
855 { WM_GETMINMAXINFO
, sent
|defwinproc
},
856 { WM_ENTERSIZEMOVE
, sent
|defwinproc
},
857 { WM_SIZING
, sent
|defwinproc
|wparam
, 4}, /* one for each mouse movement */
858 { WM_WINDOWPOSCHANGING
, sent
|wparam
|defwinproc
, 0 },
859 { WM_GETMINMAXINFO
, sent
|defwinproc
},
860 { WM_NCCALCSIZE
, sent
|defwinproc
|wparam
, 1 },
861 { WM_NCPAINT
, sent
|defwinproc
|wparam
, 1 },
862 { WM_GETTEXT
, sent
|defwinproc
},
863 { WM_ERASEBKGND
, sent
|defwinproc
},
864 { WM_WINDOWPOSCHANGED
, sent
|wparam
|defwinproc
, 0 },
865 { WM_MOVE
, sent
|defwinproc
},
866 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_RESTORED
},
867 { WM_EXITSIZEMOVE
, sent
|defwinproc
},
870 /* Resizing child window with MoveWindow (32) */
871 static const struct message WmResizingChildWithMoveWindowSeq
[] = {
872 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_NOACTIVATE
},
873 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
874 { WM_ERASEBKGND
, sent
|optional
},
875 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_NOACTIVATE
},
876 { WM_MOVE
, sent
|defwinproc
},
877 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_RESTORED
},
878 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
881 /* Clicking on inactive button */
882 static const struct message WmClickInactiveButtonSeq
[] = { /* FIXME: add */
883 { WM_NCHITTEST
, sent
},
884 { WM_PARENTNOTIFY
, sent
|parent
|wparam
, WM_LBUTTONDOWN
},
885 { WM_MOUSEACTIVATE
, sent
},
886 { WM_MOUSEACTIVATE
, sent
|parent
|defwinproc
},
887 { WM_SETCURSOR
, sent
},
888 { WM_SETCURSOR
, sent
|parent
|defwinproc
},
889 { WM_LBUTTONDOWN
, posted
},
890 { WM_KILLFOCUS
, posted
|parent
},
891 { WM_SETFOCUS
, posted
},
892 { WM_CTLCOLORBTN
, posted
|parent
},
893 { BM_SETSTATE
, posted
},
894 { WM_CTLCOLORBTN
, posted
|parent
},
895 { WM_LBUTTONUP
, posted
},
896 { BM_SETSTATE
, posted
},
897 { WM_CTLCOLORBTN
, posted
|parent
},
898 { WM_COMMAND
, posted
|parent
},
901 /* Reparenting a button (16/32) */
902 /* The last child (button) reparented gets topmost for its new parent. */
903 static const struct message WmReparentButtonSeq
[] = { /* FIXME: add */
904 { WM_SHOWWINDOW
, sent
|wparam
, 0 },
905 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_HIDEWINDOW
|SWP_NOACTIVATE
|SWP_NOMOVE
|SWP_NOSIZE
},
906 { EVENT_OBJECT_HIDE
, winevent_hook
|wparam
|lparam
, 0, 0 },
907 { WM_ERASEBKGND
, sent
|parent
},
908 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_HIDEWINDOW
|SWP_NOACTIVATE
|SWP_NOMOVE
|SWP_NOSIZE
},
909 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_NOSIZE
},
910 { WM_CHILDACTIVATE
, sent
},
911 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_NOSIZE
|SWP_NOREDRAW
},
912 { WM_MOVE
, sent
|defwinproc
},
913 { WM_SHOWWINDOW
, sent
|wparam
, 1 },
916 /* Creation of a custom dialog (32) */
917 static const struct message WmCreateCustomDialogSeq
[] = {
918 { HCBT_CREATEWND
, hook
},
919 { WM_GETMINMAXINFO
, sent
},
920 { WM_NCCREATE
, sent
},
921 { WM_NCCALCSIZE
, sent
|wparam
, 0 },
922 { EVENT_OBJECT_REORDER
, winevent_hook
|wparam
|lparam
, 0, 0 },
924 { EVENT_OBJECT_CREATE
, winevent_hook
|wparam
|lparam
, 0, 0 },
925 { WM_SHOWWINDOW
, sent
|wparam
, 1 },
926 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
},
927 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, 0, 0 },
928 { HCBT_ACTIVATE
, hook
},
929 { EVENT_SYSTEM_FOREGROUND
, winevent_hook
|wparam
|lparam
, 0, 0 },
932 { WM_QUERYNEWPALETTE
, sent
|wparam
|lparam
|optional
, 0, 0 },
934 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_NOSIZE
|SWP_NOMOVE
},
936 { WM_NCACTIVATE
, sent
|wparam
, 1 },
937 { WM_GETTEXT
, sent
|optional
|defwinproc
},
938 { WM_GETTEXT
, sent
|optional
|defwinproc
},
939 { EVENT_OBJECT_DEFACTIONCHANGE
, winevent_hook
|wparam
|lparam
|optional
, OBJID_CLIENT
, 0 },
940 { WM_ACTIVATE
, sent
|wparam
, 1 },
941 { WM_KILLFOCUS
, sent
|parent
},
942 { WM_IME_SETCONTEXT
, sent
|parent
|wparam
|optional
, 0 },
943 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 1 },
944 { WM_IME_NOTIFY
, sent
|wparam
|defwinproc
|optional
, 2 },
945 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
946 { WM_SETFOCUS
, sent
},
947 { WM_GETDLGCODE
, sent
|defwinproc
|wparam
, 0 },
948 { WM_NCPAINT
, sent
|wparam
, 1 },
949 { WM_GETTEXT
, sent
|optional
|defwinproc
},
950 { WM_GETTEXT
, sent
|optional
|defwinproc
},
951 { WM_ERASEBKGND
, sent
},
952 { WM_CTLCOLORDLG
, sent
|defwinproc
},
953 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
954 { WM_GETTEXT
, sent
|optional
},
955 { WM_GETTEXT
, sent
|optional
},
956 { WM_NCCALCSIZE
, sent
|optional
},
957 { WM_NCPAINT
, sent
|optional
},
958 { WM_GETTEXT
, sent
|optional
|defwinproc
},
959 { WM_GETTEXT
, sent
|optional
|defwinproc
},
960 { WM_ERASEBKGND
, sent
|optional
},
961 { WM_CTLCOLORDLG
, sent
|optional
|defwinproc
},
962 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
963 { WM_SIZE
, sent
|wparam
, SIZE_RESTORED
},
967 /* Calling EndDialog for a custom dialog (32) */
968 static const struct message WmEndCustomDialogSeq
[] = {
969 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_HIDEWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
970 { EVENT_OBJECT_HIDE
, winevent_hook
|wparam
|lparam
, 0, 0 },
971 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_HIDEWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
972 { WM_GETTEXT
, sent
|optional
},
973 { HCBT_ACTIVATE
, hook
},
974 { WM_NCACTIVATE
, sent
|wparam
, 0 },
975 { WM_GETTEXT
, sent
|optional
|defwinproc
},
976 { WM_GETTEXT
, sent
|optional
|defwinproc
},
977 { WM_ACTIVATE
, sent
|wparam
, 0 },
978 { EVENT_SYSTEM_FOREGROUND
, winevent_hook
|wparam
|lparam
, 0, 0 },
979 { WM_WINDOWPOSCHANGING
, sent
|wparam
|optional
, SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
980 { HCBT_SETFOCUS
, hook
},
981 { WM_KILLFOCUS
, sent
},
982 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 0 },
983 { WM_IME_SETCONTEXT
, sent
|parent
|wparam
|defwinproc
|optional
, 1 },
984 { WM_IME_NOTIFY
, sent
|wparam
|optional
, 1 },
985 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
986 { WM_SETFOCUS
, sent
|parent
|defwinproc
},
989 /* ShowWindow(SW_SHOW) for a custom dialog (initially invisible) */
990 static const struct message WmShowCustomDialogSeq
[] = {
991 { WM_SHOWWINDOW
, sent
|wparam
, 1 },
992 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
},
993 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, 0, 0 },
994 { HCBT_ACTIVATE
, hook
},
995 { EVENT_SYSTEM_FOREGROUND
, winevent_hook
|wparam
|lparam
, 0, 0 },
997 { WM_QUERYNEWPALETTE
, sent
|wparam
|lparam
|optional
, 0, 0 },
999 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_NOSIZE
|SWP_NOMOVE
},
1000 { WM_ACTIVATEAPP
, sent
|wparam
|optional
, 1 },
1001 { WM_NCACTIVATE
, sent
|wparam
, 1 },
1002 { WM_ACTIVATE
, sent
|wparam
, 1 },
1004 { WM_KILLFOCUS
, sent
|parent
},
1005 { WM_IME_SETCONTEXT
, sent
|parent
|wparam
|optional
, 0 },
1006 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 1 },
1007 { WM_IME_NOTIFY
, sent
|wparam
|defwinproc
|optional
, 2 },
1008 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
1009 { WM_SETFOCUS
, sent
},
1010 { WM_GETDLGCODE
, sent
|defwinproc
|wparam
, 0 },
1011 { WM_NCPAINT
, sent
|wparam
, 1 },
1012 { WM_ERASEBKGND
, sent
},
1013 { WM_CTLCOLORDLG
, sent
|defwinproc
},
1014 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
1017 /* Creation and destruction of a modal dialog (32) */
1018 static const struct message WmModalDialogSeq
[] = {
1019 { WM_CANCELMODE
, sent
|parent
},
1020 { HCBT_SETFOCUS
, hook
},
1021 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
1022 { WM_KILLFOCUS
, sent
|parent
},
1023 { WM_IME_SETCONTEXT
, sent
|parent
|wparam
|optional
, 0 },
1024 { EVENT_OBJECT_STATECHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
1025 { WM_ENABLE
, sent
|parent
|wparam
, 0 },
1026 { HCBT_CREATEWND
, hook
},
1027 { EVENT_OBJECT_REORDER
, winevent_hook
|wparam
|lparam
, 0, 0 },
1028 { EVENT_OBJECT_CREATE
, winevent_hook
|wparam
|lparam
, 0, 0 },
1029 { WM_SETFONT
, sent
},
1030 { WM_INITDIALOG
, sent
},
1031 { WM_CHANGEUISTATE
, sent
|optional
},
1032 { WM_UPDATEUISTATE
, sent
|optional
},
1033 { WM_SHOWWINDOW
, sent
},
1034 { HCBT_ACTIVATE
, hook
},
1035 { EVENT_SYSTEM_FOREGROUND
, winevent_hook
|wparam
|lparam
, 0, 0 },
1036 { WM_QUERYNEWPALETTE
, sent
|wparam
|lparam
|optional
, 0, 0 },
1037 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_NOSIZE
|SWP_NOMOVE
},
1038 { WM_NCACTIVATE
, sent
|wparam
, 1 },
1039 { WM_GETTEXT
, sent
|optional
},
1040 { WM_ACTIVATE
, sent
|wparam
, 1 },
1041 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOACTIVATE
},
1042 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, 0, 0 },
1043 { WM_NCPAINT
, sent
},
1044 { WM_GETTEXT
, sent
|optional
},
1045 { WM_ERASEBKGND
, sent
},
1046 { WM_CTLCOLORDLG
, sent
},
1047 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOACTIVATE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
1048 { WM_GETTEXT
, sent
|optional
},
1049 { WM_NCCALCSIZE
, sent
|optional
},
1050 { WM_NCPAINT
, sent
|optional
},
1051 { WM_GETTEXT
, sent
|optional
},
1052 { WM_ERASEBKGND
, sent
|optional
},
1053 { WM_CTLCOLORDLG
, sent
|optional
},
1054 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
1055 { WM_PAINT
, sent
|optional
},
1056 { WM_CTLCOLORBTN
, sent
},
1057 { WM_ENTERIDLE
, sent
|parent
|optional
},
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
},
1078 { EVENT_OBJECT_STATECHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
1079 { WM_ENABLE
, sent
|parent
|wparam
, 1 },
1080 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_HIDEWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOACTIVATE
},
1081 { EVENT_OBJECT_HIDE
, winevent_hook
|wparam
|lparam
, 0, 0 },
1082 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_HIDEWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOACTIVATE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
1083 { WM_GETTEXT
, sent
|optional
},
1084 { HCBT_ACTIVATE
, hook
},
1085 { WM_NCACTIVATE
, sent
|wparam
, 0 },
1086 { WM_GETTEXT
, sent
|optional
},
1087 { WM_ACTIVATE
, sent
|wparam
, 0 },
1088 { EVENT_SYSTEM_FOREGROUND
, winevent_hook
|wparam
|lparam
, 0, 0 },
1089 { WM_WINDOWPOSCHANGING
, sent
|optional
},
1090 { HCBT_SETFOCUS
, hook
},
1091 { WM_IME_SETCONTEXT
, sent
|parent
|wparam
|defwinproc
|optional
, 1 },
1092 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
1093 { WM_SETFOCUS
, sent
|parent
|defwinproc
},
1094 { EVENT_SYSTEM_DIALOGEND
, winevent_hook
|wparam
|lparam
, 0, 0 },
1095 { HCBT_DESTROYWND
, hook
},
1096 { EVENT_OBJECT_DESTROY
, winevent_hook
|wparam
|lparam
, 0, 0 },
1097 { WM_DESTROY
, sent
},
1098 { WM_NCDESTROY
, sent
},
1101 /* Creation of a modal dialog that is resized inside WM_INITDIALOG (32) */
1102 static const struct message WmCreateModalDialogResizeSeq
[] = { /* FIXME: add */
1103 /* (inside dialog proc, handling WM_INITDIALOG) */
1104 { WM_WINDOWPOSCHANGING
, sent
|wparam
, 0 },
1105 { WM_NCCALCSIZE
, sent
},
1106 { WM_NCACTIVATE
, sent
|parent
|wparam
, 0 },
1107 { WM_GETTEXT
, sent
|defwinproc
},
1108 { WM_ACTIVATE
, sent
|parent
|wparam
, 0 },
1109 { WM_WINDOWPOSCHANGING
, sent
|wparam
, 0 },
1110 { WM_WINDOWPOSCHANGING
, sent
|parent
},
1111 { WM_NCACTIVATE
, sent
|wparam
, 1 },
1112 { WM_ACTIVATE
, sent
|wparam
, 1 },
1113 { WM_WINDOWPOSCHANGED
, sent
|wparam
, 0 },
1114 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_RESTORED
},
1115 /* (setting focus) */
1116 { WM_SHOWWINDOW
, sent
|wparam
, 1 },
1117 { WM_WINDOWPOSCHANGING
, sent
|wparam
, 0 },
1118 { WM_NCPAINT
, sent
},
1119 { WM_GETTEXT
, sent
|defwinproc
},
1120 { WM_ERASEBKGND
, sent
},
1121 { WM_CTLCOLORDLG
, sent
|defwinproc
},
1122 { WM_WINDOWPOSCHANGED
, sent
|wparam
, 0 },
1124 /* (bunch of WM_CTLCOLOR* for each control) */
1125 { WM_PAINT
, sent
|parent
},
1126 { WM_ENTERIDLE
, sent
|parent
|wparam
, 0 },
1127 { WM_SETCURSOR
, sent
|parent
},
1130 /* SetMenu for NonVisible windows with size change*/
1131 static const struct message WmSetMenuNonVisibleSizeChangeSeq
[] = {
1132 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
1133 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
1134 { EVENT_OBJECT_REORDER
, winevent_hook
|wparam
|lparam
, 0, 0 },
1135 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOREDRAW
},
1136 { WM_MOVE
, sent
|defwinproc
},
1137 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_RESTORED
},
1138 { WM_NCCALCSIZE
,sent
|wparam
|optional
, 1 }, /* XP */
1139 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
1140 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
|optional
, 0, 0 }, /* XP sends a duplicate */
1141 { WM_GETTEXT
, sent
|optional
},
1142 { WM_NCCALCSIZE
, sent
|wparam
|optional
, 1 },
1145 /* SetMenu for NonVisible windows with no size change */
1146 static const struct message WmSetMenuNonVisibleNoSizeChangeSeq
[] = {
1147 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
1148 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
1149 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOREDRAW
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
1150 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
1153 /* SetMenu for Visible windows with size change */
1154 static const struct message WmSetMenuVisibleSizeChangeSeq
[] = {
1155 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
1156 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
1157 { EVENT_OBJECT_REORDER
, winevent_hook
|wparam
|lparam
, 0, 0 },
1158 { WM_NCPAINT
, sent
}, /* wparam != 1 */
1159 { WM_GETTEXT
, sent
|defwinproc
|optional
},
1160 { WM_ERASEBKGND
, sent
|optional
},
1161 { WM_ACTIVATE
, sent
|optional
},
1162 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
1163 { WM_MOVE
, sent
|defwinproc
},
1164 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_RESTORED
},
1165 { WM_NCCALCSIZE
, sent
|wparam
|optional
, 1 },
1166 { WM_NCPAINT
, sent
|optional
}, /* wparam != 1 */
1167 { WM_ERASEBKGND
, sent
|optional
},
1168 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
1169 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
|optional
, 0, 0 }, /* XP sends a duplicate */
1172 /* SetMenu for Visible windows with no size change */
1173 static const struct message WmSetMenuVisibleNoSizeChangeSeq
[] = {
1174 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
1175 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
1176 { WM_NCPAINT
, sent
}, /* wparam != 1 */
1177 { WM_GETTEXT
, sent
|defwinproc
|optional
},
1178 { WM_ERASEBKGND
, sent
|optional
},
1179 { WM_ACTIVATE
, sent
|optional
},
1180 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
1181 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
1184 /* DrawMenuBar for a visible window */
1185 static const struct message WmDrawMenuBarSeq
[] =
1187 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
1188 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
1189 { WM_NCPAINT
, sent
}, /* wparam != 1 */
1190 { WM_GETTEXT
, sent
|defwinproc
|optional
},
1191 { WM_ERASEBKGND
, sent
|optional
},
1192 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
1193 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
1197 static const struct message WmSetRedrawFalseSeq
[] =
1199 { WM_SETREDRAW
, sent
|wparam
, 0 },
1203 static const struct message WmSetRedrawTrueSeq
[] =
1205 { WM_SETREDRAW
, sent
|wparam
, 1 },
1209 static const struct message WmEnableWindowSeq_1
[] =
1211 { WM_CANCELMODE
, sent
|wparam
|lparam
, 0, 0 },
1212 { EVENT_OBJECT_STATECHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
1213 { WM_ENABLE
, sent
|wparam
|lparam
, FALSE
, 0 },
1217 static const struct message WmEnableWindowSeq_2
[] =
1219 { EVENT_OBJECT_STATECHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
1220 { WM_ENABLE
, sent
|wparam
|lparam
, TRUE
, 0 },
1224 static const struct message WmGetScrollRangeSeq
[] =
1226 { SBM_GETRANGE
, sent
},
1229 static const struct message WmGetScrollInfoSeq
[] =
1231 { SBM_GETSCROLLINFO
, sent
},
1234 static const struct message WmSetScrollRangeSeq
[] =
1236 /* MSDN claims that Windows sends SBM_SETRANGE message, but win2k SP4
1237 sends SBM_SETSCROLLINFO.
1239 { SBM_SETSCROLLINFO
, sent
},
1242 /* SetScrollRange for a window without a non-client area */
1243 static const struct message WmSetScrollRangeHSeq_empty
[] =
1245 { EVENT_OBJECT_VALUECHANGE
, winevent_hook
|wparam
|lparam
, OBJID_HSCROLL
, 0 },
1248 static const struct message WmSetScrollRangeVSeq_empty
[] =
1250 { EVENT_OBJECT_VALUECHANGE
, winevent_hook
|wparam
|lparam
, OBJID_VSCROLL
, 0 },
1253 static const struct message WmSetScrollRangeHVSeq
[] =
1255 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOMOVE
|SWP_NOSIZE
},
1256 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
1257 { WM_GETTEXT
, sent
|defwinproc
|optional
},
1258 { WM_ERASEBKGND
, sent
|optional
},
1259 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOMOVE
|SWP_NOSIZE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
1260 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
1261 { EVENT_OBJECT_VALUECHANGE
, winevent_hook
|lparam
|optional
, 0/*OBJID_HSCROLL or OBJID_VSCROLL*/, 0 },
1264 /* SetScrollRange for a window with a non-client area */
1265 static const struct message WmSetScrollRangeHV_NC_Seq
[] =
1267 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOMOVE
|SWP_NOSIZE
},
1268 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
1269 { EVENT_OBJECT_REORDER
, winevent_hook
|wparam
|lparam
, 0, 0 },
1270 { WM_NCPAINT
, sent
|optional
},
1271 { WM_GETTEXT
, sent
|defwinproc
|optional
},
1272 { WM_GETTEXT
, sent
|defwinproc
|optional
},
1273 { WM_ERASEBKGND
, sent
|optional
},
1274 { WM_CTLCOLORDLG
, sent
|defwinproc
|optional
}, /* sent to a parent of the dialog */
1275 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOMOVE
|SWP_NOSIZE
|SWP_NOCLIENTMOVE
},
1276 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_RESTORED
},
1277 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
1278 { EVENT_OBJECT_VALUECHANGE
, winevent_hook
|lparam
|optional
, 0/*OBJID_HSCROLL or OBJID_VSCROLL*/, 0 },
1279 { WM_GETTEXT
, sent
|optional
},
1280 { WM_GETTEXT
, sent
|optional
},
1281 { WM_GETTEXT
, sent
|optional
},
1282 { WM_GETTEXT
, sent
|optional
},
1285 /* test if we receive the right sequence of messages */
1286 /* after calling ShowWindow( SW_SHOWNA) */
1287 static const struct message WmSHOWNAChildInvisParInvis
[] = {
1288 { WM_SHOWWINDOW
, sent
|wparam
, 1 },
1291 static const struct message WmSHOWNAChildVisParInvis
[] = {
1292 { WM_SHOWWINDOW
, sent
|wparam
, 1 },
1295 static const struct message WmSHOWNAChildVisParVis
[] = {
1296 { WM_SHOWWINDOW
, sent
|wparam
, 1 },
1297 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOACTIVATE
},
1300 static const struct message WmSHOWNAChildInvisParVis
[] = {
1301 { WM_SHOWWINDOW
, sent
|wparam
, 1 },
1302 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
1303 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, 0, 0 },
1304 { WM_ERASEBKGND
, sent
|optional
},
1305 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOACTIVATE
|SWP_NOCLIENTMOVE
},
1308 static const struct message WmSHOWNATopVisible
[] = {
1309 { WM_SHOWWINDOW
, sent
|wparam
, 1 },
1310 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOACTIVATE
},
1313 static const struct message WmSHOWNATopInvisible
[] = {
1314 { WM_SHOWWINDOW
, sent
|wparam
, 1 },
1315 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
1316 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, 0, 0 },
1317 { WM_NCPAINT
, sent
|wparam
, 1 },
1318 { WM_GETTEXT
, sent
|defwinproc
|optional
},
1319 { WM_ERASEBKGND
, sent
|optional
},
1320 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
1321 { WM_NCCALCSIZE
, sent
|wparam
|optional
, 1 },
1322 { WM_NCPAINT
, sent
|wparam
|optional
, 1 },
1323 { WM_ERASEBKGND
, sent
|optional
},
1324 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
1325 { WM_SIZE
, sent
|wparam
, SIZE_RESTORED
},
1330 static int after_end_dialog
, test_def_id
;
1331 static int sequence_cnt
, sequence_size
;
1332 static struct message
* sequence
;
1333 static int log_all_parent_messages
;
1335 static void add_message(const struct message
*msg
)
1340 sequence
= HeapAlloc( GetProcessHeap(), 0, sequence_size
* sizeof (struct message
) );
1342 if (sequence_cnt
== sequence_size
)
1345 sequence
= HeapReAlloc( GetProcessHeap(), 0, sequence
, sequence_size
* sizeof (struct message
) );
1349 sequence
[sequence_cnt
].message
= msg
->message
;
1350 sequence
[sequence_cnt
].flags
= msg
->flags
;
1351 sequence
[sequence_cnt
].wParam
= msg
->wParam
;
1352 sequence
[sequence_cnt
].lParam
= msg
->lParam
;
1357 /* try to make sure pending X events have been processed before continuing */
1358 static void flush_events(void)
1362 DWORD time
= GetTickCount() + diff
;
1366 MsgWaitForMultipleObjects( 0, NULL
, FALSE
, diff
, QS_ALLINPUT
);
1367 while (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
1368 diff
= time
- GetTickCount();
1372 static void flush_sequence(void)
1374 HeapFree(GetProcessHeap(), 0, sequence
);
1376 sequence_cnt
= sequence_size
= 0;
1379 #define ok_sequence( exp, contx, todo) \
1380 ok_sequence_( (exp), (contx), (todo), __FILE__, __LINE__)
1383 static void ok_sequence_(const struct message
*expected
, const char *context
, int todo
,
1384 const char *file
, int line
)
1386 static const struct message end_of_sequence
= { 0, 0, 0, 0 };
1387 const struct message
*actual
;
1390 add_message(&end_of_sequence
);
1394 while (expected
->message
&& actual
->message
)
1396 trace_( file
, line
)("expected %04x - actual %04x\n", expected
->message
, actual
->message
);
1398 if (expected
->message
== actual
->message
)
1400 if (expected
->flags
& wparam
)
1402 if (expected
->wParam
!= actual
->wParam
&& todo
)
1406 ok_( file
, line
) (FALSE
,
1407 "%s: in msg 0x%04x expecting wParam 0x%x got 0x%x\n",
1408 context
, expected
->message
, expected
->wParam
, actual
->wParam
);
1412 ok_( file
, line
) (expected
->wParam
== actual
->wParam
,
1413 "%s: in msg 0x%04x expecting wParam 0x%x got 0x%x\n",
1414 context
, expected
->message
, expected
->wParam
, actual
->wParam
);
1416 if (expected
->flags
& lparam
)
1418 if (expected
->lParam
!= actual
->lParam
&& todo
)
1422 ok_( file
, line
) (FALSE
,
1423 "%s: in msg 0x%04x expecting lParam 0x%lx got 0x%lx\n",
1424 context
, expected
->message
, expected
->lParam
, actual
->lParam
);
1428 ok_( file
, line
) (expected
->lParam
== actual
->lParam
,
1429 "%s: in msg 0x%04x expecting lParam 0x%lx got 0x%lx\n",
1430 context
, expected
->message
, expected
->lParam
, actual
->lParam
);
1432 if ((expected
->flags
& defwinproc
) != (actual
->flags
& defwinproc
) && todo
)
1436 ok_( file
, line
) (FALSE
,
1437 "%s: the msg 0x%04x should %shave been sent by DefWindowProc\n",
1438 context
, expected
->message
, (expected
->flags
& defwinproc
) ? "" : "NOT ");
1442 ok_( file
, line
) ((expected
->flags
& defwinproc
) == (actual
->flags
& defwinproc
),
1443 "%s: the msg 0x%04x should %shave been sent by DefWindowProc\n",
1444 context
, expected
->message
, (expected
->flags
& defwinproc
) ? "" : "NOT ");
1445 ok_( file
, line
) ((expected
->flags
& beginpaint
) == (actual
->flags
& beginpaint
),
1446 "%s: the msg 0x%04x should %shave been sent by BeginPaint\n",
1447 context
, expected
->message
, (expected
->flags
& beginpaint
) ? "" : "NOT ");
1448 ok_( file
, line
) ((expected
->flags
& (sent
|posted
)) == (actual
->flags
& (sent
|posted
)),
1449 "%s: the msg 0x%04x should have been %s\n",
1450 context
, expected
->message
, (expected
->flags
& posted
) ? "posted" : "sent");
1451 ok_( file
, line
) ((expected
->flags
& parent
) == (actual
->flags
& parent
),
1452 "%s: the msg 0x%04x was expected in %s\n",
1453 context
, expected
->message
, (expected
->flags
& parent
) ? "parent" : "child");
1454 ok_( file
, line
) ((expected
->flags
& hook
) == (actual
->flags
& hook
),
1455 "%s: the msg 0x%04x should have been sent by a hook\n",
1456 context
, expected
->message
);
1457 ok_( file
, line
) ((expected
->flags
& winevent_hook
) == (actual
->flags
& winevent_hook
),
1458 "%s: the msg 0x%04x should have been sent by a winevent hook\n",
1459 context
, expected
->message
);
1463 /* silently drop winevent messages if there is no support for them */
1464 else if ((expected
->flags
& optional
) || ((expected
->flags
& winevent_hook
) && !hEvent_hook
))
1470 ok_( file
, line
) (FALSE
, "%s: the msg 0x%04x was expected, but got msg 0x%04x instead\n",
1471 context
, expected
->message
, actual
->message
);
1478 ok_( file
, line
) (FALSE
, "%s: the msg 0x%04x was expected, but got msg 0x%04x instead\n",
1479 context
, expected
->message
, actual
->message
);
1485 /* skip all optional trailing messages */
1486 while (expected
->message
&& ((expected
->flags
& optional
) ||
1487 ((expected
->flags
& winevent_hook
) && !hEvent_hook
)))
1493 if (expected
->message
|| actual
->message
) {
1495 ok_( file
, line
) (FALSE
, "%s: the msg sequence is not complete: expected %04x - actual %04x\n",
1496 context
, expected
->message
, actual
->message
);
1502 if (expected
->message
|| actual
->message
)
1503 ok_( file
, line
) (FALSE
, "%s: the msg sequence is not complete: expected %04x - actual %04x\n",
1504 context
, expected
->message
, actual
->message
);
1506 if( todo
&& !failcount
) /* succeeded yet marked todo */
1508 ok_( file
, line
)( TRUE
, "%s: marked \"todo_wine\" but succeeds\n", context
);
1514 /******************************** MDI test **********************************/
1516 /* CreateWindow for MDI frame window, initially visible */
1517 static const struct message WmCreateMDIframeSeq
[] = {
1518 { HCBT_CREATEWND
, hook
},
1519 { WM_GETMINMAXINFO
, sent
},
1520 { WM_NCCREATE
, sent
},
1521 { WM_NCCALCSIZE
, sent
|wparam
, 0 },
1522 { EVENT_OBJECT_REORDER
, winevent_hook
|wparam
|lparam
, 0, 0 },
1523 { WM_CREATE
, sent
},
1524 { EVENT_OBJECT_CREATE
, winevent_hook
|wparam
|lparam
, 0, 0 },
1525 { WM_SHOWWINDOW
, sent
|wparam
, 1 },
1526 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
},
1527 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, 0, 0 },
1528 { HCBT_ACTIVATE
, hook
},
1529 { EVENT_SYSTEM_FOREGROUND
, winevent_hook
|wparam
|lparam
, 0, 0 },
1530 { WM_QUERYNEWPALETTE
, sent
|wparam
|lparam
|optional
, 0, 0 },
1531 { WM_WINDOWPOSCHANGING
, sent
|wparam
|optional
, SWP_NOSIZE
|SWP_NOMOVE
}, /* XP */
1532 { WM_ACTIVATEAPP
, sent
|wparam
|optional
, 1 }, /* Win9x doesn't send it */
1533 { WM_NCACTIVATE
, sent
|wparam
, 1 },
1534 { WM_GETTEXT
, sent
|defwinproc
|optional
},
1535 { WM_ACTIVATE
, sent
|wparam
, 1 },
1536 { WM_WINDOWPOSCHANGING
, sent
|wparam
|optional
, SWP_NOSIZE
|SWP_NOMOVE
}, /* Win9x */
1537 { HCBT_SETFOCUS
, hook
},
1538 { WM_IME_SETCONTEXT
, sent
|wparam
|defwinproc
|optional
, 1 },
1539 { WM_IME_NOTIFY
, sent
|wparam
|defwinproc
|optional
, 2 },
1540 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
1541 { WM_SETFOCUS
, sent
|wparam
|defwinproc
, 0 },
1542 /* Win9x adds SWP_NOZORDER below */
1543 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
1544 { WM_NCCALCSIZE
, sent
|wparam
|optional
, 1 }, /* XP */
1545 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
1546 { WM_SIZE
, sent
|wparam
, SIZE_RESTORED
},
1550 /* DestroyWindow for MDI frame window, initially visible */
1551 static const struct message WmDestroyMDIframeSeq
[] = {
1552 { HCBT_DESTROYWND
, hook
},
1553 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_HIDEWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
1554 { EVENT_OBJECT_HIDE
, winevent_hook
|wparam
|lparam
, 0, 0 },
1555 { WM_NCACTIVATE
, sent
|wparam
|optional
, 0 }, /* Win9x */
1556 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_HIDEWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
1557 { WM_NCACTIVATE
, sent
|wparam
|optional
, 0 }, /* XP */
1558 { WM_ACTIVATE
, sent
|wparam
|optional
, 0 }, /* Win9x */
1559 { WM_ACTIVATEAPP
, sent
|wparam
|optional
, 0 }, /* Win9x */
1560 { EVENT_OBJECT_HIDE
, winevent_hook
|wparam
|lparam
, OBJID_CARET
, 0 },
1561 { EVENT_OBJECT_DESTROY
, winevent_hook
|wparam
|lparam
, 0, 0 },
1562 { WM_DESTROY
, sent
},
1563 { WM_NCDESTROY
, sent
},
1566 /* CreateWindow for MDI client window, initially visible */
1567 static const struct message WmCreateMDIclientSeq
[] = {
1568 { HCBT_CREATEWND
, hook
},
1569 { WM_NCCREATE
, sent
},
1570 { WM_NCCALCSIZE
, sent
|wparam
, 0 },
1571 { EVENT_OBJECT_REORDER
, winevent_hook
|wparam
|lparam
|optional
, 0, 0 },
1572 { WM_CREATE
, sent
},
1573 { EVENT_OBJECT_REORDER
, winevent_hook
|wparam
|lparam
|optional
, 0, 0 },
1574 { EVENT_OBJECT_CREATE
, winevent_hook
|wparam
|lparam
, 0, 0 },
1575 { WM_SIZE
, sent
|wparam
, SIZE_RESTORED
},
1577 { WM_PARENTNOTIFY
, sent
|wparam
, WM_CREATE
}, /* in MDI frame */
1578 { WM_SHOWWINDOW
, sent
|wparam
, 1 },
1579 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
1580 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, 0, 0 },
1581 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
1584 /* ShowWindow(SW_SHOW) for MDI client window */
1585 static const struct message WmShowMDIclientSeq
[] = {
1586 { WM_SHOWWINDOW
, sent
|wparam
, 1 },
1587 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
1588 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, 0, 0 },
1589 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
1592 /* ShowWindow(SW_HIDE) for MDI client window */
1593 static const struct message WmHideMDIclientSeq
[] = {
1594 { WM_SHOWWINDOW
, sent
|wparam
, 0 },
1595 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_HIDEWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
1596 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
|optional
, 0, 0 }, /* win2000 */
1597 { EVENT_OBJECT_HIDE
, winevent_hook
|wparam
|lparam
|optional
, 0, 0 }, /* XP */
1598 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_HIDEWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
1601 /* DestroyWindow for MDI client window, initially visible */
1602 static const struct message WmDestroyMDIclientSeq
[] = {
1603 { HCBT_DESTROYWND
, hook
},
1604 { WM_PARENTNOTIFY
, sent
|wparam
, WM_DESTROY
}, /* in MDI frame */
1605 { WM_SHOWWINDOW
, sent
|wparam
, 0 },
1606 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_HIDEWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
1607 { EVENT_OBJECT_HIDE
, winevent_hook
|wparam
|lparam
, 0, 0 },
1608 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_HIDEWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
1609 { EVENT_OBJECT_DESTROY
, winevent_hook
|wparam
|lparam
, 0, 0 },
1610 { WM_DESTROY
, sent
},
1611 { WM_NCDESTROY
, sent
},
1614 /* CreateWindow for MDI child window, initially visible */
1615 static const struct message WmCreateMDIchildVisibleSeq
[] = {
1616 { HCBT_CREATEWND
, hook
},
1617 { WM_NCCREATE
, sent
},
1618 { WM_NCCALCSIZE
, sent
|wparam
, 0 },
1619 { WM_CREATE
, sent
},
1620 { EVENT_OBJECT_CREATE
, winevent_hook
|wparam
|lparam
, 0, 0 },
1621 { WM_SIZE
, sent
|wparam
, SIZE_RESTORED
},
1623 /* Win2k sends wparam set to
1624 * MAKEWPARAM(WM_CREATE, MDI_FIRST_CHILD_ID + nTotalCreated),
1625 * while Win9x doesn't bother to set child window id according to
1626 * CLIENTCREATESTRUCT.idFirstChild
1628 { WM_PARENTNOTIFY
, sent
/*|wparam, WM_CREATE*/ }, /* in MDI client */
1629 { WM_SHOWWINDOW
, sent
|wparam
, 1 },
1630 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
1631 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, 0, 0 },
1632 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
1633 { WM_MDIREFRESHMENU
, sent
/*|wparam|lparam, 0, 0*/ },
1634 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
},
1635 { WM_CHILDACTIVATE
, sent
|wparam
|lparam
, 0, 0 },
1636 { WM_WINDOWPOSCHANGING
, sent
|wparam
|defwinproc
, SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
1638 /* Win9x: message sequence terminates here. */
1640 { WM_NCACTIVATE
, sent
|wparam
|defwinproc
, 1 },
1641 { HCBT_SETFOCUS
, hook
}, /* in MDI client */
1642 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 1 }, /* in MDI client */
1643 { WM_IME_NOTIFY
, sent
|wparam
|optional
, 2 }, /* in MDI client */
1644 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
1645 { WM_SETFOCUS
, sent
}, /* in MDI client */
1646 { HCBT_SETFOCUS
, hook
},
1647 { WM_KILLFOCUS
, sent
}, /* in MDI client */
1648 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 0 }, /* in MDI client */
1649 { WM_IME_SETCONTEXT
, sent
|wparam
|defwinproc
|optional
, 1 },
1650 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
1651 { WM_SETFOCUS
, sent
|defwinproc
},
1652 { WM_MDIACTIVATE
, sent
|defwinproc
},
1655 /* CreateWindow for MDI child window with invisible parent */
1656 static const struct message WmCreateMDIchildInvisibleParentSeq
[] = {
1657 { HCBT_CREATEWND
, hook
},
1658 { WM_GETMINMAXINFO
, sent
},
1659 { WM_NCCREATE
, sent
},
1660 { WM_NCCALCSIZE
, sent
|wparam
, 0 },
1661 { EVENT_OBJECT_REORDER
, winevent_hook
|wparam
|lparam
|optional
, 0, 0 },
1662 { WM_CREATE
, sent
},
1663 { EVENT_OBJECT_CREATE
, winevent_hook
|wparam
|lparam
, 0, 0 },
1664 { WM_SIZE
, sent
|wparam
, SIZE_RESTORED
},
1666 { WM_PARENTNOTIFY
, sent
/*|wparam, WM_CREATE*/ }, /* in MDI client */
1667 { WM_SHOWWINDOW
, sent
|wparam
, 1 },
1668 { WM_MDIREFRESHMENU
, sent
}, /* in MDI client */
1669 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
},
1670 { WM_CHILDACTIVATE
, sent
|wparam
|lparam
, 0, 0 },
1671 { WM_WINDOWPOSCHANGING
, sent
|wparam
|defwinproc
, SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
1673 /* Win9x: message sequence terminates here. */
1675 { WM_NCACTIVATE
, sent
|wparam
|defwinproc
, 1 },
1676 { HCBT_SETFOCUS
, hook
}, /* in MDI client */
1677 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 1 }, /* in MDI client */
1678 { WM_IME_NOTIFY
, sent
|wparam
|optional
, 2 }, /* in MDI client */
1679 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
1680 { WM_SETFOCUS
, sent
}, /* in MDI client */
1681 { HCBT_SETFOCUS
, hook
},
1682 { WM_KILLFOCUS
, sent
}, /* in MDI client */
1683 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 0 }, /* in MDI client */
1684 { WM_IME_SETCONTEXT
, sent
|wparam
|defwinproc
|optional
, 1 },
1685 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
1686 { WM_SETFOCUS
, sent
|defwinproc
},
1687 { WM_MDIACTIVATE
, sent
|defwinproc
},
1690 /* DestroyWindow for MDI child window, initially visible */
1691 static const struct message WmDestroyMDIchildVisibleSeq
[] = {
1692 { HCBT_DESTROYWND
, hook
},
1693 /* Win2k sends wparam set to
1694 * MAKEWPARAM(WM_DESTROY, MDI_FIRST_CHILD_ID + nTotalCreated),
1695 * while Win9x doesn't bother to set child window id according to
1696 * CLIENTCREATESTRUCT.idFirstChild
1698 { WM_PARENTNOTIFY
, sent
/*|wparam, WM_DESTROY*/ }, /* in MDI client */
1699 { WM_SHOWWINDOW
, sent
|wparam
, 0 },
1700 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_HIDEWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
1701 { EVENT_OBJECT_HIDE
, winevent_hook
|wparam
|lparam
, 0, 0 },
1702 { WM_ERASEBKGND
, sent
|parent
|optional
},
1703 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_HIDEWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
1705 /* { WM_DESTROY, sent }
1706 * Win9x: message sequence terminates here.
1709 { HCBT_SETFOCUS
, hook
}, /* set focus to MDI client */
1710 { WM_KILLFOCUS
, sent
},
1711 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 0 },
1712 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 1 }, /* in MDI client */
1713 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
1714 { WM_SETFOCUS
, sent
}, /* in MDI client */
1716 { HCBT_SETFOCUS
, hook
}, /* MDI client sets focus back to MDI child */
1717 { WM_KILLFOCUS
, sent
}, /* in MDI client */
1718 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 0 }, /* in MDI client */
1719 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 1 },
1720 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
1721 { WM_SETFOCUS
, sent
}, /* in MDI client */
1723 { EVENT_OBJECT_DESTROY
, winevent_hook
|wparam
|lparam
, 0, 0 },
1725 { HCBT_SETFOCUS
, hook
}, /* set focus to MDI client */
1726 { WM_KILLFOCUS
, sent
},
1727 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 0 },
1728 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 1 }, /* in MDI client */
1729 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
1730 { WM_SETFOCUS
, sent
}, /* in MDI client */
1732 { HCBT_SETFOCUS
, hook
}, /* MDI client sets focus back to MDI child */
1733 { WM_KILLFOCUS
, sent
}, /* in MDI client */
1734 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 0 }, /* in MDI client */
1735 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 1 },
1736 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
1737 { WM_SETFOCUS
, sent
}, /* in MDI client */
1739 { WM_DESTROY
, sent
},
1741 { HCBT_SETFOCUS
, hook
}, /* set focus to MDI client */
1742 { WM_KILLFOCUS
, sent
},
1743 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 0 },
1744 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 1 }, /* in MDI client */
1745 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
1746 { WM_SETFOCUS
, sent
}, /* in MDI client */
1748 { HCBT_SETFOCUS
, hook
}, /* MDI client sets focus back to MDI child */
1749 { WM_KILLFOCUS
, sent
}, /* in MDI client */
1750 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 0 }, /* in MDI client */
1751 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 1 },
1752 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
1753 { WM_SETFOCUS
, sent
}, /* in MDI client */
1755 { WM_NCDESTROY
, sent
},
1758 /* CreateWindow for MDI child window, initially invisible */
1759 static const struct message WmCreateMDIchildInvisibleSeq
[] = {
1760 { HCBT_CREATEWND
, hook
},
1761 { WM_NCCREATE
, sent
},
1762 { WM_NCCALCSIZE
, sent
|wparam
, 0 },
1763 { WM_CREATE
, sent
},
1764 { EVENT_OBJECT_CREATE
, winevent_hook
|wparam
|lparam
, 0, 0 },
1765 { WM_SIZE
, sent
|wparam
, SIZE_RESTORED
},
1767 /* Win2k sends wparam set to
1768 * MAKEWPARAM(WM_CREATE, MDI_FIRST_CHILD_ID + nTotalCreated),
1769 * while Win9x doesn't bother to set child window id according to
1770 * CLIENTCREATESTRUCT.idFirstChild
1772 { WM_PARENTNOTIFY
, sent
/*|wparam, WM_CREATE*/ }, /* in MDI client */
1775 /* DestroyWindow for MDI child window, initially invisible */
1776 static const struct message WmDestroyMDIchildInvisibleSeq
[] = {
1777 { HCBT_DESTROYWND
, hook
},
1778 /* Win2k sends wparam set to
1779 * MAKEWPARAM(WM_DESTROY, MDI_FIRST_CHILD_ID + nTotalCreated),
1780 * while Win9x doesn't bother to set child window id according to
1781 * CLIENTCREATESTRUCT.idFirstChild
1783 { WM_PARENTNOTIFY
, sent
/*|wparam, WM_DESTROY*/ }, /* in MDI client */
1784 { EVENT_OBJECT_DESTROY
, winevent_hook
|wparam
|lparam
, 0, 0 },
1785 { WM_DESTROY
, sent
},
1786 { WM_NCDESTROY
, sent
},
1787 /* FIXME: Wine destroys an icon/title window while Windows doesn't */
1788 { WM_PARENTNOTIFY
, sent
|wparam
|optional
, WM_DESTROY
}, /* MDI client */
1791 /* CreateWindow for the 1st MDI child window, initially visible and maximized */
1792 static const struct message WmCreateMDIchildVisibleMaxSeq1
[] = {
1793 { HCBT_CREATEWND
, hook
},
1794 { WM_NCCREATE
, sent
},
1795 { WM_NCCALCSIZE
, sent
|wparam
, 0 },
1796 { WM_CREATE
, sent
},
1797 { EVENT_OBJECT_CREATE
, winevent_hook
|wparam
|lparam
, 0, 0 },
1798 { WM_SIZE
, sent
|wparam
, SIZE_RESTORED
},
1800 { HCBT_MINMAX
, hook
|lparam
, 0, SW_MAXIMIZE
},
1801 { WM_GETMINMAXINFO
, sent
},
1802 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|0x8000 },
1803 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
1804 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOREDRAW
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
|0x8000 },
1805 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_MAXIMIZED
},
1807 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
1808 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
1809 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
1810 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI frame */
1811 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI child */
1812 /* Win2k sends wparam set to
1813 * MAKEWPARAM(WM_CREATE, MDI_FIRST_CHILD_ID + nTotalCreated),
1814 * while Win9x doesn't bother to set child window id according to
1815 * CLIENTCREATESTRUCT.idFirstChild
1817 { WM_PARENTNOTIFY
, sent
/*|wparam, WM_CREATE*/ }, /* in MDI client */
1818 { WM_SHOWWINDOW
, sent
|wparam
, 1 },
1819 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
1820 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, 0, 0 },
1821 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
1822 { WM_MDIREFRESHMENU
, sent
/*|wparam|lparam, 0, 0*/ },
1823 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
},
1824 { WM_CHILDACTIVATE
, sent
|wparam
|lparam
, 0, 0 },
1825 { WM_WINDOWPOSCHANGING
, sent
|wparam
|defwinproc
, SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
1827 /* Win9x: message sequence terminates here. */
1829 { WM_NCACTIVATE
, sent
|wparam
|defwinproc
, 1 },
1830 { HCBT_SETFOCUS
, hook
}, /* in MDI client */
1831 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 1 }, /* in MDI client */
1832 { WM_IME_NOTIFY
, sent
|wparam
|optional
, 2 }, /* in MDI client */
1833 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
1834 { WM_SETFOCUS
, sent
}, /* in MDI client */
1835 { HCBT_SETFOCUS
, hook
},
1836 { WM_KILLFOCUS
, sent
}, /* in MDI client */
1837 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 0 }, /* in MDI client */
1838 { WM_IME_SETCONTEXT
, sent
|wparam
|defwinproc
|optional
, 1 },
1839 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
1840 { WM_SETFOCUS
, sent
|defwinproc
},
1841 { WM_MDIACTIVATE
, sent
|defwinproc
},
1843 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
1844 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
1845 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
1846 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI frame */
1849 /* CreateWindow for the 2nd MDI child window, initially visible and maximized */
1850 static const struct message WmCreateMDIchildVisibleMaxSeq2
[] = {
1851 /* restore the 1st MDI child */
1852 { WM_SETREDRAW
, sent
|wparam
, 0 },
1853 { HCBT_MINMAX
, hook
|lparam
, 0, SW_SHOWNORMAL
},
1854 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|0x8000 },
1855 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
1856 { WM_CHILDACTIVATE
, sent
|wparam
|lparam
, 0, 0 },
1857 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOREDRAW
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
|0x8000 },
1858 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_RESTORED
},
1860 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
1861 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
1862 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
1863 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI frame */
1864 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI child */
1865 { WM_SETREDRAW
, sent
|wparam
, 1 }, /* in the 1st MDI child */
1866 /* create the 2nd MDI child */
1867 { HCBT_CREATEWND
, hook
},
1868 { WM_NCCREATE
, sent
},
1869 { WM_NCCALCSIZE
, sent
|wparam
, 0 },
1870 { WM_CREATE
, sent
},
1871 { EVENT_OBJECT_CREATE
, winevent_hook
|wparam
|lparam
, 0, 0 },
1872 { WM_SIZE
, sent
|wparam
, SIZE_RESTORED
},
1874 { HCBT_MINMAX
, hook
|lparam
, 0, SW_MAXIMIZE
},
1875 { WM_GETMINMAXINFO
, sent
},
1876 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|0x8000 },
1877 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
1878 { EVENT_OBJECT_REORDER
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
1879 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOREDRAW
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
|0x8000 },
1880 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_MAXIMIZED
},
1882 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
1883 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
1884 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
1885 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI frame */
1886 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI child */
1887 /* Win2k sends wparam set to
1888 * MAKEWPARAM(WM_CREATE, MDI_FIRST_CHILD_ID + nTotalCreated),
1889 * while Win9x doesn't bother to set child window id according to
1890 * CLIENTCREATESTRUCT.idFirstChild
1892 { WM_PARENTNOTIFY
, sent
/*|wparam, WM_CREATE*/ }, /* in MDI client */
1893 { WM_SHOWWINDOW
, sent
|wparam
, 1 },
1894 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
1895 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, 0, 0 },
1896 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
1897 { WM_MDIREFRESHMENU
, sent
/*|wparam|lparam, 0, 0*/ },
1898 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
},
1899 { WM_CHILDACTIVATE
, sent
|wparam
|lparam
, 0, 0 },
1901 { WM_NCACTIVATE
, sent
|wparam
|defwinproc
, 0 }, /* in the 1st MDI child */
1902 { WM_MDIACTIVATE
, sent
|defwinproc
}, /* in the 1st MDI child */
1904 { WM_WINDOWPOSCHANGING
, sent
|wparam
|defwinproc
, SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
1906 /* Win9x: message sequence terminates here. */
1908 { WM_NCACTIVATE
, sent
|wparam
|defwinproc
, 1 },
1909 { HCBT_SETFOCUS
, hook
},
1910 { WM_KILLFOCUS
, sent
|defwinproc
}, /* in the 1st MDI child */
1911 { WM_IME_SETCONTEXT
, sent
|wparam
|defwinproc
|optional
, 0 }, /* in the 1st MDI child */
1912 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 1 }, /* in MDI client */
1913 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
1914 { WM_SETFOCUS
, sent
}, /* in MDI client */
1915 { HCBT_SETFOCUS
, hook
},
1916 { WM_KILLFOCUS
, sent
}, /* in MDI client */
1917 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 0 }, /* in MDI client */
1918 { WM_IME_SETCONTEXT
, sent
|wparam
|defwinproc
|optional
, 1 },
1919 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
1920 { WM_SETFOCUS
, sent
|defwinproc
},
1922 { WM_MDIACTIVATE
, sent
|defwinproc
},
1924 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
1925 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
1926 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
1927 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI frame */
1930 /* WM_MDICREATE MDI child window, initially visible and maximized */
1931 static const struct message WmCreateMDIchildVisibleMaxSeq3
[] = {
1932 { WM_MDICREATE
, sent
},
1933 { HCBT_CREATEWND
, hook
},
1934 { WM_NCCREATE
, sent
},
1935 { WM_NCCALCSIZE
, sent
|wparam
, 0 },
1936 { WM_CREATE
, sent
},
1937 { EVENT_OBJECT_CREATE
, winevent_hook
|wparam
|lparam
, 0, 0 },
1938 { WM_SIZE
, sent
|wparam
, SIZE_RESTORED
},
1940 { HCBT_MINMAX
, hook
|lparam
, 0, SW_MAXIMIZE
},
1941 { WM_GETMINMAXINFO
, sent
},
1942 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|0x8000 },
1943 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
1944 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOREDRAW
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
|0x8000 },
1945 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_MAXIMIZED
},
1948 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
1949 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
1950 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
1951 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI frame */
1952 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI child */
1954 /* Win2k sends wparam set to
1955 * MAKEWPARAM(WM_CREATE, MDI_FIRST_CHILD_ID + nTotalCreated),
1956 * while Win9x doesn't bother to set child window id according to
1957 * CLIENTCREATESTRUCT.idFirstChild
1959 { WM_PARENTNOTIFY
, sent
/*|wparam, WM_CREATE*/ }, /* in MDI client */
1960 { WM_SHOWWINDOW
, sent
|wparam
, 1 },
1961 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
1963 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, 0, 0 },
1965 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
1966 { WM_MDIREFRESHMENU
, sent
/*|wparam|lparam, 0, 0*/ },
1967 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
},
1969 { WM_CHILDACTIVATE
, sent
|wparam
|lparam
, 0, 0 },
1970 { WM_WINDOWPOSCHANGING
, sent
|wparam
|defwinproc
, SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
1972 /* Win9x: message sequence terminates here. */
1974 { WM_NCACTIVATE
, sent
|wparam
|defwinproc
, 1 },
1975 { WM_SETFOCUS
, sent
|optional
}, /* in MDI client */
1976 { HCBT_SETFOCUS
, hook
}, /* in MDI client */
1977 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 1 }, /* in MDI client */
1978 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
|optional
, OBJID_CLIENT
, 0 },
1979 { WM_SETFOCUS
, sent
|optional
}, /* in MDI client */
1980 { HCBT_SETFOCUS
, hook
|optional
},
1981 { WM_KILLFOCUS
, sent
}, /* in MDI client */
1982 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 0 }, /* in MDI client */
1983 { WM_IME_SETCONTEXT
, sent
|wparam
|defwinproc
|optional
, 1 },
1984 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
1985 { WM_SETFOCUS
, sent
|defwinproc
},
1987 { WM_MDIACTIVATE
, sent
|defwinproc
},
1990 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
1991 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
1992 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
1993 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
1996 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
1997 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
1998 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
1999 { WM_MOVE
, sent
|defwinproc
},
2000 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_RESTORED
},
2003 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_NOACTIVATE
},
2004 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
2005 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_NOACTIVATE
|SWP_NOMOVE
|SWP_NOCLIENTMOVE
},
2006 { WM_SIZE
, sent
|wparam
, SIZE_RESTORED
},
2009 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_NOACTIVATE
},
2010 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
2011 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_NOACTIVATE
|SWP_NOMOVE
|SWP_NOCLIENTMOVE
},
2012 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_MAXIMIZED
},
2014 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI child */
2015 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI client */
2016 { WM_NCCALCSIZE
, sent
|wparam
|optional
, 1 }, /* XP sends it to MDI frame */
2017 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI frame */
2018 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* XP sends a duplicate */
2022 /* CreateWindow for the 1st MDI child window, initially invisible and maximized */
2023 static const struct message WmCreateMDIchildInvisibleMaxSeq4
[] = {
2024 { HCBT_CREATEWND
, hook
},
2025 { WM_GETMINMAXINFO
, sent
},
2026 { WM_NCCREATE
, sent
},
2027 { WM_NCCALCSIZE
, sent
|wparam
, 0 },
2028 { EVENT_OBJECT_REORDER
, winevent_hook
|wparam
|lparam
, 0, 0 },
2029 { WM_CREATE
, sent
},
2030 { EVENT_OBJECT_CREATE
, winevent_hook
|wparam
|lparam
, 0, 0 },
2031 { WM_SIZE
, sent
|wparam
, SIZE_RESTORED
},
2033 { HCBT_MINMAX
, hook
|lparam
, 0, SW_MAXIMIZE
},
2034 { WM_GETMINMAXINFO
, sent
},
2035 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|0x8000 },
2036 { WM_GETMINMAXINFO
, sent
|defwinproc
},
2037 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
2038 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOREDRAW
|SWP_NOCLIENTSIZE
|0x8000 },
2039 { WM_MOVE
, sent
|defwinproc
},
2040 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_MAXIMIZED
},
2042 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
2043 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
2044 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
2045 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI frame */
2046 { WM_NCCALCSIZE
, sent
|wparam
|optional
, 1 }, /* MDI child */
2047 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI child */
2048 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI child */
2049 /* Win2k sends wparam set to
2050 * MAKEWPARAM(WM_CREATE, MDI_FIRST_CHILD_ID + nTotalCreated),
2051 * while Win9x doesn't bother to set child window id according to
2052 * CLIENTCREATESTRUCT.idFirstChild
2054 { WM_PARENTNOTIFY
, sent
/*|wparam, WM_CREATE*/ }, /* in MDI client */
2057 /* WM_SYSCOMMAND/SC_CLOSE for the 2nd MDI child window, initially visible and maximized */
2058 static const struct message WmDestroyMDIchildVisibleMaxSeq2
[] = {
2059 { WM_SYSCOMMAND
, sent
|wparam
, SC_CLOSE
},
2060 { HCBT_SYSCOMMAND
, hook
},
2061 { WM_CLOSE
, sent
|defwinproc
},
2062 { WM_MDIDESTROY
, sent
}, /* in MDI client */
2064 /* bring the 1st MDI child to top */
2065 { WM_WINDOWPOSCHANGING
, sent
|wparam
|defwinproc
, SWP_NOSIZE
|SWP_NOMOVE
}, /* in the 1st MDI child */
2066 { WM_WINDOWPOSCHANGING
, sent
|wparam
|defwinproc
, SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
}, /* in the 2nd MDI child */
2068 { EVENT_OBJECT_REORDER
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
2070 { WM_CHILDACTIVATE
, sent
|defwinproc
|wparam
|lparam
, 0, 0 }, /* in the 1st MDI child */
2071 { WM_NCACTIVATE
, sent
|wparam
|defwinproc
, 0 }, /* in the 1st MDI child */
2072 { WM_MDIACTIVATE
, sent
|defwinproc
}, /* in the 1st MDI child */
2074 /* maximize the 1st MDI child */
2075 { HCBT_MINMAX
, hook
|lparam
, 0, SW_MAXIMIZE
},
2076 { WM_GETMINMAXINFO
, sent
|defwinproc
},
2077 { WM_WINDOWPOSCHANGING
, sent
|wparam
|defwinproc
, SWP_FRAMECHANGED
|0x8000 },
2078 { WM_NCCALCSIZE
, sent
|defwinproc
|wparam
, 1 },
2079 { WM_CHILDACTIVATE
, sent
|defwinproc
|wparam
|lparam
, 0, 0 },
2080 { WM_WINDOWPOSCHANGED
, sent
|wparam
|defwinproc
, SWP_FRAMECHANGED
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOREDRAW
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
|0x8000 },
2081 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_MAXIMIZED
},
2083 /* restore the 2nd MDI child */
2084 { WM_SETREDRAW
, sent
|defwinproc
|wparam
, 0 },
2085 { HCBT_MINMAX
, hook
|lparam
, 0, SW_NORMALNA
},
2086 { WM_WINDOWPOSCHANGING
, sent
|wparam
|defwinproc
, SWP_NOACTIVATE
|SWP_FRAMECHANGED
|SWP_SHOWWINDOW
|0x8000 },
2087 { WM_NCCALCSIZE
, sent
|defwinproc
|wparam
, 1 },
2089 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, 0, 0 },
2091 { WM_WINDOWPOSCHANGED
, sent
|wparam
|defwinproc
, SWP_NOACTIVATE
|SWP_FRAMECHANGED
|SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOREDRAW
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
|0x8000 },
2092 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_RESTORED
},
2094 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI frame */
2096 { WM_SETREDRAW
, sent
|defwinproc
|wparam
, 1 },
2098 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
2099 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
2100 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
2101 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI frame */
2102 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI child */
2104 /* bring the 1st MDI child to top */
2105 { WM_WINDOWPOSCHANGING
, sent
|wparam
|defwinproc
, SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
2106 { WM_NCACTIVATE
, sent
|wparam
|defwinproc
, 1 },
2107 { HCBT_SETFOCUS
, hook
},
2108 { WM_KILLFOCUS
, sent
|defwinproc
},
2109 { WM_IME_SETCONTEXT
, sent
|wparam
|defwinproc
|optional
, 0 },
2110 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 1 }, /* in MDI client */
2111 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
2112 { WM_SETFOCUS
, sent
}, /* in MDI client */
2113 { HCBT_SETFOCUS
, hook
},
2114 { WM_KILLFOCUS
, sent
}, /* in MDI client */
2115 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 0 }, /* in MDI client */
2116 { WM_IME_SETCONTEXT
, sent
|wparam
|defwinproc
|optional
, 1 },
2117 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
2118 { WM_SETFOCUS
, sent
|defwinproc
},
2119 { WM_MDIACTIVATE
, sent
|defwinproc
},
2120 { WM_WINDOWPOSCHANGED
, sent
|wparam
|defwinproc
, SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOREDRAW
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
2122 /* apparently ShowWindow(SW_SHOW) on an MDI client */
2123 { WM_SHOWWINDOW
, sent
|wparam
, 1 },
2124 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
2125 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, 0, 0 },
2126 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
2127 { WM_MDIREFRESHMENU
, sent
},
2129 { HCBT_DESTROYWND
, hook
},
2130 /* Win2k sends wparam set to
2131 * MAKEWPARAM(WM_DESTROY, MDI_FIRST_CHILD_ID + nTotalCreated),
2132 * while Win9x doesn't bother to set child window id according to
2133 * CLIENTCREATESTRUCT.idFirstChild
2135 { WM_PARENTNOTIFY
, sent
/*|wparam, WM_DESTROY*/ }, /* in MDI client */
2136 { WM_SHOWWINDOW
, sent
|defwinproc
|wparam
, 0 },
2137 { WM_WINDOWPOSCHANGING
, sent
|wparam
|defwinproc
, SWP_HIDEWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
2138 { EVENT_OBJECT_HIDE
, winevent_hook
|wparam
|lparam
, 0, 0 },
2139 { WM_ERASEBKGND
, sent
|parent
|optional
},
2140 { WM_WINDOWPOSCHANGED
, sent
|wparam
|defwinproc
, SWP_HIDEWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
2142 { EVENT_OBJECT_DESTROY
, winevent_hook
|wparam
|lparam
, 0, 0 },
2143 { WM_DESTROY
, sent
|defwinproc
},
2144 { WM_NCDESTROY
, sent
|defwinproc
},
2147 /* WM_MDIDESTROY for the single MDI child window, initially visible and maximized */
2148 static const struct message WmDestroyMDIchildVisibleMaxSeq1
[] = {
2149 { WM_MDIDESTROY
, sent
}, /* in MDI client */
2150 { WM_SHOWWINDOW
, sent
|wparam
, 0 },
2151 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_HIDEWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
2152 { EVENT_OBJECT_HIDE
, winevent_hook
|wparam
|lparam
, 0, 0 },
2153 { WM_ERASEBKGND
, sent
|parent
|optional
},
2154 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_HIDEWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
2156 { HCBT_SETFOCUS
, hook
},
2157 { WM_KILLFOCUS
, sent
},
2158 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 0 },
2159 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 1 }, /* in MDI client */
2160 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
2161 { WM_SETFOCUS
, sent
}, /* in MDI client */
2162 { HCBT_SETFOCUS
, hook
},
2163 { WM_KILLFOCUS
, sent
}, /* in MDI client */
2164 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 0 }, /* in MDI client */
2165 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 1 },
2166 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
2167 { WM_SETFOCUS
, sent
},
2170 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
2171 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
2172 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOREDRAW
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
2173 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI child */
2176 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
2177 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
2178 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
2179 { WM_MOVE
, sent
|defwinproc
},
2180 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_RESTORED
},
2183 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_NOACTIVATE
},
2184 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
2185 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_NOACTIVATE
|SWP_NOMOVE
|SWP_NOCLIENTMOVE
},
2186 { WM_SIZE
, sent
|wparam
, SIZE_RESTORED
},
2189 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_NOACTIVATE
},
2190 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
2191 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_NOACTIVATE
|SWP_NOMOVE
|SWP_NOREDRAW
|SWP_NOCLIENTMOVE
},
2192 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_MAXIMIZED
},
2195 { WM_WINDOWPOSCHANGING
, sent
|wparam
|defwinproc
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
2196 { WM_NCCALCSIZE
, sent
|wparam
|defwinproc
, 1 },
2197 { WM_WINDOWPOSCHANGED
, sent
|wparam
|defwinproc
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOREDRAW
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
2198 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI child */
2201 { WM_WINDOWPOSCHANGING
, sent
|wparam
|defwinproc
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
2202 { WM_NCCALCSIZE
, sent
|wparam
|defwinproc
, 1 },
2203 { WM_WINDOWPOSCHANGED
, sent
|wparam
|defwinproc
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
2204 { WM_MOVE
, sent
|defwinproc
},
2205 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_RESTORED
},
2208 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_NOACTIVATE
},
2209 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
2210 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_NOACTIVATE
|SWP_NOMOVE
|SWP_NOCLIENTMOVE
},
2211 { WM_SIZE
, sent
|wparam
, SIZE_RESTORED
},
2214 { WM_WINDOWPOSCHANGING
, sent
|wparam
|defwinproc
, SWP_NOACTIVATE
},
2215 { WM_NCCALCSIZE
, sent
|wparam
|defwinproc
, 1 },
2216 { WM_WINDOWPOSCHANGED
, sent
|wparam
|defwinproc
, SWP_NOACTIVATE
|SWP_NOMOVE
|SWP_NOREDRAW
|SWP_NOCLIENTMOVE
},
2217 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_MAXIMIZED
},
2218 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI child */
2219 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI client */
2221 { WM_NCCALCSIZE
, sent
|wparam
|defwinproc
|optional
, 1 }, /* XP sends it to MDI frame */
2223 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI frame */
2224 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI child */
2225 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI client */
2226 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI frame */
2227 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* XP sends a duplicate */
2230 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
2231 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
2232 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
2233 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI frame */
2235 { WM_NCACTIVATE
, sent
|wparam
, 0 },
2236 { WM_MDIACTIVATE
, sent
},
2238 { HCBT_MINMAX
, hook
|lparam
, 0, SW_SHOWNORMAL
},
2239 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_SHOWWINDOW
|0x8000 },
2240 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
2242 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, 0, 0 },
2244 { WM_CHILDACTIVATE
, sent
|wparam
|lparam
, 0, 0 },
2245 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_SHOWWINDOW
|SWP_NOMOVE
|SWP_NOCLIENTMOVE
|0x8000 },
2246 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_RESTORED
},
2249 { WM_WINDOWPOSCHANGING
, sent
|wparam
|defwinproc
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
2250 { WM_NCCALCSIZE
, sent
|wparam
|defwinproc
, 1 },
2251 { WM_WINDOWPOSCHANGED
, sent
|wparam
|defwinproc
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
2252 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI child */
2255 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
2256 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
2257 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
2258 { WM_MOVE
, sent
|defwinproc
},
2259 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_RESTORED
},
2262 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_NOACTIVATE
},
2263 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
2264 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_NOACTIVATE
|SWP_NOMOVE
|SWP_NOCLIENTMOVE
},
2265 { WM_SIZE
, sent
|wparam
, SIZE_RESTORED
},
2266 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI child */
2267 { WM_NCCALCSIZE
, sent
|wparam
|optional
, 1 }, /* XP */
2268 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI client */
2269 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI frame */
2270 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* XP sends a duplicate */
2272 { HCBT_SETFOCUS
, hook
},
2273 { WM_KILLFOCUS
, sent
},
2274 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 0 },
2275 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 1 }, /* in MDI client */
2276 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
2277 { WM_SETFOCUS
, sent
}, /* in MDI client */
2279 { WM_MDIREFRESHMENU
, sent
}, /* in MDI client */
2281 { HCBT_DESTROYWND
, hook
},
2282 /* Win2k sends wparam set to
2283 * MAKEWPARAM(WM_DESTROY, MDI_FIRST_CHILD_ID + nTotalCreated),
2284 * while Win9x doesn't bother to set child window id according to
2285 * CLIENTCREATESTRUCT.idFirstChild
2287 { WM_PARENTNOTIFY
, sent
/*|wparam, WM_DESTROY*/ }, /* in MDI client */
2289 { WM_SHOWWINDOW
, sent
|wparam
, 0 },
2290 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_HIDEWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
2291 { EVENT_OBJECT_HIDE
, winevent_hook
|wparam
|lparam
, 0, 0 },
2292 { WM_ERASEBKGND
, sent
|parent
|optional
},
2293 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_HIDEWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
2295 { EVENT_OBJECT_DESTROY
, winevent_hook
|wparam
|lparam
, 0, 0 },
2296 { WM_DESTROY
, sent
},
2297 { WM_NCDESTROY
, sent
},
2300 /* ShowWindow(SW_MAXIMIZE) for a not visible MDI child window */
2301 static const struct message WmMaximizeMDIchildInvisibleSeq
[] = {
2302 { HCBT_MINMAX
, hook
|lparam
, 0, SW_MAXIMIZE
},
2303 { WM_GETMINMAXINFO
, sent
},
2304 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_FRAMECHANGED
|0x8000 },
2305 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
2306 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, 0, 0 },
2307 { WM_CHILDACTIVATE
, sent
|wparam
|lparam
, 0, 0 },
2309 { WM_WINDOWPOSCHANGING
, sent
|wparam
|defwinproc
, SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
2310 { WM_NCACTIVATE
, sent
|wparam
|defwinproc
, 1 },
2311 { HCBT_SETFOCUS
, hook
},
2312 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 1 }, /* in MDI client */
2313 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
2314 { WM_SETFOCUS
, sent
}, /* in MDI client */
2315 { HCBT_SETFOCUS
, hook
},
2316 { WM_KILLFOCUS
, sent
}, /* in MDI client */
2317 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 0 }, /* in MDI client */
2318 { WM_IME_SETCONTEXT
, sent
|wparam
|defwinproc
|optional
, 1 },
2319 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
2320 { WM_SETFOCUS
, sent
|defwinproc
},
2321 { WM_MDIACTIVATE
, sent
|defwinproc
},
2322 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_FRAMECHANGED
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
|0x8000 },
2323 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_MAXIMIZED
},
2325 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
2326 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
2327 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
2328 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI frame */
2329 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI child */
2332 /* ShowWindow(SW_MAXIMIZE) for a not visible maximized MDI child window */
2333 static const struct message WmMaximizeMDIchildInvisibleSeq2
[] = {
2334 { HCBT_MINMAX
, hook
|lparam
, 0, SW_MAXIMIZE
},
2335 { WM_GETMINMAXINFO
, sent
},
2336 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_FRAMECHANGED
},
2337 { WM_GETMINMAXINFO
, sent
|defwinproc
},
2338 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
2339 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, 0, 0 },
2340 { WM_CHILDACTIVATE
, sent
|wparam
|lparam
, 0, 0 },
2342 { WM_WINDOWPOSCHANGING
, sent
|wparam
|defwinproc
, SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
2343 { WM_NCACTIVATE
, sent
|wparam
|defwinproc
, 1 },
2344 { HCBT_SETFOCUS
, hook
},
2345 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 1 }, /* in MDI client */
2346 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
2347 { WM_SETFOCUS
, sent
}, /* in MDI client */
2348 { HCBT_SETFOCUS
, hook
},
2349 { WM_KILLFOCUS
, sent
}, /* in MDI client */
2350 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 0 }, /* in MDI client */
2351 { WM_IME_SETCONTEXT
, sent
|wparam
|defwinproc
|optional
, 1 },
2352 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
2353 { WM_SETFOCUS
, sent
|defwinproc
},
2354 { WM_MDIACTIVATE
, sent
|defwinproc
},
2355 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_FRAMECHANGED
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
2356 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI child */
2359 /* WM_MDIMAXIMIZE for an MDI child window with invisible parent */
2360 static const struct message WmMaximizeMDIchildInvisibleParentSeq
[] = {
2361 { WM_MDIMAXIMIZE
, sent
}, /* in MDI client */
2362 { HCBT_MINMAX
, hook
|lparam
, 0, SW_MAXIMIZE
},
2363 { WM_GETMINMAXINFO
, sent
},
2364 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|0x8000 },
2365 { WM_GETMINMAXINFO
, sent
|defwinproc
},
2366 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
2367 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
|optional
, 0, 0 }, /* XP doesn't send it */
2368 { WM_CHILDACTIVATE
, sent
|wparam
|lparam
, 0, 0 },
2369 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOREDRAW
|0x8000 },
2370 { WM_MOVE
, sent
|defwinproc
},
2371 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_MAXIMIZED
},
2373 { WM_WINDOWPOSCHANGING
, sent
|wparam
|defwinproc
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
2374 { WM_NCCALCSIZE
, sent
|wparam
|defwinproc
, 1 },
2375 { WM_WINDOWPOSCHANGED
, sent
|wparam
|defwinproc
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOREDRAW
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
2376 { WM_NCCALCSIZE
, sent
|wparam
|defwinproc
|optional
, 1 },
2377 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
|optional
, 0, 0 }, /* MDI child XP */
2378 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
|optional
, 0, 0 }, /* MDI client XP */
2380 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
2381 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
2382 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
2383 { WM_MOVE
, sent
|defwinproc
},
2384 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_RESTORED
},
2385 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
|optional
, 0, 0 }, /* MDI frame win2000 */
2387 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_NOACTIVATE
},
2388 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
2389 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_NOACTIVATE
|SWP_NOMOVE
|SWP_NOREDRAW
|SWP_NOCLIENTMOVE
},
2390 { WM_SIZE
, sent
|wparam
, SIZE_RESTORED
},
2392 { WM_WINDOWPOSCHANGING
, sent
|wparam
|defwinproc
, SWP_NOACTIVATE
},
2393 { WM_GETMINMAXINFO
, sent
|defwinproc
},
2394 { WM_NCCALCSIZE
, sent
|wparam
|defwinproc
, 1 },
2395 { WM_WINDOWPOSCHANGED
, sent
|wparam
|defwinproc
, SWP_NOACTIVATE
|SWP_NOMOVE
|SWP_NOREDRAW
|SWP_NOCLIENTMOVE
},
2396 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_MAXIMIZED
},
2397 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
|optional
, 0, 0 }, /* MDI child win2000 */
2398 { WM_NCCALCSIZE
, sent
|wparam
|defwinproc
|optional
, 1 },
2399 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
|optional
, 0, 0 }, /* MDI child XP */
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 client XP */
2403 { WM_NCCALCSIZE
, sent
|wparam
|optional
, 1 },
2404 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
|optional
, 0, 0 }, /* MDI frame XP */
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 child XP */
2409 /* ShowWindow(SW_MAXIMIZE) for a visible MDI child window */
2410 static const struct message WmMaximizeMDIchildVisibleSeq
[] = {
2411 { HCBT_MINMAX
, hook
|lparam
, 0, SW_MAXIMIZE
},
2412 { WM_GETMINMAXINFO
, sent
},
2413 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|0x8000 },
2414 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
2415 { WM_CHILDACTIVATE
, sent
|wparam
|lparam
, 0, 0 },
2416 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
|0x8000 },
2417 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_MAXIMIZED
},
2419 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
2420 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
2421 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
2422 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI frame */
2423 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI child */
2426 /* ShowWindow(SW_RESTORE) for a visible maximized MDI child window */
2427 static const struct message WmRestoreMDIchildVisibleSeq
[] = {
2428 { HCBT_MINMAX
, hook
|lparam
, 0, SW_RESTORE
},
2429 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|0x8000 },
2430 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
2431 { WM_CHILDACTIVATE
, sent
|wparam
|lparam
, 0, 0 },
2432 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
|0x8000 },
2433 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_RESTORED
},
2435 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
2436 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
2437 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
2438 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI frame */
2439 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI child */
2442 /* ShowWindow(SW_RESTORE) for a visible minimized MDI child window */
2443 static const struct message WmRestoreMDIchildVisibleSeq_2
[] = {
2444 { HCBT_MINMAX
, hook
|lparam
, 0, SW_RESTORE
},
2445 { WM_QUERYOPEN
, sent
|wparam
|lparam
, 0, 0 },
2446 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOCOPYBITS
|0x8000 },
2447 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
2448 { WM_CHILDACTIVATE
, sent
|wparam
|lparam
, 0, 0 },
2449 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOCOPYBITS
|SWP_NOCLIENTSIZE
|0x8000 },
2450 { WM_MOVE
, sent
|defwinproc
},
2451 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_RESTORED
},
2452 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI child */
2453 { EVENT_SYSTEM_MINIMIZEEND
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI child */
2454 { HCBT_SETFOCUS
, hook
},
2455 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 1 },
2456 { WM_IME_NOTIFY
, sent
|wparam
|defwinproc
|optional
, 2 },
2457 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
2458 { WM_SETFOCUS
, sent
},
2461 /* ShowWindow(SW_MINIMIZE) for a visible restored MDI child window */
2462 static const struct message WmMinimizeMDIchildVisibleSeq
[] = {
2463 { HCBT_MINMAX
, hook
|lparam
, 0, SW_MINIMIZE
},
2464 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOCOPYBITS
|0x8000 },
2465 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
2466 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOCOPYBITS
|SWP_NOCLIENTSIZE
|0x8000 },
2467 { WM_MOVE
, sent
|defwinproc
},
2468 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_MINIMIZED
},
2469 { WM_CHILDACTIVATE
, sent
|wparam
|lparam
|defwinproc
, 0, 0 },
2470 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI child */
2471 { EVENT_SYSTEM_MINIMIZESTART
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI child */
2472 /* FIXME: Wine creates an icon/title window while Windows doesn't */
2473 { WM_PARENTNOTIFY
, sent
|parent
|wparam
|optional
, WM_CREATE
}, /* MDI client */
2476 /* ShowWindow(SW_RESTORE) for a not visible MDI child window */
2477 static const struct message WmRestoreMDIchildInisibleSeq
[] = {
2478 { HCBT_MINMAX
, hook
|lparam
, 0, SW_RESTORE
},
2479 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_FRAMECHANGED
|0x8000 },
2480 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
2481 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, 0, 0 },
2482 { WM_CHILDACTIVATE
, sent
|wparam
|lparam
, 0, 0 },
2483 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_FRAMECHANGED
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
|0x8000 },
2484 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_RESTORED
},
2486 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
2487 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
2488 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
2489 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI frame */
2490 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI child */
2494 static HWND mdi_client
;
2495 static WNDPROC old_mdi_client_proc
;
2497 static LRESULT WINAPI
mdi_client_hook_proc(HWND hwnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
2501 /* do not log painting messages */
2502 if (message
!= WM_PAINT
&&
2503 message
!= WM_NCPAINT
&&
2504 message
!= WM_SYNCPAINT
&&
2505 message
!= WM_ERASEBKGND
&&
2506 message
!= WM_NCPAINT
&&
2507 message
!= WM_NCHITTEST
&&
2508 message
!= WM_GETTEXT
&&
2509 message
!= WM_MDIGETACTIVE
&&
2510 message
!= WM_GETICON
&&
2511 message
!= WM_DEVICECHANGE
)
2513 trace("mdi client: %p, %04x, %08x, %08lx\n", hwnd
, message
, wParam
, lParam
);
2517 case WM_WINDOWPOSCHANGING
:
2518 case WM_WINDOWPOSCHANGED
:
2520 WINDOWPOS
*winpos
= (WINDOWPOS
*)lParam
;
2522 trace("%s\n", (message
== WM_WINDOWPOSCHANGING
) ? "WM_WINDOWPOSCHANGING" : "WM_WINDOWPOSCHANGED");
2523 trace("%p after %p, x %d, y %d, cx %d, cy %d flags %08x\n",
2524 winpos
->hwnd
, winpos
->hwndInsertAfter
,
2525 winpos
->x
, winpos
->y
, winpos
->cx
, winpos
->cy
, winpos
->flags
);
2526 dump_winpos_flags(winpos
->flags
);
2528 /* Log only documented flags, win2k uses 0x1000 and 0x2000
2529 * in the high word for internal purposes
2531 wParam
= winpos
->flags
& 0xffff;
2532 /* We are not interested in the flags that don't match under XP and Win9x */
2533 wParam
&= ~(SWP_NOZORDER
);
2538 msg
.message
= message
;
2539 msg
.flags
= sent
|wparam
|lparam
;
2540 msg
.wParam
= wParam
;
2541 msg
.lParam
= lParam
;
2545 return CallWindowProcA(old_mdi_client_proc
, hwnd
, message
, wParam
, lParam
);
2548 static LRESULT WINAPI
mdi_child_wnd_proc(HWND hwnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
2550 static long defwndproc_counter
= 0;
2554 /* do not log painting messages */
2555 if (message
!= WM_PAINT
&&
2556 message
!= WM_NCPAINT
&&
2557 message
!= WM_SYNCPAINT
&&
2558 message
!= WM_ERASEBKGND
&&
2559 message
!= WM_NCPAINT
&&
2560 message
!= WM_NCHITTEST
&&
2561 message
!= WM_GETTEXT
&&
2562 message
!= WM_GETICON
&&
2563 message
!= WM_DEVICECHANGE
)
2565 trace("mdi child: %p, %04x, %08x, %08lx\n", hwnd
, message
, wParam
, lParam
);
2569 case WM_WINDOWPOSCHANGING
:
2570 case WM_WINDOWPOSCHANGED
:
2572 WINDOWPOS
*winpos
= (WINDOWPOS
*)lParam
;
2574 trace("%s\n", (message
== WM_WINDOWPOSCHANGING
) ? "WM_WINDOWPOSCHANGING" : "WM_WINDOWPOSCHANGED");
2575 trace("%p after %p, x %d, y %d, cx %d, cy %d flags %08x\n",
2576 winpos
->hwnd
, winpos
->hwndInsertAfter
,
2577 winpos
->x
, winpos
->y
, winpos
->cx
, winpos
->cy
, winpos
->flags
);
2578 dump_winpos_flags(winpos
->flags
);
2580 /* Log only documented flags, win2k uses 0x1000 and 0x2000
2581 * in the high word for internal purposes
2583 wParam
= winpos
->flags
& 0xffff;
2584 /* We are not interested in the flags that don't match under XP and Win9x */
2585 wParam
&= ~(SWP_NOZORDER
);
2589 case WM_MDIACTIVATE
:
2591 HWND active
, client
= GetParent(hwnd
);
2593 active
= (HWND
)SendMessageA(client
, WM_MDIGETACTIVE
, 0, 0);
2595 if (hwnd
== (HWND
)lParam
) /* if we are being activated */
2596 ok (active
== (HWND
)lParam
, "new active %p != active %p\n", (HWND
)lParam
, active
);
2598 ok (active
== (HWND
)wParam
, "old active %p != active %p\n", (HWND
)wParam
, active
);
2603 msg
.message
= message
;
2604 msg
.flags
= sent
|wparam
|lparam
;
2605 if (defwndproc_counter
) msg
.flags
|= defwinproc
;
2606 msg
.wParam
= wParam
;
2607 msg
.lParam
= lParam
;
2611 defwndproc_counter
++;
2612 ret
= DefMDIChildProcA(hwnd
, message
, wParam
, lParam
);
2613 defwndproc_counter
--;
2618 static LRESULT WINAPI
mdi_frame_wnd_proc(HWND hwnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
2620 static long defwndproc_counter
= 0;
2624 /* do not log painting messages */
2625 if (message
!= WM_PAINT
&&
2626 message
!= WM_NCPAINT
&&
2627 message
!= WM_SYNCPAINT
&&
2628 message
!= WM_ERASEBKGND
&&
2629 message
!= WM_NCPAINT
&&
2630 message
!= WM_NCHITTEST
&&
2631 message
!= WM_GETTEXT
&&
2632 message
!= WM_GETICON
&&
2633 message
!= WM_DEVICECHANGE
)
2635 trace("mdi frame: %p, %04x, %08x, %08lx\n", hwnd
, message
, wParam
, lParam
);
2639 case WM_WINDOWPOSCHANGING
:
2640 case WM_WINDOWPOSCHANGED
:
2642 WINDOWPOS
*winpos
= (WINDOWPOS
*)lParam
;
2644 trace("%s\n", (message
== WM_WINDOWPOSCHANGING
) ? "WM_WINDOWPOSCHANGING" : "WM_WINDOWPOSCHANGED");
2645 trace("%p after %p, x %d, y %d, cx %d, cy %d flags %08x\n",
2646 winpos
->hwnd
, winpos
->hwndInsertAfter
,
2647 winpos
->x
, winpos
->y
, winpos
->cx
, winpos
->cy
, winpos
->flags
);
2648 dump_winpos_flags(winpos
->flags
);
2650 /* Log only documented flags, win2k uses 0x1000 and 0x2000
2651 * in the high word for internal purposes
2653 wParam
= winpos
->flags
& 0xffff;
2654 /* We are not interested in the flags that don't match under XP and Win9x */
2655 wParam
&= ~(SWP_NOZORDER
);
2660 msg
.message
= message
;
2661 msg
.flags
= sent
|wparam
|lparam
;
2662 if (defwndproc_counter
) msg
.flags
|= defwinproc
;
2663 msg
.wParam
= wParam
;
2664 msg
.lParam
= lParam
;
2668 defwndproc_counter
++;
2669 ret
= DefFrameProcA(hwnd
, mdi_client
, message
, wParam
, lParam
);
2670 defwndproc_counter
--;
2675 static BOOL
mdi_RegisterWindowClasses(void)
2680 cls
.lpfnWndProc
= mdi_frame_wnd_proc
;
2683 cls
.hInstance
= GetModuleHandleA(0);
2685 cls
.hCursor
= LoadCursorA(0, (LPSTR
)IDC_ARROW
);
2686 cls
.hbrBackground
= GetStockObject(WHITE_BRUSH
);
2687 cls
.lpszMenuName
= NULL
;
2688 cls
.lpszClassName
= "MDI_frame_class";
2689 if (!RegisterClassA(&cls
)) return FALSE
;
2691 cls
.lpfnWndProc
= mdi_child_wnd_proc
;
2692 cls
.lpszClassName
= "MDI_child_class";
2693 if (!RegisterClassA(&cls
)) return FALSE
;
2695 if (!GetClassInfoA(0, "MDIClient", &cls
)) assert(0);
2696 old_mdi_client_proc
= cls
.lpfnWndProc
;
2697 cls
.hInstance
= GetModuleHandleA(0);
2698 cls
.lpfnWndProc
= mdi_client_hook_proc
;
2699 cls
.lpszClassName
= "MDI_client_class";
2700 if (!RegisterClassA(&cls
)) assert(0);
2705 static void test_mdi_messages(void)
2707 MDICREATESTRUCTA mdi_cs
;
2708 CLIENTCREATESTRUCT client_cs
;
2709 HWND mdi_frame
, mdi_child
, mdi_child2
, active_child
;
2711 HMENU hMenu
= CreateMenu();
2713 assert(mdi_RegisterWindowClasses());
2717 trace("creating MDI frame window\n");
2718 mdi_frame
= CreateWindowExA(0, "MDI_frame_class", "MDI frame window",
2719 WS_CAPTION
| WS_SYSMENU
| WS_MINIMIZEBOX
|
2720 WS_MAXIMIZEBOX
| WS_VISIBLE
,
2721 100, 100, CW_USEDEFAULT
, CW_USEDEFAULT
,
2722 GetDesktopWindow(), hMenu
,
2723 GetModuleHandleA(0), NULL
);
2725 ok_sequence(WmCreateMDIframeSeq
, "Create MDI frame window", FALSE
);
2727 ok(GetActiveWindow() == mdi_frame
, "wrong active window %p\n", GetActiveWindow());
2728 ok(GetFocus() == mdi_frame
, "wrong focus window %p\n", GetFocus());
2730 trace("creating MDI client window\n");
2731 client_cs
.hWindowMenu
= 0;
2732 client_cs
.idFirstChild
= MDI_FIRST_CHILD_ID
;
2733 mdi_client
= CreateWindowExA(0, "MDI_client_class",
2735 WS_CHILD
| WS_VISIBLE
| MDIS_ALLCHILDSTYLES
,
2737 mdi_frame
, 0, GetModuleHandleA(0), &client_cs
);
2739 ok_sequence(WmCreateMDIclientSeq
, "Create visible MDI client window", FALSE
);
2741 ok(GetActiveWindow() == mdi_frame
, "wrong active window %p\n", GetActiveWindow());
2742 ok(GetFocus() == mdi_frame
, "input focus should be on MDI frame not on %p\n", GetFocus());
2744 active_child
= (HWND
)SendMessageA(mdi_client
, WM_MDIGETACTIVE
, 0, (LPARAM
)&zoomed
);
2745 ok(!active_child
, "wrong active MDI child %p\n", active_child
);
2746 ok(!zoomed
, "wrong zoomed state %d\n", zoomed
);
2751 trace("creating invisible MDI child window\n");
2752 mdi_child
= CreateWindowExA(WS_EX_MDICHILD
, "MDI_child_class", "MDI child",
2754 0, 0, CW_USEDEFAULT
, CW_USEDEFAULT
,
2755 mdi_client
, 0, GetModuleHandleA(0), NULL
);
2759 ShowWindow(mdi_child
, SW_SHOWNORMAL
);
2760 ok_sequence(WmShowChildSeq
, "ShowWindow(SW_SHOWNORMAL) MDI child window", FALSE
);
2762 ok(GetWindowLongA(mdi_child
, GWL_STYLE
) & WS_VISIBLE
, "MDI child should be visible\n");
2763 ok(IsWindowVisible(mdi_child
), "MDI child should be visible\n");
2765 ok(GetActiveWindow() == mdi_frame
, "wrong active window %p\n", GetActiveWindow());
2766 ok(GetFocus() == 0, "wrong focus window %p\n", GetFocus());
2768 active_child
= (HWND
)SendMessageA(mdi_client
, WM_MDIGETACTIVE
, 0, (LPARAM
)&zoomed
);
2769 ok(!active_child
, "wrong active MDI child %p\n", active_child
);
2770 ok(!zoomed
, "wrong zoomed state %d\n", zoomed
);
2772 ShowWindow(mdi_child
, SW_HIDE
);
2773 ok_sequence(WmHideChildSeq
, "ShowWindow(SW_HIDE) MDI child window", FALSE
);
2776 ShowWindow(mdi_child
, SW_SHOW
);
2777 ok_sequence(WmShowChildSeq
, "ShowWindow(SW_SHOW) MDI child window", FALSE
);
2779 ok(GetWindowLongA(mdi_child
, GWL_STYLE
) & WS_VISIBLE
, "MDI child should be visible\n");
2780 ok(IsWindowVisible(mdi_child
), "MDI child should be visible\n");
2782 ok(GetActiveWindow() == mdi_frame
, "wrong active window %p\n", GetActiveWindow());
2783 ok(GetFocus() == 0, "wrong focus window %p\n", GetFocus());
2785 active_child
= (HWND
)SendMessageA(mdi_client
, WM_MDIGETACTIVE
, 0, (LPARAM
)&zoomed
);
2786 ok(!active_child
, "wrong active MDI child %p\n", active_child
);
2787 ok(!zoomed
, "wrong zoomed state %d\n", zoomed
);
2789 DestroyWindow(mdi_child
);
2792 trace("creating visible MDI child window\n");
2793 mdi_child
= CreateWindowExA(WS_EX_MDICHILD
, "MDI_child_class", "MDI child",
2794 WS_CHILD
| WS_VISIBLE
,
2795 0, 0, CW_USEDEFAULT
, CW_USEDEFAULT
,
2796 mdi_client
, 0, GetModuleHandleA(0), NULL
);
2798 ok_sequence(WmCreateMDIchildVisibleSeq
, "Create visible MDI child window", FALSE
);
2800 ok(GetWindowLongA(mdi_child
, GWL_STYLE
) & WS_VISIBLE
, "MDI child should be visible\n");
2801 ok(IsWindowVisible(mdi_child
), "MDI child should be visible\n");
2803 ok(GetActiveWindow() == mdi_frame
, "wrong active window %p\n", GetActiveWindow());
2804 ok(GetFocus() == mdi_child
, "wrong focus window %p\n", GetFocus());
2806 active_child
= (HWND
)SendMessageA(mdi_client
, WM_MDIGETACTIVE
, 0, (LPARAM
)&zoomed
);
2807 ok(active_child
== mdi_child
, "wrong active MDI child %p\n", active_child
);
2808 ok(!zoomed
, "wrong zoomed state %d\n", zoomed
);
2811 DestroyWindow(mdi_child
);
2812 ok_sequence(WmDestroyMDIchildVisibleSeq
, "Destroy visible MDI child window", TRUE
);
2814 ok(GetActiveWindow() == mdi_frame
, "wrong active window %p\n", GetActiveWindow());
2815 ok(GetFocus() == 0, "wrong focus window %p\n", GetFocus());
2817 /* Win2k: MDI client still returns a just destroyed child as active
2818 * Win9x: MDI client returns 0
2820 active_child
= (HWND
)SendMessageA(mdi_client
, WM_MDIGETACTIVE
, 0, (LPARAM
)&zoomed
);
2821 ok(active_child
== mdi_child
|| /* win2k */
2822 !active_child
, /* win9x */
2823 "wrong active MDI child %p\n", active_child
);
2824 ok(!zoomed
, "wrong zoomed state %d\n", zoomed
);
2828 trace("creating invisible MDI child window\n");
2829 mdi_child2
= CreateWindowExA(WS_EX_MDICHILD
, "MDI_child_class", "MDI child",
2831 0, 0, CW_USEDEFAULT
, CW_USEDEFAULT
,
2832 mdi_client
, 0, GetModuleHandleA(0), NULL
);
2834 ok_sequence(WmCreateMDIchildInvisibleSeq
, "Create invisible MDI child window", FALSE
);
2836 ok(!(GetWindowLongA(mdi_child2
, GWL_STYLE
) & WS_VISIBLE
), "MDI child should not be visible\n");
2837 ok(!IsWindowVisible(mdi_child2
), "MDI child should not be visible\n");
2839 ok(GetActiveWindow() == mdi_frame
, "wrong active window %p\n", GetActiveWindow());
2840 ok(GetFocus() == 0, "wrong focus window %p\n", GetFocus());
2842 /* Win2k: MDI client still returns a just destroyed child as active
2843 * Win9x: MDI client returns mdi_child2
2845 active_child
= (HWND
)SendMessageA(mdi_client
, WM_MDIGETACTIVE
, 0, (LPARAM
)&zoomed
);
2846 ok(active_child
== mdi_child
|| /* win2k */
2847 active_child
== mdi_child2
, /* win9x */
2848 "wrong active MDI child %p\n", active_child
);
2849 ok(!zoomed
, "wrong zoomed state %d\n", zoomed
);
2852 ShowWindow(mdi_child2
, SW_MAXIMIZE
);
2853 ok_sequence(WmMaximizeMDIchildInvisibleSeq
, "ShowWindow(SW_MAXIMIZE):invisible MDI child", FALSE
);
2855 ok(GetWindowLongA(mdi_child2
, GWL_STYLE
) & WS_VISIBLE
, "MDI child should be visible\n");
2856 ok(IsWindowVisible(mdi_child2
), "MDI child should be visible\n");
2858 active_child
= (HWND
)SendMessageA(mdi_client
, WM_MDIGETACTIVE
, 0, (LPARAM
)&zoomed
);
2859 ok(active_child
== mdi_child2
, "wrong active MDI child %p\n", active_child
);
2860 ok(zoomed
, "wrong zoomed state %d\n", zoomed
);
2863 ok(GetActiveWindow() == mdi_frame
, "wrong active window %p\n", GetActiveWindow());
2864 ok(GetFocus() == mdi_child2
|| /* win2k */
2865 GetFocus() == 0, /* win9x */
2866 "wrong focus window %p\n", GetFocus());
2871 ShowWindow(mdi_child2
, SW_HIDE
);
2872 ok_sequence(WmHideChildSeq
, "ShowWindow(SW_HIDE):MDI child", FALSE
);
2874 ShowWindow(mdi_child2
, SW_RESTORE
);
2875 ok_sequence(WmRestoreMDIchildInisibleSeq
, "ShowWindow(SW_RESTORE):invisible MDI child", FALSE
);
2878 ok(GetWindowLongA(mdi_child2
, GWL_STYLE
) & WS_VISIBLE
, "MDI child should be visible\n");
2879 ok(IsWindowVisible(mdi_child2
), "MDI child should be visible\n");
2881 active_child
= (HWND
)SendMessageA(mdi_client
, WM_MDIGETACTIVE
, 0, (LPARAM
)&zoomed
);
2882 ok(active_child
== mdi_child2
, "wrong active MDI child %p\n", active_child
);
2883 ok(!zoomed
, "wrong zoomed state %d\n", zoomed
);
2889 ShowWindow(mdi_child2
, SW_HIDE
);
2890 ok_sequence(WmHideChildSeq
, "ShowWindow(SW_HIDE):MDI child", FALSE
);
2892 ShowWindow(mdi_child2
, SW_SHOW
);
2893 ok_sequence(WmShowChildSeq
, "ShowWindow(SW_SHOW):MDI child", FALSE
);
2895 ok(GetActiveWindow() == mdi_frame
, "wrong active window %p\n", GetActiveWindow());
2896 ok(GetFocus() == 0, "wrong focus window %p\n", GetFocus());
2898 ShowWindow(mdi_child2
, SW_MAXIMIZE
);
2899 ok_sequence(WmMaximizeMDIchildVisibleSeq
, "ShowWindow(SW_MAXIMIZE):MDI child", FALSE
);
2901 ok(GetActiveWindow() == mdi_frame
, "wrong active window %p\n", GetActiveWindow());
2902 ok(GetFocus() == 0, "wrong focus window %p\n", GetFocus());
2904 ShowWindow(mdi_child2
, SW_RESTORE
);
2905 ok_sequence(WmRestoreMDIchildVisibleSeq
, "ShowWindow(SW_RESTORE):maximized MDI child", FALSE
);
2907 ok(GetActiveWindow() == mdi_frame
, "wrong active window %p\n", GetActiveWindow());
2908 ok(GetFocus() == 0, "wrong focus window %p\n", GetFocus());
2910 ShowWindow(mdi_child2
, SW_MINIMIZE
);
2911 ok_sequence(WmMinimizeMDIchildVisibleSeq
, "ShowWindow(SW_MINIMIZE):MDI child", TRUE
);
2913 ok(GetActiveWindow() == mdi_frame
, "wrong active window %p\n", GetActiveWindow());
2914 ok(GetFocus() == 0, "wrong focus window %p\n", GetFocus());
2916 active_child
= (HWND
)SendMessageA(mdi_client
, WM_MDIGETACTIVE
, 0, (LPARAM
)&zoomed
);
2917 ok(active_child
== mdi_child2
, "wrong active MDI child %p\n", active_child
);
2918 ok(!zoomed
, "wrong zoomed state %d\n", zoomed
);
2921 ShowWindow(mdi_child2
, SW_RESTORE
);
2922 ok_sequence(WmRestoreMDIchildVisibleSeq_2
, "ShowWindow(SW_RESTORE):minimized MDI child", TRUE
);
2924 ok(GetActiveWindow() == mdi_frame
, "wrong active window %p\n", GetActiveWindow());
2925 ok(GetFocus() == mdi_child2
, "wrong focus window %p\n", GetFocus());
2927 active_child
= (HWND
)SendMessageA(mdi_client
, WM_MDIGETACTIVE
, 0, (LPARAM
)&zoomed
);
2928 ok(active_child
== mdi_child2
, "wrong active MDI child %p\n", active_child
);
2929 ok(!zoomed
, "wrong zoomed state %d\n", zoomed
);
2935 ShowWindow(mdi_child2
, SW_HIDE
);
2936 ok_sequence(WmHideChildSeq
, "ShowWindow(SW_HIDE):MDI child", FALSE
);
2938 ok(GetActiveWindow() == mdi_frame
, "wrong active window %p\n", GetActiveWindow());
2939 ok(GetFocus() == 0, "wrong focus window %p\n", GetFocus());
2941 DestroyWindow(mdi_child2
);
2942 ok_sequence(WmDestroyMDIchildInvisibleSeq
, "Destroy invisible MDI child window", FALSE
);
2944 ok(GetActiveWindow() == mdi_frame
, "wrong active window %p\n", GetActiveWindow());
2945 ok(GetFocus() == 0, "wrong focus window %p\n", GetFocus());
2947 /* test for maximized MDI children */
2948 trace("creating maximized visible MDI child window 1\n");
2949 mdi_child
= CreateWindowExA(WS_EX_MDICHILD
, "MDI_child_class", "MDI child",
2950 WS_CHILD
| WS_VISIBLE
| WS_MAXIMIZEBOX
| WS_MAXIMIZE
,
2951 0, 0, CW_USEDEFAULT
, CW_USEDEFAULT
,
2952 mdi_client
, 0, GetModuleHandleA(0), NULL
);
2954 ok_sequence(WmCreateMDIchildVisibleMaxSeq1
, "Create maximized visible 1st MDI child window", TRUE
);
2955 ok(IsZoomed(mdi_child
), "1st MDI child should be maximized\n");
2957 ok(GetActiveWindow() == mdi_frame
, "wrong active window %p\n", GetActiveWindow());
2958 ok(GetFocus() == mdi_child
|| /* win2k */
2959 GetFocus() == 0, /* win9x */
2960 "wrong focus window %p\n", GetFocus());
2962 active_child
= (HWND
)SendMessageA(mdi_client
, WM_MDIGETACTIVE
, 0, (LPARAM
)&zoomed
);
2963 ok(active_child
== mdi_child
, "wrong active MDI child %p\n", active_child
);
2964 ok(zoomed
, "wrong zoomed state %d\n", zoomed
);
2967 trace("creating maximized visible MDI child window 2\n");
2968 mdi_child2
= CreateWindowExA(WS_EX_MDICHILD
, "MDI_child_class", "MDI child",
2969 WS_CHILD
| WS_VISIBLE
| WS_MAXIMIZEBOX
| WS_MAXIMIZE
,
2970 0, 0, CW_USEDEFAULT
, CW_USEDEFAULT
,
2971 mdi_client
, 0, GetModuleHandleA(0), NULL
);
2973 ok_sequence(WmCreateMDIchildVisibleMaxSeq2
, "Create maximized visible 2nd MDI child 2 window", TRUE
);
2974 ok(IsZoomed(mdi_child2
), "2nd MDI child should be maximized\n");
2975 ok(!IsZoomed(mdi_child
), "1st MDI child should NOT be maximized\n");
2977 ok(GetActiveWindow() == mdi_frame
, "wrong active window %p\n", GetActiveWindow());
2978 ok(GetFocus() == mdi_child2
, "wrong focus window %p\n", GetFocus());
2980 active_child
= (HWND
)SendMessageA(mdi_client
, WM_MDIGETACTIVE
, 0, (LPARAM
)&zoomed
);
2981 ok(active_child
== mdi_child2
, "wrong active MDI child %p\n", active_child
);
2982 ok(zoomed
, "wrong zoomed state %d\n", zoomed
);
2985 trace("destroying maximized visible MDI child window 2\n");
2986 DestroyWindow(mdi_child2
);
2987 ok_sequence(WmDestroyMDIchildVisibleSeq
, "Destroy visible MDI child window", TRUE
);
2989 ok(!IsZoomed(mdi_child
), "1st MDI child should NOT be maximized\n");
2991 ok(GetActiveWindow() == mdi_frame
, "wrong active window %p\n", GetActiveWindow());
2992 ok(GetFocus() == 0, "wrong focus window %p\n", GetFocus());
2994 /* Win2k: MDI client still returns a just destroyed child as active
2995 * Win9x: MDI client returns 0
2997 active_child
= (HWND
)SendMessageA(mdi_client
, WM_MDIGETACTIVE
, 0, (LPARAM
)&zoomed
);
2998 ok(active_child
== mdi_child2
|| /* win2k */
2999 !active_child
, /* win9x */
3000 "wrong active MDI child %p\n", active_child
);
3003 ShowWindow(mdi_child
, SW_MAXIMIZE
);
3004 ok(IsZoomed(mdi_child
), "1st MDI child should be maximized\n");
3007 ok(GetActiveWindow() == mdi_frame
, "wrong active window %p\n", GetActiveWindow());
3008 ok(GetFocus() == mdi_child
, "wrong focus window %p\n", GetFocus());
3010 trace("re-creating maximized visible MDI child window 2\n");
3011 mdi_child2
= CreateWindowExA(WS_EX_MDICHILD
, "MDI_child_class", "MDI child",
3012 WS_CHILD
| WS_VISIBLE
| WS_MAXIMIZEBOX
| WS_MAXIMIZE
,
3013 0, 0, CW_USEDEFAULT
, CW_USEDEFAULT
,
3014 mdi_client
, 0, GetModuleHandleA(0), NULL
);
3016 ok_sequence(WmCreateMDIchildVisibleMaxSeq2
, "Create maximized visible 2nd MDI child 2 window", TRUE
);
3017 ok(IsZoomed(mdi_child2
), "2nd MDI child should be maximized\n");
3018 ok(!IsZoomed(mdi_child
), "1st MDI child should NOT be maximized\n");
3020 ok(GetActiveWindow() == mdi_frame
, "wrong active window %p\n", GetActiveWindow());
3021 ok(GetFocus() == mdi_child2
, "wrong focus window %p\n", GetFocus());
3023 active_child
= (HWND
)SendMessageA(mdi_client
, WM_MDIGETACTIVE
, 0, (LPARAM
)&zoomed
);
3024 ok(active_child
== mdi_child2
, "wrong active MDI child %p\n", active_child
);
3025 ok(zoomed
, "wrong zoomed state %d\n", zoomed
);
3028 SendMessageA(mdi_child2
, WM_SYSCOMMAND
, SC_CLOSE
, 0);
3029 ok_sequence(WmDestroyMDIchildVisibleMaxSeq2
, "WM_SYSCOMMAND/SC_CLOSE on a visible maximized MDI child window", TRUE
);
3030 ok(!IsWindow(mdi_child2
), "MDI child 2 should be destroyed\n");
3032 ok(IsZoomed(mdi_child
), "1st MDI child should be maximized\n");
3033 ok(GetActiveWindow() == mdi_frame
, "wrong active window %p\n", GetActiveWindow());
3034 ok(GetFocus() == mdi_child
, "wrong focus window %p\n", GetFocus());
3036 active_child
= (HWND
)SendMessageA(mdi_client
, WM_MDIGETACTIVE
, 0, (LPARAM
)&zoomed
);
3037 ok(active_child
== mdi_child
, "wrong active MDI child %p\n", active_child
);
3038 ok(zoomed
, "wrong zoomed state %d\n", zoomed
);
3041 DestroyWindow(mdi_child
);
3042 ok_sequence(WmDestroyMDIchildVisibleSeq
, "Destroy visible MDI child window", TRUE
);
3044 ok(GetActiveWindow() == mdi_frame
, "wrong active window %p\n", GetActiveWindow());
3045 ok(GetFocus() == 0, "wrong focus window %p\n", GetFocus());
3047 /* Win2k: MDI client still returns a just destroyed child as active
3048 * Win9x: MDI client returns 0
3050 active_child
= (HWND
)SendMessageA(mdi_client
, WM_MDIGETACTIVE
, 0, (LPARAM
)&zoomed
);
3051 ok(active_child
== mdi_child
|| /* win2k */
3052 !active_child
, /* win9x */
3053 "wrong active MDI child %p\n", active_child
);
3056 trace("creating maximized invisible MDI child window\n");
3057 mdi_child2
= CreateWindowExA(WS_EX_MDICHILD
, "MDI_child_class", "MDI child",
3058 WS_CHILD
| WS_MAXIMIZE
| WS_CAPTION
| WS_THICKFRAME
,
3059 0, 0, CW_USEDEFAULT
, CW_USEDEFAULT
,
3060 mdi_client
, 0, GetModuleHandleA(0), NULL
);
3062 ok_sequence(WmCreateMDIchildInvisibleMaxSeq4
, "Create maximized invisible MDI child window", TRUE
);
3063 ok(IsZoomed(mdi_child2
), "MDI child should be maximized\n");
3064 ok(!(GetWindowLongA(mdi_child2
, GWL_STYLE
) & WS_VISIBLE
), "MDI child should be not visible\n");
3065 ok(!IsWindowVisible(mdi_child2
), "MDI child should be not visible\n");
3067 /* Win2k: MDI client still returns a just destroyed child as active
3068 * Win9x: MDI client returns 0
3070 active_child
= (HWND
)SendMessageA(mdi_client
, WM_MDIGETACTIVE
, 0, (LPARAM
)&zoomed
);
3071 ok(active_child
== mdi_child
|| /* win2k */
3072 !active_child
, /* win9x */
3073 "wrong active MDI child %p\n", active_child
);
3076 trace("call ShowWindow(mdi_child, SW_MAXIMIZE)\n");
3077 ShowWindow(mdi_child2
, SW_MAXIMIZE
);
3078 ok_sequence(WmMaximizeMDIchildInvisibleSeq2
, "ShowWindow(SW_MAXIMIZE):invisible maximized MDI child", FALSE
);
3079 ok(IsZoomed(mdi_child2
), "MDI child should be maximized\n");
3080 ok(GetWindowLongA(mdi_child2
, GWL_STYLE
) & WS_VISIBLE
, "MDI child should be visible\n");
3081 ok(IsWindowVisible(mdi_child2
), "MDI child should be visible\n");
3083 active_child
= (HWND
)SendMessageA(mdi_client
, WM_MDIGETACTIVE
, 0, (LPARAM
)&zoomed
);
3084 ok(active_child
== mdi_child2
, "wrong active MDI child %p\n", active_child
);
3085 ok(zoomed
, "wrong zoomed state %d\n", zoomed
);
3088 SendMessageA(mdi_client
, WM_MDIDESTROY
, (WPARAM
)mdi_child2
, 0);
3091 /* end of test for maximized MDI children */
3093 mdi_cs
.szClass
= "MDI_child_Class";
3094 mdi_cs
.szTitle
= "MDI child";
3095 mdi_cs
.hOwner
= GetModuleHandleA(0);
3098 mdi_cs
.cx
= CW_USEDEFAULT
;
3099 mdi_cs
.cy
= CW_USEDEFAULT
;
3100 mdi_cs
.style
= WS_CHILD
| WS_SYSMENU
| WS_VISIBLE
| WS_MAXIMIZEBOX
| WS_MAXIMIZE
;
3102 mdi_child
= (HWND
)SendMessageA(mdi_client
, WM_MDICREATE
, 0, (LPARAM
)&mdi_cs
);
3103 ok(mdi_child
!= 0, "MDI child creation failed\n");
3104 ok_sequence(WmCreateMDIchildVisibleMaxSeq3
, "WM_MDICREATE for maximized visible MDI child window", TRUE
);
3106 ok(GetMenuItemID(hMenu
, GetMenuItemCount(hMenu
) - 1) == SC_CLOSE
, "SC_CLOSE menu item not found\n");
3108 active_child
= (HWND
)SendMessageA(mdi_client
, WM_MDIGETACTIVE
, 0, (LPARAM
)&zoomed
);
3109 ok(active_child
== mdi_child
, "wrong active MDI child %p\n", active_child
);
3111 ok(IsZoomed(mdi_child
), "MDI child should be maximized\n");
3112 ok(GetActiveWindow() == mdi_frame
, "wrong active window %p\n", GetActiveWindow());
3113 ok(GetFocus() == mdi_child
, "wrong focus window %p\n", GetFocus());
3115 active_child
= (HWND
)SendMessageA(mdi_client
, WM_MDIGETACTIVE
, 0, (LPARAM
)&zoomed
);
3116 ok(active_child
== mdi_child
, "wrong active MDI child %p\n", active_child
);
3117 ok(zoomed
, "wrong zoomed state %d\n", zoomed
);
3120 SendMessageA(mdi_client
, WM_MDIDESTROY
, (WPARAM
)mdi_child
, 0);
3121 ok_sequence(WmDestroyMDIchildVisibleMaxSeq1
, "Destroy visible maximized MDI child window", TRUE
);
3123 ok(!IsWindow(mdi_child
), "MDI child should be destroyed\n");
3124 active_child
= (HWND
)SendMessageA(mdi_client
, WM_MDIGETACTIVE
, 0, (LPARAM
)&zoomed
);
3125 ok(!active_child
, "wrong active MDI child %p\n", active_child
);
3130 DestroyWindow(mdi_client
);
3131 ok_sequence(WmDestroyMDIclientSeq
, "Destroy MDI client window", FALSE
);
3133 /* test maximization of MDI child with invisible parent */
3134 client_cs
.hWindowMenu
= 0;
3135 mdi_client
= CreateWindow("MDI_client_class",
3137 WS_CHILD
| WS_CLIPCHILDREN
| WS_VSCROLL
| WS_HSCROLL
| WS_VISIBLE
,
3139 mdi_frame
, 0, GetModuleHandleA(0), &client_cs
);
3140 ok_sequence(WmCreateMDIclientSeq
, "Create MDI client window", FALSE
);
3142 ShowWindow(mdi_client
, SW_HIDE
);
3143 ok_sequence(WmHideMDIclientSeq
, "Hide MDI client window", FALSE
);
3145 mdi_child
= CreateWindowExA(WS_EX_MDICHILD
, "MDI_child_class", "MDI child",
3146 WS_CHILD
| WS_CLIPCHILDREN
| WS_VSCROLL
| WS_HSCROLL
,
3148 mdi_client
, 0, GetModuleHandleA(0), NULL
);
3149 ok_sequence(WmCreateMDIchildInvisibleParentSeq
, "Create MDI child window with invisible parent", FALSE
);
3151 SendMessage(mdi_client
, WM_MDIMAXIMIZE
, (WPARAM
) mdi_child
, 0);
3152 ok_sequence(WmMaximizeMDIchildInvisibleParentSeq
, "Maximize MDI child window with invisible parent", TRUE
);
3153 zoomed
= IsZoomed(mdi_child
);
3154 ok(zoomed
, "wrong zoomed state %d\n", zoomed
);
3156 ShowWindow(mdi_client
, SW_SHOW
);
3157 ok_sequence(WmShowMDIclientSeq
, "Show MDI client window", FALSE
);
3159 DestroyWindow(mdi_child
);
3160 ok_sequence(WmDestroyMDIchildVisibleSeq
, "Destroy visible maximized MDI child window", TRUE
);
3162 DestroyWindow(mdi_client
);
3163 ok_sequence(WmDestroyMDIclientSeq
, "Destroy MDI client window", FALSE
);
3164 /* end of test for maximization of MDI child with invisible parent */
3166 DestroyWindow(mdi_frame
);
3167 ok_sequence(WmDestroyMDIframeSeq
, "Destroy MDI frame window", FALSE
);
3169 /************************* End of MDI test **********************************/
3171 static void test_WM_SETREDRAW(HWND hwnd
)
3173 DWORD style
= GetWindowLongA(hwnd
, GWL_STYLE
);
3177 SendMessageA(hwnd
, WM_SETREDRAW
, FALSE
, 0);
3178 ok_sequence(WmSetRedrawFalseSeq
, "SetRedraw:FALSE", FALSE
);
3180 ok(!(GetWindowLongA(hwnd
, GWL_STYLE
) & WS_VISIBLE
), "WS_VISIBLE should NOT be set\n");
3181 ok(!IsWindowVisible(hwnd
), "IsWindowVisible() should return FALSE\n");
3184 SendMessageA(hwnd
, WM_SETREDRAW
, TRUE
, 0);
3185 ok_sequence(WmSetRedrawTrueSeq
, "SetRedraw:TRUE", FALSE
);
3187 ok(GetWindowLongA(hwnd
, GWL_STYLE
) & WS_VISIBLE
, "WS_VISIBLE should be set\n");
3188 ok(IsWindowVisible(hwnd
), "IsWindowVisible() should return TRUE\n");
3190 /* restore original WS_VISIBLE state */
3191 SetWindowLongA(hwnd
, GWL_STYLE
, style
);
3196 static INT_PTR CALLBACK
TestModalDlgProcA(HWND hwnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
3200 trace("dialog: %p, %04x, %08x, %08lx\n", hwnd
, message
, wParam
, lParam
);
3202 /* explicitly ignore WM_GETICON message */
3203 if (message
== WM_GETICON
) return 0;
3210 case WM_DEVICECHANGE
:
3215 case WM_WINDOWPOSCHANGING
:
3216 case WM_WINDOWPOSCHANGED
:
3218 WINDOWPOS
*winpos
= (WINDOWPOS
*)lParam
;
3220 trace("%s\n", (message
== WM_WINDOWPOSCHANGING
) ? "WM_WINDOWPOSCHANGING" : "WM_WINDOWPOSCHANGED");
3221 trace("%p after %p, x %d, y %d, cx %d, cy %d flags %08x\n",
3222 winpos
->hwnd
, winpos
->hwndInsertAfter
,
3223 winpos
->x
, winpos
->y
, winpos
->cx
, winpos
->cy
, winpos
->flags
);
3224 dump_winpos_flags(winpos
->flags
);
3226 /* Log only documented flags, win2k uses 0x1000 and 0x2000
3227 * in the high word for internal purposes
3229 wParam
= winpos
->flags
& 0xffff;
3230 /* We are not interested in the flags that don't match under XP and Win9x */
3231 wParam
&= ~(SWP_NOZORDER
);
3236 msg
.message
= message
;
3237 msg
.flags
= sent
|wparam
|lparam
;
3238 msg
.wParam
= wParam
;
3239 msg
.lParam
= lParam
;
3242 if (message
== WM_INITDIALOG
) SetTimer( hwnd
, 1, 100, NULL
);
3243 if (message
== WM_TIMER
) EndDialog( hwnd
, 0 );
3247 static void test_hv_scroll_1(HWND hwnd
, INT ctl
, DWORD clear
, DWORD set
, INT min
, INT max
)
3249 DWORD style
, exstyle
;
3253 exstyle
= GetWindowLongA(hwnd
, GWL_EXSTYLE
);
3254 style
= GetWindowLongA(hwnd
, GWL_STYLE
);
3255 /* do not be confused by WS_DLGFRAME set */
3256 if ((style
& WS_CAPTION
) == WS_CAPTION
) style
&= ~WS_CAPTION
;
3258 if (clear
) ok(style
& clear
, "style %08x should be set\n", clear
);
3259 if (set
) ok(!(style
& set
), "style %08x should not be set\n", set
);
3261 ret
= SetScrollRange(hwnd
, ctl
, min
, max
, FALSE
);
3262 ok( ret
, "SetScrollRange(%d) error %d\n", ctl
, GetLastError());
3263 if ((style
& (WS_DLGFRAME
| WS_BORDER
| WS_THICKFRAME
)) || (exstyle
& WS_EX_DLGMODALFRAME
))
3264 ok_sequence(WmSetScrollRangeHV_NC_Seq
, "SetScrollRange(SB_HORZ/SB_VERT) NC", FALSE
);
3266 ok_sequence(WmSetScrollRangeHVSeq
, "SetScrollRange(SB_HORZ/SB_VERT)", FALSE
);
3268 style
= GetWindowLongA(hwnd
, GWL_STYLE
);
3269 if (set
) ok(style
& set
, "style %08x should be set\n", set
);
3270 if (clear
) ok(!(style
& clear
), "style %08x should not be set\n", clear
);
3272 /* a subsequent call should do nothing */
3273 ret
= SetScrollRange(hwnd
, ctl
, min
, max
, FALSE
);
3274 ok( ret
, "SetScrollRange(%d) error %d\n", ctl
, GetLastError());
3275 ok_sequence(WmEmptySeq
, "SetScrollRange(SB_HORZ/SB_VERT) empty sequence", FALSE
);
3279 trace("Ignore GetScrollRange error below if you are on Win9x\n");
3280 ret
= GetScrollRange(hwnd
, ctl
, &xmin
, &xmax
);
3281 ok( ret
, "GetScrollRange(%d) error %d\n", ctl
, GetLastError());
3282 ok_sequence(WmEmptySeq
, "GetScrollRange(SB_HORZ/SB_VERT) empty sequence", FALSE
);
3283 ok(xmin
== min
, "unexpected min scroll value %d\n", xmin
);
3284 ok(xmax
== max
, "unexpected max scroll value %d\n", xmax
);
3287 static void test_hv_scroll_2(HWND hwnd
, INT ctl
, DWORD clear
, DWORD set
, INT min
, INT max
)
3289 DWORD style
, exstyle
;
3293 exstyle
= GetWindowLongA(hwnd
, GWL_EXSTYLE
);
3294 style
= GetWindowLongA(hwnd
, GWL_STYLE
);
3295 /* do not be confused by WS_DLGFRAME set */
3296 if ((style
& WS_CAPTION
) == WS_CAPTION
) style
&= ~WS_CAPTION
;
3298 if (clear
) ok(style
& clear
, "style %08x should be set\n", clear
);
3299 if (set
) ok(!(style
& set
), "style %08x should not be set\n", set
);
3301 si
.cbSize
= sizeof(si
);
3302 si
.fMask
= SIF_RANGE
;
3305 SetScrollInfo(hwnd
, ctl
, &si
, TRUE
);
3306 if ((style
& (WS_DLGFRAME
| WS_BORDER
| WS_THICKFRAME
)) || (exstyle
& WS_EX_DLGMODALFRAME
))
3307 ok_sequence(WmSetScrollRangeHV_NC_Seq
, "SetScrollInfo(SB_HORZ/SB_VERT) NC", FALSE
);
3309 ok_sequence(WmSetScrollRangeHVSeq
, "SetScrollInfo(SB_HORZ/SB_VERT)", FALSE
);
3311 style
= GetWindowLongA(hwnd
, GWL_STYLE
);
3312 if (set
) ok(style
& set
, "style %08x should be set\n", set
);
3313 if (clear
) ok(!(style
& clear
), "style %08x should not be set\n", clear
);
3315 /* a subsequent call should do nothing */
3316 SetScrollInfo(hwnd
, ctl
, &si
, TRUE
);
3317 if (style
& WS_HSCROLL
)
3318 ok_sequence(WmSetScrollRangeHSeq_empty
, "SetScrollInfo(SB_HORZ/SB_VERT) empty sequence", FALSE
);
3319 else if (style
& WS_VSCROLL
)
3320 ok_sequence(WmSetScrollRangeVSeq_empty
, "SetScrollInfo(SB_HORZ/SB_VERT) empty sequence", FALSE
);
3322 ok_sequence(WmEmptySeq
, "SetScrollInfo(SB_HORZ/SB_VERT) empty sequence", FALSE
);
3324 si
.fMask
= SIF_PAGE
;
3326 SetScrollInfo(hwnd
, ctl
, &si
, FALSE
);
3327 ok_sequence(WmEmptySeq
, "SetScrollInfo(SB_HORZ/SB_VERT) empty sequence", FALSE
);
3331 SetScrollInfo(hwnd
, ctl
, &si
, FALSE
);
3332 ok_sequence(WmEmptySeq
, "SetScrollInfo(SB_HORZ/SB_VERT) empty sequence", FALSE
);
3334 si
.fMask
= SIF_RANGE
;
3335 si
.nMin
= 0xdeadbeef;
3336 si
.nMax
= 0xdeadbeef;
3337 ret
= GetScrollInfo(hwnd
, ctl
, &si
);
3338 ok( ret
, "GetScrollInfo error %d\n", GetLastError());
3339 ok_sequence(WmEmptySeq
, "GetScrollRange(SB_HORZ/SB_VERT) empty sequence", FALSE
);
3340 ok(si
.nMin
== min
, "unexpected min scroll value %d\n", si
.nMin
);
3341 ok(si
.nMax
== max
, "unexpected max scroll value %d\n", si
.nMax
);
3344 /* Win9x sends WM_USER+xxx while and NT versions send SBM_xxx messages */
3345 static void test_scroll_messages(HWND hwnd
)
3353 ret
= GetScrollRange(hwnd
, SB_CTL
, &min
, &max
);
3354 ok( ret
, "GetScrollRange error %d\n", GetLastError());
3355 if (sequence
->message
!= WmGetScrollRangeSeq
[0].message
)
3356 trace("GetScrollRange(SB_CTL) generated unknown message %04x\n", sequence
->message
);
3357 /* values of min and max are undefined */
3360 ret
= SetScrollRange(hwnd
, SB_CTL
, 10, 150, FALSE
);
3361 ok( ret
, "SetScrollRange error %d\n", GetLastError());
3362 if (sequence
->message
!= WmSetScrollRangeSeq
[0].message
)
3363 trace("SetScrollRange(SB_CTL) generated unknown message %04x\n", sequence
->message
);
3368 ret
= GetScrollRange(hwnd
, SB_CTL
, &min
, &max
);
3369 ok( ret
, "GetScrollRange error %d\n", GetLastError());
3370 if (sequence
->message
!= WmGetScrollRangeSeq
[0].message
)
3371 trace("GetScrollRange(SB_CTL) generated unknown message %04x\n", sequence
->message
);
3372 /* values of min and max are undefined */
3375 si
.cbSize
= sizeof(si
);
3376 si
.fMask
= SIF_RANGE
;
3379 SetScrollInfo(hwnd
, SB_CTL
, &si
, FALSE
);
3380 if (sequence
->message
!= WmSetScrollRangeSeq
[0].message
)
3381 trace("SetScrollInfo(SB_CTL) generated unknown message %04x\n", sequence
->message
);
3384 si
.fMask
= SIF_PAGE
;
3386 SetScrollInfo(hwnd
, SB_CTL
, &si
, FALSE
);
3387 if (sequence
->message
!= WmSetScrollRangeSeq
[0].message
)
3388 trace("SetScrollInfo(SB_CTL) generated unknown message %04x\n", sequence
->message
);
3393 SetScrollInfo(hwnd
, SB_CTL
, &si
, FALSE
);
3394 if (sequence
->message
!= WmSetScrollRangeSeq
[0].message
)
3395 trace("SetScrollInfo(SB_CTL) generated unknown message %04x\n", sequence
->message
);
3398 si
.fMask
= SIF_RANGE
;
3399 si
.nMin
= 0xdeadbeef;
3400 si
.nMax
= 0xdeadbeef;
3401 ret
= GetScrollInfo(hwnd
, SB_CTL
, &si
);
3402 ok( ret
, "GetScrollInfo error %d\n", GetLastError());
3403 if (sequence
->message
!= WmGetScrollInfoSeq
[0].message
)
3404 trace("GetScrollInfo(SB_CTL) generated unknown message %04x\n", sequence
->message
);
3405 /* values of min and max are undefined */
3408 /* set WS_HSCROLL */
3409 test_hv_scroll_1(hwnd
, SB_HORZ
, 0, WS_HSCROLL
, 10, 150);
3410 /* clear WS_HSCROLL */
3411 test_hv_scroll_1(hwnd
, SB_HORZ
, WS_HSCROLL
, 0, 0, 0);
3413 /* set WS_HSCROLL */
3414 test_hv_scroll_2(hwnd
, SB_HORZ
, 0, WS_HSCROLL
, 10, 150);
3415 /* clear WS_HSCROLL */
3416 test_hv_scroll_2(hwnd
, SB_HORZ
, WS_HSCROLL
, 0, 0, 0);
3418 /* set WS_VSCROLL */
3419 test_hv_scroll_1(hwnd
, SB_VERT
, 0, WS_VSCROLL
, 10, 150);
3420 /* clear WS_VSCROLL */
3421 test_hv_scroll_1(hwnd
, SB_VERT
, WS_VSCROLL
, 0, 0, 0);
3423 /* set WS_VSCROLL */
3424 test_hv_scroll_2(hwnd
, SB_VERT
, 0, WS_VSCROLL
, 10, 150);
3425 /* clear WS_VSCROLL */
3426 test_hv_scroll_2(hwnd
, SB_VERT
, WS_VSCROLL
, 0, 0, 0);
3429 static void test_showwindow(void)
3434 hwnd
= CreateWindowExA(0, "TestWindowClass", "Test overlapped", WS_OVERLAPPEDWINDOW
,
3435 100, 100, 200, 200, 0, 0, 0, NULL
);
3436 ok (hwnd
!= 0, "Failed to create overlapped window\n");
3437 hchild
= CreateWindowExA(0, "TestWindowClass", "Test child", WS_CHILD
,
3438 0, 0, 10, 10, hwnd
, 0, 0, NULL
);
3439 ok (hchild
!= 0, "Failed to create child\n");
3442 /* ShowWindow( SW_SHOWNA) for invisible top level window */
3443 trace("calling ShowWindow( SW_SHOWNA) for invisible top level window\n");
3444 ok( ShowWindow(hwnd
, SW_SHOWNA
) == FALSE
, "ShowWindow: window was visible\n" );
3445 ok_sequence(WmSHOWNATopInvisible
, "ShowWindow(SW_SHOWNA) on invisible top level window", TRUE
);
3448 /* ShowWindow( SW_SHOWNA) for now visible top level window */
3449 trace("calling ShowWindow( SW_SHOWNA) for now visible top level window\n");
3450 ok( ShowWindow(hwnd
, SW_SHOWNA
) != FALSE
, "ShowWindow: window was invisible\n" );
3451 ok_sequence(WmSHOWNATopVisible
, "ShowWindow(SW_SHOWNA) on visible top level window", FALSE
);
3453 /* back to invisible */
3454 ShowWindow(hchild
, SW_HIDE
);
3455 ShowWindow(hwnd
, SW_HIDE
);
3457 /* ShowWindow(SW_SHOWNA) with child and parent invisible */
3458 trace("calling ShowWindow( SW_SHOWNA) for invisible child with invisible parent\n");
3459 ok( ShowWindow(hchild
, SW_SHOWNA
) == FALSE
, "ShowWindow: window was visible\n" );
3460 ok_sequence(WmSHOWNAChildInvisParInvis
, "ShowWindow(SW_SHOWNA) invisible child and parent", FALSE
);
3462 /* ShowWindow(SW_SHOWNA) with child visible and parent invisible */
3463 ok( ShowWindow(hchild
, SW_SHOW
) != FALSE
, "ShowWindow: window was invisible\n" );
3465 trace("calling ShowWindow( SW_SHOWNA) for the visible child and invisible parent\n");
3466 ok( ShowWindow(hchild
, SW_SHOWNA
) != FALSE
, "ShowWindow: window was invisible\n" );
3467 ok_sequence(WmSHOWNAChildVisParInvis
, "ShowWindow(SW_SHOWNA) visible child and invisible parent", FALSE
);
3469 /* ShowWindow(SW_SHOWNA) with child visible and parent visible */
3470 ShowWindow( hwnd
, SW_SHOW
);
3472 trace("calling ShowWindow( SW_SHOWNA) for the visible child and parent\n");
3473 ok( ShowWindow(hchild
, SW_SHOWNA
) != FALSE
, "ShowWindow: window was invisible\n" );
3474 ok_sequence(WmSHOWNAChildVisParVis
, "ShowWindow(SW_SHOWNA) for the visible child and parent", FALSE
);
3477 /* ShowWindow(SW_SHOWNA) with child invisible and parent visible */
3478 ShowWindow( hchild
, SW_HIDE
);
3480 trace("calling ShowWindow( SW_SHOWNA) for the invisible child and visible parent\n");
3481 ok( ShowWindow(hchild
, SW_SHOWNA
) == FALSE
, "ShowWindow: window was visible\n" );
3482 ok_sequence(WmSHOWNAChildInvisParVis
, "ShowWindow(SW_SHOWNA) for the invisible child and visible parent", FALSE
);
3486 ok(GetCapture() == hchild
, "wrong capture window %p\n", GetCapture());
3487 DestroyWindow(hchild
);
3488 ok(!GetCapture(), "wrong capture window %p\n", GetCapture());
3490 DestroyWindow(hwnd
);
3495 * 1. Create invisible maximized popup window.
3496 * 2. Move and resize it.
3497 * 3. Show it maximized.
3499 trace("calling CreateWindowExA( WS_MAXIMIZE ) for invisible maximized popup window\n");
3500 hwnd
= CreateWindowExA(0, "TestWindowClass", "Test popup", WS_POPUP
| WS_MAXIMIZE
,
3501 100, 100, 200, 200, 0, 0, 0, NULL
);
3502 ok (hwnd
!= 0, "Failed to create popup window\n");
3503 ok(IsZoomed(hwnd
), "window should be maximized\n");
3504 ok_sequence(WmCreateInvisibleMaxPopupSeq
, "CreateWindow(WS_MAXIMIZED):popup", FALSE
);
3507 GetWindowRect(hwnd
, &rc
);
3508 ok( rc
.right
-rc
.left
== GetSystemMetrics(SM_CXSCREEN
) &&
3509 rc
.bottom
-rc
.top
== GetSystemMetrics(SM_CYSCREEN
),
3510 "Invalid maximized size before ShowWindow (%d,%d)-(%d,%d)\n",
3511 rc
.left
, rc
.top
, rc
.right
, rc
.bottom
);
3512 /* Reset window's size & position */
3513 SetWindowPos(hwnd
, 0, 10, 10, 200, 200, SWP_NOZORDER
| SWP_NOACTIVATE
);
3514 ok(IsZoomed(hwnd
), "window should be maximized\n");
3517 trace("calling ShowWindow( SW_SHOWMAXIMIZE ) for invisible maximized popup window\n");
3518 ShowWindow(hwnd
, SW_SHOWMAXIMIZED
);
3519 ok(IsZoomed(hwnd
), "window should be maximized\n");
3520 ok_sequence(WmShowMaxPopupResizedSeq
, "ShowWindow(SW_SHOWMAXIMIZED):invisible maximized and resized popup", FALSE
);
3523 GetWindowRect(hwnd
, &rc
);
3524 ok( rc
.right
-rc
.left
== GetSystemMetrics(SM_CXSCREEN
) &&
3525 rc
.bottom
-rc
.top
== GetSystemMetrics(SM_CYSCREEN
),
3526 "Invalid maximized size after ShowWindow (%d,%d)-(%d,%d)\n",
3527 rc
.left
, rc
.top
, rc
.right
, rc
.bottom
);
3528 DestroyWindow(hwnd
);
3532 * 1. Create invisible maximized popup window.
3533 * 2. Show it maximized.
3535 trace("calling CreateWindowExA( WS_MAXIMIZE ) for invisible maximized popup window\n");
3536 hwnd
= CreateWindowExA(0, "TestWindowClass", "Test popup", WS_POPUP
| WS_MAXIMIZE
,
3537 100, 100, 200, 200, 0, 0, 0, NULL
);
3538 ok (hwnd
!= 0, "Failed to create popup window\n");
3539 ok(IsZoomed(hwnd
), "window should be maximized\n");
3540 ok_sequence(WmCreateInvisibleMaxPopupSeq
, "CreateWindow(WS_MAXIMIZED):popup", FALSE
);
3543 trace("calling ShowWindow( SW_SHOWMAXIMIZE ) for invisible maximized popup window\n");
3544 ShowWindow(hwnd
, SW_SHOWMAXIMIZED
);
3545 ok(IsZoomed(hwnd
), "window should be maximized\n");
3546 ok_sequence(WmShowMaxPopupSeq
, "ShowWindow(SW_SHOWMAXIMIZED):invisible maximized popup", FALSE
);
3548 DestroyWindow(hwnd
);
3552 * 1. Create visible maximized popup window.
3554 trace("calling CreateWindowExA( WS_MAXIMIZE ) for maximized popup window\n");
3555 hwnd
= CreateWindowExA(0, "TestWindowClass", "Test popup", WS_POPUP
| WS_MAXIMIZE
| WS_VISIBLE
,
3556 100, 100, 200, 200, 0, 0, 0, NULL
);
3557 ok (hwnd
!= 0, "Failed to create popup window\n");
3558 ok(IsZoomed(hwnd
), "window should be maximized\n");
3559 ok_sequence(WmCreateMaxPopupSeq
, "CreateWindow(WS_MAXIMIZED):popup", FALSE
);
3561 DestroyWindow(hwnd
);
3565 * 1. Create visible popup window.
3568 trace("calling CreateWindowExA( WS_VISIBLE ) for popup window\n");
3569 hwnd
= CreateWindowExA(0, "TestWindowClass", "Test popup", WS_POPUP
| WS_VISIBLE
,
3570 100, 100, 200, 200, 0, 0, 0, NULL
);
3571 ok (hwnd
!= 0, "Failed to create popup window\n");
3572 ok(!IsZoomed(hwnd
), "window should NOT be maximized\n");
3573 ok_sequence(WmCreatePopupSeq
, "CreateWindow(WS_VISIBLE):popup", TRUE
);
3576 trace("calling ShowWindow( SW_SHOWMAXIMIZE ) for visible popup window\n");
3577 ShowWindow(hwnd
, SW_SHOWMAXIMIZED
);
3578 ok(IsZoomed(hwnd
), "window should be maximized\n");
3579 ok_sequence(WmShowVisMaxPopupSeq
, "ShowWindow(SW_SHOWMAXIMIZED):popup", FALSE
);
3581 DestroyWindow(hwnd
);
3585 static void test_sys_menu(void)
3591 hwnd
= CreateWindowExA(0, "TestWindowClass", NULL
, WS_OVERLAPPEDWINDOW
,
3592 100, 100, 200, 200, 0, 0, 0, NULL
);
3593 ok (hwnd
!= 0, "Failed to create overlapped window\n");
3597 /* test existing window without CS_NOCLOSE style */
3598 hmenu
= GetSystemMenu(hwnd
, FALSE
);
3599 ok(hmenu
!= 0, "GetSystemMenu error %d\n", GetLastError());
3601 state
= GetMenuState(hmenu
, SC_CLOSE
, MF_BYCOMMAND
);
3602 ok(state
!= 0xffffffff, "wrong SC_CLOSE state %x\n", state
);
3603 ok(!(state
& (MF_DISABLED
| MF_GRAYED
)), "wrong SC_CLOSE state %x\n", state
);
3605 EnableMenuItem(hmenu
, SC_CLOSE
, MF_BYCOMMAND
| MF_GRAYED
);
3606 ok_sequence(WmEmptySeq
, "WmEnableMenuItem", FALSE
);
3608 state
= GetMenuState(hmenu
, SC_CLOSE
, MF_BYCOMMAND
);
3609 ok(state
!= 0xffffffff, "wrong SC_CLOSE state %x\n", state
);
3610 ok((state
& (MF_DISABLED
| MF_GRAYED
)) == MF_GRAYED
, "wrong SC_CLOSE state %x\n", state
);
3612 EnableMenuItem(hmenu
, SC_CLOSE
, 0);
3613 ok_sequence(WmEmptySeq
, "WmEnableMenuItem", FALSE
);
3615 state
= GetMenuState(hmenu
, SC_CLOSE
, MF_BYCOMMAND
);
3616 ok(state
!= 0xffffffff, "wrong SC_CLOSE state %x\n", state
);
3617 ok(!(state
& (MF_DISABLED
| MF_GRAYED
)), "wrong SC_CLOSE state %x\n", state
);
3619 /* test whether removing WS_SYSMENU destroys a system menu */
3620 SetWindowLongW(hwnd
, GWL_STYLE
, WS_POPUP
);
3621 SetWindowPos(hwnd
, 0, 0, 0, 0, 0, SWP_NOZORDER
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_FRAMECHANGED
);
3623 hmenu
= GetSystemMenu(hwnd
, FALSE
);
3624 ok(hmenu
!= 0, "GetSystemMenu error %d\n", GetLastError());
3626 DestroyWindow(hwnd
);
3628 /* test new window with CS_NOCLOSE style */
3629 hwnd
= CreateWindowExA(0, "NoCloseWindowClass", NULL
, WS_OVERLAPPEDWINDOW
,
3630 100, 100, 200, 200, 0, 0, 0, NULL
);
3631 ok (hwnd
!= 0, "Failed to create overlapped window\n");
3633 hmenu
= GetSystemMenu(hwnd
, FALSE
);
3634 ok(hmenu
!= 0, "GetSystemMenu error %d\n", GetLastError());
3636 state
= GetMenuState(hmenu
, SC_CLOSE
, MF_BYCOMMAND
);
3637 ok(state
== 0xffffffff, "wrong SC_CLOSE state %x\n", state
);
3639 DestroyWindow(hwnd
);
3641 /* test new window without WS_SYSMENU style */
3642 hwnd
= CreateWindowExA(0, "NoCloseWindowClass", NULL
, WS_OVERLAPPEDWINDOW
& ~WS_SYSMENU
,
3643 100, 100, 200, 200, 0, 0, 0, NULL
);
3644 ok(hwnd
!= 0, "Failed to create overlapped window\n");
3646 hmenu
= GetSystemMenu(hwnd
, FALSE
);
3647 ok(!hmenu
, "GetSystemMenu error %d\n", GetLastError());
3649 DestroyWindow(hwnd
);
3652 /* For shown WS_OVERLAPPEDWINDOW */
3653 static const struct message WmSetIcon_1
[] = {
3654 { WM_SETICON
, sent
},
3655 { 0x00AE, sent
|defwinproc
|optional
}, /* XP */
3656 { WM_GETTEXT
, sent
|defwinproc
|optional
},
3657 { WM_GETTEXT
, sent
|defwinproc
|optional
}, /* XP sends a duplicate */
3661 /* For WS_POPUP and hidden WS_OVERLAPPEDWINDOW */
3662 static const struct message WmSetIcon_2
[] = {
3663 { WM_SETICON
, sent
},
3667 static void test_MsgWaitForMultipleObjects(HWND hwnd
)
3672 ret
= MsgWaitForMultipleObjects(0, NULL
, FALSE
, 0, QS_POSTMESSAGE
);
3673 ok(ret
== WAIT_TIMEOUT
, "MsgWaitForMultipleObjects returned %x\n", ret
);
3675 PostMessageA(hwnd
, WM_USER
, 0, 0);
3677 ret
= MsgWaitForMultipleObjects(0, NULL
, FALSE
, 0, QS_POSTMESSAGE
);
3678 ok(ret
== WAIT_OBJECT_0
, "MsgWaitForMultipleObjects returned %x\n", ret
);
3680 ok(PeekMessageW( &msg
, 0, 0, 0, PM_REMOVE
), "PeekMessage should succeed\n");
3681 ok(msg
.message
== WM_USER
, "got %04x instead of WM_USER\n", msg
.message
);
3683 ret
= MsgWaitForMultipleObjects(0, NULL
, FALSE
, 0, QS_POSTMESSAGE
);
3684 ok(ret
== WAIT_TIMEOUT
, "MsgWaitForMultipleObjects returned %x\n", ret
);
3686 PostMessageA(hwnd
, WM_USER
, 0, 0);
3688 ret
= MsgWaitForMultipleObjects(0, NULL
, FALSE
, 0, QS_POSTMESSAGE
);
3689 ok(ret
== WAIT_OBJECT_0
, "MsgWaitForMultipleObjects returned %x\n", ret
);
3691 ok(PeekMessageW( &msg
, 0, 0, 0, PM_NOREMOVE
), "PeekMessage should succeed\n");
3692 ok(msg
.message
== WM_USER
, "got %04x instead of WM_USER\n", msg
.message
);
3694 /* shows QS_POSTMESSAGE flag is cleared in the PeekMessage call */
3695 ret
= MsgWaitForMultipleObjects(0, NULL
, FALSE
, 0, QS_POSTMESSAGE
);
3696 ok(ret
== WAIT_TIMEOUT
, "MsgWaitForMultipleObjects returned %x\n", ret
);
3698 PostMessageA(hwnd
, WM_USER
, 0, 0);
3700 /* new incoming message causes it to become signaled again */
3701 ret
= MsgWaitForMultipleObjects(0, NULL
, FALSE
, 0, QS_POSTMESSAGE
);
3702 ok(ret
== WAIT_OBJECT_0
, "MsgWaitForMultipleObjects returned %x\n", ret
);
3704 ok(PeekMessageW( &msg
, 0, 0, 0, PM_REMOVE
), "PeekMessage should succeed\n");
3705 ok(msg
.message
== WM_USER
, "got %04x instead of WM_USER\n", msg
.message
);
3706 ok(PeekMessageW( &msg
, 0, 0, 0, PM_REMOVE
), "PeekMessage should succeed\n");
3707 ok(msg
.message
== WM_USER
, "got %04x instead of WM_USER\n", msg
.message
);
3710 /* test if we receive the right sequence of messages */
3711 static void test_messages(void)
3713 HWND hwnd
, hparent
, hchild
;
3714 HWND hchild2
, hbutton
;
3720 hwnd
= CreateWindowExA(0, "TestWindowClass", "Test overlapped", WS_OVERLAPPEDWINDOW
,
3721 100, 100, 200, 200, 0, 0, 0, NULL
);
3722 ok (hwnd
!= 0, "Failed to create overlapped window\n");
3723 ok_sequence(WmCreateOverlappedSeq
, "CreateWindow:overlapped", FALSE
);
3725 /* test ShowWindow(SW_HIDE) on a newly created invisible window */
3726 ok( ShowWindow(hwnd
, SW_HIDE
) == FALSE
, "ShowWindow: window was visible\n" );
3727 ok_sequence(WmEmptySeq
, "ShowWindow(SW_HIDE):overlapped, invisible", FALSE
);
3729 /* test WM_SETREDRAW on a not visible top level window */
3730 test_WM_SETREDRAW(hwnd
);
3732 SetWindowPos(hwnd
, 0,0,0,0,0, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
);
3733 ok_sequence(WmSWP_ShowOverlappedSeq
, "SetWindowPos:SWP_SHOWWINDOW:overlapped", FALSE
);
3734 ok(IsWindowVisible(hwnd
), "window should be visible at this point\n");
3736 ok(GetActiveWindow() == hwnd
, "window should be active\n");
3737 ok(GetFocus() == hwnd
, "window should have input focus\n");
3738 ShowWindow(hwnd
, SW_HIDE
);
3739 ok_sequence(WmHideOverlappedSeq
, "ShowWindow(SW_HIDE):overlapped", TRUE
);
3741 ShowWindow(hwnd
, SW_SHOW
);
3742 ok_sequence(WmShowOverlappedSeq
, "ShowWindow(SW_SHOW):overlapped", TRUE
);
3744 ShowWindow(hwnd
, SW_HIDE
);
3745 ok_sequence(WmHideOverlappedSeq
, "ShowWindow(SW_HIDE):overlapped", FALSE
);
3747 ShowWindow(hwnd
, SW_SHOWMAXIMIZED
);
3748 ok_sequence(WmShowMaxOverlappedSeq
, "ShowWindow(SW_SHOWMAXIMIZED):overlapped", TRUE
);
3750 ShowWindow(hwnd
, SW_RESTORE
);
3751 /* FIXME: add ok_sequence() here */
3754 ShowWindow(hwnd
, SW_MINIMIZE
);
3755 ok_sequence(WmShowMinOverlappedSeq
, "ShowWindow(SW_SHOWMINIMIZED):overlapped", TRUE
);
3758 ShowWindow(hwnd
, SW_RESTORE
);
3759 /* FIXME: add ok_sequence() here */
3762 ShowWindow(hwnd
, SW_SHOW
);
3763 ok_sequence(WmEmptySeq
, "ShowWindow(SW_SHOW):overlapped already visible", FALSE
);
3765 ok(GetActiveWindow() == hwnd
, "window should be active\n");
3766 ok(GetFocus() == hwnd
, "window should have input focus\n");
3767 SetWindowPos(hwnd
, 0,0,0,0,0, SWP_HIDEWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
);
3768 ok_sequence(WmSWP_HideOverlappedSeq
, "SetWindowPos:SWP_HIDEWINDOW:overlapped", FALSE
);
3769 ok(!IsWindowVisible(hwnd
), "window should not be visible at this point\n");
3770 ok(GetActiveWindow() == hwnd
, "window should still be active\n");
3772 /* test WM_SETREDRAW on a visible top level window */
3773 ShowWindow(hwnd
, SW_SHOW
);
3774 test_WM_SETREDRAW(hwnd
);
3776 trace("testing scroll APIs on a visible top level window %p\n", hwnd
);
3777 test_scroll_messages(hwnd
);
3779 /* test resizing and moving */
3780 SetWindowPos( hwnd
, 0, 0, 0, 300, 300, SWP_NOMOVE
|SWP_NOACTIVATE
);
3781 ok_sequence(WmSWP_ResizeSeq
, "SetWindowPos:Resize", FALSE
);
3784 SetWindowPos( hwnd
, 0, 200, 200, 0, 0, SWP_NOSIZE
|SWP_NOACTIVATE
);
3785 ok_sequence(WmSWP_MoveSeq
, "SetWindowPos:Move", FALSE
);
3788 SetWindowPos( hwnd
, 0, 200, 200, 250, 250, SWP_NOZORDER
);
3789 ok_sequence(WmSWP_ResizeNoZOrder
, "SetWindowPos:WmSWP_ResizeNoZOrder", FALSE
);
3793 /* popups don't get WM_GETMINMAXINFO */
3794 SetWindowLongW( hwnd
, GWL_STYLE
, WS_VISIBLE
|WS_POPUP
);
3795 SetWindowPos( hwnd
, 0, 0, 0, 0, 0, SWP_NOZORDER
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_FRAMECHANGED
);
3797 SetWindowPos( hwnd
, 0, 0, 0, 200, 200, SWP_NOMOVE
|SWP_NOACTIVATE
);
3798 ok_sequence(WmSWP_ResizePopupSeq
, "SetWindowPos:ResizePopup", FALSE
);
3800 DestroyWindow(hwnd
);
3801 ok_sequence(WmDestroyOverlappedSeq
, "DestroyWindow:overlapped", FALSE
);
3803 hparent
= CreateWindowExA(0, "TestParentClass", "Test parent", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
3804 100, 100, 200, 200, 0, 0, 0, NULL
);
3805 ok (hparent
!= 0, "Failed to create parent window\n");
3808 hchild
= CreateWindowExA(0, "TestWindowClass", "Test child", WS_CHILD
| WS_MAXIMIZE
,
3809 0, 0, 10, 10, hparent
, 0, 0, NULL
);
3810 ok (hchild
!= 0, "Failed to create child window\n");
3811 ok_sequence(WmCreateMaximizedChildSeq
, "CreateWindow:maximized child", FALSE
);
3812 DestroyWindow(hchild
);
3815 /* visible child window with a caption */
3816 hchild
= CreateWindowExA(0, "TestWindowClass", "Test child",
3817 WS_CHILD
| WS_VISIBLE
| WS_CAPTION
,
3818 0, 0, 10, 10, hparent
, 0, 0, NULL
);
3819 ok (hchild
!= 0, "Failed to create child window\n");
3820 ok_sequence(WmCreateVisibleChildSeq
, "CreateWindow:visible child", FALSE
);
3822 trace("testing scroll APIs on a visible child window %p\n", hchild
);
3823 test_scroll_messages(hchild
);
3825 SetWindowPos(hchild
, 0,0,0,0,0, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
);
3826 ok_sequence(WmShowChildSeq_4
, "SetWindowPos(SWP_SHOWWINDOW):child with a caption", FALSE
);
3828 DestroyWindow(hchild
);
3831 hchild
= CreateWindowExA(0, "TestWindowClass", "Test child", WS_CHILD
,
3832 0, 0, 10, 10, hparent
, 0, 0, NULL
);
3833 ok (hchild
!= 0, "Failed to create child window\n");
3834 ok_sequence(WmCreateChildSeq
, "CreateWindow:child", FALSE
);
3836 hchild2
= CreateWindowExA(0, "SimpleWindowClass", "Test child2", WS_CHILD
,
3837 100, 100, 50, 50, hparent
, 0, 0, NULL
);
3838 ok (hchild2
!= 0, "Failed to create child2 window\n");
3841 hbutton
= CreateWindowExA(0, "TestWindowClass", "Test button", WS_CHILD
,
3842 0, 100, 50, 50, hchild
, 0, 0, NULL
);
3843 ok (hbutton
!= 0, "Failed to create button window\n");
3845 /* test WM_SETREDRAW on a not visible child window */
3846 test_WM_SETREDRAW(hchild
);
3848 ShowWindow(hchild
, SW_SHOW
);
3849 ok_sequence(WmShowChildSeq
, "ShowWindow(SW_SHOW):child", FALSE
);
3851 ShowWindow(hchild
, SW_HIDE
);
3852 ok_sequence(WmHideChildSeq
, "ShowWindow(SW_HIDE):child", FALSE
);
3854 ShowWindow(hchild
, SW_SHOW
);
3855 ok_sequence(WmShowChildSeq
, "ShowWindow(SW_SHOW):child", FALSE
);
3857 /* test WM_SETREDRAW on a visible child window */
3858 test_WM_SETREDRAW(hchild
);
3860 MoveWindow(hchild
, 10, 10, 20, 20, TRUE
);
3861 ok_sequence(WmResizingChildWithMoveWindowSeq
, "MoveWindow:child", FALSE
);
3863 ShowWindow(hchild
, SW_HIDE
);
3865 SetWindowPos(hchild
, 0,0,0,0,0, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
);
3866 ok_sequence(WmShowChildSeq_2
, "SetWindowPos:show_child_2", FALSE
);
3868 ShowWindow(hchild
, SW_HIDE
);
3870 SetWindowPos(hchild
, 0,0,0,0,0, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOACTIVATE
);
3871 ok_sequence(WmShowChildSeq_3
, "SetWindowPos:show_child_3", FALSE
);
3873 /* DestroyWindow sequence below expects that a child has focus */
3877 DestroyWindow(hchild
);
3878 ok_sequence(WmDestroyChildSeq
, "DestroyWindow:child", FALSE
);
3879 DestroyWindow(hchild2
);
3880 DestroyWindow(hbutton
);
3883 hchild
= CreateWindowExA(0, "TestWindowClass", "Test Child Popup", WS_CHILD
| WS_POPUP
,
3884 0, 0, 100, 100, hparent
, 0, 0, NULL
);
3885 ok (hchild
!= 0, "Failed to create child popup window\n");
3886 ok_sequence(WmCreateChildPopupSeq
, "CreateWindow:child_popup", FALSE
);
3887 DestroyWindow(hchild
);
3889 /* test what happens to a window which sets WS_VISIBLE in WM_CREATE */
3891 hchild
= CreateWindowExA(0, "TestPopupClass", "Test Popup", WS_POPUP
,
3892 0, 0, 100, 100, hparent
, 0, 0, NULL
);
3893 ok (hchild
!= 0, "Failed to create popup window\n");
3894 ok_sequence(WmCreateInvisiblePopupSeq
, "CreateWindow:invisible_popup", FALSE
);
3895 ok(GetWindowLongA(hchild
, GWL_STYLE
) & WS_VISIBLE
, "WS_VISIBLE should be set\n");
3896 ok(IsWindowVisible(hchild
), "IsWindowVisible() should return TRUE\n");
3898 ShowWindow(hchild
, SW_SHOW
);
3899 ok_sequence(WmEmptySeq
, "ShowWindow:show_visible_popup", FALSE
);
3901 SetWindowPos(hchild
, 0,0,0,0,0, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOACTIVATE
|SWP_NOZORDER
);
3902 ok_sequence(WmShowVisiblePopupSeq_2
, "SetWindowPos:show_visible_popup_2", FALSE
);
3904 SetWindowPos(hchild
, 0,0,0,0,0, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
);
3905 ok_sequence(WmShowVisiblePopupSeq_3
, "SetWindowPos:show_visible_popup_3", FALSE
);
3906 DestroyWindow(hchild
);
3908 /* this time add WS_VISIBLE for CreateWindowEx, but this fact actually
3909 * changes nothing in message sequences.
3912 hchild
= CreateWindowExA(0, "TestPopupClass", "Test Popup", WS_POPUP
| WS_VISIBLE
,
3913 0, 0, 100, 100, hparent
, 0, 0, NULL
);
3914 ok (hchild
!= 0, "Failed to create popup window\n");
3915 ok_sequence(WmCreateInvisiblePopupSeq
, "CreateWindow:invisible_popup", FALSE
);
3916 ok(GetWindowLongA(hchild
, GWL_STYLE
) & WS_VISIBLE
, "WS_VISIBLE should be set\n");
3917 ok(IsWindowVisible(hchild
), "IsWindowVisible() should return TRUE\n");
3919 ShowWindow(hchild
, SW_SHOW
);
3920 ok_sequence(WmEmptySeq
, "ShowWindow:show_visible_popup", FALSE
);
3922 SetWindowPos(hchild
, 0,0,0,0,0, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOACTIVATE
|SWP_NOZORDER
);
3923 ok_sequence(WmShowVisiblePopupSeq_2
, "SetWindowPos:show_visible_popup_2", FALSE
);
3924 DestroyWindow(hchild
);
3927 hwnd
= CreateWindowExA(WS_EX_DLGMODALFRAME
, "TestDialogClass", NULL
, WS_VISIBLE
|WS_CAPTION
|WS_SYSMENU
|WS_DLGFRAME
,
3928 0, 0, 100, 100, hparent
, 0, 0, NULL
);
3929 ok(hwnd
!= 0, "Failed to create custom dialog window\n");
3930 ok_sequence(WmCreateCustomDialogSeq
, "CreateCustomDialog", TRUE
);
3933 trace("testing scroll APIs on a visible dialog %p\n", hwnd);
3934 test_scroll_messages(hwnd);
3940 SendMessage(hwnd
, WM_NULL
, 0, 0);
3943 after_end_dialog
= 1;
3944 EndDialog( hwnd
, 0 );
3945 ok_sequence(WmEndCustomDialogSeq
, "EndCustomDialog", FALSE
);
3947 DestroyWindow(hwnd
);
3948 after_end_dialog
= 0;
3951 hwnd
= CreateWindowExA(0, "TestDialogClass", NULL
, WS_POPUP
,
3952 0, 0, 100, 100, 0, 0, GetModuleHandleA(0), NULL
);
3953 ok(hwnd
!= 0, "Failed to create custom dialog window\n");
3955 trace("call ShowWindow(%p, SW_SHOW)\n", hwnd
);
3956 ShowWindow(hwnd
, SW_SHOW
);
3957 ok_sequence(WmShowCustomDialogSeq
, "ShowCustomDialog", TRUE
);
3958 DestroyWindow(hwnd
);
3961 DialogBoxA( 0, "TEST_DIALOG", hparent
, TestModalDlgProcA
);
3962 ok_sequence(WmModalDialogSeq
, "ModalDialog", TRUE
);
3964 DestroyWindow(hparent
);
3967 /* Message sequence for SetMenu */
3968 ok(!DrawMenuBar(hwnd
), "DrawMenuBar should return FALSE for a window without a menu\n");
3969 ok_sequence(WmEmptySeq
, "DrawMenuBar for a window without a menu", FALSE
);
3971 hmenu
= CreateMenu();
3972 ok (hmenu
!= 0, "Failed to create menu\n");
3973 ok (InsertMenuA(hmenu
, -1, MF_BYPOSITION
, 0x1000, "foo"), "InsertMenu failed\n");
3974 hwnd
= CreateWindowExA(0, "TestWindowClass", "Test overlapped", WS_OVERLAPPEDWINDOW
,
3975 100, 100, 200, 200, 0, hmenu
, 0, NULL
);
3976 ok_sequence(WmCreateOverlappedSeq
, "CreateWindow:overlapped", FALSE
);
3977 ok (SetMenu(hwnd
, 0), "SetMenu\n");
3978 ok_sequence(WmSetMenuNonVisibleSizeChangeSeq
, "SetMenu:NonVisibleSizeChange", FALSE
);
3979 ok (SetMenu(hwnd
, 0), "SetMenu\n");
3980 ok_sequence(WmSetMenuNonVisibleNoSizeChangeSeq
, "SetMenu:NonVisibleNoSizeChange", FALSE
);
3981 ShowWindow(hwnd
, SW_SHOW
);
3982 UpdateWindow( hwnd
);
3983 while (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
3985 ok (SetMenu(hwnd
, 0), "SetMenu\n");
3986 ok_sequence(WmSetMenuVisibleNoSizeChangeSeq
, "SetMenu:VisibleNoSizeChange", FALSE
);
3987 ok (SetMenu(hwnd
, hmenu
), "SetMenu\n");
3988 ok_sequence(WmSetMenuVisibleSizeChangeSeq
, "SetMenu:VisibleSizeChange", FALSE
);
3990 UpdateWindow( hwnd
);
3991 while (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
3993 ok(DrawMenuBar(hwnd
), "DrawMenuBar\n");
3994 while (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
3995 ok_sequence(WmDrawMenuBarSeq
, "DrawMenuBar", FALSE
);
3997 DestroyWindow(hwnd
);
4000 /* Message sequence for EnableWindow */
4001 hparent
= CreateWindowExA(0, "TestWindowClass", "Test parent", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
4002 100, 100, 200, 200, 0, 0, 0, NULL
);
4003 ok (hparent
!= 0, "Failed to create parent window\n");
4004 hchild
= CreateWindowExA(0, "TestWindowClass", "Test child", WS_CHILD
| WS_VISIBLE
,
4005 0, 0, 10, 10, hparent
, 0, 0, NULL
);
4006 ok (hchild
!= 0, "Failed to create child window\n");
4012 EnableWindow(hparent
, FALSE
);
4013 ok_sequence(WmEnableWindowSeq_1
, "EnableWindow(FALSE)", FALSE
);
4015 EnableWindow(hparent
, TRUE
);
4016 ok_sequence(WmEnableWindowSeq_2
, "EnableWindow(TRUE)", FALSE
);
4018 while (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
4021 test_MsgWaitForMultipleObjects(hparent
);
4023 /* the following test causes an exception in user.exe under win9x */
4024 if (!PostMessageW( hparent
, WM_USER
, 0, 0 ))
4026 DestroyWindow(hparent
);
4030 PostMessageW( hparent
, WM_USER
+1, 0, 0 );
4031 /* PeekMessage(NULL) fails, but still removes the message */
4032 SetLastError(0xdeadbeef);
4033 ok( !PeekMessageW( NULL
, 0, 0, 0, PM_REMOVE
), "PeekMessage(NULL) should fail\n" );
4034 ok( GetLastError() == ERROR_NOACCESS
|| /* Win2k */
4035 GetLastError() == 0xdeadbeef, /* NT4 */
4036 "last error is %d\n", GetLastError() );
4037 ok( PeekMessageW( &msg
, 0, 0, 0, PM_REMOVE
), "PeekMessage should succeed\n" );
4038 ok( msg
.message
== WM_USER
+1, "got %x instead of WM_USER+1\n", msg
.message
);
4040 DestroyWindow(hchild
);
4041 DestroyWindow(hparent
);
4044 /* Message sequences for WM_SETICON */
4045 trace("testing WM_SETICON\n");
4046 hwnd
= CreateWindowExA(0, "TestWindowClass", NULL
, WS_OVERLAPPEDWINDOW
,
4047 CW_USEDEFAULT
, CW_USEDEFAULT
, 300, 300, 0,
4049 ShowWindow(hwnd
, SW_SHOW
);
4051 while (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
4053 SendMessage(hwnd
, WM_SETICON
, ICON_SMALL
, (LPARAM
)LoadIcon(0, IDI_APPLICATION
));
4054 ok_sequence(WmSetIcon_1
, "WM_SETICON for shown window with caption", FALSE
);
4056 ShowWindow(hwnd
, SW_HIDE
);
4057 while (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
4059 SendMessage(hwnd
, WM_SETICON
, ICON_SMALL
, (LPARAM
)LoadIcon(0, IDI_APPLICATION
));
4060 ok_sequence(WmSetIcon_2
, "WM_SETICON for hidden window with caption", FALSE
);
4061 DestroyWindow(hwnd
);
4064 hwnd
= CreateWindowExA(0, "TestPopupClass", NULL
, WS_POPUP
,
4065 CW_USEDEFAULT
, CW_USEDEFAULT
, 300, 300, 0,
4067 ShowWindow(hwnd
, SW_SHOW
);
4069 while (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
4071 SendMessage(hwnd
, WM_SETICON
, ICON_SMALL
, (LPARAM
)LoadIcon(0, IDI_APPLICATION
));
4072 ok_sequence(WmSetIcon_2
, "WM_SETICON for shown window without caption", FALSE
);
4074 ShowWindow(hwnd
, SW_HIDE
);
4075 while (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
4077 SendMessage(hwnd
, WM_SETICON
, ICON_SMALL
, (LPARAM
)LoadIcon(0, IDI_APPLICATION
));
4078 ok_sequence(WmSetIcon_2
, "WM_SETICON for hidden window without caption", FALSE
);
4079 DestroyWindow(hwnd
);
4083 static void invisible_parent_tests(void)
4085 HWND hparent
, hchild
;
4087 hparent
= CreateWindowExA(0, "TestParentClass", "Test parent", WS_OVERLAPPEDWINDOW
,
4088 100, 100, 200, 200, 0, 0, 0, NULL
);
4089 ok (hparent
!= 0, "Failed to create parent window\n");
4092 /* test showing child with hidden parent */
4094 hchild
= CreateWindowExA(0, "TestWindowClass", "Test child", WS_CHILD
,
4095 0, 0, 10, 10, hparent
, 0, 0, NULL
);
4096 ok (hchild
!= 0, "Failed to create child window\n");
4097 ok_sequence(WmCreateChildSeq
, "CreateWindow:child", FALSE
);
4099 ShowWindow( hchild
, SW_MINIMIZE
);
4100 ok_sequence(WmShowChildInvisibleParentSeq_1
, "ShowWindow(SW_MINIMIZE) child with invisible parent", FALSE
);
4101 ok(GetWindowLongA(hchild
, GWL_STYLE
) & WS_VISIBLE
, "WS_VISIBLE should be set\n");
4102 ok(!IsWindowVisible(hchild
), "IsWindowVisible() should return FALSE\n");
4107 ShowWindow( hchild
, SW_MINIMIZE
);
4108 ok_sequence(WmShowChildInvisibleParentSeq_1r
, "ShowWindow(SW_MINIMIZE) child with invisible parent", FALSE
);
4110 DestroyWindow(hchild
);
4111 hchild
= CreateWindowExA(0, "TestWindowClass", "Test child", WS_CHILD
,
4112 0, 0, 10, 10, hparent
, 0, 0, NULL
);
4115 ShowWindow( hchild
, SW_MAXIMIZE
);
4116 ok_sequence(WmShowChildInvisibleParentSeq_2
, "ShowWindow(SW_MAXIMIZE) child with invisible parent", FALSE
);
4117 ok(GetWindowLongA(hchild
, GWL_STYLE
) & WS_VISIBLE
, "WS_VISIBLE should be set\n");
4118 ok(!IsWindowVisible(hchild
), "IsWindowVisible() should return FALSE\n");
4123 ShowWindow( hchild
, SW_MAXIMIZE
);
4124 ok_sequence(WmShowChildInvisibleParentSeq_2r
, "ShowWindow(SW_MAXIMIZE) child with invisible parent", FALSE
);
4126 DestroyWindow(hchild
);
4127 hchild
= CreateWindowExA(0, "TestWindowClass", "Test child", WS_CHILD
,
4128 0, 0, 10, 10, hparent
, 0, 0, NULL
);
4131 ShowWindow( hchild
, SW_RESTORE
);
4132 ok_sequence(WmShowChildInvisibleParentSeq_5
, "ShowWindow(SW_RESTORE) child with invisible parent", FALSE
);
4133 ok(GetWindowLongA(hchild
, GWL_STYLE
) & WS_VISIBLE
, "WS_VISIBLE should be set\n");
4134 ok(!IsWindowVisible(hchild
), "IsWindowVisible() should return FALSE\n");
4136 DestroyWindow(hchild
);
4137 hchild
= CreateWindowExA(0, "TestWindowClass", "Test child", WS_CHILD
,
4138 0, 0, 10, 10, hparent
, 0, 0, NULL
);
4141 ShowWindow( hchild
, SW_SHOWMINIMIZED
);
4142 ok_sequence(WmShowChildInvisibleParentSeq_3
, "ShowWindow(SW_SHOWMINIMIZED) child with invisible parent", FALSE
);
4143 ok(GetWindowLongA(hchild
, GWL_STYLE
) & WS_VISIBLE
, "WS_VISIBLE should be set\n");
4144 ok(!IsWindowVisible(hchild
), "IsWindowVisible() should return FALSE\n");
4149 ShowWindow( hchild
, SW_SHOWMINIMIZED
);
4150 ok_sequence(WmShowChildInvisibleParentSeq_3r
, "ShowWindow(SW_SHOWMINIMIZED) child with invisible parent", FALSE
);
4152 DestroyWindow(hchild
);
4153 hchild
= CreateWindowExA(0, "TestWindowClass", "Test child", WS_CHILD
,
4154 0, 0, 10, 10, hparent
, 0, 0, NULL
);
4157 /* same as ShowWindow( hchild, SW_MAXIMIZE ); */
4158 ShowWindow( hchild
, SW_SHOWMAXIMIZED
);
4159 ok_sequence(WmShowChildInvisibleParentSeq_2
, "ShowWindow(SW_SHOWMAXIMIZED) child with invisible parent", FALSE
);
4160 ok(GetWindowLongA(hchild
, GWL_STYLE
) & WS_VISIBLE
, "WS_VISIBLE should be set\n");
4161 ok(!IsWindowVisible(hchild
), "IsWindowVisible() should return FALSE\n");
4163 DestroyWindow(hchild
);
4164 hchild
= CreateWindowExA(0, "TestWindowClass", "Test child", WS_CHILD
,
4165 0, 0, 10, 10, hparent
, 0, 0, NULL
);
4168 ShowWindow( hchild
, SW_SHOWMINNOACTIVE
);
4169 ok_sequence(WmShowChildInvisibleParentSeq_4
, "ShowWindow(SW_SHOWMINNOACTIVE) child with invisible parent", FALSE
);
4170 ok(GetWindowLongA(hchild
, GWL_STYLE
) & WS_VISIBLE
, "WS_VISIBLE should be set\n");
4171 ok(!IsWindowVisible(hchild
), "IsWindowVisible() should return FALSE\n");
4176 ShowWindow( hchild
, SW_SHOWMINNOACTIVE
);
4177 ok_sequence(WmShowChildInvisibleParentSeq_4r
, "ShowWindow(SW_SHOWMINNOACTIVE) child with invisible parent", FALSE
);
4179 DestroyWindow(hchild
);
4180 hchild
= CreateWindowExA(0, "TestWindowClass", "Test child", WS_CHILD
,
4181 0, 0, 10, 10, hparent
, 0, 0, NULL
);
4184 /* FIXME: looks like XP SP2 doesn't know about SW_FORCEMINIMIZE at all */
4185 ShowWindow( hchild
, SW_FORCEMINIMIZE
);
4186 ok_sequence(WmEmptySeq
, "ShowWindow(SW_FORCEMINIMIZE) child with invisible parent", TRUE
);
4188 ok(!(GetWindowLongA(hchild
, GWL_STYLE
) & WS_VISIBLE
), "WS_VISIBLE should be not set\n");
4190 ok(!IsWindowVisible(hchild
), "IsWindowVisible() should return FALSE\n");
4192 DestroyWindow(hchild
);
4193 hchild
= CreateWindowExA(0, "TestWindowClass", "Test child", WS_CHILD
,
4194 0, 0, 10, 10, hparent
, 0, 0, NULL
);
4197 ShowWindow( hchild
, SW_SHOWNA
);
4198 ok_sequence(WmShowChildInvisibleParentSeq_5
, "ShowWindow(SW_SHOWNA) child with invisible parent", FALSE
);
4199 ok(GetWindowLongA(hchild
, GWL_STYLE
) & WS_VISIBLE
, "WS_VISIBLE should be set\n");
4200 ok(!IsWindowVisible(hchild
), "IsWindowVisible() should return FALSE\n");
4205 ShowWindow( hchild
, SW_SHOWNA
);
4206 ok_sequence(WmShowChildInvisibleParentSeq_5
, "ShowWindow(SW_SHOWNA) child with invisible parent", FALSE
);
4208 DestroyWindow(hchild
);
4209 hchild
= CreateWindowExA(0, "TestWindowClass", "Test child", WS_CHILD
,
4210 0, 0, 10, 10, hparent
, 0, 0, NULL
);
4213 ShowWindow( hchild
, SW_SHOW
);
4214 ok_sequence(WmShowChildInvisibleParentSeq_5
, "ShowWindow(SW_SHOW) child with invisible parent", FALSE
);
4215 ok(GetWindowLongA(hchild
, GWL_STYLE
) & WS_VISIBLE
, "WS_VISIBLE should be set\n");
4216 ok(!IsWindowVisible(hchild
), "IsWindowVisible() should return FALSE\n");
4221 ShowWindow( hchild
, SW_SHOW
);
4222 ok_sequence(WmEmptySeq
, "ShowWindow(SW_SHOW) child with invisible parent", FALSE
);
4224 ShowWindow( hchild
, SW_HIDE
);
4225 ok_sequence(WmHideChildInvisibleParentSeq
, "ShowWindow:hide child with invisible parent", FALSE
);
4226 ok(!(GetWindowLongA(hchild
, GWL_STYLE
) & WS_VISIBLE
), "WS_VISIBLE should be not set\n");
4227 ok(!IsWindowVisible(hchild
), "IsWindowVisible() should return FALSE\n");
4229 SetWindowPos(hchild
, 0,0,0,0,0, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOACTIVATE
|SWP_NOZORDER
);
4230 ok_sequence(WmShowChildInvisibleParentSeq_6
, "SetWindowPos:show child with invisible parent", FALSE
);
4231 ok(GetWindowLongA(hchild
, GWL_STYLE
) & WS_VISIBLE
, "WS_VISIBLE should be set\n");
4232 ok(!IsWindowVisible(hchild
), "IsWindowVisible() should return FALSE\n");
4234 SetWindowPos(hchild
, 0,0,0,0,0, SWP_HIDEWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOACTIVATE
|SWP_NOZORDER
);
4235 ok_sequence(WmHideChildInvisibleParentSeq_2
, "SetWindowPos:hide child with invisible parent", FALSE
);
4236 ok(!(GetWindowLongA(hchild
, GWL_STYLE
) & WS_VISIBLE
), "WS_VISIBLE should not be set\n");
4237 ok(!IsWindowVisible(hchild
), "IsWindowVisible() should return FALSE\n");
4239 SetWindowPos(hchild
, 0,0,0,0,0, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOACTIVATE
|SWP_NOZORDER
);
4241 DestroyWindow(hchild
);
4242 ok_sequence(WmDestroyInvisibleChildSeq
, "DestroyInvisibleChildSeq", FALSE
);
4244 DestroyWindow(hparent
);
4248 /****************** button message test *************************/
4249 static const struct message WmSetFocusButtonSeq
[] =
4251 { HCBT_SETFOCUS
, hook
},
4252 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 1 },
4253 { WM_IME_NOTIFY
, sent
|wparam
|defwinproc
|optional
, 2 },
4254 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
4255 { WM_SETFOCUS
, sent
|wparam
, 0 },
4256 { WM_CTLCOLORBTN
, sent
|defwinproc
},
4259 static const struct message WmKillFocusButtonSeq
[] =
4261 { HCBT_SETFOCUS
, hook
},
4262 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
4263 { WM_KILLFOCUS
, sent
|wparam
, 0 },
4264 { WM_CTLCOLORBTN
, sent
|defwinproc
},
4265 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 0 },
4266 { WM_IME_NOTIFY
, sent
|wparam
|defwinproc
|optional
, 1 },
4269 static const struct message WmSetFocusStaticSeq
[] =
4271 { HCBT_SETFOCUS
, hook
},
4272 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 1 },
4273 { WM_IME_NOTIFY
, sent
|wparam
|defwinproc
|optional
, 2 },
4274 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
4275 { WM_SETFOCUS
, sent
|wparam
, 0 },
4276 { WM_CTLCOLORSTATIC
, sent
|defwinproc
},
4279 static const struct message WmKillFocusStaticSeq
[] =
4281 { HCBT_SETFOCUS
, hook
},
4282 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
4283 { WM_KILLFOCUS
, sent
|wparam
, 0 },
4284 { WM_CTLCOLORSTATIC
, sent
|defwinproc
},
4285 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 0 },
4286 { WM_IME_NOTIFY
, sent
|wparam
|defwinproc
|optional
, 1 },
4289 static const struct message WmLButtonDownSeq
[] =
4291 { WM_LBUTTONDOWN
, sent
|wparam
|lparam
, 0, 0 },
4292 { EVENT_SYSTEM_CAPTURESTART
, winevent_hook
|wparam
|lparam
, 0, 0 },
4293 { HCBT_SETFOCUS
, hook
},
4294 { WM_IME_SETCONTEXT
, sent
|wparam
|defwinproc
|optional
, 1 },
4295 { WM_IME_NOTIFY
, sent
|wparam
|defwinproc
|optional
, 2 },
4296 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
4297 { WM_SETFOCUS
, sent
|wparam
|defwinproc
, 0 },
4298 { WM_CTLCOLORBTN
, sent
|defwinproc
},
4299 { BM_SETSTATE
, sent
|wparam
|defwinproc
, TRUE
},
4300 { WM_CTLCOLORBTN
, sent
|defwinproc
},
4301 { EVENT_OBJECT_STATECHANGE
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
4304 static const struct message WmLButtonUpSeq
[] =
4306 { WM_LBUTTONUP
, sent
|wparam
|lparam
, 0, 0 },
4307 { BM_SETSTATE
, sent
|wparam
|defwinproc
, FALSE
},
4308 { WM_CTLCOLORBTN
, sent
|defwinproc
},
4309 { EVENT_OBJECT_STATECHANGE
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
4310 { EVENT_SYSTEM_CAPTUREEND
, winevent_hook
|wparam
|lparam
, 0, 0 },
4311 { WM_CAPTURECHANGED
, sent
|wparam
|defwinproc
, 0 },
4314 static const struct message WmSetFontButtonSeq
[] =
4316 { WM_SETFONT
, sent
},
4318 { WM_ERASEBKGND
, sent
|defwinproc
|optional
},
4319 { WM_CTLCOLORBTN
, sent
|defwinproc
},
4323 static WNDPROC old_button_proc
;
4325 static LRESULT CALLBACK
button_hook_proc(HWND hwnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
4327 static long defwndproc_counter
= 0;
4331 trace("button: %p, %04x, %08x, %08lx\n", hwnd
, message
, wParam
, lParam
);
4333 /* explicitly ignore WM_GETICON message */
4334 if (message
== WM_GETICON
) return 0;
4336 msg
.message
= message
;
4337 msg
.flags
= sent
|wparam
|lparam
;
4338 if (defwndproc_counter
) msg
.flags
|= defwinproc
;
4339 msg
.wParam
= wParam
;
4340 msg
.lParam
= lParam
;
4343 if (message
== BM_SETSTATE
)
4344 ok(GetCapture() == hwnd
, "GetCapture() = %p\n", GetCapture());
4346 defwndproc_counter
++;
4347 ret
= CallWindowProcA(old_button_proc
, hwnd
, message
, wParam
, lParam
);
4348 defwndproc_counter
--;
4353 static void subclass_button(void)
4357 if (!GetClassInfoA(0, "button", &cls
)) assert(0);
4359 old_button_proc
= cls
.lpfnWndProc
;
4361 cls
.hInstance
= GetModuleHandle(0);
4362 cls
.lpfnWndProc
= button_hook_proc
;
4363 cls
.lpszClassName
= "my_button_class";
4364 UnregisterClass(cls
.lpszClassName
, cls
.hInstance
);
4365 if (!RegisterClassA(&cls
)) assert(0);
4368 static void test_button_messages(void)
4374 const struct message
*setfocus
;
4375 const struct message
*killfocus
;
4377 { BS_PUSHBUTTON
, DLGC_BUTTON
| DLGC_UNDEFPUSHBUTTON
,
4378 WmSetFocusButtonSeq
, WmKillFocusButtonSeq
},
4379 { BS_DEFPUSHBUTTON
, DLGC_BUTTON
| DLGC_DEFPUSHBUTTON
,
4380 WmSetFocusButtonSeq
, WmKillFocusButtonSeq
},
4381 { BS_CHECKBOX
, DLGC_BUTTON
,
4382 WmSetFocusStaticSeq
, WmKillFocusStaticSeq
},
4383 { BS_AUTOCHECKBOX
, DLGC_BUTTON
,
4384 WmSetFocusStaticSeq
, WmKillFocusStaticSeq
},
4385 { BS_RADIOBUTTON
, DLGC_BUTTON
| DLGC_RADIOBUTTON
,
4386 WmSetFocusStaticSeq
, WmKillFocusStaticSeq
},
4387 { BS_3STATE
, DLGC_BUTTON
,
4388 WmSetFocusStaticSeq
, WmKillFocusStaticSeq
},
4389 { BS_AUTO3STATE
, DLGC_BUTTON
,
4390 WmSetFocusStaticSeq
, WmKillFocusStaticSeq
},
4391 { BS_GROUPBOX
, DLGC_STATIC
,
4392 WmSetFocusStaticSeq
, WmKillFocusStaticSeq
},
4393 { BS_USERBUTTON
, DLGC_BUTTON
| DLGC_UNDEFPUSHBUTTON
,
4394 WmSetFocusButtonSeq
, WmKillFocusButtonSeq
},
4395 { BS_AUTORADIOBUTTON
, DLGC_BUTTON
| DLGC_RADIOBUTTON
,
4396 WmSetFocusStaticSeq
, WmKillFocusStaticSeq
},
4397 { BS_OWNERDRAW
, DLGC_BUTTON
,
4398 WmSetFocusButtonSeq
, WmKillFocusButtonSeq
}
4407 for (i
= 0; i
< sizeof(button
)/sizeof(button
[0]); i
++)
4409 hwnd
= CreateWindowExA(0, "my_button_class", "test", button
[i
].style
| WS_POPUP
,
4410 0, 0, 50, 14, 0, 0, 0, NULL
);
4411 ok(hwnd
!= 0, "Failed to create button window\n");
4413 dlg_code
= SendMessageA(hwnd
, WM_GETDLGCODE
, 0, 0);
4414 ok(dlg_code
== button
[i
].dlg_code
, "%u: wrong dlg_code %08x\n", i
, dlg_code
);
4416 ShowWindow(hwnd
, SW_SHOW
);
4421 trace("button style %08x\n", button
[i
].style
);
4423 ok_sequence(button
[i
].setfocus
, "SetFocus(hwnd) on a button", FALSE
);
4426 ok_sequence(button
[i
].killfocus
, "SetFocus(0) on a button", FALSE
);
4428 DestroyWindow(hwnd
);
4431 hwnd
= CreateWindowExA(0, "my_button_class", "test", BS_PUSHBUTTON
| WS_POPUP
| WS_VISIBLE
,
4432 0, 0, 50, 14, 0, 0, 0, NULL
);
4433 ok(hwnd
!= 0, "Failed to create button window\n");
4438 SendMessageA(hwnd
, WM_LBUTTONDOWN
, 0, 0);
4439 ok_sequence(WmLButtonDownSeq
, "WM_LBUTTONDOWN on a button", FALSE
);
4441 SendMessageA(hwnd
, WM_LBUTTONUP
, 0, 0);
4442 ok_sequence(WmLButtonUpSeq
, "WM_LBUTTONUP on a button", FALSE
);
4445 zfont
= (HFONT
)GetStockObject(SYSTEM_FONT
);
4446 SendMessageA(hwnd
, WM_SETFONT
, (WPARAM
)zfont
, TRUE
);
4448 ok_sequence(WmSetFontButtonSeq
, "WM_SETFONT on a button", FALSE
);
4450 DestroyWindow(hwnd
);
4453 /****************** static message test *************************/
4454 static const struct message WmSetFontStaticSeq
[] =
4456 { WM_SETFONT
, sent
},
4457 { WM_PAINT
, sent
|defwinproc
},
4458 { WM_ERASEBKGND
, sent
|defwinproc
|optional
},
4459 { WM_CTLCOLORSTATIC
, sent
|defwinproc
},
4463 static WNDPROC old_static_proc
;
4465 static LRESULT CALLBACK
static_hook_proc(HWND hwnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
4467 static long defwndproc_counter
= 0;
4471 trace("static: %p, %04x, %08x, %08lx\n", hwnd
, message
, wParam
, lParam
);
4473 /* explicitly ignore WM_GETICON message */
4474 if (message
== WM_GETICON
) return 0;
4476 msg
.message
= message
;
4477 msg
.flags
= sent
|wparam
|lparam
;
4478 if (defwndproc_counter
) msg
.flags
|= defwinproc
;
4479 msg
.wParam
= wParam
;
4480 msg
.lParam
= lParam
;
4484 defwndproc_counter
++;
4485 ret
= CallWindowProcA(old_static_proc
, hwnd
, message
, wParam
, lParam
);
4486 defwndproc_counter
--;
4491 static void subclass_static(void)
4495 if (!GetClassInfoA(0, "static", &cls
)) assert(0);
4497 old_static_proc
= cls
.lpfnWndProc
;
4499 cls
.hInstance
= GetModuleHandle(0);
4500 cls
.lpfnWndProc
= static_hook_proc
;
4501 cls
.lpszClassName
= "my_static_class";
4502 UnregisterClass(cls
.lpszClassName
, cls
.hInstance
);
4503 if (!RegisterClassA(&cls
)) assert(0);
4506 static void test_static_messages(void)
4508 /* FIXME: make as comprehensive as the button message test */
4513 const struct message
*setfont
;
4515 { SS_LEFT
, DLGC_STATIC
,
4516 WmSetFontStaticSeq
}
4524 for (i
= 0; i
< sizeof(static_ctrl
)/sizeof(static_ctrl
[0]); i
++)
4526 hwnd
= CreateWindowExA(0, "my_static_class", "test", static_ctrl
[i
].style
| WS_POPUP
,
4527 0, 0, 50, 14, 0, 0, 0, NULL
);
4528 ok(hwnd
!= 0, "Failed to create static window\n");
4530 dlg_code
= SendMessageA(hwnd
, WM_GETDLGCODE
, 0, 0);
4531 ok(dlg_code
== static_ctrl
[i
].dlg_code
, "%u: wrong dlg_code %08x\n", i
, dlg_code
);
4533 ShowWindow(hwnd
, SW_SHOW
);
4538 trace("static style %08x\n", static_ctrl
[i
].style
);
4539 SendMessage(hwnd
, WM_SETFONT
, (WPARAM
)GetStockObject(DEFAULT_GUI_FONT
), TRUE
);
4540 ok_sequence(static_ctrl
[i
].setfont
, "WM_SETFONT on a static", FALSE
);
4542 DestroyWindow(hwnd
);
4546 /************* painting message test ********************/
4548 void dump_region(HRGN hrgn
)
4551 RGNDATA
*data
= NULL
;
4556 printf( "null region\n" );
4559 if (!(size
= GetRegionData( hrgn
, 0, NULL
))) return;
4560 if (!(data
= HeapAlloc( GetProcessHeap(), 0, size
))) return;
4561 GetRegionData( hrgn
, size
, data
);
4562 printf("%d rects:", data
->rdh
.nCount
);
4563 for (i
= 0, rect
= (RECT
*)data
->Buffer
; i
< data
->rdh
.nCount
; i
++, rect
++)
4564 printf( " (%d,%d)-(%d,%d)", rect
->left
, rect
->top
, rect
->right
, rect
->bottom
);
4566 HeapFree( GetProcessHeap(), 0, data
);
4569 static void check_update_rgn( HWND hwnd
, HRGN hrgn
)
4573 HRGN tmp
= CreateRectRgn( 0, 0, 0, 0 );
4574 HRGN update
= CreateRectRgn( 0, 0, 0, 0 );
4576 ret
= GetUpdateRgn( hwnd
, update
, FALSE
);
4577 ok( ret
!= ERROR
, "GetUpdateRgn failed\n" );
4578 if (ret
== NULLREGION
)
4580 ok( !hrgn
, "Update region shouldn't be empty\n" );
4584 if (CombineRgn( tmp
, hrgn
, update
, RGN_XOR
) != NULLREGION
)
4586 ok( 0, "Regions are different\n" );
4587 if (winetest_debug
> 0)
4589 printf( "Update region: " );
4590 dump_region( update
);
4591 printf( "Wanted region: " );
4592 dump_region( hrgn
);
4596 GetRgnBox( update
, &r1
);
4597 GetUpdateRect( hwnd
, &r2
, FALSE
);
4598 ok( r1
.left
== r2
.left
&& r1
.top
== r2
.top
&& r1
.right
== r2
.right
&& r1
.bottom
== r2
.bottom
,
4599 "Rectangles are different: %d,%d-%d,%d / %d,%d-%d,%d\n",
4600 r1
.left
, r1
.top
, r1
.right
, r1
.bottom
, r2
.left
, r2
.top
, r2
.right
, r2
.bottom
);
4602 DeleteObject( tmp
);
4603 DeleteObject( update
);
4606 static const struct message WmInvalidateRgn
[] = {
4607 { WM_NCPAINT
, sent
},
4608 { WM_GETTEXT
, sent
|defwinproc
|optional
},
4612 static const struct message WmGetUpdateRect
[] = {
4613 { WM_NCPAINT
, sent
},
4614 { WM_GETTEXT
, sent
|defwinproc
|optional
},
4619 static const struct message WmInvalidateFull
[] = {
4620 { WM_NCPAINT
, sent
|wparam
, 1 },
4621 { WM_GETTEXT
, sent
|defwinproc
|optional
},
4625 static const struct message WmInvalidateErase
[] = {
4626 { WM_NCPAINT
, sent
|wparam
, 1 },
4627 { WM_GETTEXT
, sent
|defwinproc
|optional
},
4628 { WM_ERASEBKGND
, sent
},
4632 static const struct message WmInvalidatePaint
[] = {
4634 { WM_NCPAINT
, sent
|wparam
|beginpaint
, 1 },
4635 { WM_GETTEXT
, sent
|beginpaint
|defwinproc
|optional
},
4639 static const struct message WmInvalidateErasePaint
[] = {
4641 { WM_NCPAINT
, sent
|wparam
|beginpaint
, 1 },
4642 { WM_GETTEXT
, sent
|beginpaint
|defwinproc
|optional
},
4643 { WM_ERASEBKGND
, sent
|beginpaint
},
4647 static const struct message WmInvalidateErasePaint2
[] = {
4649 { WM_NCPAINT
, sent
|beginpaint
},
4650 { WM_GETTEXT
, sent
|beginpaint
|defwinproc
|optional
},
4651 { WM_ERASEBKGND
, sent
|beginpaint
},
4655 static const struct message WmErase
[] = {
4656 { WM_ERASEBKGND
, sent
},
4660 static const struct message WmPaint
[] = {
4665 static const struct message WmParentOnlyPaint
[] = {
4666 { WM_PAINT
, sent
|parent
},
4670 static const struct message WmInvalidateParent
[] = {
4671 { WM_NCPAINT
, sent
|parent
},
4672 { WM_GETTEXT
, sent
|defwinproc
|parent
|optional
},
4673 { WM_ERASEBKGND
, sent
|parent
},
4677 static const struct message WmInvalidateParentChild
[] = {
4678 { WM_NCPAINT
, sent
|parent
},
4679 { WM_GETTEXT
, sent
|defwinproc
|parent
|optional
},
4680 { WM_ERASEBKGND
, sent
|parent
},
4681 { WM_NCPAINT
, sent
},
4682 { WM_GETTEXT
, sent
|defwinproc
|optional
},
4683 { WM_ERASEBKGND
, sent
},
4687 static const struct message WmInvalidateParentChild2
[] = {
4688 { WM_ERASEBKGND
, sent
|parent
},
4689 { WM_NCPAINT
, sent
},
4690 { WM_GETTEXT
, sent
|defwinproc
|optional
},
4691 { WM_ERASEBKGND
, sent
},
4695 static const struct message WmParentPaint
[] = {
4696 { WM_PAINT
, sent
|parent
},
4701 static const struct message WmParentPaintNc
[] = {
4702 { WM_PAINT
, sent
|parent
},
4704 { WM_NCPAINT
, sent
|beginpaint
},
4705 { WM_GETTEXT
, sent
|beginpaint
|defwinproc
|optional
},
4706 { WM_ERASEBKGND
, sent
|beginpaint
},
4710 static const struct message WmChildPaintNc
[] = {
4712 { WM_NCPAINT
, sent
|beginpaint
},
4713 { WM_GETTEXT
, sent
|beginpaint
|defwinproc
|optional
},
4714 { WM_ERASEBKGND
, sent
|beginpaint
},
4718 static const struct message WmParentErasePaint
[] = {
4719 { WM_PAINT
, sent
|parent
},
4720 { WM_NCPAINT
, sent
|parent
|beginpaint
},
4721 { WM_GETTEXT
, sent
|parent
|beginpaint
|defwinproc
|optional
},
4722 { WM_ERASEBKGND
, sent
|parent
|beginpaint
},
4724 { WM_NCPAINT
, sent
|beginpaint
},
4725 { WM_GETTEXT
, sent
|beginpaint
|defwinproc
|optional
},
4726 { WM_ERASEBKGND
, sent
|beginpaint
},
4730 static const struct message WmParentOnlyNcPaint
[] = {
4731 { WM_PAINT
, sent
|parent
},
4732 { WM_NCPAINT
, sent
|parent
|beginpaint
},
4733 { WM_GETTEXT
, sent
|parent
|beginpaint
|defwinproc
|optional
},
4737 static const struct message WmSetParentStyle
[] = {
4738 { WM_STYLECHANGING
, sent
|parent
},
4739 { WM_STYLECHANGED
, sent
|parent
},
4743 static void test_paint_messages(void)
4749 HWND hparent
, hchild
;
4750 HRGN hrgn
= CreateRectRgn( 0, 0, 0, 0 );
4751 HRGN hrgn2
= CreateRectRgn( 0, 0, 0, 0 );
4752 HWND hwnd
= CreateWindowExA(0, "TestWindowClass", "Test overlapped", WS_OVERLAPPEDWINDOW
,
4753 100, 100, 200, 200, 0, 0, 0, NULL
);
4754 ok (hwnd
!= 0, "Failed to create overlapped window\n");
4756 ShowWindow( hwnd
, SW_SHOW
);
4757 UpdateWindow( hwnd
);
4761 check_update_rgn( hwnd
, 0 );
4762 SetRectRgn( hrgn
, 10, 10, 20, 20 );
4763 ret
= RedrawWindow( hwnd
, NULL
, hrgn
, RDW_INVALIDATE
);
4764 ok(ret
, "RedrawWindow returned %d instead of TRUE\n", ret
);
4765 check_update_rgn( hwnd
, hrgn
);
4766 SetRectRgn( hrgn2
, 20, 20, 30, 30 );
4767 ret
= RedrawWindow( hwnd
, NULL
, hrgn2
, RDW_INVALIDATE
);
4768 ok(ret
, "RedrawWindow returned %d instead of TRUE\n", ret
);
4769 CombineRgn( hrgn
, hrgn
, hrgn2
, RGN_OR
);
4770 check_update_rgn( hwnd
, hrgn
);
4771 /* validate everything */
4772 ret
= RedrawWindow( hwnd
, NULL
, NULL
, RDW_VALIDATE
);
4773 ok(ret
, "RedrawWindow returned %d instead of TRUE\n", ret
);
4774 check_update_rgn( hwnd
, 0 );
4776 /* test empty region */
4777 SetRectRgn( hrgn
, 10, 10, 10, 15 );
4778 ret
= RedrawWindow( hwnd
, NULL
, hrgn
, RDW_INVALIDATE
);
4779 ok(ret
, "RedrawWindow returned %d instead of TRUE\n", ret
);
4780 check_update_rgn( hwnd
, 0 );
4781 /* test empty rect */
4782 SetRect( &rect
, 10, 10, 10, 15 );
4783 ret
= RedrawWindow( hwnd
, &rect
, NULL
, RDW_INVALIDATE
);
4784 ok(ret
, "RedrawWindow returned %d instead of TRUE\n", ret
);
4785 check_update_rgn( hwnd
, 0 );
4787 /* flush pending messages */
4788 while (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
4791 GetClientRect( hwnd
, &rect
);
4792 SetRectRgn( hrgn
, 0, 0, rect
.right
- rect
.left
, rect
.bottom
- rect
.top
);
4793 /* MSDN: if hwnd parameter is NULL, InvalidateRect invalidates and redraws
4794 * all windows and sends WM_ERASEBKGND and WM_NCPAINT.
4796 trace("testing InvalidateRect(0, NULL, FALSE)\n");
4797 SetRectEmpty( &rect
);
4798 ok(InvalidateRect(0, &rect
, FALSE
), "InvalidateRect(0, &rc, FALSE) should fail\n");
4799 check_update_rgn( hwnd
, hrgn
);
4800 ok_sequence( WmInvalidateErase
, "InvalidateErase", FALSE
);
4801 while (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
4802 ok_sequence( WmPaint
, "Paint", FALSE
);
4803 RedrawWindow( hwnd
, NULL
, NULL
, RDW_VALIDATE
);
4804 check_update_rgn( hwnd
, 0 );
4806 /* MSDN: if hwnd parameter is NULL, ValidateRect invalidates and redraws
4807 * all windows and sends WM_ERASEBKGND and WM_NCPAINT.
4809 trace("testing ValidateRect(0, NULL)\n");
4810 SetRectEmpty( &rect
);
4811 ok(ValidateRect(0, &rect
), "ValidateRect(0, &rc) should not fail\n");
4812 check_update_rgn( hwnd
, hrgn
);
4813 ok_sequence( WmInvalidateErase
, "InvalidateErase", FALSE
);
4814 while (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
4815 ok_sequence( WmPaint
, "Paint", FALSE
);
4816 RedrawWindow( hwnd
, NULL
, NULL
, RDW_VALIDATE
);
4817 check_update_rgn( hwnd
, 0 );
4819 trace("testing InvalidateRgn(0, NULL, FALSE)\n");
4820 SetLastError(0xdeadbeef);
4821 ok(!InvalidateRgn(0, NULL
, FALSE
), "InvalidateRgn(0, NULL, FALSE) should fail\n");
4822 ok(GetLastError() == ERROR_INVALID_WINDOW_HANDLE
, "wrong error code %d\n", GetLastError());
4823 check_update_rgn( hwnd
, 0 );
4824 while (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
4825 ok_sequence( WmEmptySeq
, "WmEmptySeq", FALSE
);
4827 trace("testing ValidateRgn(0, NULL)\n");
4828 SetLastError(0xdeadbeef);
4829 ok(!ValidateRgn(0, NULL
), "ValidateRgn(0, NULL) should fail\n");
4830 ok(GetLastError() == ERROR_INVALID_WINDOW_HANDLE
, "wrong error code %d\n", GetLastError());
4831 check_update_rgn( hwnd
, 0 );
4832 while (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
4833 ok_sequence( WmEmptySeq
, "WmEmptySeq", FALSE
);
4835 /* now with frame */
4836 SetRectRgn( hrgn
, -5, -5, 20, 20 );
4838 /* flush pending messages */
4839 while (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
4842 RedrawWindow( hwnd
, NULL
, hrgn
, RDW_INVALIDATE
| RDW_FRAME
);
4843 ok_sequence( WmEmptySeq
, "EmptySeq", FALSE
);
4845 SetRectRgn( hrgn
, 0, 0, 20, 20 ); /* GetUpdateRgn clips to client area */
4846 check_update_rgn( hwnd
, hrgn
);
4849 RedrawWindow( hwnd
, NULL
, hrgn
, RDW_INVALIDATE
| RDW_FRAME
| RDW_ERASENOW
);
4850 ok_sequence( WmInvalidateRgn
, "InvalidateRgn", FALSE
);
4853 RedrawWindow( hwnd
, NULL
, NULL
, RDW_INVALIDATE
| RDW_FRAME
| RDW_ERASENOW
);
4854 ok_sequence( WmInvalidateFull
, "InvalidateFull", FALSE
);
4856 GetClientRect( hwnd
, &rect
);
4857 SetRectRgn( hrgn
, rect
.left
, rect
.top
, rect
.right
, rect
.bottom
);
4858 check_update_rgn( hwnd
, hrgn
);
4861 RedrawWindow( hwnd
, NULL
, NULL
, RDW_INVALIDATE
| RDW_FRAME
| RDW_ERASE
| RDW_ERASENOW
);
4862 ok_sequence( WmInvalidateErase
, "InvalidateErase", FALSE
);
4865 RedrawWindow( hwnd
, NULL
, NULL
, RDW_INVALIDATE
| RDW_FRAME
| RDW_ERASENOW
| RDW_UPDATENOW
);
4866 ok_sequence( WmInvalidatePaint
, "InvalidatePaint", FALSE
);
4867 check_update_rgn( hwnd
, 0 );
4870 RedrawWindow( hwnd
, NULL
, NULL
, RDW_INVALIDATE
| RDW_FRAME
| RDW_ERASE
| RDW_UPDATENOW
);
4871 ok_sequence( WmInvalidateErasePaint
, "InvalidateErasePaint", FALSE
);
4872 check_update_rgn( hwnd
, 0 );
4875 SetRectRgn( hrgn
, 0, 0, 100, 100 );
4876 RedrawWindow( hwnd
, NULL
, hrgn
, RDW_INVALIDATE
);
4877 SetRectRgn( hrgn
, 0, 0, 50, 100 );
4878 RedrawWindow( hwnd
, NULL
, hrgn
, RDW_VALIDATE
);
4879 SetRectRgn( hrgn
, 50, 0, 100, 100 );
4880 check_update_rgn( hwnd
, hrgn
);
4881 RedrawWindow( hwnd
, NULL
, hrgn
, RDW_VALIDATE
| RDW_ERASENOW
);
4882 ok_sequence( WmEmptySeq
, "EmptySeq", FALSE
); /* must not generate messages, everything is valid */
4883 check_update_rgn( hwnd
, 0 );
4886 SetRectRgn( hrgn
, 0, 0, 100, 100 );
4887 RedrawWindow( hwnd
, NULL
, hrgn
, RDW_INVALIDATE
| RDW_ERASE
);
4888 SetRectRgn( hrgn
, 0, 0, 100, 50 );
4889 RedrawWindow( hwnd
, NULL
, hrgn
, RDW_VALIDATE
| RDW_ERASENOW
);
4890 ok_sequence( WmErase
, "Erase", FALSE
);
4891 SetRectRgn( hrgn
, 0, 50, 100, 100 );
4892 check_update_rgn( hwnd
, hrgn
);
4895 SetRectRgn( hrgn
, 0, 0, 100, 100 );
4896 RedrawWindow( hwnd
, NULL
, hrgn
, RDW_INVALIDATE
| RDW_ERASE
);
4897 SetRectRgn( hrgn
, 0, 0, 50, 50 );
4898 RedrawWindow( hwnd
, NULL
, hrgn
, RDW_VALIDATE
| RDW_NOERASE
| RDW_UPDATENOW
);
4899 ok_sequence( WmPaint
, "Paint", FALSE
);
4902 SetRectRgn( hrgn
, -4, -4, -2, -2 );
4903 RedrawWindow( hwnd
, NULL
, hrgn
, RDW_INVALIDATE
| RDW_FRAME
);
4904 SetRectRgn( hrgn
, -200, -200, -198, -198 );
4905 RedrawWindow( hwnd
, NULL
, hrgn
, RDW_VALIDATE
| RDW_NOFRAME
| RDW_ERASENOW
);
4906 ok_sequence( WmEmptySeq
, "EmptySeq", FALSE
);
4909 SetRectRgn( hrgn
, -4, -4, -2, -2 );
4910 RedrawWindow( hwnd
, NULL
, hrgn
, RDW_INVALIDATE
| RDW_FRAME
);
4911 SetRectRgn( hrgn
, -4, -4, -3, -3 );
4912 RedrawWindow( hwnd
, NULL
, hrgn
, RDW_VALIDATE
| RDW_NOFRAME
);
4913 SetRectRgn( hrgn
, 0, 0, 1, 1 );
4914 RedrawWindow( hwnd
, NULL
, hrgn
, RDW_INVALIDATE
| RDW_UPDATENOW
);
4915 ok_sequence( WmPaint
, "Paint", FALSE
);
4918 SetRectRgn( hrgn
, -4, -4, -1, -1 );
4919 RedrawWindow( hwnd
, NULL
, hrgn
, RDW_INVALIDATE
| RDW_FRAME
);
4920 RedrawWindow( hwnd
, NULL
, 0, RDW_ERASENOW
);
4921 /* make sure no WM_PAINT was generated */
4922 while (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
4923 ok_sequence( WmInvalidateRgn
, "InvalidateRgn", FALSE
);
4926 SetRectRgn( hrgn
, -4, -4, -1, -1 );
4927 RedrawWindow( hwnd
, NULL
, hrgn
, RDW_INVALIDATE
| RDW_FRAME
);
4928 while (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
))
4930 if (msg
.hwnd
== hwnd
&& msg
.message
== WM_PAINT
)
4932 /* GetUpdateRgn must return empty region since only nonclient area is invalidated */
4933 INT ret
= GetUpdateRgn( hwnd
, hrgn
, FALSE
);
4934 ok( ret
== NULLREGION
, "Invalid GetUpdateRgn result %d\n", ret
);
4935 ret
= GetUpdateRect( hwnd
, &rect
, FALSE
);
4936 ok( ret
, "Invalid GetUpdateRect result %d\n", ret
);
4937 /* this will send WM_NCPAINT and validate the non client area */
4938 ret
= GetUpdateRect( hwnd
, &rect
, TRUE
);
4939 ok( !ret
, "Invalid GetUpdateRect result %d\n", ret
);
4941 DispatchMessage( &msg
);
4943 ok_sequence( WmGetUpdateRect
, "GetUpdateRect", FALSE
);
4945 DestroyWindow( hwnd
);
4947 /* now test with a child window */
4949 hparent
= CreateWindowExA(0, "TestParentClass", "Test parent", WS_OVERLAPPEDWINDOW
,
4950 100, 100, 200, 200, 0, 0, 0, NULL
);
4951 ok (hparent
!= 0, "Failed to create parent window\n");
4953 hchild
= CreateWindowExA(0, "TestWindowClass", "Test child", WS_CHILD
| WS_VISIBLE
| WS_BORDER
,
4954 10, 10, 100, 100, hparent
, 0, 0, NULL
);
4955 ok (hchild
!= 0, "Failed to create child window\n");
4957 ShowWindow( hparent
, SW_SHOW
);
4958 UpdateWindow( hparent
);
4959 UpdateWindow( hchild
);
4962 log_all_parent_messages
++;
4964 SetRect( &rect
, 0, 0, 50, 50 );
4965 RedrawWindow( hparent
, &rect
, 0, RDW_INVALIDATE
| RDW_ERASE
| RDW_FRAME
);
4966 RedrawWindow( hparent
, NULL
, 0, RDW_ERASENOW
| RDW_ALLCHILDREN
);
4967 ok_sequence( WmInvalidateParentChild
, "InvalidateParentChild", FALSE
);
4969 RedrawWindow( hparent
, &rect
, 0, RDW_INVALIDATE
| RDW_ERASE
| RDW_FRAME
);
4971 MapWindowPoints( hchild
, hparent
, &pt
, 1 );
4972 SetRectRgn( hrgn
, 0, 0, 50 - pt
.x
, 50 - pt
.y
);
4973 check_update_rgn( hchild
, hrgn
);
4974 SetRectRgn( hrgn
, 0, 0, 50, 50 );
4975 check_update_rgn( hparent
, hrgn
);
4976 RedrawWindow( hparent
, NULL
, 0, RDW_ERASENOW
);
4977 ok_sequence( WmInvalidateParent
, "InvalidateParent", FALSE
);
4978 RedrawWindow( hchild
, NULL
, 0, RDW_ERASENOW
);
4979 ok_sequence( WmEmptySeq
, "EraseNow child", FALSE
);
4981 while (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
4982 ok_sequence( WmParentPaintNc
, "WmParentPaintNc", FALSE
);
4984 RedrawWindow( hparent
, &rect
, 0, RDW_INVALIDATE
| RDW_ERASE
| RDW_FRAME
| RDW_ALLCHILDREN
);
4985 RedrawWindow( hparent
, NULL
, 0, RDW_ERASENOW
);
4986 ok_sequence( WmInvalidateParent
, "InvalidateParent2", FALSE
);
4987 RedrawWindow( hchild
, NULL
, 0, RDW_ERASENOW
);
4988 ok_sequence( WmEmptySeq
, "EraseNow child", FALSE
);
4990 RedrawWindow( hparent
, &rect
, 0, RDW_INVALIDATE
| RDW_ERASE
);
4991 RedrawWindow( hparent
, NULL
, 0, RDW_ERASENOW
| RDW_ALLCHILDREN
);
4992 ok_sequence( WmInvalidateParentChild2
, "InvalidateParentChild2", FALSE
);
4994 SetWindowLong( hparent
, GWL_STYLE
, GetWindowLong(hparent
,GWL_STYLE
) | WS_CLIPCHILDREN
);
4996 RedrawWindow( hparent
, &rect
, 0, RDW_INVALIDATE
| RDW_ERASE
| RDW_FRAME
| RDW_ALLCHILDREN
);
4997 RedrawWindow( hparent
, NULL
, 0, RDW_ERASENOW
);
4998 ok_sequence( WmInvalidateParentChild
, "InvalidateParentChild3", FALSE
);
5000 /* flush all paint messages */
5001 while (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
5004 /* RDW_UPDATENOW on child with WS_CLIPCHILDREN doesn't change corresponding parent area */
5005 RedrawWindow( hparent
, &rect
, 0, RDW_INVALIDATE
| RDW_ERASE
| RDW_FRAME
| RDW_ALLCHILDREN
);
5006 SetRectRgn( hrgn
, 0, 0, 50, 50 );
5007 check_update_rgn( hparent
, hrgn
);
5008 RedrawWindow( hchild
, NULL
, 0, RDW_UPDATENOW
);
5009 ok_sequence( WmInvalidateErasePaint2
, "WmInvalidateErasePaint2", FALSE
);
5010 SetRectRgn( hrgn
, 0, 0, 50, 50 );
5011 check_update_rgn( hparent
, hrgn
);
5013 /* flush all paint messages */
5014 while (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
5015 SetWindowLong( hparent
, GWL_STYLE
, GetWindowLong(hparent
,GWL_STYLE
) & ~WS_CLIPCHILDREN
);
5018 /* RDW_UPDATENOW on child without WS_CLIPCHILDREN will validate corresponding parent area */
5019 RedrawWindow( hparent
, &rect
, 0, RDW_INVALIDATE
| RDW_ERASE
| RDW_FRAME
);
5020 SetRectRgn( hrgn
, 0, 0, 50, 50 );
5021 check_update_rgn( hparent
, hrgn
);
5022 RedrawWindow( hchild
, NULL
, 0, RDW_UPDATENOW
);
5023 ok_sequence( WmInvalidateErasePaint2
, "WmInvalidateErasePaint2", FALSE
);
5024 SetRectRgn( hrgn2
, 10, 10, 50, 50 );
5025 CombineRgn( hrgn
, hrgn
, hrgn2
, RGN_DIFF
);
5026 check_update_rgn( hparent
, hrgn
);
5027 /* flush all paint messages */
5028 while (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
5031 /* same as above but parent gets completely validated */
5032 SetRect( &rect
, 20, 20, 30, 30 );
5033 RedrawWindow( hparent
, &rect
, 0, RDW_INVALIDATE
| RDW_ERASE
| RDW_FRAME
);
5034 SetRectRgn( hrgn
, 20, 20, 30, 30 );
5035 check_update_rgn( hparent
, hrgn
);
5036 RedrawWindow( hchild
, NULL
, 0, RDW_UPDATENOW
);
5037 ok_sequence( WmInvalidateErasePaint2
, "WmInvalidateErasePaint2", FALSE
);
5038 check_update_rgn( hparent
, 0 ); /* no update region */
5039 while (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
5040 ok_sequence( WmEmptySeq
, "WmEmpty", FALSE
); /* and no paint messages */
5042 /* make sure RDW_VALIDATE on child doesn't have the same effect */
5044 RedrawWindow( hparent
, &rect
, 0, RDW_INVALIDATE
| RDW_ERASE
| RDW_FRAME
);
5045 SetRectRgn( hrgn
, 20, 20, 30, 30 );
5046 check_update_rgn( hparent
, hrgn
);
5047 RedrawWindow( hchild
, NULL
, 0, RDW_VALIDATE
| RDW_NOERASE
);
5048 SetRectRgn( hrgn
, 20, 20, 30, 30 );
5049 check_update_rgn( hparent
, hrgn
);
5051 /* same as above but normal WM_PAINT doesn't validate parent */
5053 SetRect( &rect
, 20, 20, 30, 30 );
5054 RedrawWindow( hparent
, &rect
, 0, RDW_INVALIDATE
| RDW_ERASE
| RDW_FRAME
);
5055 SetRectRgn( hrgn
, 20, 20, 30, 30 );
5056 check_update_rgn( hparent
, hrgn
);
5057 /* no WM_PAINT in child while parent still pending */
5058 while (PeekMessage( &msg
, hchild
, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
5059 ok_sequence( WmEmptySeq
, "No WM_PAINT", FALSE
);
5060 while (PeekMessage( &msg
, hparent
, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
5061 ok_sequence( WmParentErasePaint
, "WmParentErasePaint", FALSE
);
5064 RedrawWindow( hparent
, &rect
, 0, RDW_INVALIDATE
| RDW_ERASE
| RDW_FRAME
);
5065 /* no WM_PAINT in child while parent still pending */
5066 while (PeekMessage( &msg
, hchild
, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
5067 ok_sequence( WmEmptySeq
, "No WM_PAINT", FALSE
);
5068 RedrawWindow( hparent
, &rect
, 0, RDW_VALIDATE
| RDW_NOERASE
| RDW_NOCHILDREN
);
5069 /* now that parent is valid child should get WM_PAINT */
5070 while (PeekMessage( &msg
, hchild
, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
5071 ok_sequence( WmInvalidateErasePaint2
, "WmInvalidateErasePaint2", FALSE
);
5072 while (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
5073 ok_sequence( WmEmptySeq
, "No other message", FALSE
);
5075 /* same thing with WS_CLIPCHILDREN in parent */
5077 SetWindowLong( hparent
, GWL_STYLE
, GetWindowLong(hparent
,GWL_STYLE
) | WS_CLIPCHILDREN
);
5078 ok_sequence( WmSetParentStyle
, "WmSetParentStyle", FALSE
);
5079 /* changing style invalidates non client area, but we need to invalidate something else to see it */
5080 RedrawWindow( hparent
, &rect
, 0, RDW_UPDATENOW
);
5081 ok_sequence( WmEmptySeq
, "No message", FALSE
);
5082 RedrawWindow( hparent
, &rect
, 0, RDW_INVALIDATE
| RDW_UPDATENOW
);
5083 ok_sequence( WmParentOnlyNcPaint
, "WmParentOnlyNcPaint", FALSE
);
5086 RedrawWindow( hparent
, &rect
, 0, RDW_INVALIDATE
| RDW_ERASE
| RDW_ALLCHILDREN
);
5087 SetRectRgn( hrgn
, 20, 20, 30, 30 );
5088 check_update_rgn( hparent
, hrgn
);
5089 /* no WM_PAINT in child while parent still pending */
5090 while (PeekMessage( &msg
, hchild
, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
5091 ok_sequence( WmEmptySeq
, "No WM_PAINT", FALSE
);
5092 /* WM_PAINT in parent first */
5093 while (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
5094 ok_sequence( WmParentPaintNc
, "WmParentPaintNc2", FALSE
);
5096 /* no RDW_ERASE in parent still causes RDW_ERASE and RDW_FRAME in child */
5098 SetRect( &rect
, 0, 0, 30, 30 );
5099 RedrawWindow( hparent
, &rect
, 0, RDW_INVALIDATE
| RDW_ALLCHILDREN
);
5100 SetRectRgn( hrgn
, 0, 0, 30, 30 );
5101 check_update_rgn( hparent
, hrgn
);
5102 while (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
5103 ok_sequence( WmParentPaintNc
, "WmParentPaintNc3", FALSE
);
5105 /* validate doesn't cause RDW_NOERASE or RDW_NOFRAME in child */
5107 SetRect( &rect
, -10, 0, 30, 30 );
5108 RedrawWindow( hchild
, &rect
, 0, RDW_INVALIDATE
| RDW_FRAME
| RDW_ERASE
);
5109 SetRect( &rect
, 0, 0, 20, 20 );
5110 RedrawWindow( hparent
, &rect
, 0, RDW_VALIDATE
| RDW_ALLCHILDREN
);
5111 RedrawWindow( hparent
, NULL
, 0, RDW_UPDATENOW
);
5112 ok_sequence( WmChildPaintNc
, "WmChildPaintNc", FALSE
);
5114 /* validate doesn't cause RDW_NOERASE or RDW_NOFRAME in child */
5116 SetRect( &rect
, -10, 0, 30, 30 );
5117 RedrawWindow( hchild
, &rect
, 0, RDW_INVALIDATE
| RDW_FRAME
| RDW_ERASE
);
5118 SetRect( &rect
, 0, 0, 100, 100 );
5119 RedrawWindow( hparent
, &rect
, 0, RDW_VALIDATE
| RDW_ALLCHILDREN
);
5120 RedrawWindow( hparent
, NULL
, 0, RDW_UPDATENOW
);
5121 ok_sequence( WmEmptySeq
, "WmChildPaintNc2", FALSE
);
5122 RedrawWindow( hparent
, NULL
, 0, RDW_ERASENOW
);
5123 ok_sequence( WmEmptySeq
, "WmChildPaintNc3", FALSE
);
5125 /* test RDW_INTERNALPAINT behavior */
5128 RedrawWindow( hparent
, NULL
, 0, RDW_INTERNALPAINT
| RDW_NOCHILDREN
);
5129 while (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
5130 ok_sequence( WmParentOnlyPaint
, "WmParentOnlyPaint", FALSE
);
5132 RedrawWindow( hparent
, NULL
, 0, RDW_INTERNALPAINT
| RDW_ALLCHILDREN
);
5133 while (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
5134 ok_sequence( WmParentPaint
, "WmParentPaint", FALSE
);
5136 RedrawWindow( hparent
, NULL
, 0, RDW_INTERNALPAINT
);
5137 while (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
5138 ok_sequence( WmParentOnlyPaint
, "WmParentOnlyPaint", FALSE
);
5140 assert( GetWindowLong(hparent
, GWL_STYLE
) & WS_CLIPCHILDREN
);
5141 UpdateWindow( hparent
);
5142 while (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
5144 trace("testing SWP_FRAMECHANGED on parent with WS_CLIPCHILDREN\n");
5145 RedrawWindow( hchild
, NULL
, 0, RDW_INVALIDATE
| RDW_ERASE
| RDW_FRAME
);
5146 SetWindowPos( hparent
, 0, 0, 0, 0, 0, SWP_NOSIZE
| SWP_NOMOVE
|
5147 SWP_NOACTIVATE
| SWP_NOZORDER
| SWP_FRAMECHANGED
);
5148 while (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
5149 ok_sequence(WmSWP_FrameChanged_clip
, "SetWindowPos:FrameChanged_clip", FALSE
);
5151 UpdateWindow( hparent
);
5152 while (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
5154 trace("testing SWP_FRAMECHANGED|SWP_DEFERERASE on parent with WS_CLIPCHILDREN\n");
5155 RedrawWindow( hchild
, NULL
, 0, RDW_INVALIDATE
| RDW_ERASE
| RDW_FRAME
);
5156 SetWindowPos( hparent
, 0, 0, 0, 0, 0, SWP_NOSIZE
| SWP_NOMOVE
| SWP_DEFERERASE
|
5157 SWP_NOACTIVATE
| SWP_NOZORDER
| SWP_FRAMECHANGED
);
5158 while (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
5159 ok_sequence(WmSWP_FrameChangedDeferErase
, "SetWindowPos:FrameChangedDeferErase", FALSE
);
5161 SetWindowLong( hparent
, GWL_STYLE
, GetWindowLong(hparent
,GWL_STYLE
) & ~WS_CLIPCHILDREN
);
5162 ok_sequence( WmSetParentStyle
, "WmSetParentStyle", FALSE
);
5163 RedrawWindow( hparent
, NULL
, 0, RDW_INTERNALPAINT
);
5164 while (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
5165 ok_sequence( WmParentPaint
, "WmParentPaint", FALSE
);
5167 assert( !(GetWindowLong(hparent
, GWL_STYLE
) & WS_CLIPCHILDREN
) );
5168 UpdateWindow( hparent
);
5169 while (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
5171 trace("testing SWP_FRAMECHANGED on parent without WS_CLIPCHILDREN\n");
5172 RedrawWindow( hchild
, NULL
, 0, RDW_INVALIDATE
| RDW_ERASE
| RDW_FRAME
);
5173 SetWindowPos( hparent
, 0, 0, 0, 0, 0, SWP_NOSIZE
| SWP_NOMOVE
|
5174 SWP_NOACTIVATE
| SWP_NOZORDER
| SWP_FRAMECHANGED
);
5175 while (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
5176 ok_sequence(WmSWP_FrameChanged_noclip
, "SetWindowPos:FrameChanged_noclip", FALSE
);
5178 UpdateWindow( hparent
);
5179 while (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
5181 trace("testing SWP_FRAMECHANGED|SWP_DEFERERASE on parent without WS_CLIPCHILDREN\n");
5182 RedrawWindow( hchild
, NULL
, 0, RDW_INVALIDATE
| RDW_ERASE
| RDW_FRAME
);
5183 SetWindowPos( hparent
, 0, 0, 0, 0, 0, SWP_NOSIZE
| SWP_NOMOVE
| SWP_DEFERERASE
|
5184 SWP_NOACTIVATE
| SWP_NOZORDER
| SWP_FRAMECHANGED
);
5185 while (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
5186 ok_sequence(WmSWP_FrameChangedDeferErase
, "SetWindowPos:FrameChangedDeferErase", FALSE
);
5188 log_all_parent_messages
--;
5189 DestroyWindow( hparent
);
5190 ok(!IsWindow(hchild
), "child must be destroyed with its parent\n");
5192 DeleteObject( hrgn
);
5193 DeleteObject( hrgn2
);
5202 static DWORD WINAPI
thread_proc(void *param
)
5205 struct wnd_event
*wnd_event
= (struct wnd_event
*)param
;
5207 wnd_event
->hwnd
= CreateWindowExA(0, "TestWindowClass", "window caption text", WS_OVERLAPPEDWINDOW
,
5208 100, 100, 200, 200, 0, 0, 0, NULL
);
5209 ok(wnd_event
->hwnd
!= 0, "Failed to create overlapped window\n");
5211 SetEvent(wnd_event
->event
);
5213 while (GetMessage(&msg
, 0, 0, 0))
5215 TranslateMessage(&msg
);
5216 DispatchMessage(&msg
);
5219 ok(IsWindow(wnd_event
->hwnd
), "window should still exist\n");
5224 static void test_interthread_messages(void)
5231 int len
, expected_len
;
5232 struct wnd_event wnd_event
;
5235 wnd_event
.event
= CreateEventW(NULL
, 0, 0, NULL
);
5236 if (!wnd_event
.event
)
5238 trace("skipping interthread message test under win9x\n");
5242 hThread
= CreateThread(NULL
, 0, thread_proc
, &wnd_event
, 0, &tid
);
5243 ok(hThread
!= NULL
, "CreateThread failed, error %d\n", GetLastError());
5245 ok(WaitForSingleObject(wnd_event
.event
, INFINITE
) == WAIT_OBJECT_0
, "WaitForSingleObject failed\n");
5247 CloseHandle(wnd_event
.event
);
5249 SetLastError(0xdeadbeef);
5250 ok(!DestroyWindow(wnd_event
.hwnd
), "DestroyWindow succeded\n");
5251 ok(GetLastError() == ERROR_ACCESS_DENIED
, "wrong error code %d\n", GetLastError());
5253 proc
= (WNDPROC
)GetWindowLongPtrA(wnd_event
.hwnd
, GWLP_WNDPROC
);
5254 ok(proc
!= NULL
, "GetWindowLongPtrA(GWLP_WNDPROC) error %d\n", GetLastError());
5256 expected_len
= lstrlenA("window caption text");
5257 memset(buf
, 0, sizeof(buf
));
5258 SetLastError(0xdeadbeef);
5259 len
= CallWindowProcA(proc
, wnd_event
.hwnd
, WM_GETTEXT
, sizeof(buf
), (LPARAM
)buf
);
5260 ok(len
== expected_len
, "CallWindowProcA(WM_GETTEXT) error %d, len %d, expected len %d\n", GetLastError(), len
, expected_len
);
5261 ok(!lstrcmpA(buf
, "window caption text"), "window text mismatch\n");
5263 msg
.hwnd
= wnd_event
.hwnd
;
5264 msg
.message
= WM_GETTEXT
;
5265 msg
.wParam
= sizeof(buf
);
5266 msg
.lParam
= (LPARAM
)buf
;
5267 memset(buf
, 0, sizeof(buf
));
5268 SetLastError(0xdeadbeef);
5269 len
= DispatchMessageA(&msg
);
5270 ok(!len
&& GetLastError() == ERROR_MESSAGE_SYNC_ONLY
,
5271 "DispatchMessageA(WM_GETTEXT) succeded on another thread window: ret %d, error %d\n", len
, GetLastError());
5273 /* the following test causes an exception in user.exe under win9x */
5274 msg
.hwnd
= wnd_event
.hwnd
;
5275 msg
.message
= WM_TIMER
;
5277 msg
.lParam
= GetWindowLongPtrA(wnd_event
.hwnd
, GWLP_WNDPROC
);
5278 SetLastError(0xdeadbeef);
5279 len
= DispatchMessageA(&msg
);
5280 ok(!len
&& GetLastError() == 0xdeadbeef,
5281 "DispatchMessageA(WM_TIMER) failed on another thread window: ret %d, error %d\n", len
, GetLastError());
5283 ret
= PostMessageA(wnd_event
.hwnd
, WM_QUIT
, 0, 0);
5284 ok( ret
, "PostMessageA(WM_QUIT) error %d\n", GetLastError());
5286 ok(WaitForSingleObject(hThread
, INFINITE
) == WAIT_OBJECT_0
, "WaitForSingleObject failed\n");
5287 CloseHandle(hThread
);
5289 ok(!IsWindow(wnd_event
.hwnd
), "window should be destroyed on thread exit\n");
5293 static const struct message WmVkN
[] = {
5294 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, 'N', 1 }, /* XP */
5295 { WM_KEYDOWN
, wparam
|lparam
, 'N', 1 },
5296 { WM_KEYDOWN
, sent
|wparam
|lparam
, 'N', 1 },
5297 { WM_CHAR
, wparam
|lparam
, 'n', 1 },
5298 { WM_COMMAND
, sent
|wparam
|lparam
, MAKEWPARAM(1002,1), 0 },
5299 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, 'N', 0xc0000001 }, /* XP */
5300 { WM_KEYUP
, wparam
|lparam
, 'N', 0xc0000001 },
5301 { WM_KEYUP
, sent
|wparam
|lparam
, 'N', 0xc0000001 },
5304 static const struct message WmShiftVkN
[] = {
5305 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_SHIFT
, 1 }, /* XP */
5306 { WM_KEYDOWN
, wparam
|lparam
, VK_SHIFT
, 1 },
5307 { WM_KEYDOWN
, sent
|wparam
|lparam
, VK_SHIFT
, 1 },
5308 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, 'N', 1 }, /* XP */
5309 { WM_KEYDOWN
, wparam
|lparam
, 'N', 1 },
5310 { WM_KEYDOWN
, sent
|wparam
|lparam
, 'N', 1 },
5311 { WM_CHAR
, wparam
|lparam
, 'N', 1 },
5312 { WM_COMMAND
, sent
|wparam
|lparam
, MAKEWPARAM(1001,1), 0 },
5313 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, 'N', 0xc0000001 }, /* XP */
5314 { WM_KEYUP
, wparam
|lparam
, 'N', 0xc0000001 },
5315 { WM_KEYUP
, sent
|wparam
|lparam
, 'N', 0xc0000001 },
5316 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_SHIFT
, 0xc0000001 }, /* XP */
5317 { WM_KEYUP
, wparam
|lparam
, VK_SHIFT
, 0xc0000001 },
5318 { WM_KEYUP
, sent
|wparam
|lparam
, VK_SHIFT
, 0xc0000001 },
5321 static const struct message WmCtrlVkN
[] = {
5322 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_CONTROL
, 1 }, /* XP */
5323 { WM_KEYDOWN
, wparam
|lparam
, VK_CONTROL
, 1 },
5324 { WM_KEYDOWN
, sent
|wparam
|lparam
, VK_CONTROL
, 1 },
5325 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, 'N', 1 }, /* XP */
5326 { WM_KEYDOWN
, wparam
|lparam
, 'N', 1 },
5327 { WM_KEYDOWN
, sent
|wparam
|lparam
, 'N', 1 },
5328 { WM_CHAR
, wparam
|lparam
, 0x000e, 1 },
5329 { WM_COMMAND
, sent
|wparam
|lparam
, MAKEWPARAM(1000,1), 0 },
5330 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, 'N', 0xc0000001 }, /* XP */
5331 { WM_KEYUP
, wparam
|lparam
, 'N', 0xc0000001 },
5332 { WM_KEYUP
, sent
|wparam
|lparam
, 'N', 0xc0000001 },
5333 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_CONTROL
, 0xc0000001 }, /* XP */
5334 { WM_KEYUP
, wparam
|lparam
, VK_CONTROL
, 0xc0000001 },
5335 { WM_KEYUP
, sent
|wparam
|lparam
, VK_CONTROL
, 0xc0000001 },
5338 static const struct message WmCtrlVkN_2
[] = {
5339 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_CONTROL
, 1 }, /* XP */
5340 { WM_KEYDOWN
, wparam
|lparam
, VK_CONTROL
, 1 },
5341 { WM_KEYDOWN
, sent
|wparam
|lparam
, VK_CONTROL
, 1 },
5342 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, 'N', 1 }, /* XP */
5343 { WM_KEYDOWN
, wparam
|lparam
, 'N', 1 },
5344 { WM_COMMAND
, sent
|wparam
|lparam
, MAKEWPARAM(1000,1), 0 },
5345 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, 'N', 0xc0000001 }, /* XP */
5346 { WM_KEYUP
, wparam
|lparam
, 'N', 0xc0000001 },
5347 { WM_KEYUP
, sent
|wparam
|lparam
, 'N', 0xc0000001 },
5348 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_CONTROL
, 0xc0000001 }, /* XP */
5349 { WM_KEYUP
, wparam
|lparam
, VK_CONTROL
, 0xc0000001 },
5350 { WM_KEYUP
, sent
|wparam
|lparam
, VK_CONTROL
, 0xc0000001 },
5353 static const struct message WmAltVkN
[] = {
5354 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_MENU
, 0x20000001 }, /* XP */
5355 { WM_SYSKEYDOWN
, wparam
|lparam
, VK_MENU
, 0x20000001 },
5356 { WM_SYSKEYDOWN
, sent
|wparam
|lparam
, VK_MENU
, 0x20000001 },
5357 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, 'N', 0x20000001 }, /* XP */
5358 { WM_SYSKEYDOWN
, wparam
|lparam
, 'N', 0x20000001 },
5359 { WM_SYSKEYDOWN
, sent
|wparam
|lparam
, 'N', 0x20000001 },
5360 { WM_SYSCHAR
, wparam
|lparam
, 'n', 0x20000001 },
5361 { WM_SYSCHAR
, sent
|wparam
|lparam
, 'n', 0x20000001 },
5362 { WM_SYSCOMMAND
, sent
|defwinproc
|wparam
|lparam
, SC_KEYMENU
, 'n' },
5363 { HCBT_SYSCOMMAND
, hook
},
5364 { WM_ENTERMENULOOP
, sent
|defwinproc
|wparam
|lparam
, 0, 0 },
5365 { EVENT_SYSTEM_CAPTURESTART
, winevent_hook
|wparam
|lparam
, 0, 0 },
5366 { 0x00AE, sent
|defwinproc
|optional
}, /* XP */
5367 { WM_GETTEXT
, sent
|defwinproc
|optional
}, /* XP */
5368 { WM_INITMENU
, sent
|defwinproc
},
5369 { EVENT_SYSTEM_MENUSTART
, winevent_hook
|wparam
|lparam
, OBJID_SYSMENU
, 0 },
5370 { WM_MENUCHAR
, sent
|defwinproc
|wparam
, MAKEWPARAM('n',MF_SYSMENU
) },
5371 { EVENT_SYSTEM_CAPTUREEND
, winevent_hook
|wparam
|lparam
, 0, 0 },
5372 { WM_CAPTURECHANGED
, sent
|defwinproc
},
5373 { WM_MENUSELECT
, sent
|defwinproc
|wparam
, MAKEWPARAM(0,0xffff) },
5374 { EVENT_SYSTEM_MENUEND
, winevent_hook
|wparam
|lparam
, OBJID_SYSMENU
, 0 },
5375 { WM_EXITMENULOOP
, sent
|defwinproc
},
5376 { WM_MENUSELECT
, sent
|defwinproc
|wparam
|optional
, MAKEWPARAM(0,0xffff) }, /* Win95 bug */
5377 { WM_EXITMENULOOP
, sent
|defwinproc
|optional
}, /* Win95 bug */
5378 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, 'N', 0xe0000001 }, /* XP */
5379 { WM_SYSKEYUP
, wparam
|lparam
, 'N', 0xe0000001 },
5380 { WM_SYSKEYUP
, sent
|wparam
|lparam
, 'N', 0xe0000001 },
5381 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_MENU
, 0xc0000001 }, /* XP */
5382 { WM_KEYUP
, wparam
|lparam
, VK_MENU
, 0xc0000001 },
5383 { WM_KEYUP
, sent
|wparam
|lparam
, VK_MENU
, 0xc0000001 },
5386 static const struct message WmAltVkN_2
[] = {
5387 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_MENU
, 0x20000001 }, /* XP */
5388 { WM_SYSKEYDOWN
, wparam
|lparam
, VK_MENU
, 0x20000001 },
5389 { WM_SYSKEYDOWN
, sent
|wparam
|lparam
, VK_MENU
, 0x20000001 },
5390 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, 'N', 0x20000001 }, /* XP */
5391 { WM_SYSKEYDOWN
, wparam
|lparam
, 'N', 0x20000001 },
5392 { WM_COMMAND
, sent
|wparam
|lparam
, MAKEWPARAM(1003,1), 0 },
5393 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, 'N', 0xe0000001 }, /* XP */
5394 { WM_SYSKEYUP
, wparam
|lparam
, 'N', 0xe0000001 },
5395 { WM_SYSKEYUP
, sent
|wparam
|lparam
, 'N', 0xe0000001 },
5396 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_MENU
, 0xc0000001 }, /* XP */
5397 { WM_KEYUP
, wparam
|lparam
, VK_MENU
, 0xc0000001 },
5398 { WM_KEYUP
, sent
|wparam
|lparam
, VK_MENU
, 0xc0000001 },
5401 static const struct message WmCtrlAltVkN
[] = {
5402 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_CONTROL
, 1 }, /* XP */
5403 { WM_KEYDOWN
, wparam
|lparam
, VK_CONTROL
, 1 },
5404 { WM_KEYDOWN
, sent
|wparam
|lparam
, VK_CONTROL
, 1 },
5405 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_MENU
, 0x20000001 }, /* XP */
5406 { WM_KEYDOWN
, wparam
|lparam
, VK_MENU
, 0x20000001 },
5407 { WM_KEYDOWN
, sent
|wparam
|lparam
, VK_MENU
, 0x20000001 },
5408 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, 'N', 0x20000001 }, /* XP */
5409 { WM_KEYDOWN
, wparam
|lparam
, 'N', 0x20000001 },
5410 { WM_KEYDOWN
, sent
|wparam
|lparam
, 'N', 0x20000001 },
5411 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, 'N', 0xe0000001 }, /* XP */
5412 { WM_KEYUP
, wparam
|lparam
, 'N', 0xe0000001 },
5413 { WM_KEYUP
, sent
|wparam
|lparam
, 'N', 0xe0000001 },
5414 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_MENU
, 0xc0000001 }, /* XP */
5415 { WM_KEYUP
, wparam
|lparam
, VK_MENU
, 0xc0000001 },
5416 { WM_KEYUP
, sent
|wparam
|lparam
, VK_MENU
, 0xc0000001 },
5417 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_CONTROL
, 0xc0000001 }, /* XP */
5418 { WM_KEYUP
, wparam
|lparam
, VK_CONTROL
, 0xc0000001 },
5419 { WM_KEYUP
, sent
|wparam
|lparam
, VK_CONTROL
, 0xc0000001 },
5422 static const struct message WmCtrlShiftVkN
[] = {
5423 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_CONTROL
, 1 }, /* XP */
5424 { WM_KEYDOWN
, wparam
|lparam
, VK_CONTROL
, 1 },
5425 { WM_KEYDOWN
, sent
|wparam
|lparam
, VK_CONTROL
, 1 },
5426 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_SHIFT
, 1 }, /* XP */
5427 { WM_KEYDOWN
, wparam
|lparam
, VK_SHIFT
, 1 },
5428 { WM_KEYDOWN
, sent
|wparam
|lparam
, VK_SHIFT
, 1 },
5429 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, 'N', 1 }, /* XP */
5430 { WM_KEYDOWN
, wparam
|lparam
, 'N', 1 },
5431 { WM_COMMAND
, sent
|wparam
|lparam
, MAKEWPARAM(1004,1), 0 },
5432 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, 'N', 0xc0000001 }, /* XP */
5433 { WM_KEYUP
, wparam
|lparam
, 'N', 0xc0000001 },
5434 { WM_KEYUP
, sent
|wparam
|lparam
, 'N', 0xc0000001 },
5435 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_SHIFT
, 0xc0000001 }, /* XP */
5436 { WM_KEYUP
, wparam
|lparam
, VK_SHIFT
, 0xc0000001 },
5437 { WM_KEYUP
, sent
|wparam
|lparam
, VK_SHIFT
, 0xc0000001 },
5438 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_CONTROL
, 0xc0000001 }, /* XP */
5439 { WM_KEYUP
, wparam
|lparam
, VK_CONTROL
, 0xc0000001 },
5440 { WM_KEYUP
, sent
|wparam
|lparam
, VK_CONTROL
, 0xc0000001 },
5443 static const struct message WmCtrlAltShiftVkN
[] = {
5444 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_CONTROL
, 1 }, /* XP */
5445 { WM_KEYDOWN
, wparam
|lparam
, VK_CONTROL
, 1 },
5446 { WM_KEYDOWN
, sent
|wparam
|lparam
, VK_CONTROL
, 1 },
5447 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_MENU
, 0x20000001 }, /* XP */
5448 { WM_KEYDOWN
, wparam
|lparam
, VK_MENU
, 0x20000001 },
5449 { WM_KEYDOWN
, sent
|wparam
|lparam
, VK_MENU
, 0x20000001 },
5450 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_SHIFT
, 0x20000001 }, /* XP */
5451 { WM_KEYDOWN
, wparam
|lparam
, VK_SHIFT
, 0x20000001 },
5452 { WM_KEYDOWN
, sent
|wparam
|lparam
, VK_SHIFT
, 0x20000001 },
5453 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, 'N', 0x20000001 }, /* XP */
5454 { WM_KEYDOWN
, wparam
|lparam
, 'N', 0x20000001 },
5455 { WM_COMMAND
, sent
|wparam
|lparam
, MAKEWPARAM(1005,1), 0 },
5456 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, 'N', 0xe0000001 }, /* XP */
5457 { WM_KEYUP
, wparam
|lparam
, 'N', 0xe0000001 },
5458 { WM_KEYUP
, sent
|wparam
|lparam
, 'N', 0xe0000001 },
5459 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_SHIFT
, 0xe0000001 }, /* XP */
5460 { WM_KEYUP
, wparam
|lparam
, VK_SHIFT
, 0xe0000001 },
5461 { WM_KEYUP
, sent
|wparam
|lparam
, VK_SHIFT
, 0xe0000001 },
5462 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_MENU
, 0xc0000001 }, /* XP */
5463 { WM_KEYUP
, wparam
|lparam
, VK_MENU
, 0xc0000001 },
5464 { WM_KEYUP
, sent
|wparam
|lparam
, VK_MENU
, 0xc0000001 },
5465 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_CONTROL
, 0xc0000001 }, /* XP */
5466 { WM_KEYUP
, wparam
|lparam
, VK_CONTROL
, 0xc0000001 },
5467 { WM_KEYUP
, sent
|wparam
|lparam
, VK_CONTROL
, 0xc0000001 },
5470 static const struct message WmAltPressRelease
[] = {
5471 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_MENU
, 0x20000001 }, /* XP */
5472 { WM_SYSKEYDOWN
, wparam
|lparam
, VK_MENU
, 0x20000001 },
5473 { WM_SYSKEYDOWN
, sent
|wparam
|lparam
, VK_MENU
, 0x20000001 },
5474 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_MENU
, 0xc0000001 }, /* XP */
5475 { WM_SYSKEYUP
, wparam
|lparam
, VK_MENU
, 0xc0000001 },
5476 { WM_SYSKEYUP
, sent
|wparam
|lparam
, VK_MENU
, 0xc0000001 },
5477 { WM_SYSCOMMAND
, sent
|defwinproc
|wparam
|lparam
, SC_KEYMENU
, 0 },
5478 { HCBT_SYSCOMMAND
, hook
},
5479 { WM_ENTERMENULOOP
, sent
|defwinproc
|wparam
|lparam
, 0, 0 },
5480 { EVENT_SYSTEM_CAPTURESTART
, winevent_hook
|wparam
|lparam
, 0, 0 },
5481 { WM_INITMENU
, sent
|defwinproc
},
5482 { EVENT_SYSTEM_MENUSTART
, winevent_hook
|wparam
|lparam
, OBJID_SYSMENU
, 0 },
5483 { WM_MENUSELECT
, sent
|defwinproc
|wparam
, MAKEWPARAM(0,MF_SYSMENU
|MF_POPUP
|MF_HILITE
) },
5484 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_SYSMENU
, 1 },
5486 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_MENU
, 0x30000001 }, /* XP */
5488 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_SYSMENU
, 0 },
5489 { EVENT_SYSTEM_CAPTUREEND
, winevent_hook
|wparam
|lparam
, 0, 0, },
5490 { WM_CAPTURECHANGED
, sent
|defwinproc
},
5491 { WM_MENUSELECT
, sent
|defwinproc
|wparam
|optional
, MAKEWPARAM(0,0xffff) },
5492 { EVENT_SYSTEM_MENUEND
, winevent_hook
|wparam
|lparam
, OBJID_SYSMENU
, 0 },
5493 { WM_EXITMENULOOP
, sent
|defwinproc
},
5494 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_MENU
, 0xc0000001 }, /* XP */
5495 { WM_SYSKEYUP
, wparam
|lparam
, VK_MENU
, 0xc0000001 },
5496 { WM_SYSKEYUP
, sent
|wparam
|lparam
, VK_MENU
, 0xc0000001 },
5499 static const struct message WmAltMouseButton
[] = {
5500 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_MENU
, 0x20000001 }, /* XP */
5501 { WM_SYSKEYDOWN
, wparam
|lparam
, VK_MENU
, 0x20000001 },
5502 { WM_SYSKEYDOWN
, sent
|wparam
|lparam
, VK_MENU
, 0x20000001 },
5503 { WM_MOUSEMOVE
, wparam
|optional
, 0, 0 },
5504 { WM_MOUSEMOVE
, sent
|wparam
|optional
, 0, 0 },
5505 { WM_LBUTTONDOWN
, wparam
, MK_LBUTTON
, 0 },
5506 { WM_LBUTTONDOWN
, sent
|wparam
, MK_LBUTTON
, 0 },
5507 { WM_LBUTTONUP
, wparam
, 0, 0 },
5508 { WM_LBUTTONUP
, sent
|wparam
, 0, 0 },
5509 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_MENU
, 0xc0000001 }, /* XP */
5510 { WM_SYSKEYUP
, wparam
|lparam
, VK_MENU
, 0xc0000001 },
5511 { WM_SYSKEYUP
, sent
|wparam
|lparam
, VK_MENU
, 0xc0000001 },
5514 static const struct message WmF1Seq
[] = {
5515 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_F1
, 1 }, /* XP */
5516 { WM_KEYDOWN
, wparam
|lparam
, VK_F1
, 1 },
5517 { WM_KEYDOWN
, sent
|wparam
|lparam
, VK_F1
, 0x00000001 },
5518 { 0x4d, wparam
|lparam
, 0, 0 },
5519 { 0x4d, sent
|wparam
|lparam
, 0, 0 },
5520 { WM_HELP
, sent
|defwinproc
},
5521 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_F1
, 0xc0000001 }, /* XP */
5522 { WM_KEYUP
, wparam
|lparam
, VK_F1
, 0xc0000001 },
5523 { WM_KEYUP
, sent
|wparam
|lparam
, VK_F1
, 0xc0000001 },
5526 static const struct message WmVkAppsSeq
[] = {
5527 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_APPS
, 1 }, /* XP */
5528 { WM_KEYDOWN
, wparam
|lparam
, VK_APPS
, 1 },
5529 { WM_KEYDOWN
, sent
|wparam
|lparam
, VK_APPS
, 0x00000001 },
5530 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_APPS
, 0xc0000001 }, /* XP */
5531 { WM_KEYUP
, wparam
|lparam
, VK_APPS
, 0xc0000001 },
5532 { WM_KEYUP
, sent
|wparam
|lparam
, VK_APPS
, 0xc0000001 },
5533 { WM_CONTEXTMENU
, lparam
, /*hwnd*/0, (LPARAM
)-1 },
5534 { WM_CONTEXTMENU
, sent
|lparam
, /*hwnd*/0, (LPARAM
)-1 },
5538 static void pump_msg_loop(HWND hwnd
, HACCEL hAccel
)
5542 while (PeekMessageA(&msg
, 0, 0, 0, PM_REMOVE
))
5544 struct message log_msg
;
5546 trace("accel: %p, %04x, %08x, %08lx\n", msg
.hwnd
, msg
.message
, msg
.wParam
, msg
.lParam
);
5548 /* ignore some unwanted messages */
5549 if (msg
.message
== WM_MOUSEMOVE
||
5550 msg
.message
== WM_GETICON
||
5551 msg
.message
== WM_DEVICECHANGE
)
5554 log_msg
.message
= msg
.message
;
5555 log_msg
.flags
= wparam
|lparam
;
5556 log_msg
.wParam
= msg
.wParam
;
5557 log_msg
.lParam
= msg
.lParam
;
5558 add_message(&log_msg
);
5560 if (!hAccel
|| !TranslateAccelerator(hwnd
, hAccel
, &msg
))
5562 TranslateMessage(&msg
);
5563 DispatchMessage(&msg
);
5568 static void test_accelerators(void)
5573 HWND hwnd
= CreateWindowExA(0, "TestWindowClass", NULL
, WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
5574 100, 100, 200, 200, 0, 0, 0, NULL
);
5583 ok(GetFocus() == hwnd
, "wrong focus window %p\n", GetFocus());
5585 state
= GetKeyState(VK_SHIFT
);
5586 ok(!(state
& 0x8000), "wrong Shift state %04x\n", state
);
5587 state
= GetKeyState(VK_CAPITAL
);
5588 ok(state
== 0, "wrong CapsLock state %04x\n", state
);
5590 hAccel
= LoadAccelerators(GetModuleHandleA(0), MAKEINTRESOURCE(1));
5591 assert(hAccel
!= 0);
5593 pump_msg_loop(hwnd
, 0);
5596 trace("testing VK_N press/release\n");
5598 keybd_event('N', 0, 0, 0);
5599 keybd_event('N', 0, KEYEVENTF_KEYUP
, 0);
5600 pump_msg_loop(hwnd
, hAccel
);
5601 ok_sequence(WmVkN
, "VK_N press/release", FALSE
);
5603 trace("testing Shift+VK_N press/release\n");
5605 keybd_event(VK_SHIFT
, 0, 0, 0);
5606 keybd_event('N', 0, 0, 0);
5607 keybd_event('N', 0, KEYEVENTF_KEYUP
, 0);
5608 keybd_event(VK_SHIFT
, 0, KEYEVENTF_KEYUP
, 0);
5609 pump_msg_loop(hwnd
, hAccel
);
5610 ok_sequence(WmShiftVkN
, "Shift+VK_N press/release", FALSE
);
5612 trace("testing Ctrl+VK_N press/release\n");
5614 keybd_event(VK_CONTROL
, 0, 0, 0);
5615 keybd_event('N', 0, 0, 0);
5616 keybd_event('N', 0, KEYEVENTF_KEYUP
, 0);
5617 keybd_event(VK_CONTROL
, 0, KEYEVENTF_KEYUP
, 0);
5618 pump_msg_loop(hwnd
, hAccel
);
5619 ok_sequence(WmCtrlVkN
, "Ctrl+VK_N press/release", FALSE
);
5621 trace("testing Alt+VK_N press/release\n");
5623 keybd_event(VK_MENU
, 0, 0, 0);
5624 keybd_event('N', 0, 0, 0);
5625 keybd_event('N', 0, KEYEVENTF_KEYUP
, 0);
5626 keybd_event(VK_MENU
, 0, KEYEVENTF_KEYUP
, 0);
5627 pump_msg_loop(hwnd
, hAccel
);
5628 ok_sequence(WmAltVkN
, "Alt+VK_N press/release", FALSE
);
5630 trace("testing Ctrl+Alt+VK_N press/release 1\n");
5632 keybd_event(VK_CONTROL
, 0, 0, 0);
5633 keybd_event(VK_MENU
, 0, 0, 0);
5634 keybd_event('N', 0, 0, 0);
5635 keybd_event('N', 0, KEYEVENTF_KEYUP
, 0);
5636 keybd_event(VK_MENU
, 0, KEYEVENTF_KEYUP
, 0);
5637 keybd_event(VK_CONTROL
, 0, KEYEVENTF_KEYUP
, 0);
5638 pump_msg_loop(hwnd
, hAccel
);
5639 ok_sequence(WmCtrlAltVkN
, "Ctrl+Alt+VK_N press/release 1", FALSE
);
5641 ret
= DestroyAcceleratorTable(hAccel
);
5642 ok( ret
, "DestroyAcceleratorTable error %d\n", GetLastError());
5644 hAccel
= LoadAccelerators(GetModuleHandleA(0), MAKEINTRESOURCE(2));
5645 assert(hAccel
!= 0);
5647 trace("testing VK_N press/release\n");
5649 keybd_event('N', 0, 0, 0);
5650 keybd_event('N', 0, KEYEVENTF_KEYUP
, 0);
5651 pump_msg_loop(hwnd
, hAccel
);
5652 ok_sequence(WmVkN
, "VK_N press/release", FALSE
);
5654 trace("testing Shift+VK_N press/release\n");
5656 keybd_event(VK_SHIFT
, 0, 0, 0);
5657 keybd_event('N', 0, 0, 0);
5658 keybd_event('N', 0, KEYEVENTF_KEYUP
, 0);
5659 keybd_event(VK_SHIFT
, 0, KEYEVENTF_KEYUP
, 0);
5660 pump_msg_loop(hwnd
, hAccel
);
5661 ok_sequence(WmShiftVkN
, "Shift+VK_N press/release", FALSE
);
5663 trace("testing Ctrl+VK_N press/release 2\n");
5665 keybd_event(VK_CONTROL
, 0, 0, 0);
5666 keybd_event('N', 0, 0, 0);
5667 keybd_event('N', 0, KEYEVENTF_KEYUP
, 0);
5668 keybd_event(VK_CONTROL
, 0, KEYEVENTF_KEYUP
, 0);
5669 pump_msg_loop(hwnd
, hAccel
);
5670 ok_sequence(WmCtrlVkN_2
, "Ctrl+VK_N press/release 2", FALSE
);
5672 trace("testing Alt+VK_N press/release 2\n");
5674 keybd_event(VK_MENU
, 0, 0, 0);
5675 keybd_event('N', 0, 0, 0);
5676 keybd_event('N', 0, KEYEVENTF_KEYUP
, 0);
5677 keybd_event(VK_MENU
, 0, KEYEVENTF_KEYUP
, 0);
5678 pump_msg_loop(hwnd
, hAccel
);
5679 ok_sequence(WmAltVkN_2
, "Alt+VK_N press/release 2", FALSE
);
5681 trace("testing Ctrl+Alt+VK_N press/release 2\n");
5683 keybd_event(VK_CONTROL
, 0, 0, 0);
5684 keybd_event(VK_MENU
, 0, 0, 0);
5685 keybd_event('N', 0, 0, 0);
5686 keybd_event('N', 0, KEYEVENTF_KEYUP
, 0);
5687 keybd_event(VK_MENU
, 0, KEYEVENTF_KEYUP
, 0);
5688 keybd_event(VK_CONTROL
, 0, KEYEVENTF_KEYUP
, 0);
5689 pump_msg_loop(hwnd
, hAccel
);
5690 ok_sequence(WmCtrlAltVkN
, "Ctrl+Alt+VK_N press/release 2", FALSE
);
5692 trace("testing Ctrl+Shift+VK_N press/release\n");
5694 keybd_event(VK_CONTROL
, 0, 0, 0);
5695 keybd_event(VK_SHIFT
, 0, 0, 0);
5696 keybd_event('N', 0, 0, 0);
5697 keybd_event('N', 0, KEYEVENTF_KEYUP
, 0);
5698 keybd_event(VK_SHIFT
, 0, KEYEVENTF_KEYUP
, 0);
5699 keybd_event(VK_CONTROL
, 0, KEYEVENTF_KEYUP
, 0);
5700 pump_msg_loop(hwnd
, hAccel
);
5701 ok_sequence(WmCtrlShiftVkN
, "Ctrl+Shift+VK_N press/release", FALSE
);
5703 trace("testing Ctrl+Alt+Shift+VK_N press/release\n");
5705 keybd_event(VK_CONTROL
, 0, 0, 0);
5706 keybd_event(VK_MENU
, 0, 0, 0);
5707 keybd_event(VK_SHIFT
, 0, 0, 0);
5708 keybd_event('N', 0, 0, 0);
5709 keybd_event('N', 0, KEYEVENTF_KEYUP
, 0);
5710 keybd_event(VK_SHIFT
, 0, KEYEVENTF_KEYUP
, 0);
5711 keybd_event(VK_MENU
, 0, KEYEVENTF_KEYUP
, 0);
5712 keybd_event(VK_CONTROL
, 0, KEYEVENTF_KEYUP
, 0);
5713 pump_msg_loop(hwnd
, hAccel
);
5714 ok_sequence(WmCtrlAltShiftVkN
, "Ctrl+Alt+Shift+VK_N press/release", FALSE
);
5716 ret
= DestroyAcceleratorTable(hAccel
);
5717 ok( ret
, "DestroyAcceleratorTable error %d\n", GetLastError());
5719 trace("testing Alt press/release\n");
5721 keybd_event(VK_MENU
, 0, 0, 0);
5722 keybd_event(VK_MENU
, 0, KEYEVENTF_KEYUP
, 0);
5723 keybd_event(VK_MENU
, 0, 0, 0);
5724 keybd_event(VK_MENU
, 0, KEYEVENTF_KEYUP
, 0);
5725 pump_msg_loop(hwnd
, 0);
5726 /* this test doesn't pass in Wine for managed windows */
5727 ok_sequence(WmAltPressRelease
, "Alt press/release", TRUE
);
5729 trace("testing Alt+MouseButton press/release\n");
5730 /* first, move mouse pointer inside of the window client area */
5731 GetClientRect(hwnd
, &rc
);
5732 MapWindowPoints(hwnd
, 0, (LPPOINT
)&rc
, 2);
5733 rc
.left
+= (rc
.right
- rc
.left
)/2;
5734 rc
.top
+= (rc
.bottom
- rc
.top
)/2;
5735 SetCursorPos(rc
.left
, rc
.top
);
5737 pump_msg_loop(hwnd
, 0);
5739 keybd_event(VK_MENU
, 0, 0, 0);
5740 mouse_event(MOUSEEVENTF_LEFTDOWN
, 0, 0, 0, 0);
5741 mouse_event(MOUSEEVENTF_LEFTUP
, 0, 0, 0, 0);
5742 keybd_event(VK_MENU
, 0, KEYEVENTF_KEYUP
, 0);
5743 pump_msg_loop(hwnd
, 0);
5744 ok_sequence(WmAltMouseButton
, "Alt+MouseButton press/release", FALSE
);
5746 trace("testing VK_F1 press/release\n");
5747 keybd_event(VK_F1
, 0, 0, 0);
5748 keybd_event(VK_F1
, 0, KEYEVENTF_KEYUP
, 0);
5749 pump_msg_loop(hwnd
, 0);
5750 ok_sequence(WmF1Seq
, "F1 press/release", TRUE
);
5752 trace("testing VK_APPS press/release\n");
5753 keybd_event(VK_APPS
, 0, 0, 0);
5754 keybd_event(VK_APPS
, 0, KEYEVENTF_KEYUP
, 0);
5755 pump_msg_loop(hwnd
, 0);
5756 ok_sequence(WmVkAppsSeq
, "VK_APPS press/release", FALSE
);
5758 DestroyWindow(hwnd
);
5761 /************* window procedures ********************/
5763 static LRESULT
MsgCheckProc (BOOL unicode
, HWND hwnd
, UINT message
,
5764 WPARAM wParam
, LPARAM lParam
)
5766 static long defwndproc_counter
= 0;
5767 static long beginpaint_counter
= 0;
5771 trace("%p, %04x, %08x, %08lx\n", hwnd
, message
, wParam
, lParam
);
5773 /* explicitly ignore WM_GETICON message */
5774 if (message
== WM_GETICON
) return 0;
5780 LONG style
= GetWindowLongA(hwnd
, GWL_STYLE
);
5781 ok((BOOL
)wParam
== !(style
& WS_DISABLED
),
5782 "wrong WS_DISABLED state: %d != %d\n", wParam
, !(style
& WS_DISABLED
));
5786 case WM_CAPTURECHANGED
:
5787 if (test_DestroyWindow_flag
)
5789 DWORD style
= GetWindowLongA(hwnd
, GWL_STYLE
);
5790 if (style
& WS_CHILD
)
5791 lParam
= GetWindowLongPtrA(hwnd
, GWLP_ID
);
5792 else if (style
& WS_POPUP
)
5793 lParam
= WND_POPUP_ID
;
5795 lParam
= WND_PARENT_ID
;
5803 ok(!GetWindow(hwnd
, GW_CHILD
), "children should be unlinked at this point\n");
5804 capture
= GetCapture();
5807 ok(capture
== hwnd
, "capture should NOT be released at this point (capture %p)\n", capture
);
5808 trace("current capture %p, releasing...\n", capture
);
5815 ok(pGetAncestor(hwnd
, GA_PARENT
) != 0, "parent should NOT be unlinked at this point\n");
5816 if (test_DestroyWindow_flag
)
5818 DWORD style
= GetWindowLongA(hwnd
, GWL_STYLE
);
5819 if (style
& WS_CHILD
)
5820 lParam
= GetWindowLongPtrA(hwnd
, GWLP_ID
);
5821 else if (style
& WS_POPUP
)
5822 lParam
= WND_POPUP_ID
;
5824 lParam
= WND_PARENT_ID
;
5828 /* test_accelerators() depends on this */
5835 case WM_DEVICECHANGE
:
5838 case WM_WINDOWPOSCHANGING
:
5839 case WM_WINDOWPOSCHANGED
:
5841 WINDOWPOS
*winpos
= (WINDOWPOS
*)lParam
;
5843 trace("%s\n", (message
== WM_WINDOWPOSCHANGING
) ? "WM_WINDOWPOSCHANGING" : "WM_WINDOWPOSCHANGED");
5844 trace("%p after %p, x %d, y %d, cx %d, cy %d flags %08x\n",
5845 winpos
->hwnd
, winpos
->hwndInsertAfter
,
5846 winpos
->x
, winpos
->y
, winpos
->cx
, winpos
->cy
, winpos
->flags
);
5847 dump_winpos_flags(winpos
->flags
);
5849 /* Log only documented flags, win2k uses 0x1000 and 0x2000
5850 * in the high word for internal purposes
5852 wParam
= winpos
->flags
& 0xffff;
5853 /* We are not interested in the flags that don't match under XP and Win9x */
5854 wParam
&= ~(SWP_NOZORDER
);
5859 msg
.message
= message
;
5860 msg
.flags
= sent
|wparam
|lparam
;
5861 if (defwndproc_counter
) msg
.flags
|= defwinproc
;
5862 if (beginpaint_counter
) msg
.flags
|= beginpaint
;
5863 msg
.wParam
= wParam
;
5864 msg
.lParam
= lParam
;
5867 if (message
== WM_GETMINMAXINFO
&& (GetWindowLongA(hwnd
, GWL_STYLE
) & WS_CHILD
))
5869 HWND parent
= GetParent(hwnd
);
5871 MINMAXINFO
*minmax
= (MINMAXINFO
*)lParam
;
5873 GetClientRect(parent
, &rc
);
5874 trace("parent %p client size = (%d x %d)\n", parent
, rc
.right
, rc
.bottom
);
5876 trace("ptReserved = (%d,%d)\n"
5877 "ptMaxSize = (%d,%d)\n"
5878 "ptMaxPosition = (%d,%d)\n"
5879 "ptMinTrackSize = (%d,%d)\n"
5880 "ptMaxTrackSize = (%d,%d)\n",
5881 minmax
->ptReserved
.x
, minmax
->ptReserved
.y
,
5882 minmax
->ptMaxSize
.x
, minmax
->ptMaxSize
.y
,
5883 minmax
->ptMaxPosition
.x
, minmax
->ptMaxPosition
.y
,
5884 minmax
->ptMinTrackSize
.x
, minmax
->ptMinTrackSize
.y
,
5885 minmax
->ptMaxTrackSize
.x
, minmax
->ptMaxTrackSize
.y
);
5887 ok(minmax
->ptMaxSize
.x
== rc
.right
, "default width of maximized child %d != %d\n",
5888 minmax
->ptMaxSize
.x
, rc
.right
);
5889 ok(minmax
->ptMaxSize
.y
== rc
.bottom
, "default height of maximized child %d != %d\n",
5890 minmax
->ptMaxSize
.y
, rc
.bottom
);
5893 if (message
== WM_PAINT
)
5896 beginpaint_counter
++;
5897 BeginPaint( hwnd
, &ps
);
5898 beginpaint_counter
--;
5899 EndPaint( hwnd
, &ps
);
5903 defwndproc_counter
++;
5904 ret
= unicode
? DefWindowProcW(hwnd
, message
, wParam
, lParam
)
5905 : DefWindowProcA(hwnd
, message
, wParam
, lParam
);
5906 defwndproc_counter
--;
5911 static LRESULT WINAPI
MsgCheckProcA(HWND hwnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
5913 return MsgCheckProc (FALSE
, hwnd
, message
, wParam
, lParam
);
5916 static LRESULT WINAPI
MsgCheckProcW(HWND hwnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
5918 return MsgCheckProc (TRUE
, hwnd
, message
, wParam
, lParam
);
5921 static LRESULT WINAPI
PopupMsgCheckProcA(HWND hwnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
5923 static long defwndproc_counter
= 0;
5927 trace("popup: %p, %04x, %08x, %08lx\n", hwnd
, message
, wParam
, lParam
);
5929 /* explicitly ignore WM_GETICON message */
5930 if (message
== WM_GETICON
) return 0;
5932 msg
.message
= message
;
5933 msg
.flags
= sent
|wparam
|lparam
;
5934 if (defwndproc_counter
) msg
.flags
|= defwinproc
;
5935 msg
.wParam
= wParam
;
5936 msg
.lParam
= lParam
;
5939 if (message
== WM_CREATE
)
5941 DWORD style
= GetWindowLongA(hwnd
, GWL_STYLE
) | WS_VISIBLE
;
5942 SetWindowLongA(hwnd
, GWL_STYLE
, style
);
5945 defwndproc_counter
++;
5946 ret
= DefWindowProcA(hwnd
, message
, wParam
, lParam
);
5947 defwndproc_counter
--;
5952 static LRESULT WINAPI
ParentMsgCheckProcA(HWND hwnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
5954 static long defwndproc_counter
= 0;
5955 static long beginpaint_counter
= 0;
5959 trace("parent: %p, %04x, %08x, %08lx\n", hwnd
, message
, wParam
, lParam
);
5961 /* explicitly ignore WM_GETICON message */
5962 if (message
== WM_GETICON
) return 0;
5964 if (log_all_parent_messages
||
5965 message
== WM_PARENTNOTIFY
|| message
== WM_CANCELMODE
||
5966 message
== WM_SETFOCUS
|| message
== WM_KILLFOCUS
||
5967 message
== WM_ENABLE
|| message
== WM_ENTERIDLE
||
5968 message
== WM_IME_SETCONTEXT
)
5982 INT ret
= GetClipBox((HDC
)wParam
, &rc
);
5984 trace("WM_ERASEBKGND: GetClipBox()=%d, (%d,%d-%d,%d)\n",
5985 ret
, rc
.left
, rc
.top
, rc
.right
, rc
.bottom
);
5989 case WM_WINDOWPOSCHANGING
:
5990 case WM_WINDOWPOSCHANGED
:
5992 WINDOWPOS
*winpos
= (WINDOWPOS
*)lParam
;
5994 trace("%s\n", (message
== WM_WINDOWPOSCHANGING
) ? "WM_WINDOWPOSCHANGING" : "WM_WINDOWPOSCHANGED");
5995 trace("%p after %p, x %d, y %d, cx %d, cy %d flags %08x\n",
5996 winpos
->hwnd
, winpos
->hwndInsertAfter
,
5997 winpos
->x
, winpos
->y
, winpos
->cx
, winpos
->cy
, winpos
->flags
);
5998 dump_winpos_flags(winpos
->flags
);
6000 /* Log only documented flags, win2k uses 0x1000 and 0x2000
6001 * in the high word for internal purposes
6003 wParam
= winpos
->flags
& 0xffff;
6004 /* We are not interested in the flags that don't match under XP and Win9x */
6005 wParam
&= ~(SWP_NOZORDER
);
6010 msg
.message
= message
;
6011 msg
.flags
= sent
|parent
|wparam
|lparam
;
6012 if (defwndproc_counter
) msg
.flags
|= defwinproc
;
6013 if (beginpaint_counter
) msg
.flags
|= beginpaint
;
6014 msg
.wParam
= wParam
;
6015 msg
.lParam
= lParam
;
6019 if (message
== WM_PAINT
)
6022 beginpaint_counter
++;
6023 BeginPaint( hwnd
, &ps
);
6024 beginpaint_counter
--;
6025 EndPaint( hwnd
, &ps
);
6029 defwndproc_counter
++;
6030 ret
= DefWindowProcA(hwnd
, message
, wParam
, lParam
);
6031 defwndproc_counter
--;
6036 static LRESULT WINAPI
TestDlgProcA(HWND hwnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
6038 static long defwndproc_counter
= 0;
6042 trace("dialog: %p, %04x, %08x, %08lx\n", hwnd
, message
, wParam
, lParam
);
6044 /* explicitly ignore WM_GETICON message */
6045 if (message
== WM_GETICON
) return 0;
6049 DefDlgProcA(hwnd
, DM_SETDEFID
, 1, 0);
6050 ret
= DefDlgProcA(hwnd
, DM_GETDEFID
, 0, 0);
6051 if (after_end_dialog
)
6052 ok( ret
== 0, "DM_GETDEFID should return 0 after EndDialog, got %lx\n", ret
);
6054 ok(HIWORD(ret
) == DC_HASDEFID
, "DM_GETDEFID should return DC_HASDEFID, got %lx\n", ret
);
6059 case WM_WINDOWPOSCHANGING
:
6060 case WM_WINDOWPOSCHANGED
:
6062 WINDOWPOS
*winpos
= (WINDOWPOS
*)lParam
;
6064 trace("%s\n", (message
== WM_WINDOWPOSCHANGING
) ? "WM_WINDOWPOSCHANGING" : "WM_WINDOWPOSCHANGED");
6065 trace("%p after %p, x %d, y %d, cx %d, cy %d flags %08x\n",
6066 winpos
->hwnd
, winpos
->hwndInsertAfter
,
6067 winpos
->x
, winpos
->y
, winpos
->cx
, winpos
->cy
, winpos
->flags
);
6068 dump_winpos_flags(winpos
->flags
);
6070 /* Log only documented flags, win2k uses 0x1000 and 0x2000
6071 * in the high word for internal purposes
6073 wParam
= winpos
->flags
& 0xffff;
6074 /* We are not interested in the flags that don't match under XP and Win9x */
6075 wParam
&= ~(SWP_NOZORDER
);
6080 msg
.message
= message
;
6081 msg
.flags
= sent
|wparam
|lparam
;
6082 if (defwndproc_counter
) msg
.flags
|= defwinproc
;
6083 msg
.wParam
= wParam
;
6084 msg
.lParam
= lParam
;
6087 defwndproc_counter
++;
6088 ret
= DefDlgProcA(hwnd
, message
, wParam
, lParam
);
6089 defwndproc_counter
--;
6094 static void dump_winpos_flags(UINT flags
)
6096 if (!winetest_debug
) return;
6098 if (flags
& SWP_SHOWWINDOW
) printf("|SWP_SHOWWINDOW");
6099 if (flags
& SWP_HIDEWINDOW
) printf("|SWP_HIDEWINDOW");
6100 if (flags
& SWP_NOACTIVATE
) printf("|SWP_NOACTIVATE");
6101 if (flags
& SWP_FRAMECHANGED
) printf("|SWP_FRAMECHANGED");
6102 if (flags
& SWP_NOCOPYBITS
) printf("|SWP_NOCOPYBITS");
6103 if (flags
& SWP_NOOWNERZORDER
) printf("|SWP_NOOWNERZORDER");
6104 if (flags
& SWP_NOSENDCHANGING
) printf("|SWP_NOSENDCHANGING");
6105 if (flags
& SWP_DEFERERASE
) printf("|SWP_DEFERERASE");
6106 if (flags
& SWP_ASYNCWINDOWPOS
) printf("|SWP_ASYNCWINDOWPOS");
6107 if (flags
& SWP_NOZORDER
) printf("|SWP_NOZORDER");
6108 if (flags
& SWP_NOREDRAW
) printf("|SWP_NOREDRAW");
6109 if (flags
& SWP_NOSIZE
) printf("|SWP_NOSIZE");
6110 if (flags
& SWP_NOMOVE
) printf("|SWP_NOMOVE");
6111 if (flags
& SWP_NOCLIENTSIZE
) printf("|SWP_NOCLIENTSIZE");
6112 if (flags
& SWP_NOCLIENTMOVE
) printf("|SWP_NOCLIENTMOVE");
6114 #define DUMPED_FLAGS \
6120 SWP_FRAMECHANGED | \
6124 SWP_NOOWNERZORDER | \
6125 SWP_NOSENDCHANGING | \
6127 SWP_ASYNCWINDOWPOS | \
6128 SWP_NOCLIENTSIZE | \
6131 if(flags
& ~DUMPED_FLAGS
) printf("|0x%04x", flags
& ~DUMPED_FLAGS
);
6136 static LRESULT WINAPI
ShowWindowProcA(HWND hwnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
6138 static long defwndproc_counter
= 0;
6142 /* log only specific messages we are interested in */
6145 #if 0 /* probably log these as well */
6151 trace("WM_SHOWWINDOW %d\n", wParam
);
6154 trace("WM_SIZE %d\n", wParam
);
6159 case WM_GETMINMAXINFO
:
6160 trace("WM_GETMINMAXINFO\n");
6163 case WM_WINDOWPOSCHANGING
:
6164 case WM_WINDOWPOSCHANGED
:
6166 WINDOWPOS
*winpos
= (WINDOWPOS
*)lParam
;
6168 trace("%s\n", (message
== WM_WINDOWPOSCHANGING
) ? "WM_WINDOWPOSCHANGING" : "WM_WINDOWPOSCHANGED");
6169 trace("%p after %p, x %d, y %d, cx %d, cy %d flags %08x\n",
6170 winpos
->hwnd
, winpos
->hwndInsertAfter
,
6171 winpos
->x
, winpos
->y
, winpos
->cx
, winpos
->cy
, winpos
->flags
);
6173 dump_winpos_flags(winpos
->flags
);
6175 /* Log only documented flags, win2k uses 0x1000 and 0x2000
6176 * in the high word for internal purposes
6178 wParam
= winpos
->flags
& 0xffff;
6179 /* We are not interested in the flags that don't match under XP and Win9x */
6180 wParam
&= ~(SWP_NOZORDER
);
6184 default: /* ignore */
6185 /*trace("showwindow: %p, %04x, %08x, %08lx\n", hwnd, message, wParam, lParam);*/
6186 return DefWindowProcA(hwnd
, message
, wParam
, lParam
);
6189 msg
.message
= message
;
6190 msg
.flags
= sent
|wparam
|lparam
;
6191 if (defwndproc_counter
) msg
.flags
|= defwinproc
;
6192 msg
.wParam
= wParam
;
6193 msg
.lParam
= lParam
;
6196 defwndproc_counter
++;
6197 ret
= DefWindowProcA(hwnd
, message
, wParam
, lParam
);
6198 defwndproc_counter
--;
6203 static BOOL
RegisterWindowClasses(void)
6208 cls
.lpfnWndProc
= MsgCheckProcA
;
6211 cls
.hInstance
= GetModuleHandleA(0);
6213 cls
.hCursor
= LoadCursorA(0, (LPSTR
)IDC_ARROW
);
6214 cls
.hbrBackground
= GetStockObject(WHITE_BRUSH
);
6215 cls
.lpszMenuName
= NULL
;
6216 cls
.lpszClassName
= "TestWindowClass";
6217 if(!RegisterClassA(&cls
)) return FALSE
;
6219 cls
.lpfnWndProc
= ShowWindowProcA
;
6220 cls
.lpszClassName
= "ShowWindowClass";
6221 if(!RegisterClassA(&cls
)) return FALSE
;
6223 cls
.lpfnWndProc
= PopupMsgCheckProcA
;
6224 cls
.lpszClassName
= "TestPopupClass";
6225 if(!RegisterClassA(&cls
)) return FALSE
;
6227 cls
.lpfnWndProc
= ParentMsgCheckProcA
;
6228 cls
.lpszClassName
= "TestParentClass";
6229 if(!RegisterClassA(&cls
)) return FALSE
;
6231 cls
.lpfnWndProc
= DefWindowProcA
;
6232 cls
.lpszClassName
= "SimpleWindowClass";
6233 if(!RegisterClassA(&cls
)) return FALSE
;
6235 cls
.style
= CS_NOCLOSE
;
6236 cls
.lpszClassName
= "NoCloseWindowClass";
6237 if(!RegisterClassA(&cls
)) return FALSE
;
6239 ok(GetClassInfoA(0, "#32770", &cls
), "GetClassInfo failed\n");
6241 cls
.hInstance
= GetModuleHandleA(0);
6242 cls
.hbrBackground
= 0;
6243 cls
.lpfnWndProc
= TestDlgProcA
;
6244 cls
.lpszClassName
= "TestDialogClass";
6245 if(!RegisterClassA(&cls
)) return FALSE
;
6250 static HHOOK hCBT_hook
;
6251 static DWORD cbt_hook_thread_id
;
6253 static LRESULT CALLBACK
cbt_hook_proc(int nCode
, WPARAM wParam
, LPARAM lParam
)
6255 static const char * const CBT_code_name
[10] = {
6262 "HCBT_CLICKSKIPPED",
6266 const char *code_name
= (nCode
>= 0 && nCode
<= HCBT_SETFOCUS
) ? CBT_code_name
[nCode
] : "Unknown";
6270 trace("CBT: %d (%s), %08x, %08lx\n", nCode
, code_name
, wParam
, lParam
);
6272 ok(cbt_hook_thread_id
== GetCurrentThreadId(), "we didn't ask for events from other threads\n");
6274 if (nCode
== HCBT_CLICKSKIPPED
)
6276 /* ignore this event, XP sends it a lot when switching focus between windows */
6277 return CallNextHookEx(hCBT_hook
, nCode
, wParam
, lParam
);
6280 if (nCode
== HCBT_SYSCOMMAND
|| nCode
== HCBT_KEYSKIPPED
)
6284 msg
.message
= nCode
;
6285 msg
.flags
= hook
|wparam
|lparam
;
6286 msg
.wParam
= wParam
;
6287 msg
.lParam
= lParam
;
6290 return CallNextHookEx(hCBT_hook
, nCode
, wParam
, lParam
);
6293 if (nCode
== HCBT_DESTROYWND
)
6295 if (test_DestroyWindow_flag
)
6297 DWORD style
= GetWindowLongA((HWND
)wParam
, GWL_STYLE
);
6298 if (style
& WS_CHILD
)
6299 lParam
= GetWindowLongPtrA((HWND
)wParam
, GWLP_ID
);
6300 else if (style
& WS_POPUP
)
6301 lParam
= WND_POPUP_ID
;
6303 lParam
= WND_PARENT_ID
;
6307 /* Log also SetFocus(0) calls */
6308 hwnd
= wParam
? (HWND
)wParam
: (HWND
)lParam
;
6310 if (GetClassNameA(hwnd
, buf
, sizeof(buf
)))
6312 if (!lstrcmpiA(buf
, "TestWindowClass") ||
6313 !lstrcmpiA(buf
, "ShowWindowClass") ||
6314 !lstrcmpiA(buf
, "TestParentClass") ||
6315 !lstrcmpiA(buf
, "TestPopupClass") ||
6316 !lstrcmpiA(buf
, "SimpleWindowClass") ||
6317 !lstrcmpiA(buf
, "TestDialogClass") ||
6318 !lstrcmpiA(buf
, "MDI_frame_class") ||
6319 !lstrcmpiA(buf
, "MDI_client_class") ||
6320 !lstrcmpiA(buf
, "MDI_child_class") ||
6321 !lstrcmpiA(buf
, "my_button_class") ||
6322 !lstrcmpiA(buf
, "my_edit_class") ||
6323 !lstrcmpiA(buf
, "static") ||
6324 !lstrcmpiA(buf
, "MyDialogClass") ||
6325 !lstrcmpiA(buf
, "#32770"))
6329 msg
.message
= nCode
;
6330 msg
.flags
= hook
|wparam
|lparam
;
6331 msg
.wParam
= wParam
;
6332 msg
.lParam
= lParam
;
6336 return CallNextHookEx(hCBT_hook
, nCode
, wParam
, lParam
);
6339 static void CALLBACK
win_event_proc(HWINEVENTHOOK hevent
,
6349 trace("WEH:%p,event %08x,hwnd %p,obj %08x,id %08x,thread %08x,time %08x\n",
6350 hevent
, event
, hwnd
, object_id
, child_id
, thread_id
, event_time
);
6352 ok(thread_id
== GetCurrentThreadId(), "we didn't ask for events from other threads\n");
6354 /* ignore mouse cursor events */
6355 if (object_id
== OBJID_CURSOR
) return;
6357 if (!hwnd
|| GetClassNameA(hwnd
, buf
, sizeof(buf
)))
6360 !lstrcmpiA(buf
, "TestWindowClass") ||
6361 !lstrcmpiA(buf
, "TestParentClass") ||
6362 !lstrcmpiA(buf
, "TestPopupClass") ||
6363 !lstrcmpiA(buf
, "SimpleWindowClass") ||
6364 !lstrcmpiA(buf
, "TestDialogClass") ||
6365 !lstrcmpiA(buf
, "MDI_frame_class") ||
6366 !lstrcmpiA(buf
, "MDI_client_class") ||
6367 !lstrcmpiA(buf
, "MDI_child_class") ||
6368 !lstrcmpiA(buf
, "my_button_class") ||
6369 !lstrcmpiA(buf
, "my_edit_class") ||
6370 !lstrcmpiA(buf
, "static") ||
6371 !lstrcmpiA(buf
, "MyDialogClass") ||
6372 !lstrcmpiA(buf
, "#32770"))
6376 msg
.message
= event
;
6377 msg
.flags
= winevent_hook
|wparam
|lparam
;
6378 msg
.wParam
= object_id
;
6379 msg
.lParam
= child_id
;
6385 static const WCHAR wszUnicode
[] = {'U','n','i','c','o','d','e',0};
6386 static const WCHAR wszAnsi
[] = {'U',0};
6388 static LRESULT CALLBACK
MsgConversionProcW(HWND hwnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
6392 case CB_FINDSTRINGEXACT
:
6393 trace("String: %p\n", (LPCWSTR
)lParam
);
6394 if (!lstrcmpW((LPCWSTR
)lParam
, wszUnicode
))
6396 if (!lstrcmpW((LPCWSTR
)lParam
, wszAnsi
))
6400 return DefWindowProcW(hwnd
, uMsg
, wParam
, lParam
);
6403 static const struct message WmGetTextLengthAfromW
[] = {
6404 { WM_GETTEXTLENGTH
, sent
},
6405 { WM_GETTEXT
, sent
},
6409 static const WCHAR testWindowClassW
[] =
6410 { 'T','e','s','t','W','i','n','d','o','w','C','l','a','s','s','W',0 };
6412 static const WCHAR dummy_window_text
[] = {'d','u','m','m','y',' ','t','e','x','t',0};
6414 /* dummy window proc for WM_GETTEXTLENGTH test */
6415 static LRESULT CALLBACK
get_text_len_proc( HWND hwnd
, UINT msg
, WPARAM wp
, LPARAM lp
)
6419 case WM_GETTEXTLENGTH
:
6420 return lstrlenW(dummy_window_text
) + 37; /* some random length */
6422 lstrcpynW( (LPWSTR
)lp
, dummy_window_text
, wp
);
6423 return lstrlenW( (LPWSTR
)lp
);
6425 return DefWindowProcW( hwnd
, msg
, wp
, lp
);
6429 static void test_message_conversion(void)
6431 static const WCHAR wszMsgConversionClass
[] =
6432 {'M','s','g','C','o','n','v','e','r','s','i','o','n','C','l','a','s','s',0};
6436 WNDPROC wndproc
, newproc
;
6440 cls
.lpfnWndProc
= MsgConversionProcW
;
6443 cls
.hInstance
= GetModuleHandleW(NULL
);
6445 cls
.hCursor
= LoadCursorW(NULL
, (LPWSTR
)IDC_ARROW
);
6446 cls
.hbrBackground
= (HBRUSH
)(COLOR_BTNFACE
+1);
6447 cls
.lpszMenuName
= NULL
;
6448 cls
.lpszClassName
= wszMsgConversionClass
;
6449 /* this call will fail on Win9x, but that doesn't matter as this test is
6450 * meaningless on those platforms */
6451 if(!RegisterClassW(&cls
)) return;
6454 cls
.lpfnWndProc
= MsgCheckProcW
;
6457 cls
.hInstance
= GetModuleHandleW(0);
6459 cls
.hCursor
= LoadCursorW(0, (LPWSTR
)IDC_ARROW
);
6460 cls
.hbrBackground
= GetStockObject(WHITE_BRUSH
);
6461 cls
.lpszMenuName
= NULL
;
6462 cls
.lpszClassName
= testWindowClassW
;
6463 if(!RegisterClassW(&cls
)) return;
6465 hwnd
= CreateWindowExW(0, wszMsgConversionClass
, NULL
, WS_OVERLAPPED
,
6466 100, 100, 200, 200, 0, 0, 0, NULL
);
6467 ok(hwnd
!= NULL
, "Window creation failed\n");
6471 wndproc
= (WNDPROC
)GetWindowLongPtrA(hwnd
, GWLP_WNDPROC
);
6472 lRes
= CallWindowProcA(wndproc
, hwnd
, CB_FINDSTRINGEXACT
, 0, (LPARAM
)wszUnicode
);
6473 ok(lRes
== 0, "String should have been converted\n");
6474 lRes
= CallWindowProcW(wndproc
, hwnd
, CB_FINDSTRINGEXACT
, 0, (LPARAM
)wszUnicode
);
6475 ok(lRes
== 1, "String shouldn't have been converted\n");
6479 wndproc
= (WNDPROC
)GetWindowLongPtrW(hwnd
, GWLP_WNDPROC
);
6480 lRes
= CallWindowProcA(wndproc
, hwnd
, CB_FINDSTRINGEXACT
, 0, (LPARAM
)wszUnicode
);
6481 ok(lRes
== 1, "String shouldn't have been converted\n");
6482 lRes
= CallWindowProcW(wndproc
, hwnd
, CB_FINDSTRINGEXACT
, 0, (LPARAM
)wszUnicode
);
6483 ok(lRes
== 1, "String shouldn't have been converted\n");
6485 /* Synchronous messages */
6487 lRes
= SendMessageA(hwnd
, CB_FINDSTRINGEXACT
, 0, (LPARAM
)wszUnicode
);
6488 ok(lRes
== 0, "String should have been converted\n");
6489 lRes
= SendMessageW(hwnd
, CB_FINDSTRINGEXACT
, 0, (LPARAM
)wszUnicode
);
6490 ok(lRes
== 1, "String shouldn't have been converted\n");
6492 /* Asynchronous messages */
6495 lRes
= PostMessageA(hwnd
, CB_FINDSTRINGEXACT
, 0, (LPARAM
)wszUnicode
);
6496 ok(lRes
== 0 && (GetLastError() == ERROR_MESSAGE_SYNC_ONLY
|| GetLastError() == ERROR_INVALID_PARAMETER
),
6497 "PostMessage on sync only message returned %ld, last error %d\n", lRes
, GetLastError());
6499 lRes
= PostMessageW(hwnd
, CB_FINDSTRINGEXACT
, 0, (LPARAM
)wszUnicode
);
6500 ok(lRes
== 0 && (GetLastError() == ERROR_MESSAGE_SYNC_ONLY
|| GetLastError() == ERROR_INVALID_PARAMETER
),
6501 "PostMessage on sync only message returned %ld, last error %d\n", lRes
, GetLastError());
6503 lRes
= PostThreadMessageA(GetCurrentThreadId(), CB_FINDSTRINGEXACT
, 0, (LPARAM
)wszUnicode
);
6504 ok(lRes
== 0 && (GetLastError() == ERROR_MESSAGE_SYNC_ONLY
|| GetLastError() == ERROR_INVALID_PARAMETER
),
6505 "PosThreadtMessage on sync only message returned %ld, last error %d\n", lRes
, GetLastError());
6507 lRes
= PostThreadMessageW(GetCurrentThreadId(), CB_FINDSTRINGEXACT
, 0, (LPARAM
)wszUnicode
);
6508 ok(lRes
== 0 && (GetLastError() == ERROR_MESSAGE_SYNC_ONLY
|| GetLastError() == ERROR_INVALID_PARAMETER
),
6509 "PosThreadtMessage on sync only message returned %ld, last error %d\n", lRes
, GetLastError());
6511 lRes
= SendNotifyMessageA(hwnd
, CB_FINDSTRINGEXACT
, 0, (LPARAM
)wszUnicode
);
6512 ok(lRes
== 0 && (GetLastError() == ERROR_MESSAGE_SYNC_ONLY
|| GetLastError() == ERROR_INVALID_PARAMETER
),
6513 "SendNotifyMessage on sync only message returned %ld, last error %d\n", lRes
, GetLastError());
6515 lRes
= SendNotifyMessageW(hwnd
, CB_FINDSTRINGEXACT
, 0, (LPARAM
)wszUnicode
);
6516 ok(lRes
== 0 && (GetLastError() == ERROR_MESSAGE_SYNC_ONLY
|| GetLastError() == ERROR_INVALID_PARAMETER
),
6517 "SendNotifyMessage on sync only message returned %ld, last error %d\n", lRes
, GetLastError());
6519 lRes
= SendMessageCallbackA(hwnd
, CB_FINDSTRINGEXACT
, 0, (LPARAM
)wszUnicode
, NULL
, 0);
6520 ok(lRes
== 0 && (GetLastError() == ERROR_MESSAGE_SYNC_ONLY
|| GetLastError() == ERROR_INVALID_PARAMETER
),
6521 "SendMessageCallback on sync only message returned %ld, last error %d\n", lRes
, GetLastError());
6523 lRes
= SendMessageCallbackW(hwnd
, CB_FINDSTRINGEXACT
, 0, (LPARAM
)wszUnicode
, NULL
, 0);
6524 ok(lRes
== 0 && (GetLastError() == ERROR_MESSAGE_SYNC_ONLY
|| GetLastError() == ERROR_INVALID_PARAMETER
),
6525 "SendMessageCallback on sync only message returned %ld, last error %d\n", lRes
, GetLastError());
6527 /* Check WM_GETTEXTLENGTH A->W behaviour, whether WM_GETTEXT is also sent or not */
6529 hwnd
= CreateWindowW (testWindowClassW
, wszUnicode
,
6530 WS_OVERLAPPEDWINDOW
,
6531 100, 100, 200, 200, 0, 0, 0, NULL
);
6534 lRes
= SendMessageA (hwnd
, WM_GETTEXTLENGTH
, 0, 0);
6535 ok_sequence(WmGetTextLengthAfromW
, "ANSI WM_GETTEXTLENGTH to Unicode window", FALSE
);
6536 ok( lRes
== WideCharToMultiByte( CP_ACP
, 0, wszUnicode
, lstrlenW(wszUnicode
), NULL
, 0, NULL
, NULL
),
6537 "got bad length %ld\n", lRes
);
6540 lRes
= CallWindowProcA( (WNDPROC
)GetWindowLongPtrA( hwnd
, GWLP_WNDPROC
),
6541 hwnd
, WM_GETTEXTLENGTH
, 0, 0);
6542 ok_sequence(WmGetTextLengthAfromW
, "ANSI WM_GETTEXTLENGTH to Unicode window", FALSE
);
6543 ok( lRes
== WideCharToMultiByte( CP_ACP
, 0, wszUnicode
, lstrlenW(wszUnicode
), NULL
, 0, NULL
, NULL
),
6544 "got bad length %ld\n", lRes
);
6546 wndproc
= (WNDPROC
)SetWindowLongPtrW( hwnd
, GWLP_WNDPROC
, (LONG_PTR
)get_text_len_proc
);
6547 newproc
= (WNDPROC
)GetWindowLongPtrA( hwnd
, GWLP_WNDPROC
);
6548 lRes
= CallWindowProcA( newproc
, hwnd
, WM_GETTEXTLENGTH
, 0, 0 );
6549 ok( lRes
== WideCharToMultiByte( CP_ACP
, 0, dummy_window_text
, lstrlenW(dummy_window_text
),
6550 NULL
, 0, NULL
, NULL
),
6551 "got bad length %ld\n", lRes
);
6553 SetWindowLongPtrW( hwnd
, GWLP_WNDPROC
, (LONG_PTR
)wndproc
); /* restore old wnd proc */
6554 lRes
= CallWindowProcA( newproc
, hwnd
, WM_GETTEXTLENGTH
, 0, 0 );
6555 ok( lRes
== WideCharToMultiByte( CP_ACP
, 0, dummy_window_text
, lstrlenW(dummy_window_text
),
6556 NULL
, 0, NULL
, NULL
),
6557 "got bad length %ld\n", lRes
);
6559 ret
= DestroyWindow(hwnd
);
6560 ok( ret
, "DestroyWindow() error %d\n", GetLastError());
6570 static VOID CALLBACK
tfunc(HWND hwnd
, UINT uMsg
, UINT id
, DWORD dwTime
)
6574 #define TIMER_ID 0x19
6576 static DWORD WINAPI
timer_thread_proc(LPVOID x
)
6578 struct timer_info
*info
= x
;
6581 r
= KillTimer(info
->hWnd
, 0x19);
6582 ok(r
,"KillTimer failed in thread\n");
6583 r
= SetTimer(info
->hWnd
,TIMER_ID
,10000,tfunc
);
6584 ok(r
,"SetTimer failed in thread\n");
6585 ok(r
==TIMER_ID
,"SetTimer id different\n");
6586 r
= SetEvent(info
->handles
[0]);
6587 ok(r
,"SetEvent failed in thread\n");
6591 static void test_timers(void)
6593 struct timer_info info
;
6596 info
.hWnd
= CreateWindow ("TestWindowClass", NULL
,
6597 WS_OVERLAPPEDWINDOW
,
6598 CW_USEDEFAULT
, CW_USEDEFAULT
, 300, 300, 0,
6601 info
.id
= SetTimer(info
.hWnd
,TIMER_ID
,10000,tfunc
);
6602 ok(info
.id
, "SetTimer failed\n");
6603 ok(info
.id
==TIMER_ID
, "SetTimer timer ID different\n");
6604 info
.handles
[0] = CreateEvent(NULL
,0,0,NULL
);
6605 info
.handles
[1] = CreateThread(NULL
,0,timer_thread_proc
,&info
,0,&id
);
6607 WaitForMultipleObjects(2, info
.handles
, FALSE
, INFINITE
);
6609 WaitForSingleObject(info
.handles
[1], INFINITE
);
6611 CloseHandle(info
.handles
[0]);
6612 CloseHandle(info
.handles
[1]);
6614 ok( KillTimer(info
.hWnd
, TIMER_ID
), "KillTimer failed\n");
6616 ok(DestroyWindow(info
.hWnd
), "failed to destroy window\n");
6619 /* Various win events with arbitrary parameters */
6620 static const struct message WmWinEventsSeq
[] = {
6621 { EVENT_SYSTEM_SOUND
, winevent_hook
|wparam
|lparam
, OBJID_WINDOW
, 0 },
6622 { EVENT_SYSTEM_ALERT
, winevent_hook
|wparam
|lparam
, OBJID_SYSMENU
, 1 },
6623 { EVENT_SYSTEM_FOREGROUND
, winevent_hook
|wparam
|lparam
, OBJID_TITLEBAR
, 2 },
6624 { EVENT_SYSTEM_MENUSTART
, winevent_hook
|wparam
|lparam
, OBJID_MENU
, 3 },
6625 { EVENT_SYSTEM_MENUEND
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 4 },
6626 { EVENT_SYSTEM_MENUPOPUPSTART
, winevent_hook
|wparam
|lparam
, OBJID_VSCROLL
, 5 },
6627 { EVENT_SYSTEM_MENUPOPUPEND
, winevent_hook
|wparam
|lparam
, OBJID_HSCROLL
, 6 },
6628 { EVENT_SYSTEM_CAPTURESTART
, winevent_hook
|wparam
|lparam
, OBJID_SIZEGRIP
, 7 },
6629 { EVENT_SYSTEM_CAPTUREEND
, winevent_hook
|wparam
|lparam
, OBJID_CARET
, 8 },
6630 /* our win event hook ignores OBJID_CURSOR events */
6631 /*{ EVENT_SYSTEM_MOVESIZESTART, winevent_hook|wparam|lparam, OBJID_CURSOR, 9 },*/
6632 { EVENT_SYSTEM_MOVESIZEEND
, winevent_hook
|wparam
|lparam
, OBJID_ALERT
, 10 },
6633 { EVENT_SYSTEM_CONTEXTHELPSTART
, winevent_hook
|wparam
|lparam
, OBJID_SOUND
, 11 },
6634 { EVENT_SYSTEM_CONTEXTHELPEND
, winevent_hook
|wparam
|lparam
, OBJID_QUERYCLASSNAMEIDX
, 12 },
6635 { EVENT_SYSTEM_DRAGDROPSTART
, winevent_hook
|wparam
|lparam
, OBJID_NATIVEOM
, 13 },
6636 { EVENT_SYSTEM_DRAGDROPEND
, winevent_hook
|wparam
|lparam
, OBJID_WINDOW
, 0 },
6637 { EVENT_SYSTEM_DIALOGSTART
, winevent_hook
|wparam
|lparam
, OBJID_SYSMENU
, 1 },
6638 { EVENT_SYSTEM_DIALOGEND
, winevent_hook
|wparam
|lparam
, OBJID_TITLEBAR
, 2 },
6639 { EVENT_SYSTEM_SCROLLINGSTART
, winevent_hook
|wparam
|lparam
, OBJID_MENU
, 3 },
6640 { EVENT_SYSTEM_SCROLLINGEND
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 4 },
6641 { EVENT_SYSTEM_SWITCHSTART
, winevent_hook
|wparam
|lparam
, OBJID_VSCROLL
, 5 },
6642 { EVENT_SYSTEM_SWITCHEND
, winevent_hook
|wparam
|lparam
, OBJID_HSCROLL
, 6 },
6643 { EVENT_SYSTEM_MINIMIZESTART
, winevent_hook
|wparam
|lparam
, OBJID_SIZEGRIP
, 7 },
6644 { EVENT_SYSTEM_MINIMIZEEND
, winevent_hook
|wparam
|lparam
, OBJID_CARET
, 8 },
6647 static const struct message WmWinEventCaretSeq
[] = {
6648 { EVENT_OBJECT_CREATE
, winevent_hook
|wparam
|lparam
, OBJID_CARET
, 0 }, /* hook 1 */
6649 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, OBJID_CARET
, 0 }, /* hook 1 */
6650 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, OBJID_CARET
, 0 }, /* hook 2 */
6651 { EVENT_OBJECT_NAMECHANGE
, winevent_hook
|wparam
|lparam
, OBJID_CARET
, 0 }, /* hook 1 */
6654 static const struct message WmWinEventCaretSeq_2
[] = {
6655 { EVENT_OBJECT_CREATE
, winevent_hook
|wparam
|lparam
, OBJID_CARET
, 0 }, /* hook 1/2 */
6656 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, OBJID_CARET
, 0 }, /* hook 1/2 */
6657 { EVENT_OBJECT_NAMECHANGE
, winevent_hook
|wparam
|lparam
, OBJID_CARET
, 0 }, /* hook 1/2 */
6660 static const struct message WmWinEventAlertSeq
[] = {
6661 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, OBJID_ALERT
, 0 },
6664 static const struct message WmWinEventAlertSeq_2
[] = {
6665 /* create window in the thread proc */
6666 { EVENT_OBJECT_CREATE
, winevent_hook
|wparam
|lparam
, OBJID_WINDOW
, 2 },
6667 /* our test event */
6668 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, OBJID_ALERT
, 2 },
6671 static const struct message WmGlobalHookSeq_1
[] = {
6672 /* create window in the thread proc */
6673 { HCBT_CREATEWND
, hook
|lparam
, 0, 2 },
6674 /* our test events */
6675 { HCBT_SYSCOMMAND
, hook
|wparam
|lparam
, SC_PREVWINDOW
, 2 },
6676 { HCBT_SYSCOMMAND
, hook
|wparam
|lparam
, SC_NEXTWINDOW
, 2 },
6679 static const struct message WmGlobalHookSeq_2
[] = {
6680 { HCBT_SYSCOMMAND
, hook
|wparam
|lparam
, SC_NEXTWINDOW
, 0 }, /* old local hook */
6681 { HCBT_SYSCOMMAND
, hook
|wparam
|lparam
, SC_NEXTWINDOW
, 2 }, /* new global hook */
6682 { HCBT_SYSCOMMAND
, hook
|wparam
|lparam
, SC_PREVWINDOW
, 0 }, /* old local hook */
6683 { HCBT_SYSCOMMAND
, hook
|wparam
|lparam
, SC_PREVWINDOW
, 2 }, /* new global hook */
6687 static const struct message WmMouseLLHookSeq
[] = {
6688 { WM_MOUSEMOVE
, hook
},
6689 { WM_LBUTTONUP
, hook
},
6690 { WM_MOUSEMOVE
, hook
},
6694 static void CALLBACK
win_event_global_hook_proc(HWINEVENTHOOK hevent
,
6704 trace("WEH_2:%p,event %08x,hwnd %p,obj %08x,id %08x,thread %08x,time %08x\n",
6705 hevent
, event
, hwnd
, object_id
, child_id
, thread_id
, event_time
);
6707 if (GetClassNameA(hwnd
, buf
, sizeof(buf
)))
6709 if (!lstrcmpiA(buf
, "TestWindowClass") ||
6710 !lstrcmpiA(buf
, "static"))
6714 msg
.message
= event
;
6715 msg
.flags
= winevent_hook
|wparam
|lparam
;
6716 msg
.wParam
= object_id
;
6717 msg
.lParam
= (thread_id
== GetCurrentThreadId()) ? child_id
: (child_id
+ 2);
6723 static HHOOK hCBT_global_hook
;
6724 static DWORD cbt_global_hook_thread_id
;
6726 static LRESULT CALLBACK
cbt_global_hook_proc(int nCode
, WPARAM wParam
, LPARAM lParam
)
6731 trace("CBT_2: %d, %08x, %08lx\n", nCode
, wParam
, lParam
);
6733 if (nCode
== HCBT_SYSCOMMAND
)
6737 msg
.message
= nCode
;
6738 msg
.flags
= hook
|wparam
|lparam
;
6739 msg
.wParam
= wParam
;
6740 msg
.lParam
= (cbt_global_hook_thread_id
== GetCurrentThreadId()) ? 1 : 2;
6743 return CallNextHookEx(hCBT_global_hook
, nCode
, wParam
, lParam
);
6745 /* WH_MOUSE_LL hook */
6746 if (nCode
== HC_ACTION
)
6749 MSLLHOOKSTRUCT
*mhll
= (MSLLHOOKSTRUCT
*)lParam
;
6751 /* we can't test for real mouse events */
6752 if (mhll
->flags
& LLMHF_INJECTED
)
6754 msg
.message
= wParam
;
6758 return CallNextHookEx(hCBT_global_hook
, nCode
, wParam
, lParam
);
6761 /* Log also SetFocus(0) calls */
6762 hwnd
= wParam
? (HWND
)wParam
: (HWND
)lParam
;
6764 if (GetClassNameA(hwnd
, buf
, sizeof(buf
)))
6766 if (!lstrcmpiA(buf
, "TestWindowClass") ||
6767 !lstrcmpiA(buf
, "static"))
6771 msg
.message
= nCode
;
6772 msg
.flags
= hook
|wparam
|lparam
;
6773 msg
.wParam
= wParam
;
6774 msg
.lParam
= (cbt_global_hook_thread_id
== GetCurrentThreadId()) ? 1 : 2;
6778 return CallNextHookEx(hCBT_global_hook
, nCode
, wParam
, lParam
);
6781 static DWORD WINAPI
win_event_global_thread_proc(void *param
)
6785 HANDLE hevent
= *(HANDLE
*)param
;
6786 HMODULE user32
= GetModuleHandleA("user32.dll");
6787 FARPROC pNotifyWinEvent
= GetProcAddress(user32
, "NotifyWinEvent");
6789 assert(pNotifyWinEvent
);
6791 hwnd
= CreateWindowExA(0, "static", NULL
, WS_POPUP
, 0,0,0,0,0,0,0, NULL
);
6793 trace("created thread window %p\n", hwnd
);
6795 *(HWND
*)param
= hwnd
;
6798 /* this event should be received only by our new hook proc,
6799 * an old one does not expect an event from another thread.
6801 pNotifyWinEvent(EVENT_OBJECT_LOCATIONCHANGE
, hwnd
, OBJID_ALERT
, 0);
6804 while (GetMessage(&msg
, 0, 0, 0))
6806 TranslateMessage(&msg
);
6807 DispatchMessage(&msg
);
6812 static DWORD WINAPI
cbt_global_hook_thread_proc(void *param
)
6816 HANDLE hevent
= *(HANDLE
*)param
;
6819 /* these events should be received only by our new hook proc,
6820 * an old one does not expect an event from another thread.
6823 hwnd
= CreateWindowExA(0, "static", NULL
, WS_POPUP
, 0,0,0,0,0,0,0, NULL
);
6825 trace("created thread window %p\n", hwnd
);
6827 *(HWND
*)param
= hwnd
;
6829 /* Windows doesn't like when a thread plays games with the focus,
6830 that leads to all kinds of misbehaviours and failures to activate
6831 a window. So, better keep next lines commented out.
6835 DefWindowProcA(hwnd
, WM_SYSCOMMAND
, SC_PREVWINDOW
, 0);
6836 DefWindowProcA(hwnd
, WM_SYSCOMMAND
, SC_NEXTWINDOW
, 0);
6840 while (GetMessage(&msg
, 0, 0, 0))
6842 TranslateMessage(&msg
);
6843 DispatchMessage(&msg
);
6848 static DWORD WINAPI
mouse_ll_global_thread_proc(void *param
)
6852 HANDLE hevent
= *(HANDLE
*)param
;
6854 hwnd
= CreateWindowExA(0, "static", NULL
, WS_POPUP
, 0,0,0,0,0,0,0, NULL
);
6856 trace("created thread window %p\n", hwnd
);
6858 *(HWND
*)param
= hwnd
;
6862 /* Windows doesn't like when a thread plays games with the focus,
6863 * that leads to all kinds of misbehaviours and failures to activate
6864 * a window. So, better don't generate a mouse click message below.
6866 mouse_event(MOUSEEVENTF_MOVE
, -1, 0, 0, 0);
6867 mouse_event(MOUSEEVENTF_LEFTUP
, 0, 0, 0, 0);
6868 mouse_event(MOUSEEVENTF_MOVE
, 1, 0, 0, 0);
6871 while (GetMessage(&msg
, 0, 0, 0))
6873 TranslateMessage(&msg
);
6874 DispatchMessage(&msg
);
6879 static void test_winevents(void)
6885 HANDLE hthread
, hevent
;
6887 HWINEVENTHOOK hhook
;
6888 const struct message
*events
= WmWinEventsSeq
;
6889 HMODULE user32
= GetModuleHandleA("user32.dll");
6890 FARPROC pSetWinEventHook
= GetProcAddress(user32
, "SetWinEventHook");
6891 FARPROC pUnhookWinEvent
= GetProcAddress(user32
, "UnhookWinEvent");
6892 FARPROC pNotifyWinEvent
= GetProcAddress(user32
, "NotifyWinEvent");
6894 hwnd
= CreateWindowExA(0, "TestWindowClass", NULL
,
6895 WS_OVERLAPPEDWINDOW
,
6896 CW_USEDEFAULT
, CW_USEDEFAULT
, 300, 300, 0,
6900 /****** start of global hook test *************/
6901 hCBT_global_hook
= SetWindowsHookExA(WH_CBT
, cbt_global_hook_proc
, GetModuleHandleA(0), 0);
6902 assert(hCBT_global_hook
);
6904 hevent
= CreateEventA(NULL
, 0, 0, NULL
);
6906 hwnd2
= (HWND
)hevent
;
6908 hthread
= CreateThread(NULL
, 0, cbt_global_hook_thread_proc
, &hwnd2
, 0, &tid
);
6909 ok(hthread
!= NULL
, "CreateThread failed, error %d\n", GetLastError());
6911 ok(WaitForSingleObject(hevent
, INFINITE
) == WAIT_OBJECT_0
, "WaitForSingleObject failed\n");
6913 ok_sequence(WmGlobalHookSeq_1
, "global hook 1", FALSE
);
6916 /* this one should be received only by old hook proc */
6917 DefWindowProcA(hwnd
, WM_SYSCOMMAND
, SC_NEXTWINDOW
, 0);
6918 /* this one should be received only by old hook proc */
6919 DefWindowProcA(hwnd
, WM_SYSCOMMAND
, SC_PREVWINDOW
, 0);
6921 ok_sequence(WmGlobalHookSeq_2
, "global hook 2", FALSE
);
6923 ret
= UnhookWindowsHookEx(hCBT_global_hook
);
6924 ok( ret
, "UnhookWindowsHookEx error %d\n", GetLastError());
6926 PostThreadMessageA(tid
, WM_QUIT
, 0, 0);
6927 ok(WaitForSingleObject(hthread
, INFINITE
) == WAIT_OBJECT_0
, "WaitForSingleObject failed\n");
6928 CloseHandle(hthread
);
6929 CloseHandle(hevent
);
6930 ok(!IsWindow(hwnd2
), "window should be destroyed on thread exit\n");
6931 /****** end of global hook test *************/
6933 if (!pSetWinEventHook
|| !pNotifyWinEvent
|| !pUnhookWinEvent
)
6935 ok(DestroyWindow(hwnd
), "failed to destroy window\n");
6943 /* this test doesn't pass under Win9x */
6944 /* win2k ignores events with hwnd == 0 */
6945 SetLastError(0xdeadbeef);
6946 pNotifyWinEvent(events
[0].message
, 0, events
[0].wParam
, events
[0].lParam
);
6947 ok(GetLastError() == ERROR_INVALID_WINDOW_HANDLE
|| /* Win2k */
6948 GetLastError() == 0xdeadbeef, /* Win9x */
6949 "unexpected error %d\n", GetLastError());
6950 ok_sequence(WmEmptySeq
, "empty notify winevents", FALSE
);
6953 for (i
= 0; i
< sizeof(WmWinEventsSeq
)/sizeof(WmWinEventsSeq
[0]); i
++)
6954 pNotifyWinEvent(events
[i
].message
, hwnd
, events
[i
].wParam
, events
[i
].lParam
);
6956 ok_sequence(WmWinEventsSeq
, "notify winevents", FALSE
);
6958 /****** start of event filtering test *************/
6959 hhook
= (HWINEVENTHOOK
)pSetWinEventHook(
6960 EVENT_OBJECT_SHOW
, /* 0x8002 */
6961 EVENT_OBJECT_LOCATIONCHANGE
, /* 0x800B */
6962 GetModuleHandleA(0), win_event_global_hook_proc
,
6963 GetCurrentProcessId(), 0,
6964 WINEVENT_INCONTEXT
);
6965 ok(hhook
!= 0, "SetWinEventHook error %d\n", GetLastError());
6967 hevent
= CreateEventA(NULL
, 0, 0, NULL
);
6969 hwnd2
= (HWND
)hevent
;
6971 hthread
= CreateThread(NULL
, 0, win_event_global_thread_proc
, &hwnd2
, 0, &tid
);
6972 ok(hthread
!= NULL
, "CreateThread failed, error %d\n", GetLastError());
6974 ok(WaitForSingleObject(hevent
, INFINITE
) == WAIT_OBJECT_0
, "WaitForSingleObject failed\n");
6976 ok_sequence(WmWinEventAlertSeq
, "alert winevent", FALSE
);
6979 /* this one should be received only by old hook proc */
6980 pNotifyWinEvent(EVENT_OBJECT_CREATE
, hwnd
, OBJID_CARET
, 0); /* 0x8000 */
6981 pNotifyWinEvent(EVENT_OBJECT_SHOW
, hwnd
, OBJID_CARET
, 0); /* 0x8002 */
6982 /* this one should be received only by old hook proc */
6983 pNotifyWinEvent(EVENT_OBJECT_NAMECHANGE
, hwnd
, OBJID_CARET
, 0); /* 0x800C */
6985 ok_sequence(WmWinEventCaretSeq
, "caret winevent", FALSE
);
6987 ret
= pUnhookWinEvent(hhook
);
6988 ok( ret
, "UnhookWinEvent error %d\n", GetLastError());
6990 PostThreadMessageA(tid
, WM_QUIT
, 0, 0);
6991 ok(WaitForSingleObject(hthread
, INFINITE
) == WAIT_OBJECT_0
, "WaitForSingleObject failed\n");
6992 CloseHandle(hthread
);
6993 CloseHandle(hevent
);
6994 ok(!IsWindow(hwnd2
), "window should be destroyed on thread exit\n");
6995 /****** end of event filtering test *************/
6997 /****** start of out of context event test *************/
6998 hhook
= (HWINEVENTHOOK
)pSetWinEventHook(
6999 EVENT_MIN
, EVENT_MAX
,
7000 0, win_event_global_hook_proc
,
7001 GetCurrentProcessId(), 0,
7002 WINEVENT_OUTOFCONTEXT
);
7003 ok(hhook
!= 0, "SetWinEventHook error %d\n", GetLastError());
7005 hevent
= CreateEventA(NULL
, 0, 0, NULL
);
7007 hwnd2
= (HWND
)hevent
;
7011 hthread
= CreateThread(NULL
, 0, win_event_global_thread_proc
, &hwnd2
, 0, &tid
);
7012 ok(hthread
!= NULL
, "CreateThread failed, error %d\n", GetLastError());
7014 ok(WaitForSingleObject(hevent
, INFINITE
) == WAIT_OBJECT_0
, "WaitForSingleObject failed\n");
7016 ok_sequence(WmEmptySeq
, "empty notify winevents", FALSE
);
7017 /* process pending winevent messages */
7018 ok(!PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
), "msg queue should be empty\n");
7019 ok_sequence(WmWinEventAlertSeq_2
, "alert winevent for out of context proc", FALSE
);
7022 /* this one should be received only by old hook proc */
7023 pNotifyWinEvent(EVENT_OBJECT_CREATE
, hwnd
, OBJID_CARET
, 0); /* 0x8000 */
7024 pNotifyWinEvent(EVENT_OBJECT_SHOW
, hwnd
, OBJID_CARET
, 0); /* 0x8002 */
7025 /* this one should be received only by old hook proc */
7026 pNotifyWinEvent(EVENT_OBJECT_NAMECHANGE
, hwnd
, OBJID_CARET
, 0); /* 0x800C */
7028 ok_sequence(WmWinEventCaretSeq_2
, "caret winevent for incontext proc", FALSE
);
7029 /* process pending winevent messages */
7030 ok(!PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
), "msg queue should be empty\n");
7031 ok_sequence(WmWinEventCaretSeq_2
, "caret winevent for out of context proc", FALSE
);
7033 ret
= pUnhookWinEvent(hhook
);
7034 ok( ret
, "UnhookWinEvent error %d\n", GetLastError());
7036 PostThreadMessageA(tid
, WM_QUIT
, 0, 0);
7037 ok(WaitForSingleObject(hthread
, INFINITE
) == WAIT_OBJECT_0
, "WaitForSingleObject failed\n");
7038 CloseHandle(hthread
);
7039 CloseHandle(hevent
);
7040 ok(!IsWindow(hwnd2
), "window should be destroyed on thread exit\n");
7041 /****** end of out of context event test *************/
7043 /****** start of MOUSE_LL hook test *************/
7044 hCBT_global_hook
= SetWindowsHookExA(WH_MOUSE_LL
, cbt_global_hook_proc
, GetModuleHandleA(0), 0);
7045 /* WH_MOUSE_LL is not supported on Win9x platforms */
7046 if (!hCBT_global_hook
)
7048 trace("Skipping WH_MOUSE_LL test on this platform\n");
7049 goto skip_mouse_ll_hook_test
;
7052 hevent
= CreateEventA(NULL
, 0, 0, NULL
);
7054 hwnd2
= (HWND
)hevent
;
7056 hthread
= CreateThread(NULL
, 0, mouse_ll_global_thread_proc
, &hwnd2
, 0, &tid
);
7057 ok(hthread
!= NULL
, "CreateThread failed, error %d\n", GetLastError());
7059 while (WaitForSingleObject(hevent
, 100) == WAIT_TIMEOUT
)
7060 while (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
7062 ok_sequence(WmMouseLLHookSeq
, "MOUSE_LL hook other thread", FALSE
);
7065 mouse_event(MOUSEEVENTF_MOVE
, -1, 0, 0, 0);
7066 mouse_event(MOUSEEVENTF_LEFTUP
, 0, 0, 0, 0);
7067 mouse_event(MOUSEEVENTF_MOVE
, 1, 0, 0, 0);
7069 ok_sequence(WmMouseLLHookSeq
, "MOUSE_LL hook same thread", FALSE
);
7071 ret
= UnhookWindowsHookEx(hCBT_global_hook
);
7072 ok( ret
, "UnhookWindowsHookEx error %d\n", GetLastError());
7074 PostThreadMessageA(tid
, WM_QUIT
, 0, 0);
7075 ok(WaitForSingleObject(hthread
, INFINITE
) == WAIT_OBJECT_0
, "WaitForSingleObject failed\n");
7076 CloseHandle(hthread
);
7077 CloseHandle(hevent
);
7078 ok(!IsWindow(hwnd2
), "window should be destroyed on thread exit\n");
7079 /****** end of MOUSE_LL hook test *************/
7080 skip_mouse_ll_hook_test
:
7082 ok(DestroyWindow(hwnd
), "failed to destroy window\n");
7085 static void test_set_hook(void)
7089 HWINEVENTHOOK hwinevent_hook
;
7090 HMODULE user32
= GetModuleHandleA("user32.dll");
7091 FARPROC pSetWinEventHook
= GetProcAddress(user32
, "SetWinEventHook");
7092 FARPROC pUnhookWinEvent
= GetProcAddress(user32
, "UnhookWinEvent");
7094 hhook
= SetWindowsHookExA(WH_CBT
, cbt_hook_proc
, GetModuleHandleA(0), GetCurrentThreadId());
7095 ok(hhook
!= 0, "local hook does not require hModule set to 0\n");
7096 UnhookWindowsHookEx(hhook
);
7100 /* this test doesn't pass under Win9x: BUG! */
7101 SetLastError(0xdeadbeef);
7102 hhook
= SetWindowsHookExA(WH_CBT
, cbt_hook_proc
, 0, 0);
7103 ok(!hhook
, "global hook requires hModule != 0\n");
7104 ok(GetLastError() == ERROR_HOOK_NEEDS_HMOD
, "unexpected error %d\n", GetLastError());
7107 SetLastError(0xdeadbeef);
7108 hhook
= SetWindowsHookExA(WH_CBT
, 0, GetModuleHandleA(0), GetCurrentThreadId());
7109 ok(!hhook
, "SetWinEventHook with invalid proc should fail\n");
7110 ok(GetLastError() == ERROR_INVALID_FILTER_PROC
|| /* Win2k */
7111 GetLastError() == 0xdeadbeef, /* Win9x */
7112 "unexpected error %d\n", GetLastError());
7114 SetLastError(0xdeadbeef);
7115 ok(!UnhookWindowsHookEx((HHOOK
)0xdeadbeef), "UnhookWindowsHookEx succeeded\n");
7116 ok(GetLastError() == ERROR_INVALID_HOOK_HANDLE
|| /* Win2k */
7117 GetLastError() == 0xdeadbeef, /* Win9x */
7118 "unexpected error %d\n", GetLastError());
7120 if (!pSetWinEventHook
|| !pUnhookWinEvent
) return;
7122 /* even process local incontext hooks require hmodule */
7123 SetLastError(0xdeadbeef);
7124 hwinevent_hook
= (HWINEVENTHOOK
)pSetWinEventHook(EVENT_MIN
, EVENT_MAX
,
7125 0, win_event_proc
, GetCurrentProcessId(), 0, WINEVENT_INCONTEXT
);
7126 ok(!hwinevent_hook
, "WINEVENT_INCONTEXT requires hModule != 0\n");
7127 ok(GetLastError() == ERROR_HOOK_NEEDS_HMOD
|| /* Win2k */
7128 GetLastError() == 0xdeadbeef, /* Win9x */
7129 "unexpected error %d\n", GetLastError());
7131 /* even thread local incontext hooks require hmodule */
7132 SetLastError(0xdeadbeef);
7133 hwinevent_hook
= (HWINEVENTHOOK
)pSetWinEventHook(EVENT_MIN
, EVENT_MAX
,
7134 0, win_event_proc
, GetCurrentProcessId(), GetCurrentThreadId(), WINEVENT_INCONTEXT
);
7135 ok(!hwinevent_hook
, "WINEVENT_INCONTEXT requires hModule != 0\n");
7136 ok(GetLastError() == ERROR_HOOK_NEEDS_HMOD
|| /* Win2k */
7137 GetLastError() == 0xdeadbeef, /* Win9x */
7138 "unexpected error %d\n", GetLastError());
7142 /* these 3 tests don't pass under Win9x */
7143 SetLastError(0xdeadbeef);
7144 hwinevent_hook
= (HWINEVENTHOOK
)pSetWinEventHook(1, 0,
7145 0, win_event_proc
, GetCurrentProcessId(), 0, WINEVENT_OUTOFCONTEXT
);
7146 ok(!hwinevent_hook
, "SetWinEventHook with invalid event range should fail\n");
7147 ok(GetLastError() == ERROR_INVALID_HOOK_FILTER
, "unexpected error %d\n", GetLastError());
7149 SetLastError(0xdeadbeef);
7150 hwinevent_hook
= (HWINEVENTHOOK
)pSetWinEventHook(-1, 1,
7151 0, win_event_proc
, GetCurrentProcessId(), 0, WINEVENT_OUTOFCONTEXT
);
7152 ok(!hwinevent_hook
, "SetWinEventHook with invalid event range should fail\n");
7153 ok(GetLastError() == ERROR_INVALID_HOOK_FILTER
, "unexpected error %d\n", GetLastError());
7155 SetLastError(0xdeadbeef);
7156 hwinevent_hook
= (HWINEVENTHOOK
)pSetWinEventHook(EVENT_MIN
, EVENT_MAX
,
7157 0, win_event_proc
, 0, 0xdeadbeef, WINEVENT_OUTOFCONTEXT
);
7158 ok(!hwinevent_hook
, "SetWinEventHook with invalid tid should fail\n");
7159 ok(GetLastError() == ERROR_INVALID_THREAD_ID
, "unexpected error %d\n", GetLastError());
7162 SetLastError(0xdeadbeef);
7163 hwinevent_hook
= (HWINEVENTHOOK
)pSetWinEventHook(0, 0,
7164 0, win_event_proc
, GetCurrentProcessId(), 0, WINEVENT_OUTOFCONTEXT
);
7165 ok(hwinevent_hook
!= 0, "SetWinEventHook error %d\n", GetLastError());
7166 ok(GetLastError() == 0xdeadbeef, "unexpected error %d\n", GetLastError());
7167 ret
= pUnhookWinEvent(hwinevent_hook
);
7168 ok( ret
, "UnhookWinEvent error %d\n", GetLastError());
7171 /* This call succeeds under win2k SP4, but fails under Wine.
7172 Does win2k test/use passed process id? */
7173 SetLastError(0xdeadbeef);
7174 hwinevent_hook
= (HWINEVENTHOOK
)pSetWinEventHook(EVENT_MIN
, EVENT_MAX
,
7175 0, win_event_proc
, 0xdeadbeef, 0, WINEVENT_OUTOFCONTEXT
);
7176 ok(hwinevent_hook
!= 0, "SetWinEventHook error %d\n", GetLastError());
7177 ok(GetLastError() == 0xdeadbeef, "unexpected error %d\n", GetLastError());
7178 ret
= pUnhookWinEvent(hwinevent_hook
);
7179 ok( ret
, "UnhookWinEvent error %d\n", GetLastError());
7182 SetLastError(0xdeadbeef);
7183 ok(!pUnhookWinEvent((HWINEVENTHOOK
)0xdeadbeef), "UnhookWinEvent succeeded\n");
7184 ok(GetLastError() == ERROR_INVALID_HANDLE
|| /* Win2k */
7185 GetLastError() == 0xdeadbeef, /* Win9x */
7186 "unexpected error %d\n", GetLastError());
7189 static const struct message ScrollWindowPaint1
[] = {
7191 { WM_ERASEBKGND
, sent
|beginpaint
},
7195 static const struct message ScrollWindowPaint2
[] = {
7200 static void test_scrollwindowex(void)
7203 RECT rect
={0,0,130,130};
7206 hwnd
= CreateWindowExA(0, "TestWindowClass", "Test Scroll",
7207 WS_VISIBLE
|WS_OVERLAPPEDWINDOW
,
7208 100, 100, 200, 200, 0, 0, 0, NULL
);
7209 ok (hwnd
!= 0, "Failed to create overlapped window\n");
7210 hchild
= CreateWindowExA(0, "TestWindowClass", "Test child",
7211 WS_VISIBLE
|WS_CAPTION
|WS_CHILD
,
7212 10, 10, 150, 150, hwnd
, 0, 0, NULL
);
7213 ok (hchild
!= 0, "Failed to create child\n");
7218 /* scroll without the child window */
7219 trace("start scroll\n");
7220 ScrollWindowEx( hwnd
, 10, 10, &rect
, NULL
, NULL
, NULL
,
7221 SW_ERASE
|SW_INVALIDATE
);
7222 ok_sequence(WmEmptySeq
, "ScrollWindowEx", 0);
7223 trace("end scroll\n");
7225 while (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
7226 ok_sequence(ScrollWindowPaint1
, "ScrollWindowEx", 0);
7230 /* Now without the SW_ERASE flag */
7231 trace("start scroll\n");
7232 ScrollWindowEx( hwnd
, 10, 10, &rect
, NULL
, NULL
, NULL
, SW_INVALIDATE
);
7233 ok_sequence(WmEmptySeq
, "ScrollWindowEx", 0);
7234 trace("end scroll\n");
7236 while (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
7237 ok_sequence(ScrollWindowPaint2
, "ScrollWindowEx", 0);
7241 /* now scroll the child window as well */
7242 trace("start scroll\n");
7243 ScrollWindowEx( hwnd
, 10, 10, &rect
, NULL
, NULL
, NULL
,
7244 SW_SCROLLCHILDREN
|SW_ERASE
|SW_INVALIDATE
);
7245 todo_wine
{ /* wine sends WM_POSCHANGING, WM_POSCHANGED messages */
7246 /* windows sometimes a WM_MOVE */
7247 ok_sequence(WmEmptySeq
, "ScrollWindowEx", 0);
7249 trace("end scroll\n");
7251 while (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
7252 ok_sequence(ScrollWindowPaint1
, "ScrollWindowEx", 0);
7256 /* now scroll with ScrollWindow() */
7257 trace("start scroll with ScrollWindow\n");
7258 ScrollWindow( hwnd
, 5, 5, NULL
, NULL
);
7259 trace("end scroll\n");
7261 while (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
7262 ok_sequence(ScrollWindowPaint1
, "ScrollWindow", 0);
7264 ok(DestroyWindow(hchild
), "failed to destroy window\n");
7265 ok(DestroyWindow(hwnd
), "failed to destroy window\n");
7269 static const struct message destroy_window_with_children
[] = {
7270 { EVENT_SYSTEM_CAPTURESTART
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* popup */
7271 { HCBT_DESTROYWND
, hook
|lparam
, 0, WND_PARENT_ID
}, /* parent */
7272 { HCBT_DESTROYWND
, hook
|lparam
, 0, WND_POPUP_ID
}, /* popup */
7273 { EVENT_OBJECT_DESTROY
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* popup */
7274 { WM_DESTROY
, sent
|wparam
|lparam
, 0, WND_POPUP_ID
}, /* popup */
7275 { WM_CAPTURECHANGED
, sent
|wparam
|lparam
, 0, WND_POPUP_ID
}, /* popup */
7276 { WM_NCDESTROY
, sent
|wparam
|lparam
, 0, WND_POPUP_ID
}, /* popup */
7277 { EVENT_OBJECT_DESTROY
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* parent */
7278 { WM_DESTROY
, sent
|wparam
|lparam
, 0, WND_PARENT_ID
}, /* parent */
7279 { WM_DESTROY
, sent
|wparam
|lparam
, 0, WND_CHILD_ID
+ 2 }, /* child2 */
7280 { WM_DESTROY
, sent
|wparam
|lparam
, 0, WND_CHILD_ID
+ 1 }, /* child1 */
7281 { WM_DESTROY
, sent
|wparam
|lparam
, 0, WND_CHILD_ID
+ 3 }, /* child3 */
7282 { WM_NCDESTROY
, sent
|wparam
|lparam
, 0, WND_CHILD_ID
+ 2 }, /* child2 */
7283 { WM_NCDESTROY
, sent
|wparam
|lparam
, 0, WND_CHILD_ID
+ 3 }, /* child3 */
7284 { WM_NCDESTROY
, sent
|wparam
|lparam
, 0, WND_CHILD_ID
+ 1 }, /* child1 */
7285 { WM_NCDESTROY
, sent
|wparam
|lparam
, 0, WND_PARENT_ID
}, /* parent */
7289 static void test_DestroyWindow(void)
7292 HWND parent
, child1
, child2
, child3
, child4
, test
;
7293 UINT child_id
= WND_CHILD_ID
+ 1;
7295 parent
= CreateWindowExA(0, "TestWindowClass", NULL
, WS_OVERLAPPEDWINDOW
,
7296 100, 100, 200, 200, 0, 0, 0, NULL
);
7297 assert(parent
!= 0);
7298 child1
= CreateWindowExA(0, "TestWindowClass", NULL
, WS_CHILD
,
7299 0, 0, 50, 50, parent
, (HMENU
)child_id
++, 0, NULL
);
7300 assert(child1
!= 0);
7301 child2
= CreateWindowExA(0, "TestWindowClass", NULL
, WS_CHILD
,
7302 0, 0, 50, 50, GetDesktopWindow(), (HMENU
)child_id
++, 0, NULL
);
7303 assert(child2
!= 0);
7304 child3
= CreateWindowExA(0, "TestWindowClass", NULL
, WS_CHILD
,
7305 0, 0, 50, 50, child1
, (HMENU
)child_id
++, 0, NULL
);
7306 assert(child3
!= 0);
7307 child4
= CreateWindowExA(0, "TestWindowClass", NULL
, WS_POPUP
,
7308 0, 0, 50, 50, parent
, 0, 0, NULL
);
7309 assert(child4
!= 0);
7311 /* test owner/parent of child2 */
7312 test
= GetParent(child2
);
7313 ok(test
== GetDesktopWindow(), "wrong parent %p\n", test
);
7314 ok(!IsChild(parent
, child2
), "wrong parent/child %p/%p\n", parent
, child2
);
7316 test
= pGetAncestor(child2
, GA_PARENT
);
7317 ok(test
== GetDesktopWindow(), "wrong parent %p\n", test
);
7319 test
= GetWindow(child2
, GW_OWNER
);
7320 ok(!test
, "wrong owner %p\n", test
);
7322 test
= SetParent(child2
, parent
);
7323 ok(test
== GetDesktopWindow(), "wrong old parent %p\n", test
);
7325 /* test owner/parent of the parent */
7326 test
= GetParent(parent
);
7327 ok(!test
, "wrong parent %p\n", test
);
7329 ok(!IsChild(GetDesktopWindow(), parent
), "wrong parent/child %p/%p\n", GetDesktopWindow(), parent
);
7332 test
= pGetAncestor(parent
, GA_PARENT
);
7333 ok(test
== GetDesktopWindow(), "wrong parent %p\n", test
);
7335 test
= GetWindow(parent
, GW_OWNER
);
7336 ok(!test
, "wrong owner %p\n", test
);
7338 /* test owner/parent of child1 */
7339 test
= GetParent(child1
);
7340 ok(test
== parent
, "wrong parent %p\n", test
);
7341 ok(IsChild(parent
, child1
), "wrong parent/child %p/%p\n", parent
, child1
);
7343 test
= pGetAncestor(child1
, GA_PARENT
);
7344 ok(test
== parent
, "wrong parent %p\n", test
);
7346 test
= GetWindow(child1
, GW_OWNER
);
7347 ok(!test
, "wrong owner %p\n", test
);
7349 /* test owner/parent of child2 */
7350 test
= GetParent(child2
);
7351 ok(test
== parent
, "wrong parent %p\n", test
);
7352 ok(IsChild(parent
, child2
), "wrong parent/child %p/%p\n", parent
, child2
);
7354 test
= pGetAncestor(child2
, GA_PARENT
);
7355 ok(test
== parent
, "wrong parent %p\n", test
);
7357 test
= GetWindow(child2
, GW_OWNER
);
7358 ok(!test
, "wrong owner %p\n", test
);
7360 /* test owner/parent of child3 */
7361 test
= GetParent(child3
);
7362 ok(test
== child1
, "wrong parent %p\n", test
);
7363 ok(IsChild(parent
, child3
), "wrong parent/child %p/%p\n", parent
, child3
);
7365 test
= pGetAncestor(child3
, GA_PARENT
);
7366 ok(test
== child1
, "wrong parent %p\n", test
);
7368 test
= GetWindow(child3
, GW_OWNER
);
7369 ok(!test
, "wrong owner %p\n", test
);
7371 /* test owner/parent of child4 */
7372 test
= GetParent(child4
);
7373 ok(test
== parent
, "wrong parent %p\n", test
);
7374 ok(!IsChild(parent
, child4
), "wrong parent/child %p/%p\n", parent
, child4
);
7376 test
= pGetAncestor(child4
, GA_PARENT
);
7377 ok(test
== GetDesktopWindow(), "wrong parent %p\n", test
);
7379 test
= GetWindow(child4
, GW_OWNER
);
7380 ok(test
== parent
, "wrong owner %p\n", test
);
7384 trace("parent %p, child1 %p, child2 %p, child3 %p, child4 %p\n",
7385 parent
, child1
, child2
, child3
, child4
);
7388 test
= GetCapture();
7389 ok(test
== child4
, "wrong capture window %p\n", test
);
7391 test_DestroyWindow_flag
= TRUE
;
7392 ret
= DestroyWindow(parent
);
7393 ok( ret
, "DestroyWindow() error %d\n", GetLastError());
7394 test_DestroyWindow_flag
= FALSE
;
7395 ok_sequence(destroy_window_with_children
, "destroy window with children", 0);
7397 ok(!IsWindow(parent
), "parent still exists\n");
7398 ok(!IsWindow(child1
), "child1 still exists\n");
7399 ok(!IsWindow(child2
), "child2 still exists\n");
7400 ok(!IsWindow(child3
), "child3 still exists\n");
7401 ok(!IsWindow(child4
), "child4 still exists\n");
7403 test
= GetCapture();
7404 ok(!test
, "wrong capture window %p\n", test
);
7408 static const struct message WmDispatchPaint
[] = {
7409 { WM_NCPAINT
, sent
},
7410 { WM_GETTEXT
, sent
|defwinproc
|optional
},
7411 { WM_GETTEXT
, sent
|defwinproc
|optional
},
7412 { WM_ERASEBKGND
, sent
},
7416 static LRESULT WINAPI
DispatchMessageCheckProc(HWND hwnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
7418 if (message
== WM_PAINT
) return 0;
7419 return MsgCheckProcA( hwnd
, message
, wParam
, lParam
);
7422 static void test_DispatchMessage(void)
7427 HWND hwnd
= CreateWindowA( "TestWindowClass", NULL
, WS_OVERLAPPEDWINDOW
,
7428 100, 100, 200, 200, 0, 0, 0, NULL
);
7429 ShowWindow( hwnd
, SW_SHOW
);
7430 UpdateWindow( hwnd
);
7431 while (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
7433 SetWindowLongPtrA( hwnd
, GWLP_WNDPROC
, (LONG_PTR
)DispatchMessageCheckProc
);
7435 SetRect( &rect
, -5, -5, 5, 5 );
7436 RedrawWindow( hwnd
, &rect
, 0, RDW_INVALIDATE
|RDW_ERASE
|RDW_FRAME
);
7438 while (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
))
7440 if (msg
.message
!= WM_PAINT
) DispatchMessage( &msg
);
7444 DispatchMessage( &msg
);
7445 /* DispatchMessage will send WM_NCPAINT if non client area is still invalid after WM_PAINT */
7446 if (!count
) ok_sequence( WmDispatchPaint
, "WmDispatchPaint", FALSE
);
7447 else ok_sequence( WmEmptySeq
, "WmEmpty", FALSE
);
7448 if (++count
> 10) break;
7451 ok( msg
.message
== WM_PAINT
&& count
> 10, "WM_PAINT messages stopped\n" );
7453 trace("now without DispatchMessage\n");
7455 RedrawWindow( hwnd
, &rect
, 0, RDW_INVALIDATE
|RDW_ERASE
|RDW_FRAME
);
7457 while (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
))
7459 if (msg
.message
!= WM_PAINT
) DispatchMessage( &msg
);
7462 HRGN hrgn
= CreateRectRgn( 0, 0, 0, 0 );
7464 /* this will send WM_NCCPAINT just like DispatchMessage does */
7465 GetUpdateRgn( hwnd
, hrgn
, TRUE
);
7466 ok_sequence( WmDispatchPaint
, "WmDispatchPaint", FALSE
);
7467 DeleteObject( hrgn
);
7468 GetClientRect( hwnd
, &rect
);
7469 ValidateRect( hwnd
, &rect
); /* this will stop WM_PAINTs */
7470 ok( !count
, "Got multiple WM_PAINTs\n" );
7471 if (++count
> 10) break;
7474 DestroyWindow(hwnd
);
7478 static const struct message WmUser
[] = {
7490 static DWORD CALLBACK
send_msg_thread( LPVOID arg
)
7492 struct sendmsg_info
*info
= arg
;
7493 info
->ret
= SendMessageTimeoutA( info
->hwnd
, WM_USER
, 0, 0, 0, info
->timeout
, NULL
);
7494 if (!info
->ret
) ok( GetLastError() == ERROR_TIMEOUT
, "unexpected error %d\n", GetLastError());
7498 static void wait_for_thread( HANDLE thread
)
7500 while (MsgWaitForMultipleObjects(1, &thread
, FALSE
, INFINITE
, QS_SENDMESSAGE
) != WAIT_OBJECT_0
)
7503 while (PeekMessageA( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage(&msg
);
7507 static LRESULT WINAPI
send_msg_delay_proc(HWND hwnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
7509 if (message
== WM_USER
) Sleep(200);
7510 return MsgCheckProcA( hwnd
, message
, wParam
, lParam
);
7513 static void test_SendMessageTimeout(void)
7517 struct sendmsg_info info
;
7520 info
.hwnd
= CreateWindowA( "TestWindowClass", NULL
, WS_OVERLAPPEDWINDOW
,
7521 100, 100, 200, 200, 0, 0, 0, NULL
);
7522 while (PeekMessageA( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
7525 info
.timeout
= 1000;
7526 info
.ret
= 0xdeadbeef;
7527 thread
= CreateThread( NULL
, 0, send_msg_thread
, &info
, 0, &tid
);
7528 wait_for_thread( thread
);
7529 CloseHandle( thread
);
7530 ok( info
.ret
== 1, "SendMessageTimeout failed\n" );
7531 ok_sequence( WmUser
, "WmUser", FALSE
);
7534 info
.ret
= 0xdeadbeef;
7535 thread
= CreateThread( NULL
, 0, send_msg_thread
, &info
, 0, &tid
);
7536 Sleep(100); /* SendMessageTimeout should timeout here */
7537 wait_for_thread( thread
);
7538 CloseHandle( thread
);
7539 ok( info
.ret
== 0, "SendMessageTimeout succeeded\n" );
7540 ok_sequence( WmEmptySeq
, "WmEmptySeq", FALSE
);
7542 /* 0 means infinite timeout */
7544 info
.ret
= 0xdeadbeef;
7545 thread
= CreateThread( NULL
, 0, send_msg_thread
, &info
, 0, &tid
);
7547 wait_for_thread( thread
);
7548 CloseHandle( thread
);
7549 ok( info
.ret
== 1, "SendMessageTimeout failed\n" );
7550 ok_sequence( WmUser
, "WmUser", FALSE
);
7552 /* timeout is treated as signed despite the prototype */
7553 info
.timeout
= 0x7fffffff;
7554 info
.ret
= 0xdeadbeef;
7555 thread
= CreateThread( NULL
, 0, send_msg_thread
, &info
, 0, &tid
);
7557 wait_for_thread( thread
);
7558 CloseHandle( thread
);
7559 ok( info
.ret
== 1, "SendMessageTimeout failed\n" );
7560 ok_sequence( WmUser
, "WmUser", FALSE
);
7562 info
.timeout
= 0x80000000;
7563 info
.ret
= 0xdeadbeef;
7564 thread
= CreateThread( NULL
, 0, send_msg_thread
, &info
, 0, &tid
);
7566 wait_for_thread( thread
);
7567 CloseHandle( thread
);
7568 ok( info
.ret
== 0, "SendMessageTimeout succeeded\n" );
7569 ok_sequence( WmEmptySeq
, "WmEmptySeq", FALSE
);
7571 /* now check for timeout during message processing */
7572 SetWindowLongPtrA( info
.hwnd
, GWLP_WNDPROC
, (LONG_PTR
)send_msg_delay_proc
);
7574 info
.ret
= 0xdeadbeef;
7575 thread
= CreateThread( NULL
, 0, send_msg_thread
, &info
, 0, &tid
);
7576 wait_for_thread( thread
);
7577 CloseHandle( thread
);
7578 /* we should timeout but still get the message */
7579 ok( info
.ret
== 0, "SendMessageTimeout failed\n" );
7580 ok_sequence( WmUser
, "WmUser", FALSE
);
7582 DestroyWindow( info
.hwnd
);
7586 /****************** edit message test *************************/
7587 #define ID_EDIT 0x1234
7588 static const struct message sl_edit_setfocus
[] =
7590 { HCBT_SETFOCUS
, hook
},
7591 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 1 },
7592 { WM_IME_NOTIFY
, sent
|wparam
|defwinproc
|optional
, 2 },
7593 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
7594 { WM_SETFOCUS
, sent
|wparam
, 0 },
7595 { WM_CTLCOLOREDIT
, sent
|parent
},
7596 { EVENT_OBJECT_CREATE
, winevent_hook
|wparam
|lparam
, OBJID_CARET
, 0 },
7597 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, OBJID_CARET
, 0 },
7598 { WM_COMMAND
, sent
|parent
|wparam
, MAKEWPARAM(ID_EDIT
, EN_SETFOCUS
) },
7601 static const struct message ml_edit_setfocus
[] =
7603 { HCBT_SETFOCUS
, hook
},
7604 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 1 },
7605 { WM_IME_NOTIFY
, sent
|wparam
|defwinproc
|optional
, 2 },
7606 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
7607 { WM_SETFOCUS
, sent
|wparam
, 0 },
7608 { EVENT_OBJECT_CREATE
, winevent_hook
|wparam
|lparam
, OBJID_CARET
, 0 },
7609 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, OBJID_CARET
, 0 },
7610 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, OBJID_CARET
, 0 },
7611 { WM_COMMAND
, sent
|parent
|wparam
, MAKEWPARAM(ID_EDIT
, EN_SETFOCUS
) },
7614 static const struct message sl_edit_killfocus
[] =
7616 { HCBT_SETFOCUS
, hook
},
7617 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
7618 { WM_KILLFOCUS
, sent
|wparam
, 0 },
7619 { EVENT_OBJECT_HIDE
, winevent_hook
|wparam
|lparam
, OBJID_CARET
, 0 },
7620 { EVENT_OBJECT_DESTROY
, winevent_hook
|wparam
|lparam
, OBJID_CARET
, 0 },
7621 { WM_COMMAND
, sent
|parent
|wparam
, MAKEWPARAM(ID_EDIT
, EN_KILLFOCUS
) },
7622 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 0 },
7623 { WM_IME_NOTIFY
, sent
|wparam
|defwinproc
|optional
, 1 },
7626 static const struct message sl_edit_lbutton_dblclk
[] =
7628 { WM_LBUTTONDBLCLK
, sent
},
7629 { EVENT_SYSTEM_CAPTURESTART
, winevent_hook
|wparam
|lparam
, 0, 0 },
7632 static const struct message sl_edit_lbutton_down
[] =
7634 { WM_LBUTTONDOWN
, sent
|wparam
|lparam
, 0, 0 },
7635 { HCBT_SETFOCUS
, hook
},
7636 { WM_IME_SETCONTEXT
, sent
|wparam
|defwinproc
|optional
, 1 },
7637 { WM_IME_NOTIFY
, sent
|wparam
|defwinproc
|optional
, 2 },
7638 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
7639 { WM_SETFOCUS
, sent
|wparam
|defwinproc
, 0 },
7640 { WM_CTLCOLOREDIT
, sent
|parent
},
7641 { EVENT_OBJECT_CREATE
, winevent_hook
|wparam
|lparam
, OBJID_CARET
, 0 },
7642 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, OBJID_CARET
, 0 },
7643 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, OBJID_CARET
, 0 },
7644 { WM_COMMAND
, sent
|parent
|wparam
, MAKEWPARAM(ID_EDIT
, EN_SETFOCUS
) },
7645 { EVENT_SYSTEM_CAPTURESTART
, winevent_hook
|wparam
|lparam
, 0, 0 },
7646 { EVENT_OBJECT_HIDE
, winevent_hook
|wparam
|lparam
, OBJID_CARET
, 0 },
7647 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, OBJID_CARET
, 0 },
7648 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, OBJID_CARET
, 0 },
7651 static const struct message ml_edit_lbutton_down
[] =
7653 { WM_LBUTTONDOWN
, sent
|wparam
|lparam
, 0, 0 },
7654 { EVENT_SYSTEM_CAPTURESTART
, winevent_hook
|wparam
|lparam
, 0, 0 },
7655 { HCBT_SETFOCUS
, hook
},
7656 { WM_IME_SETCONTEXT
, sent
|wparam
|defwinproc
|optional
, 1 },
7657 { WM_IME_NOTIFY
, sent
|wparam
|defwinproc
|optional
, 2 },
7658 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
7659 { WM_SETFOCUS
, sent
|wparam
|defwinproc
, 0 },
7660 { EVENT_OBJECT_CREATE
, winevent_hook
|wparam
|lparam
, OBJID_CARET
, 0 },
7661 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, OBJID_CARET
, 0 },
7662 { WM_COMMAND
, sent
|parent
|wparam
, MAKEWPARAM(ID_EDIT
, EN_SETFOCUS
) },
7665 static const struct message sl_edit_lbutton_up
[] =
7667 { WM_LBUTTONUP
, sent
|wparam
|lparam
, 0, 0 },
7668 { EVENT_OBJECT_HIDE
, winevent_hook
|wparam
|lparam
, OBJID_CARET
, 0 },
7669 { EVENT_SYSTEM_CAPTUREEND
, winevent_hook
|wparam
|lparam
, 0, 0 },
7670 { WM_CAPTURECHANGED
, sent
|defwinproc
},
7671 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, OBJID_CARET
, 0 },
7674 static const struct message ml_edit_lbutton_up
[] =
7676 { WM_LBUTTONUP
, sent
|wparam
|lparam
, 0, 0 },
7677 { EVENT_SYSTEM_CAPTUREEND
, winevent_hook
|wparam
|lparam
, 0, 0 },
7678 { WM_CAPTURECHANGED
, sent
|defwinproc
},
7682 static WNDPROC old_edit_proc
;
7684 static LRESULT CALLBACK
edit_hook_proc(HWND hwnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
7686 static long defwndproc_counter
= 0;
7690 trace("edit: %p, %04x, %08x, %08lx\n", hwnd
, message
, wParam
, lParam
);
7692 /* explicitly ignore WM_GETICON message */
7693 if (message
== WM_GETICON
) return 0;
7695 msg
.message
= message
;
7696 msg
.flags
= sent
|wparam
|lparam
;
7697 if (defwndproc_counter
) msg
.flags
|= defwinproc
;
7698 msg
.wParam
= wParam
;
7699 msg
.lParam
= lParam
;
7702 defwndproc_counter
++;
7703 ret
= CallWindowProcA(old_edit_proc
, hwnd
, message
, wParam
, lParam
);
7704 defwndproc_counter
--;
7709 static void subclass_edit(void)
7713 if (!GetClassInfoA(0, "edit", &cls
)) assert(0);
7715 old_edit_proc
= cls
.lpfnWndProc
;
7717 cls
.hInstance
= GetModuleHandle(0);
7718 cls
.lpfnWndProc
= edit_hook_proc
;
7719 cls
.lpszClassName
= "my_edit_class";
7720 UnregisterClass(cls
.lpszClassName
, cls
.hInstance
);
7721 if (!RegisterClassA(&cls
)) assert(0);
7724 static void test_edit_messages(void)
7730 log_all_parent_messages
++;
7732 parent
= CreateWindowExA(0, "TestParentClass", "Test parent", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
7733 100, 100, 200, 200, 0, 0, 0, NULL
);
7734 ok (parent
!= 0, "Failed to create parent window\n");
7736 /* test single line edit */
7737 hwnd
= CreateWindowExA(0, "my_edit_class", "test", WS_CHILD
,
7738 0, 0, 80, 20, parent
, (HMENU
)ID_EDIT
, 0, NULL
);
7739 ok(hwnd
!= 0, "Failed to create edit window\n");
7741 dlg_code
= SendMessageA(hwnd
, WM_GETDLGCODE
, 0, 0);
7742 ok(dlg_code
== (DLGC_WANTCHARS
|DLGC_HASSETSEL
|DLGC_WANTARROWS
), "wrong dlg_code %08x\n", dlg_code
);
7744 ShowWindow(hwnd
, SW_SHOW
);
7750 ok_sequence(sl_edit_setfocus
, "SetFocus(hwnd) on an edit", FALSE
);
7753 ok_sequence(sl_edit_killfocus
, "SetFocus(0) on an edit", FALSE
);
7759 SendMessageA(hwnd
, WM_LBUTTONDBLCLK
, 0, 0);
7760 ok_sequence(sl_edit_lbutton_dblclk
, "WM_LBUTTONDBLCLK on an edit", FALSE
);
7766 SendMessageA(hwnd
, WM_LBUTTONDOWN
, 0, 0);
7767 ok_sequence(sl_edit_lbutton_down
, "WM_LBUTTONDOWN on an edit", FALSE
);
7769 SendMessageA(hwnd
, WM_LBUTTONUP
, 0, 0);
7770 ok_sequence(sl_edit_lbutton_up
, "WM_LBUTTONUP on an edit", FALSE
);
7772 DestroyWindow(hwnd
);
7774 /* test multiline edit */
7775 hwnd
= CreateWindowExA(0, "my_edit_class", "test", WS_CHILD
| ES_MULTILINE
,
7776 0, 0, 80, 20, parent
, (HMENU
)ID_EDIT
, 0, NULL
);
7777 ok(hwnd
!= 0, "Failed to create edit window\n");
7779 dlg_code
= SendMessageA(hwnd
, WM_GETDLGCODE
, 0, 0);
7780 ok(dlg_code
== (DLGC_WANTCHARS
|DLGC_HASSETSEL
|DLGC_WANTARROWS
|DLGC_WANTALLKEYS
),
7781 "wrong dlg_code %08x\n", dlg_code
);
7783 ShowWindow(hwnd
, SW_SHOW
);
7789 ok_sequence(ml_edit_setfocus
, "SetFocus(hwnd) on multiline edit", FALSE
);
7792 ok_sequence(sl_edit_killfocus
, "SetFocus(0) on multiline edit", FALSE
);
7798 SendMessageA(hwnd
, WM_LBUTTONDBLCLK
, 0, 0);
7799 ok_sequence(sl_edit_lbutton_dblclk
, "WM_LBUTTONDBLCLK on multiline edit", FALSE
);
7805 SendMessageA(hwnd
, WM_LBUTTONDOWN
, 0, 0);
7806 ok_sequence(ml_edit_lbutton_down
, "WM_LBUTTONDOWN on multiline edit", FALSE
);
7808 SendMessageA(hwnd
, WM_LBUTTONUP
, 0, 0);
7809 ok_sequence(ml_edit_lbutton_up
, "WM_LBUTTONUP on multiline edit", FALSE
);
7811 DestroyWindow(hwnd
);
7812 DestroyWindow(parent
);
7814 log_all_parent_messages
--;
7817 /**************************** End of Edit test ******************************/
7819 static const struct message WmKeyDownSkippedSeq
[] =
7821 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, 'N', 1 }, /* XP */
7824 static const struct message WmKeyUpSkippedSeq
[] =
7826 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, 'N', 0xc0000001 }, /* XP */
7830 #define EV_START_STOP 0
7831 #define EV_SENDMSG 1
7837 HANDLE hevent
[3]; /* 0 - start/stop, 1 - SendMessage, 2 - ack */
7840 static DWORD CALLBACK
send_msg_thread_2(void *param
)
7843 struct peekmsg_info
*info
= param
;
7845 trace("thread: waiting for start\n");
7846 WaitForSingleObject(info
->hevent
[EV_START_STOP
], INFINITE
);
7847 trace("thread: looping\n");
7851 ret
= WaitForMultipleObjects(2, info
->hevent
, FALSE
, INFINITE
);
7855 case WAIT_OBJECT_0
+ EV_START_STOP
:
7856 trace("thread: exiting\n");
7859 case WAIT_OBJECT_0
+ EV_SENDMSG
:
7860 trace("thread: sending message\n");
7861 SendNotifyMessageA(info
->hwnd
, WM_USER
, 0, 0);
7862 SetEvent(info
->hevent
[EV_ACK
]);
7866 trace("unexpected return: %04x\n", ret
);
7874 static void test_PeekMessage(void)
7879 UINT qs_all_input
= QS_ALLINPUT
;
7880 UINT qs_input
= QS_INPUT
;
7882 struct peekmsg_info info
;
7884 info
.hwnd
= CreateWindowA("TestWindowClass", NULL
, WS_OVERLAPPEDWINDOW
,
7885 100, 100, 200, 200, 0, 0, 0, NULL
);
7887 ShowWindow(info
.hwnd
, SW_SHOW
);
7888 UpdateWindow(info
.hwnd
);
7889 SetFocus(info
.hwnd
);
7891 info
.hevent
[EV_START_STOP
] = CreateEventA(NULL
, 0, 0, NULL
);
7892 info
.hevent
[EV_SENDMSG
] = CreateEventA(NULL
, 0, 0, NULL
);
7893 info
.hevent
[EV_ACK
] = CreateEventA(NULL
, 0, 0, NULL
);
7895 hthread
= CreateThread(NULL
, 0, send_msg_thread_2
, &info
, 0, &tid
);
7898 trace("signalling to start looping\n");
7899 SetEvent(info
.hevent
[EV_START_STOP
]);
7901 while (PeekMessageA(&msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessageA(&msg
);
7904 SetLastError(0xdeadbeef);
7905 qstatus
= GetQueueStatus(qs_all_input
);
7906 if (GetLastError() == ERROR_INVALID_FLAGS
)
7908 trace("QS_RAWINPUT not supported on this platform\n");
7909 qs_all_input
&= ~QS_RAWINPUT
;
7910 qs_input
&= ~QS_RAWINPUT
;
7912 ok(qstatus
== 0, "wrong qstatus %08x\n", qstatus
);
7914 trace("signalling to send message\n");
7915 SetEvent(info
.hevent
[EV_SENDMSG
]);
7916 WaitForSingleObject(info
.hevent
[EV_ACK
], INFINITE
);
7918 /* pass invalid QS_xxxx flags */
7919 SetLastError(0xdeadbeef);
7920 qstatus
= GetQueueStatus(0xffffffff);
7921 ok(qstatus
== 0, "GetQueueStatus should fail: %08x\n", qstatus
);
7922 ok(GetLastError() == ERROR_INVALID_FLAGS
, "wrong error %d\n", GetLastError());
7924 qstatus
= GetQueueStatus(qs_all_input
);
7925 ok(qstatus
== MAKELONG(QS_SENDMESSAGE
, QS_SENDMESSAGE
),
7926 "wrong qstatus %08x\n", qstatus
);
7929 ret
= PeekMessageA(&msg
, 0, 0, 0, PM_REMOVE
);
7931 "PeekMessageA should have returned FALSE instead of msg %04x\n",
7933 ok_sequence(WmUser
, "WmUser", FALSE
);
7935 qstatus
= GetQueueStatus(qs_all_input
);
7936 ok(qstatus
== 0, "wrong qstatus %08x\n", qstatus
);
7938 keybd_event('N', 0, 0, 0);
7939 keybd_event('N', 0, KEYEVENTF_KEYUP
, 0);
7940 qstatus
= GetQueueStatus(qs_all_input
);
7941 ok(qstatus
== MAKELONG(QS_KEY
, QS_KEY
),
7942 "wrong qstatus %08x\n", qstatus
);
7944 PostMessageA(info
.hwnd
, WM_CHAR
, 'z', 0);
7945 qstatus
= GetQueueStatus(qs_all_input
);
7946 ok(qstatus
== MAKELONG(QS_POSTMESSAGE
, QS_POSTMESSAGE
|QS_KEY
),
7947 "wrong qstatus %08x\n", qstatus
);
7949 InvalidateRect(info
.hwnd
, NULL
, FALSE
);
7950 qstatus
= GetQueueStatus(qs_all_input
);
7951 ok(qstatus
== MAKELONG(QS_PAINT
, QS_PAINT
|QS_POSTMESSAGE
|QS_KEY
),
7952 "wrong qstatus %08x\n", qstatus
);
7954 trace("signalling to send message\n");
7955 SetEvent(info
.hevent
[EV_SENDMSG
]);
7956 WaitForSingleObject(info
.hevent
[EV_ACK
], INFINITE
);
7958 qstatus
= GetQueueStatus(qs_all_input
);
7959 ok(qstatus
== MAKELONG(QS_SENDMESSAGE
, QS_SENDMESSAGE
|QS_PAINT
|QS_POSTMESSAGE
|QS_KEY
),
7960 "wrong qstatus %08x\n", qstatus
);
7963 ret
= PeekMessageA(&msg
, 0, 0, 0, PM_REMOVE
| (qs_input
<< 16));
7965 "PeekMessageA should have returned FALSE instead of msg %04x\n",
7967 ok_sequence(WmUser
, "WmUser", FALSE
);
7969 qstatus
= GetQueueStatus(qs_all_input
);
7970 ok(qstatus
== MAKELONG(0, QS_PAINT
|QS_POSTMESSAGE
|QS_KEY
),
7971 "wrong qstatus %08x\n", qstatus
);
7973 trace("signalling to send message\n");
7974 SetEvent(info
.hevent
[EV_SENDMSG
]);
7975 WaitForSingleObject(info
.hevent
[EV_ACK
], INFINITE
);
7977 qstatus
= GetQueueStatus(qs_all_input
);
7978 ok(qstatus
== MAKELONG(QS_SENDMESSAGE
, QS_SENDMESSAGE
|QS_PAINT
|QS_POSTMESSAGE
|QS_KEY
),
7979 "wrong qstatus %08x\n", qstatus
);
7982 ret
= PeekMessageA(&msg
, 0, 0, 0, PM_REMOVE
| PM_QS_POSTMESSAGE
);
7984 "PeekMessageA should have returned FALSE instead of msg %04x\n",
7986 ok_sequence(WmUser
, "WmUser", FALSE
);
7988 qstatus
= GetQueueStatus(qs_all_input
);
7989 ok(qstatus
== MAKELONG(0, QS_PAINT
|QS_POSTMESSAGE
|QS_KEY
),
7990 "wrong qstatus %08x\n", qstatus
);
7993 ret
= PeekMessageA(&msg
, 0, 0, 0, PM_REMOVE
| PM_QS_POSTMESSAGE
);
7994 ok(ret
&& msg
.message
== WM_CHAR
&& msg
.wParam
== 'z',
7995 "got %d and %04x wParam %08x instead of TRUE and WM_CHAR wParam 'z'\n",
7996 ret
, msg
.message
, msg
.wParam
);
7997 ok_sequence(WmEmptySeq
, "WmEmptySeq", FALSE
);
7999 qstatus
= GetQueueStatus(qs_all_input
);
8000 ok(qstatus
== MAKELONG(0, QS_PAINT
|QS_KEY
),
8001 "wrong qstatus %08x\n", qstatus
);
8004 ret
= PeekMessageA(&msg
, 0, 0, 0, PM_REMOVE
| PM_QS_POSTMESSAGE
);
8006 "PeekMessageA should have returned FALSE instead of msg %04x\n",
8008 ok_sequence(WmEmptySeq
, "WmEmptySeq", FALSE
);
8010 qstatus
= GetQueueStatus(qs_all_input
);
8011 ok(qstatus
== MAKELONG(0, QS_PAINT
|QS_KEY
),
8012 "wrong qstatus %08x\n", qstatus
);
8015 ret
= PeekMessageA(&msg
, 0, 0, 0, PM_REMOVE
| PM_QS_PAINT
);
8016 ok(ret
&& msg
.message
== WM_PAINT
,
8017 "got %d and %04x instead of TRUE and WM_PAINT\n", ret
, msg
.message
);
8018 DispatchMessageA(&msg
);
8019 ok_sequence(WmPaint
, "WmPaint", FALSE
);
8021 qstatus
= GetQueueStatus(qs_all_input
);
8022 ok(qstatus
== MAKELONG(0, QS_KEY
),
8023 "wrong qstatus %08x\n", qstatus
);
8026 ret
= PeekMessageA(&msg
, 0, 0, 0, PM_REMOVE
| PM_QS_PAINT
);
8028 "PeekMessageA should have returned FALSE instead of msg %04x\n",
8030 ok_sequence(WmEmptySeq
, "WmEmptySeq", FALSE
);
8032 qstatus
= GetQueueStatus(qs_all_input
);
8033 ok(qstatus
== MAKELONG(0, QS_KEY
),
8034 "wrong qstatus %08x\n", qstatus
);
8036 trace("signalling to send message\n");
8037 SetEvent(info
.hevent
[EV_SENDMSG
]);
8038 WaitForSingleObject(info
.hevent
[EV_ACK
], INFINITE
);
8040 qstatus
= GetQueueStatus(qs_all_input
);
8041 ok(qstatus
== MAKELONG(QS_SENDMESSAGE
, QS_SENDMESSAGE
|QS_KEY
),
8042 "wrong qstatus %08x\n", qstatus
);
8044 PostMessageA(info
.hwnd
, WM_CHAR
, 'z', 0);
8046 qstatus
= GetQueueStatus(qs_all_input
);
8047 ok(qstatus
== MAKELONG(QS_POSTMESSAGE
, QS_SENDMESSAGE
|QS_POSTMESSAGE
|QS_KEY
),
8048 "wrong qstatus %08x\n", qstatus
);
8051 ret
= PeekMessageA(&msg
, 0, WM_CHAR
, WM_CHAR
, PM_REMOVE
);
8052 ok(ret
&& msg
.message
== WM_CHAR
&& msg
.wParam
== 'z',
8053 "got %d and %04x wParam %08x instead of TRUE and WM_CHAR wParam 'z'\n",
8054 ret
, msg
.message
, msg
.wParam
);
8055 ok_sequence(WmUser
, "WmUser", FALSE
);
8057 qstatus
= GetQueueStatus(qs_all_input
);
8058 ok(qstatus
== MAKELONG(0, QS_KEY
),
8059 "wrong qstatus %08x\n", qstatus
);
8062 ret
= PeekMessageA(&msg
, 0, WM_CHAR
, WM_CHAR
, PM_REMOVE
);
8064 "PeekMessageA should have returned FALSE instead of msg %04x\n",
8066 ok_sequence(WmEmptySeq
, "WmEmptySeq", FALSE
);
8068 qstatus
= GetQueueStatus(qs_all_input
);
8069 ok(qstatus
== MAKELONG(0, QS_KEY
),
8070 "wrong qstatus %08x\n", qstatus
);
8072 PostMessageA(info
.hwnd
, WM_CHAR
, 'z', 0);
8074 qstatus
= GetQueueStatus(qs_all_input
);
8075 ok(qstatus
== MAKELONG(QS_POSTMESSAGE
, QS_POSTMESSAGE
|QS_KEY
),
8076 "wrong qstatus %08x\n", qstatus
);
8078 trace("signalling to send message\n");
8079 SetEvent(info
.hevent
[EV_SENDMSG
]);
8080 WaitForSingleObject(info
.hevent
[EV_ACK
], INFINITE
);
8082 qstatus
= GetQueueStatus(qs_all_input
);
8083 ok(qstatus
== MAKELONG(QS_SENDMESSAGE
, QS_SENDMESSAGE
|QS_POSTMESSAGE
|QS_KEY
),
8084 "wrong qstatus %08x\n", qstatus
);
8087 ret
= PeekMessageA(&msg
, 0, 0, 0, PM_REMOVE
| (QS_KEY
<< 16));
8089 "PeekMessageA should have returned FALSE instead of msg %04x\n",
8091 ok_sequence(WmUser
, "WmUser", FALSE
);
8093 qstatus
= GetQueueStatus(qs_all_input
);
8094 ok(qstatus
== MAKELONG(0, QS_POSTMESSAGE
|QS_KEY
),
8095 "wrong qstatus %08x\n", qstatus
);
8098 if (qs_all_input
& QS_RAWINPUT
) /* use QS_RAWINPUT only if supported */
8099 ret
= PeekMessageA(&msg
, 0, 0, 0, PM_REMOVE
| (QS_RAWINPUT
<< 16));
8100 else /* workaround for a missing QS_RAWINPUT support */
8101 ret
= PeekMessageA(&msg
, 0, WM_KEYDOWN
, WM_KEYDOWN
, PM_REMOVE
);
8102 ok(ret
&& msg
.message
== WM_KEYDOWN
&& msg
.wParam
== 'N',
8103 "got %d and %04x wParam %08x instead of TRUE and WM_KEYDOWN wParam 'N'\n",
8104 ret
, msg
.message
, msg
.wParam
);
8105 ok_sequence(WmKeyDownSkippedSeq
, "WmKeyDownSkippedSeq", FALSE
);
8107 qstatus
= GetQueueStatus(qs_all_input
);
8108 ok(qstatus
== MAKELONG(0, QS_POSTMESSAGE
|QS_KEY
),
8109 "wrong qstatus %08x\n", qstatus
);
8112 if (qs_all_input
& QS_RAWINPUT
) /* use QS_RAWINPUT only if supported */
8113 ret
= PeekMessageA(&msg
, 0, 0, 0, PM_REMOVE
| (QS_RAWINPUT
<< 16));
8114 else /* workaround for a missing QS_RAWINPUT support */
8115 ret
= PeekMessageA(&msg
, 0, WM_KEYUP
, WM_KEYUP
, PM_REMOVE
);
8116 ok(ret
&& msg
.message
== WM_KEYUP
&& msg
.wParam
== 'N',
8117 "got %d and %04x wParam %08x instead of TRUE and WM_KEYUP wParam 'N'\n",
8118 ret
, msg
.message
, msg
.wParam
);
8119 ok_sequence(WmKeyUpSkippedSeq
, "WmKeyUpSkippedSeq", FALSE
);
8121 qstatus
= GetQueueStatus(qs_all_input
);
8122 ok(qstatus
== MAKELONG(0, QS_POSTMESSAGE
),
8123 "wrong qstatus %08x\n", qstatus
);
8126 ret
= PeekMessageA(&msg
, 0, 0, 0, PM_REMOVE
| PM_QS_SENDMESSAGE
);
8128 "PeekMessageA should have returned FALSE instead of msg %04x\n",
8130 ok_sequence(WmEmptySeq
, "WmEmptySeq", FALSE
);
8132 qstatus
= GetQueueStatus(qs_all_input
);
8133 ok(qstatus
== MAKELONG(0, QS_POSTMESSAGE
),
8134 "wrong qstatus %08x\n", qstatus
);
8137 ret
= PeekMessageA(&msg
, 0, 0, 0, PM_REMOVE
);
8138 ok(ret
&& msg
.message
== WM_CHAR
&& msg
.wParam
== 'z',
8139 "got %d and %04x wParam %08x instead of TRUE and WM_CHAR wParam 'z'\n",
8140 ret
, msg
.message
, msg
.wParam
);
8141 ok_sequence(WmEmptySeq
, "WmEmptySeq", FALSE
);
8143 qstatus
= GetQueueStatus(qs_all_input
);
8145 "wrong qstatus %08x\n", qstatus
);
8148 ret
= PeekMessageA(&msg
, 0, 0, 0, PM_REMOVE
);
8150 "PeekMessageA should have returned FALSE instead of msg %04x\n",
8152 ok_sequence(WmEmptySeq
, "WmEmptySeq", FALSE
);
8154 qstatus
= GetQueueStatus(qs_all_input
);
8156 "wrong qstatus %08x\n", qstatus
);
8158 /* test whether presence of the quit flag in the queue affects
8161 PostQuitMessage(0x1234abcd);
8163 qstatus
= GetQueueStatus(qs_all_input
);
8164 ok(qstatus
== MAKELONG(QS_POSTMESSAGE
, QS_POSTMESSAGE
),
8165 "wrong qstatus %08x\n", qstatus
);
8167 PostMessageA(info
.hwnd
, WM_USER
, 0, 0);
8169 qstatus
= GetQueueStatus(qs_all_input
);
8170 ok(qstatus
== MAKELONG(QS_POSTMESSAGE
, QS_POSTMESSAGE
),
8171 "wrong qstatus %08x\n", qstatus
);
8174 ret
= PeekMessageA(&msg
, 0, 0, 0, PM_REMOVE
);
8175 ok(ret
&& msg
.message
== WM_USER
,
8176 "got %d and %04x instead of TRUE and WM_USER\n", ret
, msg
.message
);
8177 ok_sequence(WmEmptySeq
, "WmEmptySeq", FALSE
);
8179 qstatus
= GetQueueStatus(qs_all_input
);
8180 ok(qstatus
== MAKELONG(0, QS_POSTMESSAGE
),
8181 "wrong qstatus %08x\n", qstatus
);
8184 ret
= PeekMessageA(&msg
, 0, 0, 0, PM_REMOVE
);
8185 ok(ret
&& msg
.message
== WM_QUIT
,
8186 "got %d and %04x instead of TRUE and WM_QUIT\n", ret
, msg
.message
);
8187 ok(msg
.wParam
== 0x1234abcd, "got wParam %08x instead of 0x1234abcd\n", msg
.wParam
);
8188 ok(msg
.lParam
== 0, "got lParam %08lx instead of 0\n", msg
.lParam
);
8189 ok_sequence(WmEmptySeq
, "WmEmptySeq", FALSE
);
8191 qstatus
= GetQueueStatus(qs_all_input
);
8193 ok(qstatus
== MAKELONG(0, QS_POSTMESSAGE
),
8194 "wrong qstatus %08x\n", qstatus
);
8198 ret
= PeekMessageA(&msg
, 0, 0, 0, PM_REMOVE
);
8200 "PeekMessageA should have returned FALSE instead of msg %04x\n",
8202 ok_sequence(WmEmptySeq
, "WmEmptySeq", FALSE
);
8204 qstatus
= GetQueueStatus(qs_all_input
);
8206 "wrong qstatus %08x\n", qstatus
);
8208 trace("signalling to exit\n");
8209 SetEvent(info
.hevent
[EV_START_STOP
]);
8211 WaitForSingleObject(hthread
, INFINITE
);
8213 CloseHandle(hthread
);
8214 CloseHandle(info
.hevent
[0]);
8215 CloseHandle(info
.hevent
[1]);
8216 CloseHandle(info
.hevent
[2]);
8218 DestroyWindow(info
.hwnd
);
8222 static void test_quit_message(void)
8227 /* test using PostQuitMessage */
8228 PostQuitMessage(0xbeef);
8230 ret
= PeekMessage(&msg
, NULL
, 0, 0, PM_NOREMOVE
);
8231 ok(ret
, "PeekMessage failed with error %d\n", GetLastError());
8232 ok(msg
.message
== WM_QUIT
, "Received message 0x%04x instead of WM_QUIT\n", msg
.message
);
8233 ok(msg
.wParam
== 0xbeef, "wParam was 0x%x instead of 0xbeef\n", msg
.wParam
);
8235 ret
= PostThreadMessage(GetCurrentThreadId(), WM_USER
, 0, 0);
8236 ok(ret
, "PostMessage failed with error %d\n", GetLastError());
8238 ret
= GetMessage(&msg
, NULL
, 0, 0);
8239 ok(ret
> 0, "GetMessage failed with error %d\n", GetLastError());
8240 ok(msg
.message
== WM_USER
, "Received message 0x%04x instead of WM_USER\n", msg
.message
);
8242 /* note: WM_QUIT message received after WM_USER message */
8243 ret
= GetMessage(&msg
, NULL
, 0, 0);
8244 ok(!ret
, "GetMessage return %d with error %d instead of FALSE\n", ret
, GetLastError());
8245 ok(msg
.message
== WM_QUIT
, "Received message 0x%04x instead of WM_QUIT\n", msg
.message
);
8246 ok(msg
.wParam
== 0xbeef, "wParam was 0x%x instead of 0xbeef\n", msg
.wParam
);
8248 ret
= PeekMessage(&msg
, NULL
, 0, 0, PM_REMOVE
);
8249 ok( !ret
|| msg
.message
!= WM_QUIT
, "Received WM_QUIT again\n" );
8251 /* now test with PostThreadMessage - different behaviour! */
8252 PostThreadMessage(GetCurrentThreadId(), WM_QUIT
, 0xdead, 0);
8254 ret
= PeekMessage(&msg
, NULL
, 0, 0, PM_NOREMOVE
);
8255 ok(ret
, "PeekMessage failed with error %d\n", GetLastError());
8256 ok(msg
.message
== WM_QUIT
, "Received message 0x%04x instead of WM_QUIT\n", msg
.message
);
8257 ok(msg
.wParam
== 0xdead, "wParam was 0x%x instead of 0xdead\n", msg
.wParam
);
8259 ret
= PostThreadMessage(GetCurrentThreadId(), WM_USER
, 0, 0);
8260 ok(ret
, "PostMessage failed with error %d\n", GetLastError());
8262 /* note: we receive the WM_QUIT message first this time */
8263 ret
= GetMessage(&msg
, NULL
, 0, 0);
8264 ok(!ret
, "GetMessage return %d with error %d instead of FALSE\n", ret
, GetLastError());
8265 ok(msg
.message
== WM_QUIT
, "Received message 0x%04x instead of WM_QUIT\n", msg
.message
);
8266 ok(msg
.wParam
== 0xdead, "wParam was 0x%x instead of 0xdead\n", msg
.wParam
);
8268 ret
= GetMessage(&msg
, NULL
, 0, 0);
8269 ok(ret
> 0, "GetMessage failed with error %d\n", GetLastError());
8270 ok(msg
.message
== WM_USER
, "Received message 0x%04x instead of WM_USER\n", msg
.message
);
8273 static const struct message WmMouseHoverSeq
[] = {
8274 { WM_TIMER
, sent
|optional
}, /* XP sends it */
8275 { WM_SYSTIMER
, sent
},
8276 { WM_MOUSEHOVER
, sent
|wparam
, 0 },
8280 static void pump_msg_loop_timeout(DWORD timeout
, BOOL inject_mouse_move
)
8283 DWORD start_ticks
, end_ticks
;
8285 start_ticks
= GetTickCount();
8286 /* add some deviation (5%) to cover not expected delays */
8287 start_ticks
+= timeout
/ 20;
8291 while (PeekMessage(&msg
, 0, 0, 0, PM_REMOVE
))
8293 /* Timer proc messages are not dispatched to the window proc,
8294 * and therefore not logged.
8296 if (msg
.message
== WM_TIMER
|| msg
.message
== WM_SYSTIMER
)
8298 struct message s_msg
;
8300 s_msg
.message
= msg
.message
;
8301 s_msg
.flags
= sent
|wparam
|lparam
;
8302 s_msg
.wParam
= msg
.wParam
;
8303 s_msg
.lParam
= msg
.lParam
;
8304 add_message(&s_msg
);
8306 DispatchMessage(&msg
);
8309 end_ticks
= GetTickCount();
8311 /* inject WM_MOUSEMOVE to see how it changes tracking */
8312 if (inject_mouse_move
&& start_ticks
+ timeout
/ 2 >= end_ticks
)
8314 mouse_event(MOUSEEVENTF_MOVE
, -1, 0, 0, 0);
8315 mouse_event(MOUSEEVENTF_MOVE
, 1, 0, 0, 0);
8317 inject_mouse_move
= FALSE
;
8319 } while (start_ticks
+ timeout
>= end_ticks
);
8322 static void test_TrackMouseEvent(void)
8325 TRACKMOUSEEVENT tme
;
8328 RECT rc_parent
, rc_child
;
8329 UINT default_hover_time
, hover_width
= 0, hover_height
= 0;
8331 #define track_hover(track_hwnd, track_hover_time) \
8332 tme.cbSize = sizeof(tme); \
8333 tme.dwFlags = TME_HOVER; \
8334 tme.hwndTrack = track_hwnd; \
8335 tme.dwHoverTime = track_hover_time; \
8336 SetLastError(0xdeadbeef); \
8337 ret = TrackMouseEvent(&tme); \
8338 ok(ret, "TrackMouseEvent(TME_HOVER) error %d\n", GetLastError())
8340 #define track_query(expected_track_flags, expected_track_hwnd, expected_hover_time) \
8341 tme.cbSize = sizeof(tme); \
8342 tme.dwFlags = TME_QUERY; \
8343 tme.hwndTrack = (HWND)0xdeadbeef; \
8344 tme.dwHoverTime = 0xdeadbeef; \
8345 SetLastError(0xdeadbeef); \
8346 ret = TrackMouseEvent(&tme); \
8347 ok(ret, "TrackMouseEvent(TME_QUERY) error %d\n", GetLastError());\
8348 ok(tme.cbSize == sizeof(tme), "wrong tme.cbSize %u\n", tme.cbSize); \
8349 ok(tme.dwFlags == (expected_track_flags), \
8350 "wrong tme.dwFlags %08x, expected %08x\n", tme.dwFlags, (expected_track_flags)); \
8351 ok(tme.hwndTrack == (expected_track_hwnd), \
8352 "wrong tme.hwndTrack %p, expected %p\n", tme.hwndTrack, (expected_track_hwnd)); \
8353 ok(tme.dwHoverTime == (expected_hover_time), \
8354 "wrong tme.dwHoverTime %u, expected %u\n", tme.dwHoverTime, (expected_hover_time))
8356 #define track_hover_cancel(track_hwnd) \
8357 tme.cbSize = sizeof(tme); \
8358 tme.dwFlags = TME_HOVER | TME_CANCEL; \
8359 tme.hwndTrack = track_hwnd; \
8360 tme.dwHoverTime = 0xdeadbeef; \
8361 SetLastError(0xdeadbeef); \
8362 ret = TrackMouseEvent(&tme); \
8363 ok(ret, "TrackMouseEvent(TME_HOVER | TME_CANCEL) error %d\n", GetLastError())
8365 default_hover_time
= 0xdeadbeef;
8366 SetLastError(0xdeadbeef);
8367 ret
= SystemParametersInfo(SPI_GETMOUSEHOVERTIME
, 0, &default_hover_time
, 0);
8368 ok(ret
, "SystemParametersInfo(SPI_GETMOUSEHOVERTIME) error %u\n", GetLastError());
8369 if (!ret
) default_hover_time
= 400;
8370 trace("SPI_GETMOUSEHOVERTIME returned %u ms\n", default_hover_time
);
8372 SetLastError(0xdeadbeef);
8373 ret
= SystemParametersInfo(SPI_GETMOUSEHOVERWIDTH
, 0, &hover_width
, 0);
8374 ok(ret
, "SystemParametersInfo(SPI_GETMOUSEHOVERWIDTH) error %u\n", GetLastError());
8375 if (!ret
) hover_width
= 4;
8376 SetLastError(0xdeadbeef);
8377 ret
= SystemParametersInfo(SPI_GETMOUSEHOVERHEIGHT
, 0, &hover_height
, 0);
8378 ok(ret
, "SystemParametersInfo(SPI_GETMOUSEHOVERHEIGHT) error %u\n", GetLastError());
8379 if (!ret
) hover_height
= 4;
8380 trace("hover rect is %u x %d\n", hover_width
, hover_height
);
8382 hwnd
= CreateWindowEx(0, "TestWindowClass", NULL
,
8383 WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
8384 CW_USEDEFAULT
, CW_USEDEFAULT
, 300, 300, 0,
8388 hchild
= CreateWindowEx(0, "TestWindowClass", NULL
,
8389 WS_CHILD
| WS_BORDER
| WS_VISIBLE
,
8390 50, 50, 200, 200, hwnd
,
8398 tme
.dwFlags
= TME_QUERY
;
8399 tme
.hwndTrack
= (HWND
)0xdeadbeef;
8400 tme
.dwHoverTime
= 0xdeadbeef;
8401 SetLastError(0xdeadbeef);
8402 ret
= TrackMouseEvent(&tme
);
8403 ok(!ret
, "TrackMouseEvent should fail\n");
8404 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "not expected error %d\n", GetLastError());
8406 tme
.cbSize
= sizeof(tme
);
8407 tme
.dwFlags
= TME_HOVER
;
8408 tme
.hwndTrack
= (HWND
)0xdeadbeef;
8409 tme
.dwHoverTime
= 0xdeadbeef;
8410 SetLastError(0xdeadbeef);
8411 ret
= TrackMouseEvent(&tme
);
8412 ok(!ret
, "TrackMouseEvent should fail\n");
8413 ok(GetLastError() == ERROR_INVALID_WINDOW_HANDLE
, "not expected error %d\n", GetLastError());
8415 tme
.cbSize
= sizeof(tme
);
8416 tme
.dwFlags
= TME_HOVER
| TME_CANCEL
;
8417 tme
.hwndTrack
= (HWND
)0xdeadbeef;
8418 tme
.dwHoverTime
= 0xdeadbeef;
8419 SetLastError(0xdeadbeef);
8420 ret
= TrackMouseEvent(&tme
);
8421 ok(!ret
, "TrackMouseEvent should fail\n");
8422 ok(GetLastError() == ERROR_INVALID_WINDOW_HANDLE
, "not expected error %d\n", GetLastError());
8424 GetWindowRect(hwnd
, &rc_parent
);
8425 GetWindowRect(hchild
, &rc_child
);
8426 SetCursorPos(rc_child
.left
- 10, rc_child
.top
- 10);
8428 /* Process messages so that the system updates its internal current
8429 * window and hittest, otherwise TrackMouseEvent calls don't have any
8432 while (PeekMessage(&msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage(&msg
);
8435 track_query(0, NULL
, 0);
8436 track_hover(hchild
, 0);
8437 track_query(0, NULL
, 0);
8439 while (PeekMessage(&msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage(&msg
);
8442 track_hover(hwnd
, 0);
8443 track_query(TME_HOVER
, hwnd
, default_hover_time
);
8445 pump_msg_loop_timeout(default_hover_time
, FALSE
);
8446 ok_sequence(WmMouseHoverSeq
, "WmMouseHoverSeq", FALSE
);
8448 track_query(0, NULL
, 0);
8450 track_hover(hwnd
, HOVER_DEFAULT
);
8451 track_query(TME_HOVER
, hwnd
, default_hover_time
);
8453 Sleep(default_hover_time
/ 2);
8454 mouse_event(MOUSEEVENTF_MOVE
, -1, 0, 0, 0);
8455 mouse_event(MOUSEEVENTF_MOVE
, 1, 0, 0, 0);
8457 track_query(TME_HOVER
, hwnd
, default_hover_time
);
8459 pump_msg_loop_timeout(default_hover_time
/ 2, FALSE
);
8460 ok_sequence(WmMouseHoverSeq
, "WmMouseHoverSeq", FALSE
);
8462 track_query(0, NULL
, 0);
8464 track_hover(hwnd
, HOVER_DEFAULT
);
8465 track_query(TME_HOVER
, hwnd
, default_hover_time
);
8467 pump_msg_loop_timeout(default_hover_time
, TRUE
);
8468 ok_sequence(WmMouseHoverSeq
, "WmMouseHoverSeq", FALSE
);
8470 track_query(0, NULL
, 0);
8472 track_hover(hwnd
, HOVER_DEFAULT
);
8473 track_query(TME_HOVER
, hwnd
, default_hover_time
);
8474 track_hover_cancel(hwnd
);
8476 DestroyWindow(hwnd
);
8480 #undef track_hover_cancel
8484 static const struct message WmSetWindowRgn
[] = {
8485 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
|SWP_NOACTIVATE
|SWP_FRAMECHANGED
|SWP_NOSIZE
|SWP_NOMOVE
},
8486 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
8487 { WM_NCPAINT
, sent
}, /* wparam != 1 */
8488 { WM_GETTEXT
, sent
|defwinproc
|optional
},
8489 { WM_ERASEBKGND
, sent
|optional
}, /* FIXME: remove optional once Wine is fixed */
8490 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
|SWP_NOACTIVATE
|SWP_FRAMECHANGED
|SWP_NOSIZE
|SWP_NOMOVE
},
8491 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
8495 static const struct message WmSetWindowRgn_no_redraw
[] = {
8496 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
|SWP_NOACTIVATE
|SWP_FRAMECHANGED
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOREDRAW
},
8497 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
8498 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
|SWP_NOACTIVATE
|SWP_FRAMECHANGED
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOREDRAW
},
8499 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
8503 static const struct message WmSetWindowRgn_clear
[] = {
8504 { 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 */
8505 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
8506 { WM_NCPAINT
, sent
}, /* wparam != 1 */
8507 { WM_GETTEXT
, sent
|defwinproc
|optional
},
8508 { WM_ERASEBKGND
, sent
|optional
}, /* FIXME: remove optional once Wine is fixed */
8509 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
|SWP_NOACTIVATE
|SWP_FRAMECHANGED
|SWP_NOSIZE
|SWP_NOMOVE
},
8510 { WM_NCCALCSIZE
, sent
|wparam
|optional
, 1 },
8511 { WM_NCPAINT
, sent
|optional
}, /* wparam != 1 */
8512 { WM_GETTEXT
, sent
|defwinproc
|optional
},
8513 { WM_ERASEBKGND
, sent
|optional
},
8514 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
8515 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
8519 static void test_SetWindowRgn(void)
8522 HWND hwnd
= CreateWindowExA(0, "TestWindowClass", "Test overlapped", WS_OVERLAPPEDWINDOW
,
8523 100, 100, 200, 200, 0, 0, 0, NULL
);
8524 ok( hwnd
!= 0, "Failed to create overlapped window\n" );
8526 ShowWindow( hwnd
, SW_SHOW
);
8527 UpdateWindow( hwnd
);
8531 trace("testing SetWindowRgn\n");
8532 hrgn
= CreateRectRgn( 0, 0, 150, 150 );
8533 SetWindowRgn( hwnd
, hrgn
, TRUE
);
8534 ok_sequence( WmSetWindowRgn
, "WmSetWindowRgn", FALSE
);
8536 hrgn
= CreateRectRgn( 30, 30, 160, 160 );
8537 SetWindowRgn( hwnd
, hrgn
, FALSE
);
8538 ok_sequence( WmSetWindowRgn_no_redraw
, "WmSetWindowRgn_no_redraw", FALSE
);
8540 hrgn
= CreateRectRgn( 0, 0, 180, 180 );
8541 SetWindowRgn( hwnd
, hrgn
, TRUE
);
8542 ok_sequence( WmSetWindowRgn
, "WmSetWindowRgn2", FALSE
);
8544 SetWindowRgn( hwnd
, 0, TRUE
);
8545 ok_sequence( WmSetWindowRgn_clear
, "WmSetWindowRgn_clear", FALSE
);
8547 DestroyWindow( hwnd
);
8550 /*************************** ShowWindow() test ******************************/
8551 static const struct message WmShowNormal
[] = {
8552 { WM_SHOWWINDOW
, sent
|wparam
, 1 },
8553 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
},
8554 { HCBT_ACTIVATE
, hook
},
8555 { WM_WINDOWPOSCHANGING
, sent
|wparam
|optional
, SWP_NOSIZE
|SWP_NOMOVE
}, /* win2003 doesn't send it */
8556 { HCBT_SETFOCUS
, hook
},
8557 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
8560 static const struct message WmShow
[] = {
8561 { WM_SHOWWINDOW
, sent
|wparam
, 1 },
8562 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
},
8563 { HCBT_ACTIVATE
, hook
|optional
}, /* win2000 doesn't send it */
8564 { WM_WINDOWPOSCHANGING
, sent
|wparam
|optional
, SWP_NOSIZE
|SWP_NOMOVE
}, /* win2000 doesn't send it */
8565 { HCBT_SETFOCUS
, hook
|optional
}, /* win2000 doesn't send it */
8566 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
8569 static const struct message WmShowNoActivate_1
[] = {
8570 { HCBT_MINMAX
, hook
|lparam
, 0, SW_SHOWNOACTIVATE
},
8571 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOACTIVATE
|SWP_FRAMECHANGED
|0x8000 },
8572 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOACTIVATE
|SWP_FRAMECHANGED
|0x8000 },
8573 { WM_MOVE
, sent
|defwinproc
},
8574 { WM_SIZE
, sent
|wparam
|defwinproc
, SIZE_RESTORED
},
8577 static const struct message WmShowNoActivate_2
[] = {
8578 { HCBT_MINMAX
, hook
|lparam
, 0, SW_SHOWNOACTIVATE
},
8579 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOACTIVATE
|SWP_FRAMECHANGED
|SWP_NOCOPYBITS
|0x8000 },
8580 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOACTIVATE
|SWP_FRAMECHANGED
|SWP_NOCOPYBITS
|0x8000 },
8581 { WM_MOVE
, sent
|defwinproc
},
8582 { WM_SIZE
, sent
|wparam
|defwinproc
, SIZE_RESTORED
},
8583 { HCBT_SETFOCUS
, hook
},
8584 { HCBT_ACTIVATE
, hook
|optional
}, /* win2003 doesn't send it */
8585 { WM_WINDOWPOSCHANGING
, sent
|wparam
|optional
, SWP_NOSIZE
|SWP_NOMOVE
}, /* win2003 doesn't send it */
8586 { HCBT_SETFOCUS
, hook
|optional
}, /* win2003 doesn't send it */
8589 static const struct message WmShowNA_1
[] = {
8590 { WM_SHOWWINDOW
, sent
|wparam
, 1 },
8591 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
8592 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
8595 static const struct message WmShowNA_2
[] = {
8596 { WM_SHOWWINDOW
, sent
|wparam
, 1 },
8597 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
8600 static const struct message WmRestore_1
[] = {
8601 { HCBT_MINMAX
, hook
|lparam
, 0, SW_RESTORE
},
8602 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_FRAMECHANGED
|SWP_NOCOPYBITS
|0x8000 },
8603 { HCBT_ACTIVATE
, hook
|optional
}, /* win2000 doesn't send it */
8604 { WM_WINDOWPOSCHANGING
, sent
|wparam
|optional
, SWP_NOSIZE
|SWP_NOMOVE
}, /* win2000 doesn't send it */
8605 { HCBT_SETFOCUS
, hook
|optional
}, /* win2000 doesn't send it */
8606 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_FRAMECHANGED
|SWP_NOCOPYBITS
|0x8000 },
8607 { WM_MOVE
, sent
|defwinproc
},
8608 { WM_SIZE
, sent
|wparam
|defwinproc
, SIZE_RESTORED
},
8609 { HCBT_SETFOCUS
, hook
|optional
}, /* win2000 sends it */
8612 static const struct message WmRestore_2
[] = {
8613 { WM_SHOWWINDOW
, sent
|wparam
, 1 },
8614 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
},
8615 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
8618 static const struct message WmRestore_3
[] = {
8619 { HCBT_MINMAX
, hook
|lparam
, 0, SW_RESTORE
},
8620 { WM_GETMINMAXINFO
, sent
},
8621 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOCOPYBITS
|0x8000 },
8622 { HCBT_ACTIVATE
, hook
|optional
}, /* win2003 doesn't send it */
8623 { WM_WINDOWPOSCHANGING
, sent
|wparam
|optional
, SWP_NOSIZE
|SWP_NOMOVE
}, /* win2003 doesn't send it */
8624 { HCBT_SETFOCUS
, hook
|optional
}, /* win2003 doesn't send it */
8625 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOCOPYBITS
|0x8000 },
8626 { WM_MOVE
, sent
|defwinproc
},
8627 { WM_SIZE
, sent
|wparam
|defwinproc
, SIZE_MAXIMIZED
},
8628 { HCBT_SETFOCUS
, hook
|optional
}, /* win2003 sends it */
8631 static const struct message WmRestore_4
[] = {
8632 { HCBT_MINMAX
, hook
|lparam
, 0, SW_RESTORE
},
8633 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|0x8000 },
8634 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|0x8000 },
8635 { WM_MOVE
, sent
|defwinproc
},
8636 { WM_SIZE
, sent
|wparam
|defwinproc
, SIZE_RESTORED
},
8639 static const struct message WmRestore_5
[] = {
8640 { HCBT_MINMAX
, hook
|lparam
, 0, SW_SHOWNORMAL
},
8641 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|0x8000 },
8642 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|0x8000 },
8643 { WM_MOVE
, sent
|defwinproc
},
8644 { WM_SIZE
, sent
|wparam
|defwinproc
, SIZE_RESTORED
},
8647 static const struct message WmHide_1
[] = {
8648 { WM_SHOWWINDOW
, sent
|wparam
, 0 },
8649 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_HIDEWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
},
8650 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_HIDEWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
8651 { HCBT_SETFOCUS
, hook
|optional
}, /* win2000 sends it */
8654 static const struct message WmHide_2
[] = {
8655 { WM_SHOWWINDOW
, sent
|wparam
, 0 },
8656 { WM_WINDOWPOSCHANGING
, sent
/*|wparam, SWP_HIDEWINDOW|SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOMOVE*/ }, /* win2000 doesn't add SWP_NOACTIVATE */
8657 { WM_WINDOWPOSCHANGED
, sent
/*|wparam, SWP_HIDEWINDOW|SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOMOVE|SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE*/ }, /* win2000 doesn't add SWP_NOACTIVATE */
8660 static const struct message WmHide_3
[] = {
8661 { WM_SHOWWINDOW
, sent
|wparam
, 0 },
8662 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_HIDEWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
},
8663 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_HIDEWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
8664 { HCBT_SETFOCUS
, hook
},
8667 static const struct message WmShowMinimized_1
[] = {
8668 { HCBT_MINMAX
, hook
|lparam
, 0, SW_SHOWMINIMIZED
},
8669 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_FRAMECHANGED
|SWP_NOCOPYBITS
|0x8000 },
8670 { HCBT_ACTIVATE
, hook
|optional
}, /* win2000 doesn't send it */
8671 { WM_WINDOWPOSCHANGING
, sent
|wparam
|optional
, SWP_NOSIZE
|SWP_NOMOVE
}, /* win2000 doesn't send it */
8672 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_FRAMECHANGED
|SWP_NOCOPYBITS
|0x8000 },
8673 { WM_MOVE
, sent
|defwinproc
},
8674 { WM_SIZE
, sent
|wparam
|defwinproc
, SIZE_MINIMIZED
},
8677 static const struct message WmMinimize_1
[] = {
8678 { HCBT_MINMAX
, hook
|lparam
, 0, SW_MINIMIZE
},
8679 { HCBT_SETFOCUS
, hook
|optional
}, /* win2000 doesn't send it */
8680 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOACTIVATE
|SWP_FRAMECHANGED
|SWP_NOCOPYBITS
|0x8000 },
8681 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_NOACTIVATE
|SWP_FRAMECHANGED
|SWP_NOCOPYBITS
|0x8000 },
8682 { WM_MOVE
, sent
|defwinproc
},
8683 { WM_SIZE
, sent
|wparam
|defwinproc
, SIZE_MINIMIZED
},
8686 static const struct message WmMinimize_2
[] = {
8687 { HCBT_MINMAX
, hook
|lparam
, 0, SW_MINIMIZE
},
8688 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOACTIVATE
|SWP_FRAMECHANGED
|SWP_NOCOPYBITS
|0x8000 },
8689 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_NOACTIVATE
|SWP_FRAMECHANGED
|SWP_NOCOPYBITS
|0x8000 },
8690 { WM_MOVE
, sent
|defwinproc
},
8691 { WM_SIZE
, sent
|wparam
|defwinproc
, SIZE_MINIMIZED
},
8694 static const struct message WmMinimize_3
[] = {
8695 { HCBT_MINMAX
, hook
|lparam
, 0, SW_MINIMIZE
},
8696 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOACTIVATE
|SWP_FRAMECHANGED
|SWP_NOCOPYBITS
|0x8000 },
8697 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOACTIVATE
|SWP_FRAMECHANGED
|SWP_NOCOPYBITS
|0x8000 },
8698 { WM_MOVE
, sent
|defwinproc
},
8699 { WM_SIZE
, sent
|wparam
|defwinproc
, SIZE_MINIMIZED
},
8702 static const struct message WmShowMinNoActivate
[] = {
8703 { HCBT_MINMAX
, hook
|lparam
, 0, SW_SHOWMINNOACTIVE
},
8704 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
8705 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
8708 static const struct message WmMinMax_1
[] = {
8709 { HCBT_MINMAX
, hook
|lparam
, 0, SW_SHOWMINIMIZED
},
8712 static const struct message WmMinMax_2
[] = {
8713 { HCBT_MINMAX
, hook
|lparam
, 0, SW_SHOWMAXIMIZED
},
8716 static const struct message WmMinMax_3
[] = {
8717 { HCBT_MINMAX
, hook
|lparam
, 0, SW_MINIMIZE
},
8720 static const struct message WmMinMax_4
[] = {
8721 { HCBT_MINMAX
, hook
|lparam
, 0, SW_SHOWMINNOACTIVE
},
8724 static const struct message WmShowMaximized_1
[] = {
8725 { HCBT_MINMAX
, hook
|lparam
, 0, SW_SHOWMAXIMIZED
},
8726 { WM_GETMINMAXINFO
, sent
},
8727 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_FRAMECHANGED
|SWP_NOCOPYBITS
|0x8000 },
8728 { HCBT_ACTIVATE
, hook
|optional
}, /* win2000 doesn't send it */
8729 { WM_WINDOWPOSCHANGING
, sent
|wparam
|optional
, SWP_NOSIZE
|SWP_NOMOVE
}, /* win2000 doesn't send it */
8730 { HCBT_SETFOCUS
, hook
|optional
}, /* win2000 doesn't send it */
8731 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_FRAMECHANGED
|SWP_NOCOPYBITS
|0x8000 },
8732 { WM_MOVE
, sent
|defwinproc
},
8733 { WM_SIZE
, sent
|wparam
|defwinproc
, SIZE_MAXIMIZED
},
8734 { HCBT_SETFOCUS
, hook
|optional
}, /* win2003 sends it */
8737 static const struct message WmShowMaximized_2
[] = {
8738 { HCBT_MINMAX
, hook
|lparam
, 0, SW_SHOWMAXIMIZED
},
8739 { WM_GETMINMAXINFO
, sent
},
8740 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_NOSIZE
|SWP_NOMOVE
},
8741 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
8742 { WM_MOVE
, sent
|optional
}, /* Win9x doesn't send it */
8743 { WM_SIZE
, sent
|wparam
|optional
, SIZE_MAXIMIZED
}, /* Win9x doesn't send it */
8744 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOCOPYBITS
|0x8000 },
8745 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOCOPYBITS
|0x8000 },
8746 { WM_MOVE
, sent
|defwinproc
},
8747 { WM_SIZE
, sent
|wparam
|defwinproc
, SIZE_MAXIMIZED
},
8748 { HCBT_SETFOCUS
, hook
},
8751 static const struct message WmShowMaximized_3
[] = {
8752 { HCBT_MINMAX
, hook
|lparam
, 0, SW_SHOWMAXIMIZED
},
8753 { WM_GETMINMAXINFO
, sent
},
8754 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|0x8000 },
8755 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|0x8000 },
8756 { WM_MOVE
, sent
|defwinproc
},
8757 { WM_SIZE
, sent
|wparam
|defwinproc
, SIZE_MAXIMIZED
},
8761 static void test_ShowWindow(void)
8763 /* ShowWindow commands in random order */
8766 INT cmd
; /* ShowWindow command */
8767 LPARAM ret
; /* ShowWindow return value */
8768 DWORD style
; /* window style after the command */
8769 const struct message
*msg
; /* message sequence the command produces */
8770 BOOL todo_msg
; /* message sequence doesn't match what Wine does */
8773 /* 1 */ { SW_SHOWNORMAL
, FALSE
, WS_VISIBLE
, WmShowNormal
, FALSE
},
8774 /* 2 */ { SW_SHOWNORMAL
, TRUE
, WS_VISIBLE
, WmEmptySeq
, FALSE
},
8775 /* 3 */ { SW_HIDE
, TRUE
, 0, WmHide_1
, FALSE
},
8776 /* 4 */ { SW_HIDE
, FALSE
, 0, WmEmptySeq
, FALSE
},
8777 /* 5 */ { SW_SHOWMINIMIZED
, FALSE
, WS_VISIBLE
|WS_MINIMIZE
, WmShowMinimized_1
, FALSE
},
8778 /* 6 */ { SW_SHOWMINIMIZED
, TRUE
, WS_VISIBLE
|WS_MINIMIZE
, WmMinMax_1
, FALSE
},
8779 /* 7 */ { SW_HIDE
, TRUE
, WS_MINIMIZE
, WmHide_1
, FALSE
},
8780 /* 8 */ { SW_HIDE
, FALSE
, WS_MINIMIZE
, WmEmptySeq
, FALSE
},
8781 /* 9 */ { SW_SHOWMAXIMIZED
, FALSE
, WS_VISIBLE
|WS_MAXIMIZE
, WmShowMaximized_1
, FALSE
},
8782 /* 10 */ { SW_SHOWMAXIMIZED
, TRUE
, WS_VISIBLE
|WS_MAXIMIZE
, WmMinMax_2
, FALSE
},
8783 /* 11 */ { SW_HIDE
, TRUE
, WS_MAXIMIZE
, WmHide_1
, FALSE
},
8784 /* 12 */ { SW_HIDE
, FALSE
, WS_MAXIMIZE
, WmEmptySeq
, FALSE
},
8785 /* 13 */ { SW_SHOWNOACTIVATE
, FALSE
, WS_VISIBLE
, WmShowNoActivate_1
, FALSE
},
8786 /* 14 */ { SW_SHOWNOACTIVATE
, TRUE
, WS_VISIBLE
, WmEmptySeq
, FALSE
},
8787 /* 15 */ { SW_HIDE
, TRUE
, 0, WmHide_2
, FALSE
},
8788 /* 16 */ { SW_HIDE
, FALSE
, 0, WmEmptySeq
, FALSE
},
8789 /* 17 */ { SW_SHOW
, FALSE
, WS_VISIBLE
, WmShow
, FALSE
},
8790 /* 18 */ { SW_SHOW
, TRUE
, WS_VISIBLE
, WmEmptySeq
, FALSE
},
8791 /* 19 */ { SW_MINIMIZE
, TRUE
, WS_VISIBLE
|WS_MINIMIZE
, WmMinimize_1
, TRUE
},
8792 /* 20 */ { SW_MINIMIZE
, TRUE
, WS_VISIBLE
|WS_MINIMIZE
, WmMinMax_3
, FALSE
},
8793 /* 21 */ { SW_HIDE
, TRUE
, WS_MINIMIZE
, WmHide_2
, FALSE
},
8794 /* 22 */ { SW_SHOWMINNOACTIVE
, FALSE
, WS_VISIBLE
|WS_MINIMIZE
, WmShowMinNoActivate
, TRUE
},
8795 /* 23 */ { SW_SHOWMINNOACTIVE
, TRUE
, WS_VISIBLE
|WS_MINIMIZE
, WmMinMax_4
, FALSE
},
8796 /* 24 */ { SW_HIDE
, TRUE
, WS_MINIMIZE
, WmHide_2
, FALSE
},
8797 /* 25 */ { SW_HIDE
, FALSE
, WS_MINIMIZE
, WmEmptySeq
, FALSE
},
8798 /* 26 */ { SW_SHOWNA
, FALSE
, WS_VISIBLE
|WS_MINIMIZE
, WmShowNA_1
, FALSE
},
8799 /* 27 */ { SW_SHOWNA
, TRUE
, WS_VISIBLE
|WS_MINIMIZE
, WmShowNA_2
, FALSE
},
8800 /* 28 */ { SW_HIDE
, TRUE
, WS_MINIMIZE
, WmHide_2
, FALSE
},
8801 /* 29 */ { SW_HIDE
, FALSE
, WS_MINIMIZE
, WmEmptySeq
, FALSE
},
8802 /* 30 */ { SW_RESTORE
, FALSE
, WS_VISIBLE
, WmRestore_1
, FALSE
},
8803 /* 31 */ { SW_RESTORE
, TRUE
, WS_VISIBLE
, WmEmptySeq
, FALSE
},
8804 /* 32 */ { SW_HIDE
, TRUE
, 0, WmHide_3
, TRUE
},
8805 /* 33 */ { SW_HIDE
, FALSE
, 0, WmEmptySeq
, FALSE
},
8806 /* 34 */ { SW_NORMALNA
, FALSE
, 0, WmEmptySeq
, TRUE
}, /* what does this mean?! */
8807 /* 35 */ { SW_NORMALNA
, FALSE
, 0, WmEmptySeq
, TRUE
},
8808 /* 36 */ { SW_HIDE
, FALSE
, 0, WmEmptySeq
, FALSE
},
8809 /* 37 */ { SW_RESTORE
, FALSE
, WS_VISIBLE
, WmRestore_2
, FALSE
},
8810 /* 38 */ { SW_RESTORE
, TRUE
, WS_VISIBLE
, WmEmptySeq
, FALSE
},
8811 /* 39 */ { SW_SHOWNOACTIVATE
, TRUE
, WS_VISIBLE
, WmEmptySeq
, FALSE
},
8812 /* 40 */ { SW_MINIMIZE
, TRUE
, WS_VISIBLE
|WS_MINIMIZE
, WmMinimize_2
, TRUE
},
8813 /* 41 */ { SW_MINIMIZE
, TRUE
, WS_VISIBLE
|WS_MINIMIZE
, WmMinMax_3
, FALSE
},
8814 /* 42 */ { SW_SHOWMAXIMIZED
, TRUE
, WS_VISIBLE
|WS_MAXIMIZE
, WmShowMaximized_2
, TRUE
},
8815 /* 43 */ { SW_SHOWMAXIMIZED
, TRUE
, WS_VISIBLE
|WS_MAXIMIZE
, WmMinMax_2
, FALSE
},
8816 /* 44 */ { SW_MINIMIZE
, TRUE
, WS_VISIBLE
|WS_MINIMIZE
, WmMinimize_1
, TRUE
},
8817 /* 45 */ { SW_MINIMIZE
, TRUE
, WS_VISIBLE
|WS_MINIMIZE
, WmMinMax_3
, FALSE
},
8818 /* 46 */ { SW_RESTORE
, TRUE
, WS_VISIBLE
|WS_MAXIMIZE
, WmRestore_3
, FALSE
},
8819 /* 47 */ { SW_RESTORE
, TRUE
, WS_VISIBLE
, WmRestore_4
, FALSE
},
8820 /* 48 */ { SW_SHOWMAXIMIZED
, TRUE
, WS_VISIBLE
|WS_MAXIMIZE
, WmShowMaximized_3
, FALSE
},
8821 /* 49 */ { SW_SHOW
, TRUE
, WS_VISIBLE
|WS_MAXIMIZE
, WmEmptySeq
, FALSE
},
8822 /* 50 */ { SW_SHOWNORMAL
, TRUE
, WS_VISIBLE
, WmRestore_5
, FALSE
},
8823 /* 51 */ { SW_SHOWNORMAL
, TRUE
, WS_VISIBLE
, WmEmptySeq
, FALSE
},
8824 /* 52 */ { SW_HIDE
, TRUE
, 0, WmHide_1
, FALSE
},
8825 /* 53 */ { SW_HIDE
, FALSE
, 0, WmEmptySeq
, FALSE
},
8826 /* 54 */ { SW_MINIMIZE
, FALSE
, WS_VISIBLE
|WS_MINIMIZE
, WmMinimize_3
, TRUE
},
8827 /* 55 */ { SW_HIDE
, TRUE
, WS_MINIMIZE
, WmHide_2
, FALSE
},
8828 /* 56 */ { SW_SHOWNOACTIVATE
, FALSE
, WS_VISIBLE
, WmShowNoActivate_2
, FALSE
},
8829 /* 57 */ { SW_SHOW
, TRUE
, WS_VISIBLE
, WmEmptySeq
, FALSE
}
8836 #define WS_BASE (WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX|WS_MAXIMIZEBOX|WS_POPUP|WS_CLIPSIBLINGS)
8837 hwnd
= CreateWindowEx(0, "ShowWindowClass", NULL
, WS_BASE
,
8842 style
= GetWindowLong(hwnd
, GWL_STYLE
) & ~WS_BASE
;
8843 ok(style
== 0, "expected style 0, got %08x\n", style
);
8848 for (i
= 0; i
< sizeof(sw
)/sizeof(sw
[0]); i
++)
8850 static const char * const sw_cmd_name
[13] =
8852 "SW_HIDE", "SW_SHOWNORMAL", "SW_SHOWMINIMIZED", "SW_SHOWMAXIMIZED",
8853 "SW_SHOWNOACTIVATE", "SW_SHOW", "SW_MINIMIZE", "SW_SHOWMINNOACTIVE",
8854 "SW_SHOWNA", "SW_RESTORE", "SW_SHOWDEFAULT", "SW_FORCEMINIMIZE",
8855 "SW_NORMALNA" /* 0xCC */
8858 INT idx
; /* index into the above array of names */
8860 idx
= (sw
[i
].cmd
== SW_NORMALNA
) ? 12 : sw
[i
].cmd
;
8862 style
= GetWindowLong(hwnd
, GWL_STYLE
);
8863 trace("%d: sending %s, current window style %08x\n", i
+1, sw_cmd_name
[idx
], style
);
8864 ret
= ShowWindow(hwnd
, sw
[i
].cmd
);
8865 ok(!ret
== !sw
[i
].ret
, "%d: cmd %s: expected ret %lu, got %lu\n", i
+1, sw_cmd_name
[idx
], sw
[i
].ret
, ret
);
8866 style
= GetWindowLong(hwnd
, GWL_STYLE
) & ~WS_BASE
;
8867 ok(style
== sw
[i
].style
, "%d: expected style %08x, got %08x\n", i
+1, sw
[i
].style
, style
);
8869 sprintf(comment
, "%d: ShowWindow(%s)", i
+1, sw_cmd_name
[idx
]);
8870 ok_sequence(sw
[i
].msg
, comment
, sw
[i
].todo_msg
);
8876 DestroyWindow(hwnd
);
8879 static INT_PTR WINAPI
test_dlg_proc(HWND hwnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
8883 trace("dialog: %p, %04x, %08x, %08lx\n", hwnd
, message
, wParam
, lParam
);
8887 case WM_WINDOWPOSCHANGING
:
8888 case WM_WINDOWPOSCHANGED
:
8890 WINDOWPOS
*winpos
= (WINDOWPOS
*)lParam
;
8892 trace("%s\n", (message
== WM_WINDOWPOSCHANGING
) ? "WM_WINDOWPOSCHANGING" : "WM_WINDOWPOSCHANGED");
8893 trace("%p after %p, x %d, y %d, cx %d, cy %d flags %08x\n",
8894 winpos
->hwnd
, winpos
->hwndInsertAfter
,
8895 winpos
->x
, winpos
->y
, winpos
->cx
, winpos
->cy
, winpos
->flags
);
8896 dump_winpos_flags(winpos
->flags
);
8898 /* Log only documented flags, win2k uses 0x1000 and 0x2000
8899 * in the high word for internal purposes
8901 wParam
= winpos
->flags
& 0xffff;
8902 /* We are not interested in the flags that don't match under XP and Win9x */
8903 wParam
&= ~(SWP_NOZORDER
);
8907 /* explicitly ignore WM_GETICON message */
8912 msg
.message
= message
;
8913 msg
.flags
= sent
|wparam
|lparam
;
8914 msg
.wParam
= wParam
;
8915 msg
.lParam
= lParam
;
8918 /* calling DefDlgProc leads to a recursion under XP */
8929 static const struct message WmDefDlgSetFocus_1
[] = {
8930 { WM_GETDLGCODE
, sent
|wparam
|lparam
, 0, 0 },
8931 { WM_GETTEXTLENGTH
, sent
|wparam
|lparam
|optional
, 0, 0 }, /* XP */
8932 { WM_GETTEXT
, sent
|wparam
|optional
, 6 }, /* XP */
8933 { WM_GETTEXT
, sent
|wparam
|optional
, 12 }, /* XP */
8934 { EM_SETSEL
, sent
|wparam
, 0 }, /* XP sets lparam to text length, Win9x to -2 */
8935 { HCBT_SETFOCUS
, hook
},
8936 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 1 },
8937 { WM_IME_NOTIFY
, sent
|wparam
|defwinproc
|optional
, 2 },
8938 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
8939 { WM_SETFOCUS
, sent
|wparam
, 0 },
8940 { WM_CTLCOLOREDIT
, sent
},
8941 { EVENT_OBJECT_CREATE
, winevent_hook
|wparam
|lparam
, OBJID_CARET
, 0 },
8942 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, OBJID_CARET
, 0 },
8943 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, OBJID_CARET
, 0 },
8944 { WM_COMMAND
, sent
|wparam
, MAKEWPARAM(1, EN_SETFOCUS
) },
8947 static const struct message WmDefDlgSetFocus_2
[] = {
8948 { WM_GETDLGCODE
, sent
|wparam
|lparam
, 0, 0 },
8949 { WM_GETTEXTLENGTH
, sent
|wparam
|lparam
|optional
, 0, 0 }, /* XP */
8950 { WM_GETTEXT
, sent
|wparam
|optional
, 6 }, /* XP */
8951 { WM_GETTEXT
, sent
|wparam
|optional
, 12 }, /* XP */
8952 { EM_SETSEL
, sent
|wparam
, 0 }, /* XP sets lparam to text length, Win9x to -2 */
8953 { WM_CTLCOLOREDIT
, sent
|optional
}, /* XP */
8956 /* Creation of a dialog */
8957 static const struct message WmCreateDialogParamSeq_1
[] = {
8958 { HCBT_CREATEWND
, hook
},
8959 { WM_NCCREATE
, sent
},
8960 { WM_NCCALCSIZE
, sent
|wparam
, 0 },
8961 { WM_CREATE
, sent
},
8962 { EVENT_OBJECT_CREATE
, winevent_hook
|wparam
|lparam
, 0, 0 },
8963 { WM_SIZE
, sent
|wparam
, SIZE_RESTORED
},
8965 { WM_SETFONT
, sent
},
8966 { WM_INITDIALOG
, sent
},
8967 { WM_CHANGEUISTATE
, sent
|optional
},
8970 /* Creation of a dialog */
8971 static const struct message WmCreateDialogParamSeq_2
[] = {
8972 { HCBT_CREATEWND
, hook
},
8973 { WM_NCCREATE
, sent
},
8974 { WM_NCCALCSIZE
, sent
|wparam
, 0 },
8975 { WM_CREATE
, sent
},
8976 { EVENT_OBJECT_CREATE
, winevent_hook
|wparam
|lparam
, 0, 0 },
8977 { WM_SIZE
, sent
|wparam
, SIZE_RESTORED
},
8979 { WM_CHANGEUISTATE
, sent
|optional
},
8983 static void test_dialog_messages(void)
8986 HWND hdlg
, hedit1
, hedit2
, hfocus
;
8989 #define set_selection(hctl, start, end) \
8990 ret = SendMessage(hctl, EM_SETSEL, start, end); \
8991 ok(ret == 1, "EM_SETSEL returned %ld\n", ret);
8993 #define check_selection(hctl, start, end) \
8994 ret = SendMessage(hctl, EM_GETSEL, 0, 0); \
8995 ok(ret == MAKELRESULT(start, end), "wrong selection (%d - %d)\n", LOWORD(ret), HIWORD(ret));
8999 hdlg
= CreateWindowEx(WS_EX_DLGMODALFRAME
, "TestDialogClass", NULL
,
9000 WS_VISIBLE
|WS_CAPTION
|WS_SYSMENU
|WS_DLGFRAME
,
9001 0, 0, 100, 100, 0, 0, 0, NULL
);
9002 ok(hdlg
!= 0, "Failed to create custom dialog window\n");
9004 hedit1
= CreateWindowEx(0, "my_edit_class", NULL
,
9005 WS_CHILD
|WS_BORDER
|WS_VISIBLE
|WS_TABSTOP
,
9006 0, 0, 80, 20, hdlg
, (HMENU
)1, 0, NULL
);
9007 ok(hedit1
!= 0, "Failed to create edit control\n");
9008 hedit2
= CreateWindowEx(0, "my_edit_class", NULL
,
9009 WS_CHILD
|WS_BORDER
|WS_VISIBLE
|WS_TABSTOP
,
9010 0, 40, 80, 20, hdlg
, (HMENU
)2, 0, NULL
);
9011 ok(hedit2
!= 0, "Failed to create edit control\n");
9013 SendMessage(hedit1
, WM_SETTEXT
, 0, (LPARAM
)"hello");
9014 SendMessage(hedit2
, WM_SETTEXT
, 0, (LPARAM
)"bye");
9016 hfocus
= GetFocus();
9017 ok(hfocus
== hdlg
, "wrong focus %p\n", hfocus
);
9020 hfocus
= GetFocus();
9021 ok(hfocus
== hedit2
, "wrong focus %p\n", hfocus
);
9023 check_selection(hedit1
, 0, 0);
9024 check_selection(hedit2
, 0, 0);
9026 set_selection(hedit2
, 0, -1);
9027 check_selection(hedit2
, 0, 3);
9030 hfocus
= GetFocus();
9031 ok(hfocus
== 0, "wrong focus %p\n", hfocus
);
9034 ret
= DefDlgProc(hdlg
, WM_SETFOCUS
, 0, 0);
9035 ok(ret
== 0, "WM_SETFOCUS returned %ld\n", ret
);
9036 ok_sequence(WmDefDlgSetFocus_1
, "DefDlgProc(WM_SETFOCUS) 1", FALSE
);
9038 hfocus
= GetFocus();
9039 ok(hfocus
== hedit1
, "wrong focus %p\n", hfocus
);
9041 check_selection(hedit1
, 0, 5);
9042 check_selection(hedit2
, 0, 3);
9045 ret
= DefDlgProc(hdlg
, WM_SETFOCUS
, 0, 0);
9046 ok(ret
== 0, "WM_SETFOCUS returned %ld\n", ret
);
9047 ok_sequence(WmDefDlgSetFocus_2
, "DefDlgProc(WM_SETFOCUS) 2", FALSE
);
9049 hfocus
= GetFocus();
9050 ok(hfocus
== hedit1
, "wrong focus %p\n", hfocus
);
9052 check_selection(hedit1
, 0, 5);
9053 check_selection(hedit2
, 0, 3);
9058 #undef set_selection
9059 #undef check_selection
9061 ok(GetClassInfo(0, "#32770", &cls
), "GetClassInfo failed\n");
9062 cls
.lpszClassName
= "MyDialogClass";
9063 cls
.hInstance
= GetModuleHandle(0);
9064 /* need a cast since a dlgproc is used as a wndproc */
9065 cls
.lpfnWndProc
= (WNDPROC
)test_dlg_proc
;
9066 if (!RegisterClass(&cls
)) assert(0);
9068 hdlg
= CreateDialogParam(0, "CLASS_TEST_DIALOG_2", 0, test_dlg_proc
, 0);
9069 ok(IsWindow(hdlg
), "CreateDialogParam failed\n");
9070 ok_sequence(WmCreateDialogParamSeq_1
, "CreateDialogParam_1", FALSE
);
9074 hdlg
= CreateDialogParam(0, "CLASS_TEST_DIALOG_2", 0, NULL
, 0);
9075 ok(IsWindow(hdlg
), "CreateDialogParam failed\n");
9076 ok_sequence(WmCreateDialogParamSeq_2
, "CreateDialogParam_2", FALSE
);
9080 UnregisterClass(cls
.lpszClassName
, cls
.hInstance
);
9083 static void test_nullCallback(void)
9088 hwnd
= CreateWindowExA(0, "TestWindowClass", "Test overlapped", WS_OVERLAPPEDWINDOW
,
9089 100, 100, 200, 200, 0, 0, 0, NULL
);
9090 ok (hwnd
!= 0, "Failed to create overlapped window\n");
9092 SendMessageCallbackA(hwnd
,WM_NULL
,0,0,NULL
,0);
9093 while (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
9094 DestroyWindow(hwnd
);
9100 HMODULE user32
= GetModuleHandleA("user32.dll");
9101 FARPROC pSetWinEventHook
= GetProcAddress(user32
, "SetWinEventHook");
9102 FARPROC pUnhookWinEvent
= GetProcAddress(user32
, "UnhookWinEvent");
9103 FARPROC pIsWinEventHookInstalled
= 0;/*GetProcAddress(user32, "IsWinEventHookInstalled");*/
9104 pGetAncestor
= (void*) GetProcAddress(user32
, "GetAncestor");
9106 if (!RegisterWindowClasses()) assert(0);
9108 if (pSetWinEventHook
)
9110 hEvent_hook
= (HWINEVENTHOOK
)pSetWinEventHook(EVENT_MIN
, EVENT_MAX
,
9111 GetModuleHandleA(0),
9114 GetCurrentThreadId(),
9115 WINEVENT_INCONTEXT
);
9116 assert(hEvent_hook
);
9118 if (pIsWinEventHookInstalled
)
9121 for (event
= EVENT_MIN
; event
<= EVENT_MAX
; event
++)
9122 ok(pIsWinEventHookInstalled(event
), "IsWinEventHookInstalled(%u) failed\n", event
);
9126 cbt_hook_thread_id
= GetCurrentThreadId();
9127 hCBT_hook
= SetWindowsHookExA(WH_CBT
, cbt_hook_proc
, 0, GetCurrentThreadId());
9132 /* Fix message sequences before removing 4 lines below */
9134 if (pUnhookWinEvent
&& hEvent_hook
)
9136 ret
= pUnhookWinEvent(hEvent_hook
);
9137 ok( ret
, "UnhookWinEvent error %d\n", GetLastError());
9138 pUnhookWinEvent
= 0;
9145 test_scrollwindowex();
9148 invisible_parent_tests();
9149 test_mdi_messages();
9150 test_button_messages();
9151 test_static_messages();
9152 test_paint_messages();
9153 test_interthread_messages();
9154 test_message_conversion();
9155 test_accelerators();
9158 test_DestroyWindow();
9159 test_DispatchMessage();
9160 test_SendMessageTimeout();
9161 test_edit_messages();
9162 test_quit_message();
9163 test_TrackMouseEvent();
9164 test_SetWindowRgn();
9166 test_dialog_messages();
9167 test_nullCallback();
9169 UnhookWindowsHookEx(hCBT_hook
);
9170 if (pUnhookWinEvent
)
9172 ret
= pUnhookWinEvent(hEvent_hook
);
9173 ok( ret
, "UnhookWinEvent error %d\n", GetLastError());
9174 SetLastError(0xdeadbeef);
9175 ok(!pUnhookWinEvent(hEvent_hook
), "UnhookWinEvent succeeded\n");
9176 ok(GetLastError() == ERROR_INVALID_HANDLE
|| /* Win2k */
9177 GetLastError() == 0xdeadbeef, /* Win9x */
9178 "unexpected error %d\n", GetLastError());