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
23 #define _WIN32_WINNT 0x0501 /* For WM_CHANGEUISTATE,QS_RAWINPUT */
35 #include "wine/test.h"
37 #define MDI_FIRST_CHILD_ID 2004
39 /* undocumented SWP flags - from SDK 3.1 */
40 #define SWP_NOCLIENTSIZE 0x0800
41 #define SWP_NOCLIENTMOVE 0x1000
42 #define SWP_STATECHANGED 0x8000
44 #define SW_NORMALNA 0xCC /* undoc. flag in MinMaximize */
47 #define WM_KEYF1 0x004d
51 #define WM_SYSTIMER 0x0118
54 #define WND_PARENT_ID 1
55 #define WND_POPUP_ID 2
56 #define WND_CHILD_ID 3
58 #ifndef WM_LBTRACKPOINT
59 #define WM_LBTRACKPOINT 0x0131
62 /* encoded DRAWITEMSTRUCT into an LPARAM */
69 UINT type
: 4; /* ODT_* flags */
70 UINT ctl_id
: 4; /* Control ID */
71 UINT item_id
: 4; /* Menu item ID */
72 UINT action
: 4; /* ODA_* flags */
73 UINT state
: 16; /* ODS_* flags */
79 static BOOL test_DestroyWindow_flag
;
80 static HWINEVENTHOOK hEvent_hook
;
81 static HHOOK hCBT_hook
;
82 static DWORD cbt_hook_thread_id
;
84 static const WCHAR testWindowClassW
[] =
85 { 'T','e','s','t','W','i','n','d','o','w','C','l','a','s','s','W',0 };
88 FIXME: add tests for these
89 Window Edge Styles (Win31/Win95/98 look), in order of precedence:
90 WS_EX_DLGMODALFRAME: double border, WS_CAPTION allowed
91 WS_THICKFRAME: thick border
92 WS_DLGFRAME: double border, WS_CAPTION not allowed (but possibly shown anyway)
93 WS_BORDER (default for overlapped windows): single black border
94 none (default for child (and popup?) windows): no border
111 UINT message
; /* the WM_* code */
112 msg_flags_t flags
; /* message props */
113 WPARAM wParam
; /* expected value of wParam */
114 LPARAM lParam
; /* expected value of lParam */
115 WPARAM wp_mask
; /* mask for wParam checks */
116 LPARAM lp_mask
; /* mask for lParam checks */
119 struct recvd_message
{
120 UINT message
; /* the WM_* code */
121 msg_flags_t flags
; /* message props */
122 HWND hwnd
; /* window that received the message */
123 WPARAM wParam
; /* expected value of wParam */
124 LPARAM lParam
; /* expected value of lParam */
125 int line
; /* source line where logged */
126 const char *descr
; /* description for trace output */
127 char output
[512]; /* trace output */
130 /* Empty message sequence */
131 static const struct message WmEmptySeq
[] =
135 /* CreateWindow (for overlapped window, not initially visible) (16/32) */
136 static const struct message WmCreateOverlappedSeq
[] = {
137 { HCBT_CREATEWND
, hook
},
138 { WM_GETMINMAXINFO
, sent
},
139 { WM_NCCREATE
, sent
},
140 { WM_NCCALCSIZE
, sent
|wparam
, 0 },
141 { 0x0093, sent
|defwinproc
|optional
},
142 { 0x0094, sent
|defwinproc
|optional
},
143 { EVENT_OBJECT_REORDER
, winevent_hook
|wparam
|lparam
, 0, 0 },
145 { EVENT_OBJECT_CREATE
, winevent_hook
|wparam
|lparam
, 0, 0 },
148 /* SetWindowPos(SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE)
149 * for a not visible overlapped window.
151 static const struct message WmSWP_ShowOverlappedSeq
[] = {
152 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
},
153 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, 0, 0 },
154 { WM_NCPAINT
, sent
|wparam
|optional
, 1 },
155 { WM_GETTEXT
, sent
|defwinproc
|optional
},
156 { WM_ERASEBKGND
, sent
|optional
},
157 { HCBT_ACTIVATE
, hook
},
158 { EVENT_SYSTEM_FOREGROUND
, winevent_hook
|wparam
|lparam
, 0, 0 },
159 { WM_NOTIFYFORMAT
, sent
|optional
},
160 { WM_QUERYUISTATE
, sent
|optional
},
161 { WM_QUERYNEWPALETTE
, sent
|wparam
|lparam
|optional
, 0, 0 },
162 { WM_WINDOWPOSCHANGING
, sent
|wparam
|optional
, SWP_NOSIZE
|SWP_NOMOVE
}, /* Win9x: SWP_NOSENDCHANGING */
163 { WM_ACTIVATEAPP
, sent
|wparam
, 1 },
164 { WM_NCACTIVATE
, sent
|wparam
, 1 },
165 { WM_GETTEXT
, sent
|defwinproc
|optional
},
166 { WM_ACTIVATE
, sent
|wparam
, 1 },
167 { HCBT_SETFOCUS
, hook
},
168 { WM_IME_SETCONTEXT
, sent
|wparam
|defwinproc
|optional
, 1 },
169 { WM_IME_NOTIFY
, sent
|wparam
|defwinproc
|optional
, 2 },
170 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
171 { WM_SETFOCUS
, sent
|wparam
|defwinproc
, 0 },
172 { WM_GETTEXT
, sent
|optional
},
173 { WM_NCPAINT
, sent
|wparam
|optional
, 1 },
174 { WM_GETTEXT
, sent
|defwinproc
|optional
},
175 { WM_ERASEBKGND
, sent
|optional
},
176 /* Win9x adds SWP_NOZORDER below */
177 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
178 { WM_GETTEXT
, sent
|optional
},
179 { WM_NCCALCSIZE
, sent
|wparam
|optional
, 1 },
180 { WM_NCPAINT
, sent
|wparam
|optional
, 1 },
181 { WM_ERASEBKGND
, sent
|optional
},
182 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
183 { WM_PAINT
, sent
|optional
},
184 { WM_NCPAINT
, sent
|beginpaint
|optional
},
185 { WM_ERASEBKGND
, sent
|beginpaint
|optional
},
188 /* SetWindowPos(SWP_HIDEWINDOW|SWP_NOSIZE|SWP_NOMOVE)
189 * for a visible overlapped window.
191 static const struct message WmSWP_HideOverlappedSeq
[] = {
192 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_HIDEWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
},
193 { EVENT_OBJECT_HIDE
, winevent_hook
|wparam
|lparam
, 0, 0 },
194 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_HIDEWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
198 /* SetWindowPos(SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOMOVE)
199 * for a visible overlapped window.
201 static const struct message WmSWP_ResizeSeq
[] = {
202 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_NOACTIVATE
|SWP_NOMOVE
},
203 { WM_GETMINMAXINFO
, sent
|defwinproc
},
204 { WM_NCCALCSIZE
, sent
|wparam
, TRUE
},
205 { WM_NCPAINT
, sent
|optional
},
206 { WM_GETTEXT
, sent
|defwinproc
|optional
},
207 { WM_ERASEBKGND
, sent
|optional
},
208 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_NOACTIVATE
|SWP_NOMOVE
|SWP_NOCLIENTMOVE
},
209 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_RESTORED
},
210 { WM_NCCALCSIZE
, sent
|wparam
|optional
, TRUE
},
211 { WM_NCPAINT
, sent
|optional
},
212 { WM_GETTEXT
, sent
|defwinproc
|optional
},
213 { WM_ERASEBKGND
, sent
|optional
},
214 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
215 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
|optional
, 0, 0 }, /* XP sends a duplicate */
219 /* SetWindowPos(SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOMOVE)
220 * for a visible popup window.
222 static const struct message WmSWP_ResizePopupSeq
[] = {
223 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_NOACTIVATE
|SWP_NOMOVE
},
224 { WM_GETMINMAXINFO
, sent
|defwinproc
|optional
}, /* Win9x */
225 { WM_NCCALCSIZE
, sent
|wparam
, TRUE
},
226 { WM_NCPAINT
, sent
|optional
},
227 { WM_GETTEXT
, sent
|defwinproc
|optional
},
228 { WM_ERASEBKGND
, sent
|optional
},
229 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_NOACTIVATE
|SWP_NOMOVE
|SWP_NOCLIENTMOVE
},
230 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_RESTORED
},
231 { WM_NCCALCSIZE
, sent
|wparam
|optional
, TRUE
},
232 { WM_NCPAINT
, sent
|optional
},
233 { WM_GETTEXT
, sent
|defwinproc
|optional
},
234 { WM_ERASEBKGND
, sent
|optional
},
235 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
239 /* SetWindowPos(SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOSIZE)
240 * for a visible overlapped window.
242 static const struct message WmSWP_MoveSeq
[] = {
243 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_NOACTIVATE
|SWP_NOSIZE
},
244 { WM_NCPAINT
, sent
|optional
},
245 { WM_GETTEXT
, sent
|defwinproc
|optional
},
246 { WM_ERASEBKGND
, sent
|optional
},
247 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOCLIENTSIZE
},
248 { WM_MOVE
, sent
|defwinproc
|wparam
, 0 },
249 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
252 /* Resize with SetWindowPos(SWP_NOZORDER)
253 * for a visible overlapped window
254 * SWP_NOZORDER is stripped by the logging code
256 static const struct message WmSWP_ResizeNoZOrder
[] = {
257 { WM_WINDOWPOSCHANGING
, sent
|wparam
, /*SWP_NOZORDER|*/SWP_NOACTIVATE
},
258 { WM_GETMINMAXINFO
, sent
|defwinproc
},
259 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
260 { WM_NCPAINT
, sent
},
261 { WM_GETTEXT
, sent
|defwinproc
|optional
},
262 { WM_ERASEBKGND
, sent
|optional
}, /* FIXME: remove optional once Wine is fixed */
263 { WM_WINDOWPOSCHANGED
, sent
|wparam
, /*SWP_NOZORDER|*/SWP_NOMOVE
|SWP_NOCLIENTMOVE
|SWP_NOACTIVATE
},
264 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_RESTORED
},
265 { WM_NCCALCSIZE
, sent
|wparam
|optional
, 1 }, /* Win9x doesn't send it */
266 { WM_NCPAINT
, sent
|optional
}, /* Win9x doesn't send it */
267 { WM_GETTEXT
, sent
|defwinproc
|optional
}, /* Win9x doesn't send it */
268 { WM_ERASEBKGND
, sent
|optional
}, /* Win9x doesn't send it */
269 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
270 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
274 /* Switch visible mdi children */
275 static const struct message WmSwitchChild
[] = {
276 /* Switch MDI child */
277 { WM_MDIACTIVATE
, sent
},/* in the MDI client */
278 { WM_WINDOWPOSCHANGING
, sent
|wparam
,SWP_NOSIZE
|SWP_NOMOVE
},/* in the 1st MDI child */
279 { EVENT_OBJECT_REORDER
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
280 { WM_CHILDACTIVATE
, sent
},/* in the 1st MDI child */
281 /* Deactivate 2nd MDI child */
282 { WM_NCACTIVATE
, sent
|wparam
|defwinproc
, 0 }, /* in the 2nd MDI child */
283 { WM_MDIACTIVATE
, sent
|defwinproc
}, /* in the 2nd MDI child */
284 { HCBT_MINMAX
, hook
|lparam
, 0, SW_MAXIMIZE
},
285 /* Preparing for maximize and maximaze the 1st MDI child */
286 { WM_GETMINMAXINFO
, sent
|defwinproc
}, /* in the 1st MDI child */
287 { WM_WINDOWPOSCHANGING
, sent
|wparam
|defwinproc
, SWP_FRAMECHANGED
|SWP_STATECHANGED
}, /* in the 1st MDI child */
288 { WM_NCCALCSIZE
, sent
|wparam
|defwinproc
, 1 }, /* in the 1st MDI child */
289 { WM_CHILDACTIVATE
, sent
|defwinproc
}, /* in the 1st MDI child */
290 { WM_WINDOWPOSCHANGED
, sent
|wparam
|defwinproc
, SWP_FRAMECHANGED
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
|SWP_STATECHANGED
}, /* in the 1st MDI child */
291 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_MAXIMIZED
}, /* in the 1st MDI child */
292 /* Lock redraw 2nd MDI child */
293 { WM_SETREDRAW
, sent
|wparam
|defwinproc
, 0 }, /* in the 2nd MDI child */
294 { HCBT_MINMAX
, hook
|lparam
, 0, SW_NORMALNA
},
295 /* Restore 2nd MDI child */
296 { WM_WINDOWPOSCHANGING
, sent
|wparam
|defwinproc
, SWP_SHOWWINDOW
|SWP_NOACTIVATE
|SWP_FRAMECHANGED
|SWP_STATECHANGED
},/* in the 2nd MDI child */
297 { WM_NCCALCSIZE
, sent
|wparam
|defwinproc
, 1 },/* in the 2nd MDI child */
298 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* in the 2nd MDI child */
299 { WM_WINDOWPOSCHANGED
, sent
|wparam
|defwinproc
, SWP_SHOWWINDOW
|SWP_NOACTIVATE
|SWP_FRAMECHANGED
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
|SWP_STATECHANGED
}, /* in the 2nd MDI child */
300 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_RESTORED
}, /* in the 2nd MDI child */
301 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* in the 2nd MDI child */
302 /* Redraw 2nd MDI child */
303 { WM_SETREDRAW
, sent
|wparam
|defwinproc
, 1 },/* in the 2nd MDI child */
304 /* Redraw MDI frame */
305 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_NOACTIVATE
|SWP_FRAMECHANGED
|SWP_NOSIZE
|SWP_NOMOVE
},/* in MDI frame */
306 { WM_NCCALCSIZE
, sent
|wparam
, 1 },/* in MDI frame */
307 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_NOACTIVATE
|SWP_FRAMECHANGED
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
}, /* in MDI frame */
308 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* in MDI frame */
309 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* in the 1st MDI child */
310 { WM_WINDOWPOSCHANGING
, sent
|wparam
|defwinproc
, SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
}, /* in the 1st MDI child */
311 { WM_NCACTIVATE
, sent
|wparam
|defwinproc
, 1 }, /* in the 1st MDI child */
312 { HCBT_SETFOCUS
, hook
},
313 { WM_KILLFOCUS
, sent
|defwinproc
}, /* in the 2nd MDI child */
314 { WM_IME_SETCONTEXT
, sent
|wparam
|defwinproc
|optional
, 0 },/* in the 1st MDI child */
315 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 1 }, /* in MDI client */
316 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
317 { WM_SETFOCUS
, sent
},/* in the MDI client */
318 { HCBT_SETFOCUS
, hook
},
319 { WM_KILLFOCUS
, sent
},/* in the MDI client */
320 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 0 }, /* in MDI client */
321 { WM_IME_SETCONTEXT
, sent
|wparam
|defwinproc
|optional
, 1 }, /* in the 1st MDI child */
322 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
323 { WM_SETFOCUS
, sent
|defwinproc
}, /* in the 1st MDI child */
324 { WM_MDIACTIVATE
, sent
|defwinproc
},/* in the 1st MDI child */
325 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
}, /* in the 1st MDI child */
329 /* Switch visible not maximized mdi children */
330 static const struct message WmSwitchNotMaximizedChild
[] = {
331 /* Switch not maximized MDI child */
332 { WM_MDIACTIVATE
, sent
},/* in the MDI client */
333 { WM_WINDOWPOSCHANGING
, sent
|wparam
,SWP_NOSIZE
|SWP_NOMOVE
},/* in the 2nd MDI child */
334 { EVENT_OBJECT_REORDER
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
335 { WM_CHILDACTIVATE
, sent
},/* in the 2nd MDI child */
336 /* Deactivate 1st MDI child */
337 { WM_NCACTIVATE
, sent
|wparam
|defwinproc
, 0 }, /* in the 1st MDI child */
338 { WM_MDIACTIVATE
, sent
|defwinproc
}, /* in the 1st MDI child */
339 /* Activate 2nd MDI child */
340 { WM_WINDOWPOSCHANGING
, sent
|wparam
|defwinproc
, SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOACTIVATE
}, /* in the 2nd MDI child */
341 { WM_NCACTIVATE
, sent
|wparam
|defwinproc
, 1 }, /* in the 2nd MDI child */
342 { HCBT_SETFOCUS
, hook
}, /* in the 1st MDI child */
343 { WM_KILLFOCUS
, sent
|defwinproc
}, /* in the 1st MDI child */
344 { WM_IME_SETCONTEXT
, sent
|defwinproc
|optional
}, /* in the 1st MDI child */
345 { WM_IME_SETCONTEXT
, sent
|optional
}, /* in the MDI client */
346 { WM_SETFOCUS
, sent
, 0 }, /* in the MDI client */
347 { HCBT_SETFOCUS
, hook
},
348 { WM_KILLFOCUS
, sent
}, /* in the MDI client */
349 { WM_IME_SETCONTEXT
, sent
|optional
}, /* in the MDI client */
350 { WM_IME_SETCONTEXT
, sent
|defwinproc
|optional
}, /* in the 1st MDI child */
351 { WM_SETFOCUS
, sent
|defwinproc
}, /* in the 2nd MDI child */
352 { WM_MDIACTIVATE
, sent
|defwinproc
}, /* in the 2nd MDI child */
353 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
}, /* in the 2nd MDI child */
358 /* SetWindowPos(SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE|
359 SWP_NOZORDER|SWP_FRAMECHANGED)
360 * for a visible overlapped window with WS_CLIPCHILDREN style set.
362 static const struct message WmSWP_FrameChanged_clip
[] = {
363 { WM_WINDOWPOSCHANGING
, sent
|wparam
|parent
, SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOACTIVATE
|SWP_FRAMECHANGED
},
364 { WM_NCCALCSIZE
, sent
|wparam
|parent
, 1 },
365 { WM_NCPAINT
, sent
|parent
}, /* wparam != 1 */
366 { WM_GETTEXT
, sent
|parent
|defwinproc
|optional
},
367 { WM_ERASEBKGND
, sent
|parent
|optional
}, /* FIXME: remove optional once Wine is fixed */
368 { WM_NCPAINT
, sent
}, /* wparam != 1 */
369 { WM_ERASEBKGND
, sent
},
370 { WM_WINDOWPOSCHANGED
, sent
|wparam
|parent
, SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOACTIVATE
|SWP_FRAMECHANGED
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
371 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
375 /* SetWindowPos(SWP_NOSIZE|SWP_NOMOVE|SWP_DEFERERASE|SWP_NOACTIVATE|
376 SWP_NOZORDER|SWP_FRAMECHANGED)
377 * for a visible overlapped window.
379 static const struct message WmSWP_FrameChangedDeferErase
[] = {
380 { WM_WINDOWPOSCHANGING
, sent
|wparam
|parent
, SWP_NOSIZE
|SWP_NOMOVE
|SWP_DEFERERASE
|SWP_NOACTIVATE
|SWP_FRAMECHANGED
},
381 { WM_NCCALCSIZE
, sent
|wparam
|parent
, 1 },
382 { WM_WINDOWPOSCHANGED
, sent
|wparam
|parent
, SWP_NOSIZE
|SWP_NOMOVE
|SWP_DEFERERASE
|SWP_NOACTIVATE
|SWP_FRAMECHANGED
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
383 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
384 { WM_PAINT
, sent
|parent
},
385 { WM_NCPAINT
, sent
|beginpaint
|parent
}, /* wparam != 1 */
386 { WM_GETTEXT
, sent
|beginpaint
|parent
|defwinproc
|optional
},
388 { WM_NCPAINT
, sent
|beginpaint
}, /* wparam != 1 */
389 { WM_ERASEBKGND
, sent
|beginpaint
},
393 /* SetWindowPos(SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE|
394 SWP_NOZORDER|SWP_FRAMECHANGED)
395 * for a visible overlapped window without WS_CLIPCHILDREN style set.
397 static const struct message WmSWP_FrameChanged_noclip
[] = {
398 { WM_WINDOWPOSCHANGING
, sent
|wparam
|parent
, SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOACTIVATE
|SWP_FRAMECHANGED
},
399 { WM_NCCALCSIZE
, sent
|wparam
|parent
, 1 },
400 { WM_NCPAINT
, sent
|parent
}, /* wparam != 1 */
401 { WM_GETTEXT
, sent
|parent
|defwinproc
|optional
},
402 { WM_ERASEBKGND
, sent
|parent
|optional
}, /* FIXME: remove optional once Wine is fixed */
403 { WM_WINDOWPOSCHANGED
, sent
|wparam
|parent
, SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOACTIVATE
|SWP_FRAMECHANGED
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
404 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
406 { WM_NCPAINT
, sent
|beginpaint
}, /* wparam != 1 */
407 { WM_ERASEBKGND
, sent
|beginpaint
},
411 /* ShowWindow(SW_SHOW) for a not visible overlapped window */
412 static const struct message WmShowOverlappedSeq
[] = {
413 { WM_SHOWWINDOW
, sent
|wparam
, 1 },
414 { WM_NCPAINT
, sent
|wparam
|optional
, 1 },
415 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
},
416 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, 0, 0 },
417 { WM_NCPAINT
, sent
|wparam
|optional
, 1 },
418 { WM_GETTEXT
, sent
|defwinproc
|optional
},
419 { WM_ERASEBKGND
, sent
|optional
},
420 { HCBT_ACTIVATE
, hook
},
421 { EVENT_SYSTEM_FOREGROUND
, winevent_hook
|wparam
|lparam
, 0, 0 },
422 { WM_QUERYNEWPALETTE
, sent
|wparam
|lparam
|optional
, 0, 0 },
423 { WM_WINDOWPOSCHANGING
, sent
|wparam
|optional
, SWP_NOSIZE
|SWP_NOMOVE
},
424 { WM_NCPAINT
, sent
|wparam
|optional
, 1 },
425 { WM_ACTIVATEAPP
, sent
|wparam
, 1 },
426 { WM_NCACTIVATE
, sent
|wparam
, 1 },
427 { WM_GETTEXT
, sent
|defwinproc
|optional
},
428 { WM_ACTIVATE
, sent
|wparam
, 1 },
429 { HCBT_SETFOCUS
, hook
},
430 { WM_IME_SETCONTEXT
, sent
|wparam
|defwinproc
|optional
, 1 },
431 { WM_IME_NOTIFY
, sent
|wparam
|defwinproc
|optional
, 2 },
432 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
433 { WM_SETFOCUS
, sent
|wparam
|defwinproc
, 0 },
434 { WM_GETTEXT
, sent
|optional
},
435 { WM_NCPAINT
, sent
|wparam
|optional
, 1 },
436 { WM_GETTEXT
, sent
|defwinproc
|optional
},
437 { WM_ERASEBKGND
, sent
|optional
},
438 /* Win9x adds SWP_NOZORDER below */
439 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
440 { WM_NCCALCSIZE
, sent
|optional
},
441 { WM_GETTEXT
, sent
|optional
},
442 { WM_NCPAINT
, sent
|optional
},
443 { WM_ERASEBKGND
, sent
|optional
},
444 #if 0 /* CreateWindow/ShowWindow(SW_SHOW) also generates WM_SIZE/WM_MOVE
445 * messages. Does that mean that CreateWindow doesn't set initial
446 * window dimensions for overlapped windows?
451 { WM_PAINT
, sent
|optional
},
452 { WM_NCPAINT
, sent
|beginpaint
|optional
},
455 /* ShowWindow(SW_SHOWMAXIMIZED) for a not visible overlapped window */
456 static const struct message WmShowMaxOverlappedSeq
[] = {
457 { HCBT_MINMAX
, hook
|lparam
, 0, SW_MAXIMIZE
},
458 { WM_GETMINMAXINFO
, sent
},
459 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_FRAMECHANGED
|SWP_STATECHANGED
},
460 { WM_GETMINMAXINFO
, sent
|defwinproc
},
461 { WM_NCCALCSIZE
, sent
|wparam
, TRUE
},
462 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, 0, 0 },
463 { HCBT_ACTIVATE
, hook
},
464 { EVENT_SYSTEM_FOREGROUND
, winevent_hook
|wparam
|lparam
, 0, 0 },
465 { WM_QUERYNEWPALETTE
, sent
|wparam
|lparam
|optional
, 0, 0 },
466 { WM_WINDOWPOSCHANGING
, sent
|wparam
|optional
, SWP_NOSIZE
|SWP_NOMOVE
},
467 { WM_ACTIVATEAPP
, sent
|wparam
, 1 },
468 { WM_NCACTIVATE
, sent
|wparam
, 1 },
469 { WM_GETTEXT
, sent
|defwinproc
|optional
},
470 { WM_ACTIVATE
, sent
|wparam
, 1 },
471 { HCBT_SETFOCUS
, hook
},
472 { WM_IME_SETCONTEXT
, sent
|wparam
|defwinproc
|optional
, 1 },
473 { WM_IME_NOTIFY
, sent
|wparam
|defwinproc
|optional
, 2 },
474 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
475 { WM_SETFOCUS
, sent
|wparam
|defwinproc
, 0 },
476 { WM_GETTEXT
, sent
|optional
},
477 { WM_NCPAINT
, sent
|wparam
|optional
, 1 },
478 { WM_GETTEXT
, sent
|defwinproc
|optional
},
479 { WM_ERASEBKGND
, sent
|optional
},
480 /* Win9x adds SWP_NOZORDER below */
481 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_FRAMECHANGED
|SWP_STATECHANGED
},
482 { WM_MOVE
, sent
|defwinproc
},
483 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_MAXIMIZED
},
484 { WM_GETTEXT
, sent
|optional
},
485 { WM_NCCALCSIZE
, sent
|optional
},
486 { WM_NCPAINT
, sent
|optional
},
487 { WM_ERASEBKGND
, sent
|optional
},
488 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
489 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
490 { WM_PAINT
, sent
|optional
},
491 { WM_NCPAINT
, sent
|beginpaint
|optional
},
492 { WM_ERASEBKGND
, sent
|beginpaint
|optional
},
495 /* ShowWindow(SW_RESTORE) for a not visible maximized overlapped window */
496 static const struct message WmShowRestoreMaxOverlappedSeq
[] = {
497 { HCBT_MINMAX
, hook
|lparam
, 0, SW_RESTORE
},
498 { WM_GETTEXT
, sent
|optional
},
499 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_STATECHANGED
},
500 { WM_GETMINMAXINFO
, sent
|defwinproc
},
501 { WM_NCCALCSIZE
, sent
|wparam
, TRUE
},
502 { WM_NCPAINT
, sent
|optional
},
503 { WM_GETTEXT
, sent
|defwinproc
|optional
},
504 { WM_ERASEBKGND
, sent
|optional
},
505 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_STATECHANGED
, 0, SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
|SWP_NOSIZE
|SWP_NOMOVE
},
506 { WM_MOVE
, sent
|defwinproc
|optional
},
507 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_RESTORED
},
508 { WM_NCCALCSIZE
, sent
|wparam
|optional
, TRUE
},
509 { WM_NCPAINT
, sent
|optional
},
510 { WM_ERASEBKGND
, sent
|optional
},
511 { WM_PAINT
, sent
|optional
},
512 { WM_NCPAINT
, sent
|beginpaint
|optional
},
513 { WM_ERASEBKGND
, sent
|beginpaint
|optional
},
516 /* ShowWindow(SW_RESTORE) for a not visible minimized overlapped window */
517 static const struct message WmShowRestoreMinOverlappedSeq
[] = {
518 { HCBT_MINMAX
, hook
|lparam
, 0, SW_RESTORE
},
519 { WM_QUERYOPEN
, sent
|optional
},
520 { WM_GETTEXT
, sent
|optional
},
521 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_STATECHANGED
|SWP_NOCOPYBITS
},
522 { WM_GETMINMAXINFO
, sent
|defwinproc
},
523 { WM_NCCALCSIZE
, sent
|wparam
, TRUE
},
524 { HCBT_ACTIVATE
, hook
},
525 { WM_QUERYNEWPALETTE
, sent
|wparam
|lparam
|optional
, 0, 0 },
526 { WM_WINDOWPOSCHANGING
, sent
|wparam
|optional
, SWP_NOSIZE
|SWP_NOMOVE
},
527 { WM_ACTIVATEAPP
, sent
|wparam
, 1 },
528 { WM_NCACTIVATE
, sent
|wparam
, 1 },
529 { WM_GETTEXT
, sent
|defwinproc
|optional
},
530 { WM_ACTIVATE
, sent
|wparam
, 1 },
531 { HCBT_SETFOCUS
, hook
},
532 { WM_IME_SETCONTEXT
, sent
|wparam
|defwinproc
|optional
, 1 },
533 { WM_IME_NOTIFY
, sent
|wparam
|defwinproc
|optional
, 2 },
534 { WM_SETFOCUS
, sent
|wparam
|defwinproc
, 0 },
535 { WM_GETTEXT
, sent
|optional
},
536 { WM_NCPAINT
, sent
|wparam
|optional
, 1 },
537 { WM_GETTEXT
, sent
|defwinproc
|optional
},
538 { WM_ERASEBKGND
, sent
},
539 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_STATECHANGED
|SWP_FRAMECHANGED
|SWP_NOCOPYBITS
},
540 { WM_MOVE
, sent
|defwinproc
},
541 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_RESTORED
},
542 { WM_NCCALCSIZE
, sent
|wparam
|optional
, TRUE
},
543 { WM_NCPAINT
, sent
|wparam
|optional
, 1 },
544 { WM_ERASEBKGND
, sent
|optional
},
545 { WM_ACTIVATE
, sent
|wparam
, 1 },
546 { WM_GETTEXT
, sent
|optional
},
547 { WM_PAINT
, sent
|optional
},
548 { WM_NCPAINT
, sent
|beginpaint
|optional
},
549 { WM_ERASEBKGND
, sent
|beginpaint
|optional
},
552 /* ShowWindow(SW_SHOWMINIMIZED) for a not visible overlapped window */
553 static const struct message WmShowMinOverlappedSeq
[] = {
554 { HCBT_MINMAX
, hook
|lparam
, 0, SW_MINIMIZE
},
555 { HCBT_SETFOCUS
, hook
},
556 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
557 { WM_KILLFOCUS
, sent
},
558 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 0 },
559 { WM_IME_NOTIFY
, sent
|wparam
|optional
|defwinproc
, 1 },
560 { WM_GETTEXT
, sent
|optional
},
561 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_NOCOPYBITS
|SWP_SHOWWINDOW
|SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_STATECHANGED
},
562 { WM_GETMINMAXINFO
, sent
|defwinproc
},
563 { WM_NCCALCSIZE
, sent
|wparam
, TRUE
},
564 { EVENT_OBJECT_REORDER
, winevent_hook
|wparam
|lparam
, 0, 0 },
565 { WM_NCPAINT
, sent
|optional
},
566 { WM_GETTEXT
, sent
|defwinproc
|optional
},
567 { WM_WINDOWPOSCHANGED
, sent
},
568 { WM_MOVE
, sent
|defwinproc
},
569 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_MINIMIZED
},
570 { WM_NCCALCSIZE
, sent
|optional
},
571 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
572 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
573 { EVENT_SYSTEM_MINIMIZESTART
, winevent_hook
|wparam
|lparam
, 0, 0 },
574 { WM_NCACTIVATE
, sent
|wparam
, 0 },
575 { WM_GETTEXT
, sent
|defwinproc
|optional
},
576 { WM_ACTIVATE
, sent
},
577 { WM_ACTIVATEAPP
, sent
|wparam
, 0 },
578 { WM_PAINT
, sent
|optional
},
579 { WM_NCPAINT
, sent
|beginpaint
|optional
},
580 { WM_ERASEBKGND
, sent
|beginpaint
|optional
},
583 /* ShowWindow(SW_HIDE) for a visible overlapped window */
584 static const struct message WmHideOverlappedSeq
[] = {
585 { WM_SHOWWINDOW
, sent
|wparam
, 0 },
586 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_HIDEWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
},
587 { EVENT_OBJECT_HIDE
, winevent_hook
|wparam
|lparam
, 0, 0 },
588 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_HIDEWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
589 { WM_SIZE
, sent
|optional
}, /* XP doesn't send it */
590 { WM_MOVE
, sent
|optional
}, /* XP doesn't send it */
591 { WM_NCACTIVATE
, sent
|wparam
, 0 },
592 { WM_ACTIVATE
, sent
|wparam
, 0 },
593 { WM_ACTIVATEAPP
, sent
|wparam
, 0 },
594 { WM_KILLFOCUS
, sent
|wparam
, 0 },
595 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 0 },
596 { WM_IME_NOTIFY
, sent
|wparam
|optional
|defwinproc
, 1 },
599 /* DestroyWindow for a visible overlapped window */
600 static const struct message WmDestroyOverlappedSeq
[] = {
601 { HCBT_DESTROYWND
, hook
},
602 { 0x0090, sent
|optional
},
603 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_HIDEWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
604 { EVENT_OBJECT_HIDE
, winevent_hook
|wparam
|lparam
, 0, 0 },
605 { 0x0090, sent
|optional
},
606 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_HIDEWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
607 { WM_NCACTIVATE
, sent
|optional
|wparam
, 0 },
608 { WM_ACTIVATE
, sent
|optional
|wparam
, 0 },
609 { WM_ACTIVATEAPP
, sent
|optional
|wparam
, 0 },
610 { WM_KILLFOCUS
, sent
|optional
|wparam
, 0 },
611 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 0 },
612 { WM_IME_NOTIFY
, sent
|wparam
|optional
|defwinproc
, 1 },
613 { EVENT_OBJECT_DESTROY
, winevent_hook
|wparam
|lparam
, 0, 0 },
614 { WM_DESTROY
, sent
},
615 { WM_NCDESTROY
, sent
},
618 /* CreateWindow(WS_MAXIMIZE|WS_VISIBLE) for popup window */
619 static const struct message WmCreateMaxPopupSeq
[] = {
620 { HCBT_CREATEWND
, hook
},
621 { WM_NCCREATE
, sent
},
622 { WM_NCCALCSIZE
, sent
|wparam
, 0 },
624 { EVENT_OBJECT_CREATE
, winevent_hook
|wparam
|lparam
, 0, 0 },
625 { WM_SIZE
, sent
|wparam
, SIZE_RESTORED
},
627 { HCBT_MINMAX
, hook
|lparam
, 0, SW_MAXIMIZE
},
628 { WM_GETMINMAXINFO
, sent
},
629 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_NOACTIVATE
|SWP_FRAMECHANGED
|SWP_STATECHANGED
},
630 { WM_NCCALCSIZE
, sent
|wparam
, TRUE
},
631 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_NOACTIVATE
|SWP_FRAMECHANGED
|SWP_NOREDRAW
|SWP_STATECHANGED
},
632 { WM_MOVE
, sent
|defwinproc
},
633 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_MAXIMIZED
},
634 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
635 { WM_SHOWWINDOW
, sent
|wparam
, 1 },
636 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
},
637 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, 0, 0 },
638 { HCBT_ACTIVATE
, hook
},
639 { EVENT_SYSTEM_FOREGROUND
, winevent_hook
|wparam
|lparam
, 0, 0 },
640 { WM_QUERYNEWPALETTE
, sent
|wparam
|lparam
|optional
, 0, 0 },
641 { WM_WINDOWPOSCHANGING
, sent
|wparam
|optional
, SWP_NOSIZE
|SWP_NOMOVE
},
642 { WM_NCPAINT
, sent
|wparam
|optional
, 1 },
643 { WM_ERASEBKGND
, sent
|optional
},
644 { WM_WINDOWPOSCHANGED
, sent
|wparam
|optional
, SWP_NOCLIENTMOVE
|SWP_NOCLIENTSIZE
|SWP_NOMOVE
|SWP_NOSIZE
},
645 { WM_ACTIVATEAPP
, sent
|wparam
, 1 },
646 { WM_NCACTIVATE
, sent
|wparam
, 1 },
647 { WM_ACTIVATE
, sent
|wparam
, 1 },
648 { HCBT_SETFOCUS
, hook
},
649 { WM_IME_SETCONTEXT
, sent
|wparam
|defwinproc
|optional
, 1 },
650 { WM_IME_NOTIFY
, sent
|wparam
|defwinproc
|optional
, 2 },
651 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
652 { WM_SETFOCUS
, sent
|wparam
|defwinproc
, 0 },
653 { WM_GETTEXT
, sent
|optional
},
654 { WM_SYNCPAINT
, sent
|wparam
|optional
, 4 },
655 { WM_NCPAINT
, sent
|wparam
|optional
, 1 },
656 { WM_ERASEBKGND
, sent
|optional
},
657 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_NOCLIENTMOVE
|SWP_NOCLIENTSIZE
|SWP_SHOWWINDOW
|SWP_NOMOVE
|SWP_NOSIZE
},
660 /* CreateWindow(WS_MAXIMIZE) for popup window, not initially visible */
661 static const struct message WmCreateInvisibleMaxPopupSeq
[] = {
662 { HCBT_CREATEWND
, hook
},
663 { WM_NCCREATE
, sent
},
664 { WM_NCCALCSIZE
, sent
|wparam
, 0 },
666 { EVENT_OBJECT_CREATE
, winevent_hook
|wparam
|lparam
, 0, 0 },
667 { WM_SIZE
, sent
|wparam
, SIZE_RESTORED
},
669 { HCBT_MINMAX
, hook
|lparam
, 0, SW_MAXIMIZE
},
670 { WM_GETMINMAXINFO
, sent
},
671 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_NOACTIVATE
|SWP_FRAMECHANGED
|SWP_STATECHANGED
},
672 { WM_NCCALCSIZE
, sent
|wparam
, TRUE
},
673 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_NOACTIVATE
|SWP_FRAMECHANGED
|SWP_NOREDRAW
|SWP_STATECHANGED
},
674 { WM_MOVE
, sent
|defwinproc
},
675 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_MAXIMIZED
},
676 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
679 /* ShowWindow(SW_SHOWMAXIMIZED) for a resized not visible popup window */
680 static const struct message WmShowMaxPopupResizedSeq
[] = {
681 { HCBT_MINMAX
, hook
|lparam
, 0, SW_MAXIMIZE
},
682 { WM_GETMINMAXINFO
, sent
},
683 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_FRAMECHANGED
},
684 { WM_NCCALCSIZE
, sent
|wparam
, TRUE
},
685 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, 0, 0 },
686 { HCBT_ACTIVATE
, hook
},
687 { EVENT_SYSTEM_FOREGROUND
, winevent_hook
|wparam
|lparam
, 0, 0 },
688 { WM_QUERYNEWPALETTE
, sent
|wparam
|lparam
|optional
, 0, 0 },
689 { WM_WINDOWPOSCHANGING
, sent
|wparam
|optional
, SWP_NOSIZE
|SWP_NOMOVE
},
690 { WM_ACTIVATEAPP
, sent
|wparam
, 1 },
691 { WM_NCACTIVATE
, sent
|wparam
, 1 },
692 { WM_ACTIVATE
, sent
|wparam
, 1 },
693 { HCBT_SETFOCUS
, hook
},
694 { WM_IME_SETCONTEXT
, sent
|wparam
|defwinproc
|optional
, 1 },
695 { WM_IME_NOTIFY
, sent
|wparam
|defwinproc
|optional
, 2 },
696 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
697 { WM_SETFOCUS
, sent
|wparam
|defwinproc
, 0 },
698 { WM_GETTEXT
, sent
|optional
},
699 { WM_NCPAINT
, sent
|wparam
|optional
, 1 },
700 { WM_ERASEBKGND
, sent
|optional
},
701 { WM_WINDOWPOSCHANGED
, sent
},
702 /* WinNT4.0 sends WM_MOVE */
703 { WM_MOVE
, sent
|defwinproc
|optional
},
704 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_MAXIMIZED
},
705 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
708 /* ShowWindow(SW_SHOWMAXIMIZED) for a not visible popup window */
709 static const struct message WmShowMaxPopupSeq
[] = {
710 { HCBT_MINMAX
, hook
|lparam
, 0, SW_MAXIMIZE
},
711 { WM_GETMINMAXINFO
, sent
},
712 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_FRAMECHANGED
},
713 { WM_NCCALCSIZE
, sent
|wparam
, TRUE
},
714 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, 0, 0 },
715 { HCBT_ACTIVATE
, hook
},
716 { EVENT_SYSTEM_FOREGROUND
, winevent_hook
|wparam
|lparam
, 0, 0 },
717 { WM_QUERYNEWPALETTE
, sent
|wparam
|lparam
|optional
, 0, 0 },
718 { WM_WINDOWPOSCHANGING
, sent
|wparam
|optional
, SWP_NOSIZE
|SWP_NOMOVE
},
719 { WM_ACTIVATEAPP
, sent
|wparam
, 1 },
720 { WM_NCACTIVATE
, sent
|wparam
, 1 },
721 { WM_ACTIVATE
, sent
|wparam
, 1 },
722 { HCBT_SETFOCUS
, hook
},
723 { WM_IME_SETCONTEXT
, sent
|wparam
|defwinproc
|optional
, 1 },
724 { WM_IME_NOTIFY
, sent
|wparam
|defwinproc
|optional
, 2 },
725 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
726 { WM_SETFOCUS
, sent
|wparam
|defwinproc
, 0 },
727 { WM_GETTEXT
, sent
|optional
},
728 { WM_SYNCPAINT
, sent
|wparam
|optional
, 4 },
729 { WM_NCPAINT
, sent
|wparam
|optional
, 1 },
730 { WM_ERASEBKGND
, sent
|optional
},
731 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
|SWP_SHOWWINDOW
|SWP_FRAMECHANGED
|SWP_NOMOVE
|SWP_NOSIZE
},
732 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
735 /* CreateWindow(WS_VISIBLE) for popup window */
736 static const struct message WmCreatePopupSeq
[] = {
737 { HCBT_CREATEWND
, hook
},
738 { WM_NCCREATE
, sent
},
739 { WM_NCCALCSIZE
, sent
|wparam
, 0 },
741 { EVENT_OBJECT_CREATE
, winevent_hook
|wparam
|lparam
, 0, 0 },
742 { WM_SIZE
, sent
|wparam
, SIZE_RESTORED
},
744 { WM_SHOWWINDOW
, sent
|wparam
, 1 },
745 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
},
746 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, 0, 0 },
747 { HCBT_ACTIVATE
, hook
},
748 { EVENT_SYSTEM_FOREGROUND
, winevent_hook
|wparam
|lparam
, 0, 0 },
749 { WM_QUERYNEWPALETTE
, sent
|wparam
|lparam
|optional
, 0, 0 },
750 { WM_WINDOWPOSCHANGING
, sent
|wparam
|optional
, SWP_NOSIZE
|SWP_NOMOVE
},
751 { WM_NCPAINT
, sent
|wparam
|optional
, 1 },
752 { WM_ERASEBKGND
, sent
|optional
},
753 { WM_ACTIVATEAPP
, sent
|wparam
, 1 },
754 { WM_NCACTIVATE
, sent
|wparam
, 1 },
755 { WM_ACTIVATE
, sent
|wparam
, 1 },
756 { HCBT_SETFOCUS
, hook
},
757 { WM_IME_SETCONTEXT
, sent
|wparam
|defwinproc
|optional
, 1 },
758 { WM_IME_NOTIFY
, sent
|wparam
|defwinproc
|optional
, 2 },
759 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
760 { WM_SETFOCUS
, sent
|wparam
|defwinproc
, 0 },
761 { WM_GETTEXT
, sent
|optional
},
762 { WM_SYNCPAINT
, sent
|wparam
|optional
, 4 },
763 { WM_NCPAINT
, sent
|wparam
|optional
, 1 },
764 { WM_ERASEBKGND
, sent
|optional
},
765 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_NOCLIENTMOVE
|SWP_NOCLIENTSIZE
|SWP_SHOWWINDOW
|SWP_NOMOVE
|SWP_NOSIZE
},
768 /* ShowWindow(SW_SHOWMAXIMIZED) for a visible popup window */
769 static const struct message WmShowVisMaxPopupSeq
[] = {
770 { HCBT_MINMAX
, hook
|lparam
, 0, SW_MAXIMIZE
},
771 { WM_GETMINMAXINFO
, sent
},
772 { WM_GETTEXT
, sent
|optional
},
773 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_STATECHANGED
},
774 { WM_GETTEXT
, sent
|optional
},
775 { WM_NCCALCSIZE
, sent
|wparam
, TRUE
},
776 { WM_QUERYNEWPALETTE
, sent
|wparam
|lparam
|optional
, 0, 0 },
777 { WM_NCPAINT
, sent
|wparam
|optional
, 1 },
778 { WM_ERASEBKGND
, sent
|optional
},
779 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_STATECHANGED
},
780 { WM_MOVE
, sent
|defwinproc
},
781 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_MAXIMIZED
},
782 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
785 /* CreateWindow (for a child popup window, not initially visible) */
786 static const struct message WmCreateChildPopupSeq
[] = {
787 { HCBT_CREATEWND
, hook
},
788 { WM_NCCREATE
, sent
},
789 { WM_NCCALCSIZE
, sent
|wparam
, 0 },
791 { EVENT_OBJECT_CREATE
, winevent_hook
|wparam
|lparam
, 0, 0 },
792 { WM_SIZE
, sent
|wparam
, SIZE_RESTORED
},
796 /* CreateWindow (for a popup window, not initially visible,
797 * which sets WS_VISIBLE in WM_CREATE handler)
799 static const struct message WmCreateInvisiblePopupSeq
[] = {
800 { HCBT_CREATEWND
, hook
},
801 { WM_NCCREATE
, sent
},
802 { WM_NCCALCSIZE
, sent
|wparam
, 0 },
804 { WM_STYLECHANGING
, sent
},
805 { WM_STYLECHANGED
, sent
},
806 { EVENT_OBJECT_CREATE
, winevent_hook
|wparam
|lparam
, 0, 0 },
807 { WM_SIZE
, sent
|wparam
, SIZE_RESTORED
},
811 /* SetWindowPos(SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE|SWP_NOZORDER)
812 * for a popup window with WS_VISIBLE style set
814 static const struct message WmShowVisiblePopupSeq_2
[] = {
815 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
818 /* SetWindowPos(SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE)
819 * for a popup window with WS_VISIBLE style set
821 static const struct message WmShowVisiblePopupSeq_3
[] = {
822 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
},
823 { HCBT_ACTIVATE
, hook
},
824 { EVENT_SYSTEM_FOREGROUND
, winevent_hook
|wparam
|lparam
, 0, 0 },
825 { WM_QUERYNEWPALETTE
, sent
|wparam
|lparam
|optional
, 0, 0 },
826 { WM_WINDOWPOSCHANGING
, sent
|wparam
|optional
, SWP_NOSIZE
|SWP_NOMOVE
},
827 { WM_NCACTIVATE
, sent
|wparam
, 1 },
828 { WM_ACTIVATE
, sent
|wparam
, 1 },
829 { HCBT_SETFOCUS
, hook
},
830 { WM_KILLFOCUS
, sent
|parent
},
831 { WM_IME_SETCONTEXT
, sent
|parent
|wparam
|optional
, 0 },
832 { WM_IME_SETCONTEXT
, sent
|wparam
|defwinproc
|optional
, 1 },
833 { WM_IME_NOTIFY
, sent
|wparam
|defwinproc
|optional
, 2 },
834 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
835 { WM_SETFOCUS
, sent
|defwinproc
},
836 { WM_GETTEXT
, sent
|optional
},
839 /* CreateWindow (for child window, not initially visible) */
840 static const struct message WmCreateChildSeq
[] = {
841 { HCBT_CREATEWND
, hook
},
842 { WM_NCCREATE
, sent
},
843 /* child is inserted into parent's child list after WM_NCCREATE returns */
844 { WM_NCCALCSIZE
, sent
|wparam
, 0 },
846 { EVENT_OBJECT_CREATE
, winevent_hook
|wparam
|lparam
, 0, 0 },
847 { WM_SIZE
, sent
|wparam
, SIZE_RESTORED
},
849 { WM_PARENTNOTIFY
, sent
|parent
|wparam
, WM_CREATE
},
852 /* CreateWindow (for maximized child window, not initially visible) */
853 static const struct message WmCreateMaximizedChildSeq
[] = {
854 { HCBT_CREATEWND
, hook
},
855 { WM_NCCREATE
, sent
},
856 { WM_NCCALCSIZE
, sent
|wparam
, 0 },
858 { EVENT_OBJECT_CREATE
, winevent_hook
|wparam
|lparam
, 0, 0 },
859 { WM_SIZE
, sent
|wparam
, SIZE_RESTORED
},
861 { HCBT_MINMAX
, hook
|lparam
, 0, SW_MAXIMIZE
},
862 { WM_GETMINMAXINFO
, sent
},
863 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_STATECHANGED
},
864 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
865 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOMOVE
|SWP_NOREDRAW
|SWP_NOCLIENTMOVE
|SWP_STATECHANGED
},
866 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_MAXIMIZED
},
867 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
868 { WM_PARENTNOTIFY
, sent
|parent
|wparam
, WM_CREATE
},
871 /* CreateWindow (for a child window, initially visible) */
872 static const struct message WmCreateVisibleChildSeq
[] = {
873 { HCBT_CREATEWND
, hook
},
874 { WM_NCCREATE
, sent
},
875 /* child is inserted into parent's child list after WM_NCCREATE returns */
876 { WM_NCCALCSIZE
, sent
|wparam
, 0 },
877 { EVENT_OBJECT_REORDER
, winevent_hook
|wparam
|lparam
, 0, 0 },
879 { EVENT_OBJECT_CREATE
, winevent_hook
|wparam
|lparam
, 0, 0 },
880 { WM_SIZE
, sent
|wparam
, SIZE_RESTORED
},
882 { WM_PARENTNOTIFY
, sent
|parent
|wparam
, WM_CREATE
},
883 { WM_SHOWWINDOW
, sent
|wparam
, 1 },
884 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOACTIVATE
},
885 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, 0, 0 },
886 { WM_ERASEBKGND
, sent
|parent
|optional
},
887 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOACTIVATE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
888 { WM_NCCALCSIZE
, sent
|wparam
|optional
, 1 }, /* WinXP */
889 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
892 /* ShowWindow(SW_SHOW) for a not visible child window */
893 static const struct message WmShowChildSeq
[] = {
894 { WM_SHOWWINDOW
, sent
|wparam
, 1 },
895 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
896 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, 0, 0 },
897 { WM_ERASEBKGND
, sent
|parent
|optional
},
898 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
901 /* ShowWindow(SW_HIDE) for a visible child window */
902 static const struct message WmHideChildSeq
[] = {
903 { WM_SHOWWINDOW
, sent
|wparam
, 0 },
904 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_HIDEWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
905 { EVENT_OBJECT_HIDE
, winevent_hook
|wparam
|lparam
, 0, 0 },
906 { WM_ERASEBKGND
, sent
|parent
|optional
},
907 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_HIDEWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
910 /* ShowWindow(SW_HIDE) for a visible child window checking all parent events*/
911 static const struct message WmHideChildSeq2
[] = {
912 { WM_SHOWWINDOW
, sent
|wparam
, 0 },
913 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_HIDEWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
914 { EVENT_OBJECT_HIDE
, winevent_hook
|wparam
|lparam
, 0, 0 },
915 { WM_ERASEBKGND
, sent
|parent
},
916 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_HIDEWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
919 /* SetWindowPos(SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE)
920 * for a not visible child window
922 static const struct message WmShowChildSeq_2
[] = {
923 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
},
924 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, 0, 0 },
925 { WM_CHILDACTIVATE
, sent
},
926 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
929 /* SetWindowPos(SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE)
930 * for a not visible child window
932 static const struct message WmShowChildSeq_3
[] = {
933 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOACTIVATE
},
934 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, 0, 0 },
935 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOACTIVATE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
938 /* SetWindowPos(SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE)
939 * for a visible child window with a caption
941 static const struct message WmShowChildSeq_4
[] = {
942 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
},
943 { WM_CHILDACTIVATE
, sent
},
946 /* ShowWindow(SW_MINIMIZE) for child with invisible parent */
947 static const struct message WmShowChildInvisibleParentSeq_1
[] = {
948 { HCBT_MINMAX
, hook
|lparam
, 0, SW_MINIMIZE
},
949 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_FRAMECHANGED
|SWP_NOCOPYBITS
|SWP_STATECHANGED
, 0, SWP_NOACTIVATE
},
950 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
951 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, 0, 0 },
952 { WM_CHILDACTIVATE
, sent
|optional
},
953 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_FRAMECHANGED
|SWP_NOREDRAW
|SWP_NOCOPYBITS
|SWP_STATECHANGED
, 0, SWP_NOACTIVATE
},
954 { WM_MOVE
, sent
|defwinproc
},
955 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_MINIMIZED
},
956 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
957 { EVENT_SYSTEM_MINIMIZESTART
, winevent_hook
|wparam
|lparam
, 0, 0 },
958 /* FIXME: Wine creates an icon/title window while Windows doesn't */
959 { WM_PARENTNOTIFY
, sent
|parent
|wparam
|optional
, WM_CREATE
},
960 { WM_GETTEXT
, sent
|optional
},
963 /* repeated ShowWindow(SW_MINIMIZE) for child with invisible parent */
964 static const struct message WmShowChildInvisibleParentSeq_1r
[] = {
965 { HCBT_MINMAX
, hook
|lparam
, 0, SW_MINIMIZE
},
968 /* ShowWindow(SW_MAXIMIZE) for child with invisible parent */
969 static const struct message WmShowChildInvisibleParentSeq_2
[] = {
970 { HCBT_MINMAX
, hook
|lparam
, 0, SW_MAXIMIZE
},
971 { WM_GETMINMAXINFO
, sent
},
972 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_FRAMECHANGED
|SWP_STATECHANGED
},
973 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
974 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, 0, 0 },
975 { WM_CHILDACTIVATE
, sent
},
976 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_FRAMECHANGED
|SWP_NOMOVE
|SWP_NOREDRAW
|SWP_NOCLIENTMOVE
|SWP_STATECHANGED
},
977 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_MAXIMIZED
},
978 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
981 /* repeated ShowWindow(SW_MAXIMIZE) for child with invisible parent */
982 static const struct message WmShowChildInvisibleParentSeq_2r
[] = {
983 { HCBT_MINMAX
, hook
|lparam
, 0, SW_MAXIMIZE
},
986 /* ShowWindow(SW_SHOWMINIMIZED) for child with invisible parent */
987 static const struct message WmShowChildInvisibleParentSeq_3
[] = {
988 { HCBT_MINMAX
, hook
|lparam
, 0, SW_SHOWMINIMIZED
},
989 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_FRAMECHANGED
|SWP_NOCOPYBITS
|SWP_STATECHANGED
},
990 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
991 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, 0, 0 },
992 { WM_CHILDACTIVATE
, sent
},
993 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_FRAMECHANGED
|SWP_NOREDRAW
|SWP_NOCOPYBITS
|SWP_STATECHANGED
},
994 { WM_MOVE
, sent
|defwinproc
},
995 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_MINIMIZED
},
996 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
997 { EVENT_SYSTEM_MINIMIZESTART
, winevent_hook
|wparam
|lparam
, 0, 0 },
998 /* FIXME: Wine creates an icon/title window while Windows doesn't */
999 { WM_PARENTNOTIFY
, sent
|parent
|wparam
|optional
, WM_CREATE
},
1000 { WM_GETTEXT
, sent
|optional
},
1003 /* repeated ShowWindow(SW_SHOWMINIMIZED) for child with invisible parent */
1004 static const struct message WmShowChildInvisibleParentSeq_3r
[] = {
1005 { HCBT_MINMAX
, hook
|lparam
, 0, SW_SHOWMINIMIZED
},
1008 /* ShowWindow(SW_SHOWMINNOACTIVE) for child with invisible parent */
1009 static const struct message WmShowChildInvisibleParentSeq_4
[] = {
1010 { HCBT_MINMAX
, hook
|lparam
, 0, SW_SHOWMINNOACTIVE
},
1011 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOCOPYBITS
|SWP_STATECHANGED
},
1012 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
1013 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, 0, 0 },
1014 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOREDRAW
|SWP_NOCOPYBITS
|SWP_STATECHANGED
},
1015 { WM_MOVE
, sent
|defwinproc
},
1016 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_MINIMIZED
},
1017 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
1018 { EVENT_SYSTEM_MINIMIZESTART
, winevent_hook
|wparam
|lparam
, 0, 0 },
1019 /* FIXME: Wine creates an icon/title window while Windows doesn't */
1020 { WM_PARENTNOTIFY
, sent
|parent
|wparam
|optional
, WM_CREATE
},
1021 { WM_GETTEXT
, sent
|optional
},
1024 /* repeated ShowWindow(SW_SHOWMINNOACTIVE) for child with invisible parent */
1025 static const struct message WmShowChildInvisibleParentSeq_4r
[] = {
1026 { HCBT_MINMAX
, hook
|lparam
, 0, SW_SHOWMINNOACTIVE
},
1029 /* ShowWindow(SW_SHOW) for child with invisible parent */
1030 static const struct message WmShowChildInvisibleParentSeq_5
[] = {
1031 { WM_SHOWWINDOW
, sent
|wparam
, 1 },
1034 /* ShowWindow(SW_HIDE) for child with invisible parent */
1035 static const struct message WmHideChildInvisibleParentSeq
[] = {
1036 { WM_SHOWWINDOW
, sent
|wparam
, 0 },
1039 /* SetWindowPos(SWP_SHOWWINDOW) for child with invisible parent */
1040 static const struct message WmShowChildInvisibleParentSeq_6
[] = {
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_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOACTIVATE
|SWP_NOREDRAW
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
1046 /* SetWindowPos(SWP_HIDEWINDOW) for child with invisible parent */
1047 static const struct message WmHideChildInvisibleParentSeq_2
[] = {
1048 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_HIDEWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
1049 { EVENT_OBJECT_HIDE
, winevent_hook
|wparam
|lparam
, 0, 0 },
1050 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_HIDEWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOREDRAW
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
1053 /* DestroyWindow for a visible child window */
1054 static const struct message WmDestroyChildSeq
[] = {
1055 { HCBT_DESTROYWND
, hook
},
1056 { 0x0090, sent
|optional
},
1057 { WM_PARENTNOTIFY
, sent
|parent
|wparam
, WM_DESTROY
},
1058 { WM_SHOWWINDOW
, sent
|wparam
, 0 },
1059 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_HIDEWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
1060 { EVENT_OBJECT_HIDE
, winevent_hook
|wparam
|lparam
, 0, 0 },
1061 { WM_ERASEBKGND
, sent
|parent
|optional
},
1062 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_HIDEWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
1063 { HCBT_SETFOCUS
, hook
}, /* set focus to a parent */
1064 { WM_KILLFOCUS
, sent
},
1065 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 0 },
1066 { WM_IME_SETCONTEXT
, sent
|wparam
|parent
|optional
, 1 },
1067 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
1068 { WM_SETFOCUS
, sent
|parent
},
1069 { EVENT_OBJECT_DESTROY
, winevent_hook
|wparam
|lparam
, 0, 0 },
1070 { WM_DESTROY
, sent
},
1071 { WM_DESTROY
, sent
|optional
}, /* some other (IME?) window */
1072 { WM_NCDESTROY
, sent
|optional
}, /* some other (IME?) window */
1073 { WM_NCDESTROY
, sent
},
1076 /* DestroyWindow for a visible child window with invisible parent */
1077 static const struct message WmDestroyInvisibleChildSeq
[] = {
1078 { HCBT_DESTROYWND
, hook
},
1079 { 0x0090, sent
|optional
},
1080 { WM_PARENTNOTIFY
, sent
|parent
|wparam
, WM_DESTROY
},
1081 { WM_SHOWWINDOW
, sent
|wparam
, 0 },
1082 { EVENT_OBJECT_DESTROY
, winevent_hook
|wparam
|lparam
, 0, 0 },
1083 { WM_DESTROY
, sent
},
1084 { WM_NCDESTROY
, sent
},
1087 /* Moving the mouse in nonclient area */
1088 static const struct message WmMouseMoveInNonClientAreaSeq
[] = { /* FIXME: add */
1089 { WM_NCHITTEST
, sent
},
1090 { WM_SETCURSOR
, sent
},
1091 { WM_NCMOUSEMOVE
, posted
},
1094 /* Moving the mouse in client area */
1095 static const struct message WmMouseMoveInClientAreaSeq
[] = { /* FIXME: add */
1096 { WM_NCHITTEST
, sent
},
1097 { WM_SETCURSOR
, sent
},
1098 { WM_MOUSEMOVE
, posted
},
1101 /* Moving by dragging the title bar (after WM_NCHITTEST and WM_SETCURSOR) (outline move) */
1102 static const struct message WmDragTitleBarSeq
[] = { /* FIXME: add */
1103 { WM_NCLBUTTONDOWN
, sent
|wparam
, HTCAPTION
},
1104 { WM_SYSCOMMAND
, sent
|defwinproc
|wparam
, SC_MOVE
+2 },
1105 { WM_GETMINMAXINFO
, sent
|defwinproc
},
1106 { WM_ENTERSIZEMOVE
, sent
|defwinproc
},
1107 { WM_WINDOWPOSCHANGING
, sent
|wparam
|defwinproc
, 0 },
1108 { WM_WINDOWPOSCHANGED
, sent
|wparam
|defwinproc
, 0 },
1109 { WM_MOVE
, sent
|defwinproc
},
1110 { WM_EXITSIZEMOVE
, sent
|defwinproc
},
1113 /* Sizing by dragging the thick borders (after WM_NCHITTEST and WM_SETCURSOR) (outline move) */
1114 static const struct message WmDragThickBordersBarSeq
[] = { /* FIXME: add */
1115 { WM_NCLBUTTONDOWN
, sent
|wparam
, 0xd },
1116 { WM_SYSCOMMAND
, sent
|defwinproc
|wparam
, 0xf004 },
1117 { WM_GETMINMAXINFO
, sent
|defwinproc
},
1118 { WM_ENTERSIZEMOVE
, sent
|defwinproc
},
1119 { WM_SIZING
, sent
|defwinproc
|wparam
, 4}, /* one for each mouse movement */
1120 { WM_WINDOWPOSCHANGING
, sent
|wparam
|defwinproc
, 0 },
1121 { WM_GETMINMAXINFO
, sent
|defwinproc
},
1122 { WM_NCCALCSIZE
, sent
|defwinproc
|wparam
, 1 },
1123 { WM_NCPAINT
, sent
|defwinproc
|wparam
, 1 },
1124 { WM_GETTEXT
, sent
|defwinproc
},
1125 { WM_ERASEBKGND
, sent
|defwinproc
},
1126 { WM_WINDOWPOSCHANGED
, sent
|wparam
|defwinproc
, 0 },
1127 { WM_MOVE
, sent
|defwinproc
},
1128 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_RESTORED
},
1129 { WM_EXITSIZEMOVE
, sent
|defwinproc
},
1132 /* Resizing child window with MoveWindow (32) */
1133 static const struct message WmResizingChildWithMoveWindowSeq
[] = {
1134 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_NOACTIVATE
},
1135 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
1136 { WM_ERASEBKGND
, sent
|parent
|optional
},
1137 { WM_ERASEBKGND
, sent
|optional
},
1138 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_NOACTIVATE
},
1139 { WM_MOVE
, sent
|defwinproc
},
1140 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_RESTORED
},
1141 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
1144 /* Clicking on inactive button */
1145 static const struct message WmClickInactiveButtonSeq
[] = { /* FIXME: add */
1146 { WM_NCHITTEST
, sent
},
1147 { WM_PARENTNOTIFY
, sent
|parent
|wparam
, WM_LBUTTONDOWN
},
1148 { WM_MOUSEACTIVATE
, sent
},
1149 { WM_MOUSEACTIVATE
, sent
|parent
|defwinproc
},
1150 { WM_SETCURSOR
, sent
},
1151 { WM_SETCURSOR
, sent
|parent
|defwinproc
},
1152 { WM_LBUTTONDOWN
, posted
},
1153 { WM_KILLFOCUS
, posted
|parent
},
1154 { WM_SETFOCUS
, posted
},
1155 { WM_CTLCOLORBTN
, posted
|parent
},
1156 { BM_SETSTATE
, posted
},
1157 { WM_CTLCOLORBTN
, posted
|parent
},
1158 { WM_LBUTTONUP
, posted
},
1159 { BM_SETSTATE
, posted
},
1160 { WM_CTLCOLORBTN
, posted
|parent
},
1161 { WM_COMMAND
, posted
|parent
},
1164 /* Reparenting a button (16/32) */
1165 /* The last child (button) reparented gets topmost for its new parent. */
1166 static const struct message WmReparentButtonSeq
[] = { /* FIXME: add */
1167 { WM_SHOWWINDOW
, sent
|wparam
, 0 },
1168 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_HIDEWINDOW
|SWP_NOACTIVATE
|SWP_NOMOVE
|SWP_NOSIZE
},
1169 { EVENT_OBJECT_HIDE
, winevent_hook
|wparam
|lparam
, 0, 0 },
1170 { WM_ERASEBKGND
, sent
|parent
},
1171 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_HIDEWINDOW
|SWP_NOACTIVATE
|SWP_NOMOVE
|SWP_NOSIZE
},
1172 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_NOSIZE
},
1173 { WM_CHILDACTIVATE
, sent
},
1174 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_NOSIZE
|SWP_NOREDRAW
},
1175 { WM_MOVE
, sent
|defwinproc
},
1176 { WM_SHOWWINDOW
, sent
|wparam
, 1 },
1179 /* Creation of a custom dialog (32) */
1180 static const struct message WmCreateCustomDialogSeq
[] = {
1181 { HCBT_CREATEWND
, hook
},
1182 { WM_GETMINMAXINFO
, sent
},
1183 { WM_NCCREATE
, sent
},
1184 { WM_NCCALCSIZE
, sent
|wparam
, 0 },
1185 { EVENT_OBJECT_REORDER
, winevent_hook
|wparam
|lparam
, 0, 0 },
1186 { WM_CREATE
, sent
},
1187 { EVENT_OBJECT_CREATE
, winevent_hook
|wparam
|lparam
, 0, 0 },
1188 { WM_NOTIFYFORMAT
, sent
|optional
},
1189 { WM_QUERYUISTATE
, sent
|optional
},
1190 { WM_WINDOWPOSCHANGING
, sent
|optional
},
1191 { WM_GETMINMAXINFO
, sent
|optional
},
1192 { WM_NCCALCSIZE
, sent
|optional
},
1193 { WM_WINDOWPOSCHANGED
, sent
|optional
},
1194 { WM_SHOWWINDOW
, sent
|wparam
, 1 },
1195 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
},
1196 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, 0, 0 },
1197 { HCBT_ACTIVATE
, hook
},
1198 { EVENT_SYSTEM_FOREGROUND
, winevent_hook
|wparam
|lparam
, 0, 0 },
1201 { WM_QUERYNEWPALETTE
, sent
|wparam
|lparam
|optional
, 0, 0 },
1203 { WM_WINDOWPOSCHANGING
, sent
|wparam
|optional
, SWP_NOSIZE
|SWP_NOMOVE
},
1205 { WM_NCACTIVATE
, sent
|wparam
, 1 },
1206 { WM_GETTEXT
, sent
|optional
|defwinproc
},
1207 { WM_GETTEXT
, sent
|optional
|defwinproc
},
1208 { EVENT_OBJECT_DEFACTIONCHANGE
, winevent_hook
|wparam
|lparam
|optional
, OBJID_CLIENT
, 0 },
1209 { WM_ACTIVATE
, sent
|wparam
, 1 },
1210 { WM_GETTEXT
, sent
|optional
},
1211 { WM_KILLFOCUS
, sent
|parent
},
1212 { WM_IME_SETCONTEXT
, sent
|parent
|wparam
|optional
, 0 },
1213 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 1 },
1214 { WM_IME_NOTIFY
, sent
|wparam
|defwinproc
|optional
, 2 },
1215 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
1216 { WM_SETFOCUS
, sent
},
1217 { WM_GETDLGCODE
, sent
|defwinproc
|wparam
, 0 },
1218 { WM_NCPAINT
, sent
|wparam
, 1 },
1219 { WM_GETTEXT
, sent
|optional
|defwinproc
},
1220 { WM_GETTEXT
, sent
|optional
|defwinproc
},
1221 { WM_ERASEBKGND
, sent
},
1222 { WM_CTLCOLORDLG
, sent
|defwinproc
},
1223 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
1224 { WM_GETTEXT
, sent
|optional
},
1225 { WM_GETTEXT
, sent
|optional
},
1226 { WM_NCCALCSIZE
, sent
|optional
},
1227 { WM_NCPAINT
, sent
|optional
},
1228 { WM_GETTEXT
, sent
|optional
|defwinproc
},
1229 { WM_GETTEXT
, sent
|optional
|defwinproc
},
1230 { WM_ERASEBKGND
, sent
|optional
},
1231 { WM_CTLCOLORDLG
, sent
|optional
|defwinproc
},
1232 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
1233 { WM_SIZE
, sent
|wparam
, SIZE_RESTORED
},
1237 /* Calling EndDialog for a custom dialog (32) */
1238 static const struct message WmEndCustomDialogSeq
[] = {
1239 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_HIDEWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
1240 { EVENT_OBJECT_HIDE
, winevent_hook
|wparam
|lparam
, 0, 0 },
1241 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_HIDEWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
1242 { WM_GETTEXT
, sent
|optional
},
1243 { HCBT_ACTIVATE
, hook
},
1244 { WM_NCACTIVATE
, sent
|wparam
, 0 },
1245 { WM_GETTEXT
, sent
|optional
|defwinproc
},
1246 { WM_GETTEXT
, sent
|optional
|defwinproc
},
1247 { WM_ACTIVATE
, sent
|wparam
, 0 },
1248 { EVENT_SYSTEM_FOREGROUND
, winevent_hook
|wparam
|lparam
, 0, 0 },
1249 { WM_WINDOWPOSCHANGING
, sent
|wparam
|optional
, SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
1250 { HCBT_SETFOCUS
, hook
},
1251 { WM_KILLFOCUS
, sent
},
1252 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 0 },
1253 { WM_IME_SETCONTEXT
, sent
|parent
|wparam
|defwinproc
|optional
, 1 },
1254 { WM_IME_NOTIFY
, sent
|wparam
|optional
, 1 },
1255 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
1256 { WM_SETFOCUS
, sent
|parent
|defwinproc
},
1259 /* ShowWindow(SW_SHOW) for a custom dialog (initially invisible) */
1260 static const struct message WmShowCustomDialogSeq
[] = {
1261 { WM_SHOWWINDOW
, sent
|wparam
, 1 },
1262 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
},
1263 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, 0, 0 },
1264 { HCBT_ACTIVATE
, hook
},
1265 { EVENT_SYSTEM_FOREGROUND
, winevent_hook
|wparam
|lparam
, 0, 0 },
1267 { WM_QUERYNEWPALETTE
, sent
|wparam
|lparam
|optional
, 0, 0 },
1269 { WM_WINDOWPOSCHANGING
, sent
|wparam
|optional
, SWP_NOSIZE
|SWP_NOMOVE
},
1270 { WM_ACTIVATEAPP
, sent
|wparam
|optional
, 1 },
1271 { WM_NCACTIVATE
, sent
|wparam
, 1 },
1272 { WM_ACTIVATE
, sent
|wparam
, 1 },
1273 { WM_GETTEXT
, sent
|optional
},
1275 { WM_KILLFOCUS
, sent
|parent
},
1276 { WM_IME_SETCONTEXT
, sent
|parent
|wparam
|optional
, 0 },
1277 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 1 },
1278 { WM_IME_NOTIFY
, sent
|wparam
|defwinproc
|optional
, 2 },
1279 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
1280 { WM_SETFOCUS
, sent
},
1281 { WM_GETDLGCODE
, sent
|defwinproc
|wparam
, 0 },
1282 { WM_NCPAINT
, sent
|wparam
, 1 },
1283 { WM_ERASEBKGND
, sent
},
1284 { WM_CTLCOLORDLG
, sent
|defwinproc
},
1285 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
1288 /* Creation and destruction of a modal dialog (32) */
1289 static const struct message WmModalDialogSeq
[] = {
1290 { WM_CANCELMODE
, sent
|parent
},
1291 { HCBT_SETFOCUS
, hook
},
1292 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
1293 { WM_KILLFOCUS
, sent
|parent
},
1294 { WM_IME_SETCONTEXT
, sent
|parent
|wparam
|optional
, 0 },
1295 { EVENT_OBJECT_STATECHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
1296 { WM_ENABLE
, sent
|parent
|wparam
, 0 },
1297 { HCBT_CREATEWND
, hook
},
1298 { EVENT_OBJECT_REORDER
, winevent_hook
|wparam
|lparam
, 0, 0 },
1299 { EVENT_OBJECT_CREATE
, winevent_hook
|wparam
|lparam
, 0, 0 },
1300 { WM_SETFONT
, sent
},
1301 { WM_INITDIALOG
, sent
},
1302 { WM_CHANGEUISTATE
, sent
|optional
},
1303 { WM_UPDATEUISTATE
, sent
|optional
},
1304 { WM_SHOWWINDOW
, sent
},
1305 { HCBT_ACTIVATE
, hook
},
1306 { EVENT_SYSTEM_FOREGROUND
, winevent_hook
|wparam
|lparam
, 0, 0 },
1307 { WM_QUERYNEWPALETTE
, sent
|wparam
|lparam
|optional
, 0, 0 },
1308 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_NOSIZE
|SWP_NOMOVE
},
1309 { WM_NCACTIVATE
, sent
|wparam
, 1 },
1310 { WM_GETTEXT
, sent
|optional
},
1311 { WM_ACTIVATE
, sent
|wparam
, 1 },
1312 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOACTIVATE
},
1313 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, 0, 0 },
1314 { WM_NCPAINT
, sent
},
1315 { WM_GETTEXT
, sent
|optional
},
1316 { WM_ERASEBKGND
, sent
},
1317 { WM_CTLCOLORDLG
, sent
},
1318 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOACTIVATE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
1319 { WM_GETTEXT
, sent
|optional
},
1320 { WM_NCCALCSIZE
, sent
|optional
},
1321 { WM_NCPAINT
, sent
|optional
},
1322 { WM_GETTEXT
, sent
|optional
},
1323 { WM_ERASEBKGND
, sent
|optional
},
1324 { WM_CTLCOLORDLG
, sent
|optional
},
1325 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
1326 { WM_PAINT
, sent
|optional
},
1327 { WM_CTLCOLORBTN
, sent
},
1328 { WM_ENTERIDLE
, sent
|parent
|optional
},
1329 { WM_ENTERIDLE
, sent
|parent
|optional
},
1330 { WM_ENTERIDLE
, sent
|parent
|optional
},
1331 { WM_ENTERIDLE
, sent
|parent
|optional
},
1332 { WM_ENTERIDLE
, sent
|parent
|optional
},
1333 { WM_ENTERIDLE
, sent
|parent
|optional
},
1334 { WM_ENTERIDLE
, sent
|parent
|optional
},
1335 { WM_ENTERIDLE
, sent
|parent
|optional
},
1336 { WM_ENTERIDLE
, sent
|parent
|optional
},
1337 { WM_ENTERIDLE
, sent
|parent
|optional
},
1338 { WM_ENTERIDLE
, sent
|parent
|optional
},
1339 { WM_ENTERIDLE
, sent
|parent
|optional
},
1340 { WM_ENTERIDLE
, sent
|parent
|optional
},
1341 { WM_ENTERIDLE
, sent
|parent
|optional
},
1342 { WM_ENTERIDLE
, sent
|parent
|optional
},
1343 { WM_ENTERIDLE
, sent
|parent
|optional
},
1344 { WM_ENTERIDLE
, sent
|parent
|optional
},
1345 { WM_ENTERIDLE
, sent
|parent
|optional
},
1346 { WM_ENTERIDLE
, sent
|parent
|optional
},
1347 { WM_ENTERIDLE
, sent
|parent
|optional
},
1349 { EVENT_OBJECT_STATECHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
1350 { WM_ENABLE
, sent
|parent
|wparam
, 1 },
1351 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_HIDEWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOACTIVATE
},
1352 { EVENT_OBJECT_HIDE
, winevent_hook
|wparam
|lparam
, 0, 0 },
1353 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_HIDEWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOACTIVATE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
1354 { WM_GETTEXT
, sent
|optional
},
1355 { HCBT_ACTIVATE
, hook
},
1356 { WM_NCACTIVATE
, sent
|wparam
, 0 },
1357 { WM_GETTEXT
, sent
|optional
},
1358 { WM_ACTIVATE
, sent
|wparam
, 0 },
1359 { EVENT_SYSTEM_FOREGROUND
, winevent_hook
|wparam
|lparam
, 0, 0 },
1360 { WM_WINDOWPOSCHANGING
, sent
|optional
},
1361 { WM_WINDOWPOSCHANGED
, sent
|optional
},
1362 { HCBT_SETFOCUS
, hook
},
1363 { WM_IME_SETCONTEXT
, sent
|parent
|wparam
|defwinproc
|optional
, 1 },
1364 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
1365 { WM_SETFOCUS
, sent
|parent
|defwinproc
},
1366 { EVENT_SYSTEM_DIALOGEND
, winevent_hook
|wparam
|lparam
, 0, 0 },
1367 { HCBT_DESTROYWND
, hook
},
1368 { 0x0090, sent
|optional
},
1369 { EVENT_OBJECT_DESTROY
, winevent_hook
|wparam
|lparam
, 0, 0 },
1370 { WM_DESTROY
, sent
},
1371 { WM_NCDESTROY
, sent
},
1374 /* Creation of a modal dialog that is resized inside WM_INITDIALOG (32) */
1375 static const struct message WmCreateModalDialogResizeSeq
[] = { /* FIXME: add */
1376 /* (inside dialog proc, handling WM_INITDIALOG) */
1377 { WM_WINDOWPOSCHANGING
, sent
|wparam
, 0 },
1378 { WM_NCCALCSIZE
, sent
},
1379 { WM_NCACTIVATE
, sent
|parent
|wparam
, 0 },
1380 { WM_GETTEXT
, sent
|defwinproc
},
1381 { WM_ACTIVATE
, sent
|parent
|wparam
, 0 },
1382 { WM_WINDOWPOSCHANGING
, sent
|wparam
, 0 },
1383 { WM_WINDOWPOSCHANGING
, sent
|parent
},
1384 { WM_NCACTIVATE
, sent
|wparam
, 1 },
1385 { WM_ACTIVATE
, sent
|wparam
, 1 },
1386 { WM_WINDOWPOSCHANGED
, sent
|wparam
, 0 },
1387 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_RESTORED
},
1388 /* (setting focus) */
1389 { WM_SHOWWINDOW
, sent
|wparam
, 1 },
1390 { WM_WINDOWPOSCHANGING
, sent
|wparam
, 0 },
1391 { WM_NCPAINT
, sent
},
1392 { WM_GETTEXT
, sent
|defwinproc
},
1393 { WM_ERASEBKGND
, sent
},
1394 { WM_CTLCOLORDLG
, sent
|defwinproc
},
1395 { WM_WINDOWPOSCHANGED
, sent
|wparam
, 0 },
1397 /* (bunch of WM_CTLCOLOR* for each control) */
1398 { WM_PAINT
, sent
|parent
},
1399 { WM_ENTERIDLE
, sent
|parent
|wparam
, 0 },
1400 { WM_SETCURSOR
, sent
|parent
},
1403 /* SetMenu for NonVisible windows with size change*/
1404 static const struct message WmSetMenuNonVisibleSizeChangeSeq
[] = {
1405 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
1406 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
1407 { EVENT_OBJECT_REORDER
, winevent_hook
|wparam
|lparam
, 0, 0 },
1408 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOREDRAW
},
1409 { WM_MOVE
, sent
|defwinproc
},
1410 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_RESTORED
},
1411 { WM_NCCALCSIZE
,sent
|wparam
|optional
, 1 }, /* XP */
1412 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
1413 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
|optional
, 0, 0 }, /* XP sends a duplicate */
1414 { WM_GETTEXT
, sent
|optional
},
1415 { WM_NCCALCSIZE
, sent
|wparam
|optional
, 1 },
1418 /* SetMenu for NonVisible windows with no size change */
1419 static const struct message WmSetMenuNonVisibleNoSizeChangeSeq
[] = {
1420 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
1421 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
1422 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOREDRAW
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
1423 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
1426 /* SetMenu for Visible windows with size change */
1427 static const struct message WmSetMenuVisibleSizeChangeSeq
[] = {
1428 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
1429 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
1430 { 0x0093, sent
|defwinproc
|optional
},
1431 { EVENT_OBJECT_REORDER
, winevent_hook
|wparam
|lparam
, 0, 0 },
1432 { WM_NCPAINT
, sent
|optional
}, /* wparam != 1 */
1433 { 0x0093, sent
|defwinproc
|optional
},
1434 { 0x0093, sent
|defwinproc
|optional
},
1435 { 0x0091, sent
|defwinproc
|optional
},
1436 { 0x0092, sent
|defwinproc
|optional
},
1437 { WM_GETTEXT
, sent
|defwinproc
|optional
},
1438 { WM_ERASEBKGND
, sent
|optional
},
1439 { WM_ACTIVATE
, sent
|optional
},
1440 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
1441 { WM_MOVE
, sent
|defwinproc
},
1442 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_RESTORED
},
1443 { 0x0093, sent
|optional
},
1444 { WM_NCCALCSIZE
, sent
|wparam
|optional
, 1 },
1445 { 0x0093, sent
|defwinproc
|optional
},
1446 { WM_NCPAINT
, sent
|optional
}, /* wparam != 1 */
1447 { 0x0093, sent
|defwinproc
|optional
},
1448 { 0x0093, sent
|defwinproc
|optional
},
1449 { 0x0091, sent
|defwinproc
|optional
},
1450 { 0x0092, sent
|defwinproc
|optional
},
1451 { WM_ERASEBKGND
, sent
|optional
},
1452 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
1453 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
|optional
, 0, 0 }, /* XP sends a duplicate */
1456 /* SetMenu for Visible windows with no size change */
1457 static const struct message WmSetMenuVisibleNoSizeChangeSeq
[] = {
1458 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
1459 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
1460 { WM_NCPAINT
, sent
|optional
}, /* wparam != 1 */
1461 { WM_GETTEXT
, sent
|defwinproc
|optional
},
1462 { WM_ERASEBKGND
, sent
|optional
},
1463 { WM_ACTIVATE
, sent
|optional
},
1464 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
1465 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
1468 /* DrawMenuBar for a visible window */
1469 static const struct message WmDrawMenuBarSeq
[] =
1471 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
1472 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
1473 { 0x0093, sent
|defwinproc
|optional
},
1474 { WM_NCPAINT
, sent
|optional
}, /* wparam != 1 */
1475 { 0x0093, sent
|defwinproc
|optional
},
1476 { 0x0093, sent
|defwinproc
|optional
},
1477 { 0x0091, sent
|defwinproc
|optional
},
1478 { 0x0092, sent
|defwinproc
|optional
},
1479 { WM_GETTEXT
, sent
|defwinproc
|optional
},
1480 { WM_ERASEBKGND
, sent
|optional
},
1481 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
1482 { 0x0093, sent
|optional
},
1483 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
1487 static const struct message WmSetRedrawFalseSeq
[] =
1489 { WM_SETREDRAW
, sent
|wparam
, 0 },
1493 static const struct message WmSetRedrawTrueSeq
[] =
1495 { WM_SETREDRAW
, sent
|wparam
, 1 },
1499 static const struct message WmEnableWindowSeq_1
[] =
1501 { WM_CANCELMODE
, sent
|wparam
|lparam
, 0, 0 },
1502 { EVENT_OBJECT_STATECHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
1503 { WM_ENABLE
, sent
|wparam
|lparam
, FALSE
, 0 },
1507 static const struct message WmEnableWindowSeq_2
[] =
1509 { EVENT_OBJECT_STATECHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
1510 { WM_ENABLE
, sent
|wparam
|lparam
, TRUE
, 0 },
1514 static const struct message WmGetScrollRangeSeq
[] =
1516 { SBM_GETRANGE
, sent
},
1519 static const struct message WmGetScrollInfoSeq
[] =
1521 { SBM_GETSCROLLINFO
, sent
},
1524 static const struct message WmSetScrollRangeSeq
[] =
1526 /* MSDN claims that Windows sends SBM_SETRANGE message, but win2k SP4
1527 sends SBM_SETSCROLLINFO.
1529 { SBM_SETSCROLLINFO
, sent
},
1532 /* SetScrollRange for a window without a non-client area */
1533 static const struct message WmSetScrollRangeHSeq_empty
[] =
1535 { EVENT_OBJECT_VALUECHANGE
, winevent_hook
|wparam
|lparam
, OBJID_HSCROLL
, 0 },
1538 static const struct message WmSetScrollRangeVSeq_empty
[] =
1540 { EVENT_OBJECT_VALUECHANGE
, winevent_hook
|wparam
|lparam
, OBJID_VSCROLL
, 0 },
1543 static const struct message WmSetScrollRangeHVSeq
[] =
1545 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOMOVE
|SWP_NOSIZE
},
1546 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
1547 { WM_GETTEXT
, sent
|defwinproc
|optional
},
1548 { WM_ERASEBKGND
, sent
|optional
},
1549 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOMOVE
|SWP_NOSIZE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
1550 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
1551 { EVENT_OBJECT_VALUECHANGE
, winevent_hook
|lparam
|optional
, 0/*OBJID_HSCROLL or OBJID_VSCROLL*/, 0 },
1554 /* SetScrollRange for a window with a non-client area */
1555 static const struct message WmSetScrollRangeHV_NC_Seq
[] =
1557 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOMOVE
|SWP_NOSIZE
},
1558 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
1559 { EVENT_OBJECT_REORDER
, winevent_hook
|wparam
|lparam
, 0, 0 },
1560 { WM_NCPAINT
, sent
|optional
},
1561 { WM_STYLECHANGING
, sent
|defwinproc
|optional
},
1562 { WM_STYLECHANGED
, sent
|defwinproc
|optional
},
1563 { WM_STYLECHANGING
, sent
|defwinproc
|optional
},
1564 { WM_STYLECHANGED
, sent
|defwinproc
|optional
},
1565 { WM_STYLECHANGING
, sent
|defwinproc
|optional
},
1566 { WM_STYLECHANGED
, sent
|defwinproc
|optional
},
1567 { WM_STYLECHANGING
, sent
|defwinproc
|optional
},
1568 { WM_STYLECHANGED
, sent
|defwinproc
|optional
},
1569 { WM_GETTEXT
, sent
|defwinproc
|optional
},
1570 { WM_GETTEXT
, sent
|defwinproc
|optional
},
1571 { WM_ERASEBKGND
, sent
|optional
},
1572 { WM_CTLCOLORDLG
, sent
|defwinproc
|optional
}, /* sent to a parent of the dialog */
1573 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOMOVE
|SWP_NOSIZE
|SWP_NOCLIENTMOVE
},
1574 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_RESTORED
},
1575 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
1576 { EVENT_OBJECT_VALUECHANGE
, winevent_hook
|lparam
|optional
, 0/*OBJID_HSCROLL or OBJID_VSCROLL*/, 0 },
1577 { WM_GETTEXT
, sent
|optional
},
1578 { WM_GETTEXT
, sent
|optional
},
1579 { WM_GETTEXT
, sent
|optional
},
1580 { WM_GETTEXT
, sent
|optional
},
1583 /* test if we receive the right sequence of messages */
1584 /* after calling ShowWindow( SW_SHOWNA) */
1585 static const struct message WmSHOWNAChildInvisParInvis
[] = {
1586 { WM_SHOWWINDOW
, sent
|wparam
, 1 },
1589 static const struct message WmSHOWNAChildVisParInvis
[] = {
1590 { WM_SHOWWINDOW
, sent
|wparam
, 1 },
1593 static const struct message WmSHOWNAChildVisParVis
[] = {
1594 { WM_SHOWWINDOW
, sent
|wparam
, 1 },
1595 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOACTIVATE
},
1598 static const struct message WmSHOWNAChildInvisParVis
[] = {
1599 { WM_SHOWWINDOW
, sent
|wparam
, 1 },
1600 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
1601 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, 0, 0 },
1602 { WM_ERASEBKGND
, sent
|optional
},
1603 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOACTIVATE
|SWP_NOCLIENTMOVE
},
1606 static const struct message WmSHOWNATopVisible
[] = {
1607 { WM_SHOWWINDOW
, sent
|wparam
, 1 },
1608 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOACTIVATE
},
1609 { WM_NCPAINT
, sent
|wparam
|optional
, 1 },
1610 { WM_GETTEXT
, sent
|defwinproc
|optional
},
1611 { WM_ERASEBKGND
, sent
|optional
},
1612 { WM_WINDOWPOSCHANGED
, sent
|optional
},
1615 static const struct message WmSHOWNATopInvisible
[] = {
1616 { WM_NOTIFYFORMAT
, sent
|optional
},
1617 { WM_QUERYUISTATE
, sent
|optional
},
1618 { WM_WINDOWPOSCHANGING
, sent
|optional
},
1619 { WM_GETMINMAXINFO
, sent
|optional
},
1620 { WM_NCCALCSIZE
, sent
|optional
},
1621 { WM_WINDOWPOSCHANGED
, sent
|optional
},
1622 { WM_SHOWWINDOW
, sent
|wparam
, 1 },
1623 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
1624 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, 0, 0 },
1625 { WM_NCPAINT
, sent
|wparam
, 1 },
1626 { WM_GETTEXT
, sent
|defwinproc
|optional
},
1627 { WM_ERASEBKGND
, sent
|optional
},
1628 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
1629 { WM_NCCALCSIZE
, sent
|wparam
|optional
, 1 },
1630 { WM_NCPAINT
, sent
|wparam
|optional
, 1 },
1631 { WM_ERASEBKGND
, sent
|optional
},
1632 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
1633 { WM_SIZE
, sent
|wparam
, SIZE_RESTORED
},
1638 static int after_end_dialog
, test_def_id
;
1639 static int sequence_cnt
, sequence_size
;
1640 static struct recvd_message
* sequence
;
1641 static int log_all_parent_messages
;
1642 static int paint_loop_done
;
1644 /* user32 functions */
1645 static HWND (WINAPI
*pGetAncestor
)(HWND
,UINT
);
1646 static BOOL (WINAPI
*pGetMenuInfo
)(HMENU
,LPCMENUINFO
);
1647 static void (WINAPI
*pNotifyWinEvent
)(DWORD
, HWND
, LONG
, LONG
);
1648 static BOOL (WINAPI
*pSetMenuInfo
)(HMENU
,LPCMENUINFO
);
1649 static HWINEVENTHOOK (WINAPI
*pSetWinEventHook
)(DWORD
, DWORD
, HMODULE
, WINEVENTPROC
, DWORD
, DWORD
, DWORD
);
1650 static BOOL (WINAPI
*pTrackMouseEvent
)(TRACKMOUSEEVENT
*);
1651 static BOOL (WINAPI
*pUnhookWinEvent
)(HWINEVENTHOOK
);
1652 /* kernel32 functions */
1653 static BOOL (WINAPI
*pGetCPInfoExA
)(UINT
, DWORD
, LPCPINFOEXA
);
1655 static void init_procs(void)
1657 HMODULE user32
= GetModuleHandleA("user32.dll");
1658 HMODULE kernel32
= GetModuleHandleA("kernel32.dll");
1660 #define GET_PROC(dll, func) \
1661 p ## func = (void*)GetProcAddress(dll, #func); \
1663 trace("GetProcAddress(%s) failed\n", #func); \
1666 GET_PROC(user32
, GetAncestor
)
1667 GET_PROC(user32
, GetMenuInfo
)
1668 GET_PROC(user32
, NotifyWinEvent
)
1669 GET_PROC(user32
, SetMenuInfo
)
1670 GET_PROC(user32
, SetWinEventHook
)
1671 GET_PROC(user32
, TrackMouseEvent
)
1672 GET_PROC(user32
, UnhookWinEvent
)
1674 GET_PROC(kernel32
, GetCPInfoExA
)
1679 static const char *get_winpos_flags(UINT flags
)
1681 static char buffer
[300];
1684 #define DUMP(flag) do { if (flags & flag) { strcat( buffer, "|" #flag ); flags &= ~flag; } } while(0)
1685 DUMP( SWP_SHOWWINDOW
);
1686 DUMP( SWP_HIDEWINDOW
);
1687 DUMP( SWP_NOACTIVATE
);
1688 DUMP( SWP_FRAMECHANGED
);
1689 DUMP( SWP_NOCOPYBITS
);
1690 DUMP( SWP_NOOWNERZORDER
);
1691 DUMP( SWP_NOSENDCHANGING
);
1692 DUMP( SWP_DEFERERASE
);
1693 DUMP( SWP_ASYNCWINDOWPOS
);
1694 DUMP( SWP_NOZORDER
);
1695 DUMP( SWP_NOREDRAW
);
1698 DUMP( SWP_NOCLIENTSIZE
);
1699 DUMP( SWP_NOCLIENTMOVE
);
1700 if (flags
) sprintf(buffer
+ strlen(buffer
),"|0x%04x", flags
);
1706 #define add_message(msg) add_message_(__LINE__,msg);
1707 static void add_message_(int line
, const struct recvd_message
*msg
)
1709 struct recvd_message
*seq
;
1714 sequence
= HeapAlloc( GetProcessHeap(), 0, sequence_size
* sizeof(*sequence
) );
1716 if (sequence_cnt
== sequence_size
)
1719 sequence
= HeapReAlloc( GetProcessHeap(), 0, sequence
, sequence_size
* sizeof(*sequence
) );
1723 seq
= &sequence
[sequence_cnt
];
1724 seq
->hwnd
= msg
->hwnd
;
1725 seq
->message
= msg
->message
;
1726 seq
->flags
= msg
->flags
;
1727 seq
->wParam
= msg
->wParam
;
1728 seq
->lParam
= msg
->lParam
;
1730 seq
->descr
= msg
->descr
;
1735 if (msg
->flags
& hook
)
1737 static const char * const CBT_code_name
[10] =
1745 "HCBT_CLICKSKIPPED",
1750 const char *code_name
= (msg
->message
<= HCBT_SETFOCUS
) ? CBT_code_name
[msg
->message
] : "Unknown";
1752 snprintf( seq
->output
, sizeof(seq
->output
), "%s: hook %d (%s) wp %08lx lp %08lx",
1753 msg
->descr
, msg
->message
, code_name
, msg
->wParam
, msg
->lParam
);
1755 else if (msg
->flags
& winevent_hook
)
1757 snprintf( seq
->output
, sizeof(seq
->output
), "%s: winevent %p %08x %08lx %08lx",
1758 msg
->descr
, msg
->hwnd
, msg
->message
, msg
->wParam
, msg
->lParam
);
1762 switch (msg
->message
)
1764 case WM_WINDOWPOSCHANGING
:
1765 case WM_WINDOWPOSCHANGED
:
1767 WINDOWPOS
*winpos
= (WINDOWPOS
*)msg
->lParam
;
1769 snprintf( seq
->output
, sizeof(seq
->output
),
1770 "%s: %p WM_WINDOWPOS%s wp %08lx lp %08lx after %p x %d y %d cx %d cy %d flags %s",
1771 msg
->descr
, msg
->hwnd
,
1772 (msg
->message
== WM_WINDOWPOSCHANGING
) ? "CHANGING" : "CHANGED",
1773 msg
->wParam
, msg
->lParam
, winpos
->hwndInsertAfter
,
1774 winpos
->x
, winpos
->y
, winpos
->cx
, winpos
->cy
,
1775 get_winpos_flags(winpos
->flags
) );
1777 /* Log only documented flags, win2k uses 0x1000 and 0x2000
1778 * in the high word for internal purposes
1780 seq
->wParam
= winpos
->flags
& 0xffff;
1781 /* We are not interested in the flags that don't match under XP and Win9x */
1782 seq
->wParam
&= ~SWP_NOZORDER
;
1788 DRAW_ITEM_STRUCT di
;
1789 DRAWITEMSTRUCT
*dis
= (DRAWITEMSTRUCT
*)msg
->lParam
;
1791 snprintf( seq
->output
, sizeof(seq
->output
),
1792 "%s: %p WM_DRAWITEM: type %x, ctl_id %x, item_id %x, action %x, state %x",
1793 msg
->descr
, msg
->hwnd
, dis
->CtlType
, dis
->CtlID
,
1794 dis
->itemID
, dis
->itemAction
, dis
->itemState
);
1796 di
.u
.item
.type
= dis
->CtlType
;
1797 di
.u
.item
.ctl_id
= dis
->CtlID
;
1798 di
.u
.item
.item_id
= dis
->itemID
;
1799 di
.u
.item
.action
= dis
->itemAction
;
1800 di
.u
.item
.state
= dis
->itemState
;
1802 seq
->lParam
= di
.u
.lp
;
1806 if (msg
->message
>= 0xc000) return; /* ignore registered messages */
1807 snprintf( seq
->output
, sizeof(seq
->output
), "%s: %p %04x wp %08lx lp %08lx",
1808 msg
->descr
, msg
->hwnd
, msg
->message
, msg
->wParam
, msg
->lParam
);
1816 /* try to make sure pending X events have been processed before continuing */
1817 static void flush_events(void)
1821 int min_timeout
= 100;
1822 DWORD time
= GetTickCount() + diff
;
1826 if (MsgWaitForMultipleObjects( 0, NULL
, FALSE
, min_timeout
, QS_ALLINPUT
) == WAIT_TIMEOUT
) break;
1827 while (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
1828 diff
= time
- GetTickCount();
1833 static void flush_sequence(void)
1835 HeapFree(GetProcessHeap(), 0, sequence
);
1837 sequence_cnt
= sequence_size
= 0;
1840 static void dump_sequence(const struct message
*expected
, const char *context
, const char *file
, int line
)
1842 const struct recvd_message
*actual
= sequence
;
1843 unsigned int count
= 0;
1845 trace_(file
, line
)("Failed sequence %s:\n", context
);
1846 while (expected
->message
&& actual
->message
)
1848 if (actual
->output
[0])
1850 if (expected
->flags
& hook
)
1852 trace_(file
, line
)( " %u: expected: hook %04x - actual: %s\n",
1853 count
, expected
->message
, actual
->output
);
1855 else if (expected
->flags
& winevent_hook
)
1857 trace_(file
, line
)( " %u: expected: winevent %04x - actual: %s\n",
1858 count
, expected
->message
, actual
->output
);
1862 trace_(file
, line
)( " %u: expected: msg %04x - actual: %s\n",
1863 count
, expected
->message
, actual
->output
);
1867 if (expected
->message
== actual
->message
)
1872 /* silently drop winevent messages if there is no support for them */
1873 else if ((expected
->flags
& optional
) || ((expected
->flags
& winevent_hook
) && !hEvent_hook
))
1883 /* optional trailing messages */
1884 while (expected
->message
&& ((expected
->flags
& optional
) ||
1885 ((expected
->flags
& winevent_hook
) && !hEvent_hook
)))
1891 #define ok_sequence( exp, contx, todo) \
1892 ok_sequence_( (exp), (contx), (todo), __FILE__, __LINE__)
1895 static void ok_sequence_(const struct message
*expected_list
, const char *context
, int todo
,
1896 const char *file
, int line
)
1898 static const struct recvd_message end_of_sequence
;
1899 const struct message
*expected
= expected_list
;
1900 const struct recvd_message
*actual
;
1901 int failcount
= 0, dump
= 0;
1902 unsigned int count
= 0;
1904 add_message(&end_of_sequence
);
1908 while (expected
->message
&& actual
->message
)
1910 if (expected
->message
== actual
->message
)
1912 if (expected
->flags
& wparam
)
1914 if (((expected
->wParam
^ actual
->wParam
) & ~expected
->wp_mask
) && todo
)
1918 if (strcmp(winetest_platform
, "wine")) dump
++;
1919 ok_( file
, line
) (FALSE
,
1920 "%s: %u: in msg 0x%04x expecting wParam 0x%lx got 0x%lx\n",
1921 context
, count
, expected
->message
, expected
->wParam
, actual
->wParam
);
1926 ok_( file
, line
)( ((expected
->wParam
^ actual
->wParam
) & ~expected
->wp_mask
) == 0,
1927 "%s: %u: in msg 0x%04x expecting wParam 0x%lx got 0x%lx\n",
1928 context
, count
, expected
->message
, expected
->wParam
, actual
->wParam
);
1929 if ((expected
->wParam
^ actual
->wParam
) & ~expected
->wp_mask
) dump
++;
1933 if (expected
->flags
& lparam
)
1935 if (((expected
->lParam
^ actual
->lParam
) & ~expected
->lp_mask
) && todo
)
1939 if (strcmp(winetest_platform
, "wine")) dump
++;
1940 ok_( file
, line
) (FALSE
,
1941 "%s: %u: in msg 0x%04x expecting lParam 0x%lx got 0x%lx\n",
1942 context
, count
, expected
->message
, expected
->lParam
, actual
->lParam
);
1947 ok_( file
, line
)(((expected
->lParam
^ actual
->lParam
) & ~expected
->lp_mask
) == 0,
1948 "%s: %u: in msg 0x%04x expecting lParam 0x%lx got 0x%lx\n",
1949 context
, count
, expected
->message
, expected
->lParam
, actual
->lParam
);
1950 if ((expected
->lParam
^ actual
->lParam
) & ~expected
->lp_mask
) dump
++;
1953 if ((expected
->flags
& defwinproc
) != (actual
->flags
& defwinproc
) && todo
)
1957 if (strcmp(winetest_platform
, "wine")) dump
++;
1958 ok_( file
, line
) (FALSE
,
1959 "%s: %u: the msg 0x%04x should %shave been sent by DefWindowProc\n",
1960 context
, count
, expected
->message
, (expected
->flags
& defwinproc
) ? "" : "NOT ");
1965 ok_( file
, line
) ((expected
->flags
& defwinproc
) == (actual
->flags
& defwinproc
),
1966 "%s: %u: the msg 0x%04x should %shave been sent by DefWindowProc\n",
1967 context
, count
, expected
->message
, (expected
->flags
& defwinproc
) ? "" : "NOT ");
1968 if ((expected
->flags
& defwinproc
) != (actual
->flags
& defwinproc
)) dump
++;
1971 ok_( file
, line
) ((expected
->flags
& beginpaint
) == (actual
->flags
& beginpaint
),
1972 "%s: %u: the msg 0x%04x should %shave been sent by BeginPaint\n",
1973 context
, count
, expected
->message
, (expected
->flags
& beginpaint
) ? "" : "NOT ");
1974 if ((expected
->flags
& beginpaint
) != (actual
->flags
& beginpaint
)) dump
++;
1976 ok_( file
, line
) ((expected
->flags
& (sent
|posted
)) == (actual
->flags
& (sent
|posted
)),
1977 "%s: %u: the msg 0x%04x should have been %s\n",
1978 context
, count
, expected
->message
, (expected
->flags
& posted
) ? "posted" : "sent");
1979 if ((expected
->flags
& (sent
|posted
)) != (actual
->flags
& (sent
|posted
))) dump
++;
1981 ok_( file
, line
) ((expected
->flags
& parent
) == (actual
->flags
& parent
),
1982 "%s: %u: the msg 0x%04x was expected in %s\n",
1983 context
, count
, expected
->message
, (expected
->flags
& parent
) ? "parent" : "child");
1984 if ((expected
->flags
& parent
) != (actual
->flags
& parent
)) dump
++;
1986 ok_( file
, line
) ((expected
->flags
& hook
) == (actual
->flags
& hook
),
1987 "%s: %u: the msg 0x%04x should have been sent by a hook\n",
1988 context
, count
, expected
->message
);
1989 if ((expected
->flags
& hook
) != (actual
->flags
& hook
)) dump
++;
1991 ok_( file
, line
) ((expected
->flags
& winevent_hook
) == (actual
->flags
& winevent_hook
),
1992 "%s: %u: the msg 0x%04x should have been sent by a winevent hook\n",
1993 context
, count
, expected
->message
);
1994 if ((expected
->flags
& winevent_hook
) != (actual
->flags
& winevent_hook
)) dump
++;
1999 /* silently drop hook messages if there is no support for them */
2000 else if ((expected
->flags
& optional
) ||
2001 ((expected
->flags
& hook
) && !hCBT_hook
) ||
2002 ((expected
->flags
& winevent_hook
) && !hEvent_hook
))
2008 if (strcmp(winetest_platform
, "wine")) dump
++;
2009 ok_( file
, line
) (FALSE
, "%s: %u: the msg 0x%04x was expected, but got msg 0x%04x instead\n",
2010 context
, count
, expected
->message
, actual
->message
);
2016 ok_( file
, line
) (FALSE
, "%s: %u: the msg 0x%04x was expected, but got msg 0x%04x instead\n",
2017 context
, count
, expected
->message
, actual
->message
);
2025 /* skip all optional trailing messages */
2026 while (expected
->message
&& ((expected
->flags
& optional
) ||
2027 ((expected
->flags
& hook
) && !hCBT_hook
) ||
2028 ((expected
->flags
& winevent_hook
) && !hEvent_hook
)))
2034 if (expected
->message
|| actual
->message
) {
2036 if (strcmp(winetest_platform
, "wine")) dump
++;
2037 ok_( file
, line
) (FALSE
, "%s: %u: the msg sequence is not complete: expected %04x - actual %04x\n",
2038 context
, count
, expected
->message
, actual
->message
);
2044 if (expected
->message
|| actual
->message
)
2047 ok_( file
, line
) (FALSE
, "%s: %u: the msg sequence is not complete: expected %04x - actual %04x\n",
2048 context
, count
, expected
->message
, actual
->message
);
2051 if( todo
&& !failcount
) /* succeeded yet marked todo */
2053 if (!strcmp(winetest_platform
, "wine")) dump
++;
2054 ok_( file
, line
)( TRUE
, "%s: marked \"todo_wine\" but succeeds\n", context
);
2058 if (dump
) dump_sequence(expected_list
, context
, file
, line
);
2062 #define expect(EXPECTED,GOT) ok((GOT)==(EXPECTED), "Expected %d, got %d\n", (EXPECTED), (GOT))
2064 /******************************** MDI test **********************************/
2066 /* CreateWindow for MDI frame window, initially visible */
2067 static const struct message WmCreateMDIframeSeq
[] = {
2068 { HCBT_CREATEWND
, hook
},
2069 { WM_GETMINMAXINFO
, sent
},
2070 { WM_NCCREATE
, sent
},
2071 { WM_NCCALCSIZE
, sent
|wparam
, 0 },
2072 { EVENT_OBJECT_REORDER
, winevent_hook
|wparam
|lparam
, 0, 0 },
2073 { WM_CREATE
, sent
},
2074 { EVENT_OBJECT_CREATE
, winevent_hook
|wparam
|lparam
, 0, 0 },
2075 { WM_NOTIFYFORMAT
, sent
|optional
},
2076 { WM_QUERYUISTATE
, sent
|optional
},
2077 { WM_WINDOWPOSCHANGING
, sent
|optional
},
2078 { WM_GETMINMAXINFO
, sent
|optional
},
2079 { WM_NCCALCSIZE
, sent
|optional
},
2080 { WM_WINDOWPOSCHANGED
, sent
|optional
},
2081 { WM_SHOWWINDOW
, sent
|wparam
, 1 },
2082 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
},
2083 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, 0, 0 },
2084 { HCBT_ACTIVATE
, hook
},
2085 { EVENT_SYSTEM_FOREGROUND
, winevent_hook
|wparam
|lparam
, 0, 0 },
2086 { WM_QUERYNEWPALETTE
, sent
|wparam
|lparam
|optional
, 0, 0 },
2087 { WM_WINDOWPOSCHANGING
, sent
|wparam
|optional
, SWP_NOSIZE
|SWP_NOMOVE
}, /* XP */
2088 { WM_ACTIVATEAPP
, sent
|wparam
|optional
, 1 }, /* Win9x doesn't send it */
2089 { WM_NCACTIVATE
, sent
|wparam
, 1 },
2090 { WM_GETTEXT
, sent
|defwinproc
|optional
},
2091 { WM_ACTIVATE
, sent
|wparam
, 1 },
2092 { WM_WINDOWPOSCHANGING
, sent
|wparam
|optional
, SWP_NOSIZE
|SWP_NOMOVE
}, /* Win9x */
2093 { HCBT_SETFOCUS
, hook
},
2094 { WM_IME_SETCONTEXT
, sent
|wparam
|defwinproc
|optional
, 1 },
2095 { WM_IME_NOTIFY
, sent
|wparam
|defwinproc
|optional
, 2 },
2096 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
2097 { WM_SETFOCUS
, sent
|wparam
|defwinproc
, 0 },
2098 /* Win9x adds SWP_NOZORDER below */
2099 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
2100 { WM_NCCALCSIZE
, sent
|wparam
|optional
, 1 }, /* XP */
2101 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
2102 { WM_SIZE
, sent
|wparam
, SIZE_RESTORED
},
2106 /* DestroyWindow for MDI frame window, initially visible */
2107 static const struct message WmDestroyMDIframeSeq
[] = {
2108 { HCBT_DESTROYWND
, hook
},
2109 { 0x0090, sent
|optional
},
2110 { WM_WINDOWPOSCHANGING
, sent
|wparam
|optional
, SWP_HIDEWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
2111 { EVENT_OBJECT_HIDE
, winevent_hook
|wparam
|lparam
, 0, 0 },
2112 { WM_NCACTIVATE
, sent
|wparam
|optional
, 0 }, /* Win9x */
2113 { WM_WINDOWPOSCHANGED
, sent
|wparam
|optional
, SWP_HIDEWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
2114 { WM_NCACTIVATE
, sent
|wparam
|optional
, 0 }, /* XP */
2115 { WM_ACTIVATE
, sent
|wparam
|optional
, 0 }, /* Win9x */
2116 { WM_ACTIVATEAPP
, sent
|wparam
|optional
, 0 }, /* Win9x */
2117 { EVENT_OBJECT_HIDE
, winevent_hook
|wparam
|lparam
, OBJID_CARET
, 0 },
2118 { EVENT_OBJECT_DESTROY
, winevent_hook
|wparam
|lparam
, 0, 0 },
2119 { WM_DESTROY
, sent
},
2120 { WM_NCDESTROY
, sent
},
2123 /* CreateWindow for MDI client window, initially visible */
2124 static const struct message WmCreateMDIclientSeq
[] = {
2125 { HCBT_CREATEWND
, hook
},
2126 { WM_NCCREATE
, sent
},
2127 { WM_NCCALCSIZE
, sent
|wparam
, 0 },
2128 { EVENT_OBJECT_REORDER
, winevent_hook
|wparam
|lparam
|optional
, 0, 0 },
2129 { WM_CREATE
, sent
},
2130 { EVENT_OBJECT_REORDER
, winevent_hook
|wparam
|lparam
|optional
, 0, 0 },
2131 { EVENT_OBJECT_CREATE
, winevent_hook
|wparam
|lparam
, 0, 0 },
2132 { WM_SIZE
, sent
|wparam
, SIZE_RESTORED
},
2134 { WM_PARENTNOTIFY
, sent
|wparam
, WM_CREATE
}, /* in MDI frame */
2135 { WM_SHOWWINDOW
, sent
|wparam
, 1 },
2136 { WM_WINDOWPOSCHANGING
, sent
|wparam
|optional
, SWP_SHOWWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
2137 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, 0, 0 },
2138 { WM_WINDOWPOSCHANGED
, sent
|wparam
|optional
, SWP_SHOWWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
2141 /* ShowWindow(SW_SHOW) for MDI client window */
2142 static const struct message WmShowMDIclientSeq
[] = {
2143 { WM_SHOWWINDOW
, sent
|wparam
, 1 },
2144 { WM_WINDOWPOSCHANGING
, sent
|wparam
|optional
, SWP_SHOWWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
2145 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, 0, 0 },
2146 { WM_WINDOWPOSCHANGED
, sent
|wparam
|optional
, SWP_SHOWWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
2149 /* ShowWindow(SW_HIDE) for MDI client window */
2150 static const struct message WmHideMDIclientSeq
[] = {
2151 { WM_SHOWWINDOW
, sent
|wparam
, 0 },
2152 { WM_WINDOWPOSCHANGING
, sent
|wparam
|optional
, SWP_HIDEWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
2153 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
|optional
, 0, 0 }, /* win2000 */
2154 { EVENT_OBJECT_HIDE
, winevent_hook
|wparam
|lparam
|optional
, 0, 0 }, /* XP */
2155 { WM_WINDOWPOSCHANGED
, sent
|wparam
|optional
, SWP_HIDEWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
2158 /* DestroyWindow for MDI client window, initially visible */
2159 static const struct message WmDestroyMDIclientSeq
[] = {
2160 { HCBT_DESTROYWND
, hook
},
2161 { 0x0090, sent
|optional
},
2162 { WM_PARENTNOTIFY
, sent
|wparam
, WM_DESTROY
}, /* in MDI frame */
2163 { WM_SHOWWINDOW
, sent
|wparam
, 0 },
2164 { WM_WINDOWPOSCHANGING
, sent
|wparam
|optional
, SWP_HIDEWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
2165 { EVENT_OBJECT_HIDE
, winevent_hook
|wparam
|lparam
, 0, 0 },
2166 { WM_WINDOWPOSCHANGED
, sent
|wparam
|optional
, SWP_HIDEWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
2167 { EVENT_OBJECT_DESTROY
, winevent_hook
|wparam
|lparam
, 0, 0 },
2168 { WM_DESTROY
, sent
},
2169 { WM_NCDESTROY
, sent
},
2172 /* CreateWindow for MDI child window, initially visible */
2173 static const struct message WmCreateMDIchildVisibleSeq
[] = {
2174 { HCBT_CREATEWND
, hook
},
2175 { WM_NCCREATE
, sent
},
2176 { WM_NCCALCSIZE
, sent
|wparam
, 0 },
2177 { WM_CREATE
, sent
},
2178 { EVENT_OBJECT_CREATE
, winevent_hook
|wparam
|lparam
, 0, 0 },
2179 { WM_SIZE
, sent
|wparam
, SIZE_RESTORED
},
2181 /* Win2k sends wparam set to
2182 * MAKEWPARAM(WM_CREATE, MDI_FIRST_CHILD_ID + nTotalCreated),
2183 * while Win9x doesn't bother to set child window id according to
2184 * CLIENTCREATESTRUCT.idFirstChild
2186 { WM_PARENTNOTIFY
, sent
/*|wparam, WM_CREATE*/ }, /* in MDI client */
2187 { WM_SHOWWINDOW
, sent
|wparam
, 1 },
2188 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
2189 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, 0, 0 },
2190 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
2191 { WM_MDIREFRESHMENU
, sent
/*|wparam|lparam, 0, 0*/ },
2192 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
},
2193 { WM_CHILDACTIVATE
, sent
|wparam
|lparam
, 0, 0 },
2194 { WM_WINDOWPOSCHANGING
, sent
|wparam
|defwinproc
, SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
2196 /* Win9x: message sequence terminates here. */
2198 { WM_NCACTIVATE
, sent
|wparam
|defwinproc
, 1 },
2199 { HCBT_SETFOCUS
, hook
}, /* in MDI client */
2200 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 1 }, /* in MDI client */
2201 { WM_IME_NOTIFY
, sent
|wparam
|optional
, 2 }, /* in MDI client */
2202 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
2203 { WM_SETFOCUS
, sent
}, /* in MDI client */
2204 { HCBT_SETFOCUS
, hook
},
2205 { WM_KILLFOCUS
, sent
}, /* in MDI client */
2206 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 0 }, /* in MDI client */
2207 { WM_IME_SETCONTEXT
, sent
|wparam
|defwinproc
|optional
, 1 },
2208 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
2209 { WM_SETFOCUS
, sent
|defwinproc
},
2210 { WM_MDIACTIVATE
, sent
|defwinproc
},
2213 /* CreateWindow for MDI child window with invisible parent */
2214 static const struct message WmCreateMDIchildInvisibleParentSeq
[] = {
2215 { HCBT_CREATEWND
, hook
},
2216 { WM_GETMINMAXINFO
, sent
},
2217 { WM_NCCREATE
, sent
},
2218 { WM_NCCALCSIZE
, sent
|wparam
, 0 },
2219 { EVENT_OBJECT_REORDER
, winevent_hook
|wparam
|lparam
|optional
, 0, 0 },
2220 { WM_CREATE
, sent
},
2221 { EVENT_OBJECT_CREATE
, winevent_hook
|wparam
|lparam
, 0, 0 },
2222 { WM_SIZE
, sent
|wparam
, SIZE_RESTORED
},
2224 { WM_PARENTNOTIFY
, sent
/*|wparam, WM_CREATE*/ }, /* in MDI client */
2225 { WM_SHOWWINDOW
, sent
|wparam
, 1 },
2226 { WM_MDIREFRESHMENU
, sent
}, /* in MDI client */
2227 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
},
2228 { WM_CHILDACTIVATE
, sent
|wparam
|lparam
, 0, 0 },
2229 { WM_WINDOWPOSCHANGING
, sent
|wparam
|defwinproc
, SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
2231 /* Win9x: message sequence terminates here. */
2233 { WM_NCACTIVATE
, sent
|wparam
|defwinproc
, 1 },
2234 { HCBT_SETFOCUS
, hook
}, /* in MDI client */
2235 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 1 }, /* in MDI client */
2236 { WM_IME_NOTIFY
, sent
|wparam
|optional
, 2 }, /* in MDI client */
2237 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
2238 { WM_SETFOCUS
, sent
}, /* in MDI client */
2239 { HCBT_SETFOCUS
, hook
},
2240 { WM_KILLFOCUS
, sent
}, /* in MDI client */
2241 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 0 }, /* in MDI client */
2242 { WM_IME_SETCONTEXT
, sent
|wparam
|defwinproc
|optional
, 1 },
2243 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
2244 { WM_SETFOCUS
, sent
|defwinproc
},
2245 { WM_MDIACTIVATE
, sent
|defwinproc
},
2248 /* DestroyWindow for MDI child window, initially visible */
2249 static const struct message WmDestroyMDIchildVisibleSeq
[] = {
2250 { HCBT_DESTROYWND
, hook
},
2251 /* Win2k sends wparam set to
2252 * MAKEWPARAM(WM_DESTROY, MDI_FIRST_CHILD_ID + nTotalCreated),
2253 * while Win9x doesn't bother to set child window id according to
2254 * CLIENTCREATESTRUCT.idFirstChild
2256 { 0x0090, sent
|optional
},
2257 { WM_PARENTNOTIFY
, sent
/*|wparam, WM_DESTROY*/ }, /* in MDI client */
2258 { WM_SHOWWINDOW
, sent
|wparam
, 0 },
2259 { WM_WINDOWPOSCHANGING
, sent
|wparam
|optional
, SWP_HIDEWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
2260 { EVENT_OBJECT_HIDE
, winevent_hook
|wparam
|lparam
, 0, 0 },
2261 { WM_ERASEBKGND
, sent
|parent
|optional
},
2262 { WM_WINDOWPOSCHANGED
, sent
|wparam
|optional
, SWP_HIDEWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
2264 /* { WM_DESTROY, sent }
2265 * Win9x: message sequence terminates here.
2268 { HCBT_SETFOCUS
, hook
}, /* set focus to MDI client */
2269 { WM_KILLFOCUS
, sent
},
2270 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 0 },
2271 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 1 }, /* in MDI client */
2272 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
2273 { WM_SETFOCUS
, sent
}, /* in MDI client */
2275 { HCBT_SETFOCUS
, hook
}, /* MDI client sets focus back to MDI child */
2276 { WM_KILLFOCUS
, sent
}, /* in MDI client */
2277 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 0 }, /* in MDI client */
2278 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 1 },
2279 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
2280 { WM_SETFOCUS
, sent
}, /* in MDI client */
2282 { EVENT_OBJECT_DESTROY
, winevent_hook
|wparam
|lparam
, 0, 0 },
2284 { HCBT_SETFOCUS
, hook
}, /* set focus to MDI client */
2285 { WM_KILLFOCUS
, sent
},
2286 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 0 },
2287 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 1 }, /* in MDI client */
2288 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
2289 { WM_SETFOCUS
, sent
}, /* in MDI client */
2291 { HCBT_SETFOCUS
, hook
}, /* MDI client sets focus back to MDI child */
2292 { WM_KILLFOCUS
, sent
}, /* in MDI client */
2293 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 0 }, /* in MDI client */
2294 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 1 },
2295 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
2296 { WM_SETFOCUS
, sent
}, /* in MDI client */
2298 { WM_DESTROY
, sent
},
2300 { HCBT_SETFOCUS
, hook
}, /* set focus to MDI client */
2301 { WM_KILLFOCUS
, sent
},
2302 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 0 },
2303 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 1 }, /* in MDI client */
2304 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
2305 { WM_SETFOCUS
, sent
}, /* in MDI client */
2307 { HCBT_SETFOCUS
, hook
}, /* MDI client sets focus back to MDI child */
2308 { WM_KILLFOCUS
, sent
}, /* in MDI client */
2309 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 0 }, /* in MDI client */
2310 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 1 },
2311 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
2312 { WM_SETFOCUS
, sent
}, /* in MDI client */
2314 { WM_NCDESTROY
, sent
},
2317 /* CreateWindow for MDI child window, initially invisible */
2318 static const struct message WmCreateMDIchildInvisibleSeq
[] = {
2319 { HCBT_CREATEWND
, hook
},
2320 { WM_NCCREATE
, sent
},
2321 { WM_NCCALCSIZE
, sent
|wparam
, 0 },
2322 { WM_CREATE
, sent
},
2323 { EVENT_OBJECT_CREATE
, winevent_hook
|wparam
|lparam
, 0, 0 },
2324 { WM_SIZE
, sent
|wparam
, SIZE_RESTORED
},
2326 /* Win2k sends wparam set to
2327 * MAKEWPARAM(WM_CREATE, MDI_FIRST_CHILD_ID + nTotalCreated),
2328 * while Win9x doesn't bother to set child window id according to
2329 * CLIENTCREATESTRUCT.idFirstChild
2331 { WM_PARENTNOTIFY
, sent
/*|wparam, WM_CREATE*/ }, /* in MDI client */
2334 /* DestroyWindow for MDI child window, initially invisible */
2335 static const struct message WmDestroyMDIchildInvisibleSeq
[] = {
2336 { HCBT_DESTROYWND
, hook
},
2337 /* Win2k sends wparam set to
2338 * MAKEWPARAM(WM_DESTROY, MDI_FIRST_CHILD_ID + nTotalCreated),
2339 * while Win9x doesn't bother to set child window id according to
2340 * CLIENTCREATESTRUCT.idFirstChild
2342 { 0x0090, sent
|optional
},
2343 { WM_PARENTNOTIFY
, sent
/*|wparam, WM_DESTROY*/ }, /* in MDI client */
2344 { EVENT_OBJECT_DESTROY
, winevent_hook
|wparam
|lparam
, 0, 0 },
2345 { WM_DESTROY
, sent
},
2346 { WM_NCDESTROY
, sent
},
2347 /* FIXME: Wine destroys an icon/title window while Windows doesn't */
2348 { WM_PARENTNOTIFY
, sent
|wparam
|optional
, WM_DESTROY
}, /* MDI client */
2351 /* CreateWindow for the 1st MDI child window, initially visible and maximized */
2352 static const struct message WmCreateMDIchildVisibleMaxSeq1
[] = {
2353 { HCBT_CREATEWND
, hook
},
2354 { WM_NCCREATE
, sent
},
2355 { WM_NCCALCSIZE
, sent
|wparam
, 0 },
2356 { WM_CREATE
, sent
},
2357 { EVENT_OBJECT_CREATE
, winevent_hook
|wparam
|lparam
, 0, 0 },
2358 { WM_SIZE
, sent
|wparam
, SIZE_RESTORED
},
2360 { HCBT_MINMAX
, hook
|lparam
, 0, SW_MAXIMIZE
},
2361 { WM_GETMINMAXINFO
, sent
},
2362 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_STATECHANGED
},
2363 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
2364 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOREDRAW
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
|SWP_STATECHANGED
},
2365 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_MAXIMIZED
},
2367 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
2368 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
2369 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
2370 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI frame */
2371 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI child */
2372 /* Win2k sends wparam set to
2373 * MAKEWPARAM(WM_CREATE, MDI_FIRST_CHILD_ID + nTotalCreated),
2374 * while Win9x doesn't bother to set child window id according to
2375 * CLIENTCREATESTRUCT.idFirstChild
2377 { WM_PARENTNOTIFY
, sent
/*|wparam, WM_CREATE*/ }, /* in MDI client */
2378 { WM_SHOWWINDOW
, sent
|wparam
, 1 },
2379 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
2380 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, 0, 0 },
2381 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
2382 { WM_MDIREFRESHMENU
, sent
/*|wparam|lparam, 0, 0*/ },
2383 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
},
2384 { WM_CHILDACTIVATE
, sent
|wparam
|lparam
, 0, 0 },
2385 { WM_WINDOWPOSCHANGING
, sent
|wparam
|defwinproc
|optional
, SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
2387 /* Win9x: message sequence terminates here. */
2389 { WM_NCACTIVATE
, sent
|wparam
|defwinproc
|optional
, 1 },
2390 { HCBT_SETFOCUS
, hook
}, /* in MDI client */
2391 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 1 }, /* in MDI client */
2392 { WM_IME_NOTIFY
, sent
|wparam
|optional
, 2 }, /* in MDI client */
2393 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
2394 { WM_SETFOCUS
, sent
|optional
}, /* in MDI client */
2395 { HCBT_SETFOCUS
, hook
},
2396 { WM_KILLFOCUS
, sent
|optional
}, /* in MDI client */
2397 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 0 }, /* in MDI client */
2398 { WM_IME_SETCONTEXT
, sent
|wparam
|defwinproc
|optional
, 1 },
2399 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
2400 { WM_SETFOCUS
, sent
|defwinproc
|optional
},
2401 { WM_MDIACTIVATE
, sent
|defwinproc
|optional
},
2403 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
2404 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
2405 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
2406 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI frame */
2409 /* CreateWindow for the 2nd MDI child window, initially visible and maximized */
2410 static const struct message WmCreateMDIchildVisibleMaxSeq2
[] = {
2411 /* restore the 1st MDI child */
2412 { WM_SETREDRAW
, sent
|wparam
, 0 },
2413 { HCBT_MINMAX
, hook
|lparam
, 0, SW_SHOWNORMAL
},
2414 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_STATECHANGED
},
2415 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
2416 { WM_CHILDACTIVATE
, sent
|wparam
|lparam
, 0, 0 },
2417 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOREDRAW
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
|SWP_STATECHANGED
},
2418 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_RESTORED
},
2420 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
2421 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
2422 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
2423 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI frame */
2424 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI child */
2425 { WM_SETREDRAW
, sent
|wparam
, 1 }, /* in the 1st MDI child */
2426 /* create the 2nd MDI child */
2427 { HCBT_CREATEWND
, hook
},
2428 { WM_NCCREATE
, sent
},
2429 { WM_NCCALCSIZE
, sent
|wparam
, 0 },
2430 { WM_CREATE
, sent
},
2431 { EVENT_OBJECT_CREATE
, winevent_hook
|wparam
|lparam
, 0, 0 },
2432 { WM_SIZE
, sent
|wparam
, SIZE_RESTORED
},
2434 { HCBT_MINMAX
, hook
|lparam
, 0, SW_MAXIMIZE
},
2435 { WM_GETMINMAXINFO
, sent
},
2436 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_STATECHANGED
},
2437 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
2438 { EVENT_OBJECT_REORDER
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
2439 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOREDRAW
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
|SWP_STATECHANGED
},
2440 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_MAXIMIZED
},
2442 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
2443 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
2444 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
2445 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI frame */
2446 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI child */
2447 /* Win2k sends wparam set to
2448 * MAKEWPARAM(WM_CREATE, MDI_FIRST_CHILD_ID + nTotalCreated),
2449 * while Win9x doesn't bother to set child window id according to
2450 * CLIENTCREATESTRUCT.idFirstChild
2452 { WM_PARENTNOTIFY
, sent
/*|wparam, WM_CREATE*/ }, /* in MDI client */
2453 { WM_SHOWWINDOW
, sent
|wparam
, 1 },
2454 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
2455 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, 0, 0 },
2456 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
2457 { WM_MDIREFRESHMENU
, sent
/*|wparam|lparam, 0, 0*/ },
2458 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
},
2459 { WM_CHILDACTIVATE
, sent
|wparam
|lparam
, 0, 0 },
2461 { WM_NCACTIVATE
, sent
|wparam
|defwinproc
, 0 }, /* in the 1st MDI child */
2462 { WM_MDIACTIVATE
, sent
|defwinproc
}, /* in the 1st MDI child */
2464 { WM_WINDOWPOSCHANGING
, sent
|wparam
|defwinproc
, SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
2466 /* Win9x: message sequence terminates here. */
2468 { WM_NCACTIVATE
, sent
|wparam
|defwinproc
, 1 },
2469 { HCBT_SETFOCUS
, hook
},
2470 { WM_KILLFOCUS
, sent
|defwinproc
|optional
}, /* in the 1st MDI child */
2471 { WM_IME_SETCONTEXT
, sent
|wparam
|defwinproc
|optional
, 0 }, /* in the 1st MDI child */
2472 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 1 }, /* in MDI client */
2473 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
2474 { WM_SETFOCUS
, sent
}, /* in MDI client */
2475 { HCBT_SETFOCUS
, hook
},
2476 { WM_KILLFOCUS
, sent
}, /* in MDI client */
2477 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 0 }, /* in MDI client */
2478 { WM_IME_SETCONTEXT
, sent
|wparam
|defwinproc
|optional
, 1 },
2479 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
2480 { WM_SETFOCUS
, sent
|defwinproc
},
2482 { WM_MDIACTIVATE
, sent
|defwinproc
},
2484 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
2485 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
2486 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
2487 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI frame */
2490 /* WM_MDICREATE MDI child window, initially visible and maximized */
2491 static const struct message WmCreateMDIchildVisibleMaxSeq3
[] = {
2492 { WM_MDICREATE
, sent
},
2493 { HCBT_CREATEWND
, hook
},
2494 { WM_NCCREATE
, sent
},
2495 { WM_NCCALCSIZE
, sent
|wparam
, 0 },
2496 { WM_CREATE
, sent
},
2497 { EVENT_OBJECT_CREATE
, winevent_hook
|wparam
|lparam
, 0, 0 },
2498 { WM_SIZE
, sent
|wparam
, SIZE_RESTORED
},
2500 { HCBT_MINMAX
, hook
|lparam
, 0, SW_MAXIMIZE
},
2501 { WM_GETMINMAXINFO
, sent
},
2502 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_STATECHANGED
},
2503 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
2504 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOREDRAW
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
|SWP_STATECHANGED
},
2505 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_MAXIMIZED
},
2508 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
2509 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
2510 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
2511 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI frame */
2512 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI child */
2514 /* Win2k sends wparam set to
2515 * MAKEWPARAM(WM_CREATE, MDI_FIRST_CHILD_ID + nTotalCreated),
2516 * while Win9x doesn't bother to set child window id according to
2517 * CLIENTCREATESTRUCT.idFirstChild
2519 { WM_PARENTNOTIFY
, sent
/*|wparam, WM_CREATE*/ }, /* in MDI client */
2520 { WM_SHOWWINDOW
, sent
|wparam
, 1 },
2521 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
2523 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, 0, 0 },
2525 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
2526 { WM_MDIREFRESHMENU
, sent
/*|wparam|lparam, 0, 0*/ },
2527 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
},
2529 { WM_CHILDACTIVATE
, sent
|wparam
|lparam
, 0, 0 },
2530 { WM_WINDOWPOSCHANGING
, sent
|wparam
|defwinproc
, SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
2532 /* Win9x: message sequence terminates here. */
2534 { WM_NCACTIVATE
, sent
|wparam
|defwinproc
, 1 },
2535 { WM_SETFOCUS
, sent
|optional
}, /* in MDI client */
2536 { HCBT_SETFOCUS
, hook
}, /* in MDI client */
2537 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 1 }, /* in MDI client */
2538 { WM_IME_NOTIFY
, sent
|wparam
|optional
, 2 },
2539 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
|optional
, OBJID_CLIENT
, 0 },
2540 { WM_SETFOCUS
, sent
|optional
}, /* in MDI client */
2541 { HCBT_SETFOCUS
, hook
|optional
},
2542 { WM_KILLFOCUS
, sent
}, /* in MDI client */
2543 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 0 }, /* in MDI client */
2544 { WM_IME_SETCONTEXT
, sent
|wparam
|defwinproc
|optional
, 1 },
2545 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
2546 { WM_SETFOCUS
, sent
|defwinproc
},
2548 { WM_MDIACTIVATE
, sent
|defwinproc
},
2551 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
2552 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
2553 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
2554 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
2557 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
2558 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
2559 { 0x0093, sent
|defwinproc
|optional
},
2560 { 0x0093, sent
|defwinproc
|optional
},
2561 { 0x0093, sent
|defwinproc
|optional
},
2562 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
2563 { WM_MOVE
, sent
|defwinproc
},
2564 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_RESTORED
},
2567 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_NOACTIVATE
},
2568 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
2569 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_NOACTIVATE
|SWP_NOMOVE
|SWP_NOCLIENTMOVE
},
2570 { WM_SIZE
, sent
|wparam
, SIZE_RESTORED
},
2573 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_NOACTIVATE
},
2574 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
2575 { 0x0093, sent
|optional
},
2576 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_NOACTIVATE
|SWP_NOMOVE
|SWP_NOCLIENTMOVE
},
2577 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_MAXIMIZED
},
2579 { 0x0093, sent
|optional
},
2580 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI child */
2581 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI client */
2582 { WM_NCCALCSIZE
, sent
|wparam
|optional
, 1 }, /* XP sends it to MDI frame */
2583 { 0x0093, sent
|defwinproc
|optional
},
2584 { 0x0093, sent
|defwinproc
|optional
},
2585 { 0x0093, sent
|defwinproc
|optional
},
2586 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI frame */
2587 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* XP sends a duplicate */
2591 /* CreateWindow for the 1st MDI child window, initially invisible and maximized */
2592 static const struct message WmCreateMDIchildInvisibleMaxSeq4
[] = {
2593 { HCBT_CREATEWND
, hook
},
2594 { WM_GETMINMAXINFO
, sent
},
2595 { WM_NCCREATE
, sent
},
2596 { WM_NCCALCSIZE
, sent
|wparam
, 0 },
2597 { EVENT_OBJECT_REORDER
, winevent_hook
|wparam
|lparam
, 0, 0 },
2598 { WM_CREATE
, sent
},
2599 { EVENT_OBJECT_CREATE
, winevent_hook
|wparam
|lparam
, 0, 0 },
2600 { WM_SIZE
, sent
|wparam
, SIZE_RESTORED
},
2601 { WM_WINDOWPOSCHANGING
, sent
|wparam
|optional
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
, 0, SWP_NOZORDER
}, /* MDI frame */
2602 { WM_NCCALCSIZE
, sent
|wparam
|optional
, 1 }, /* MDI frame */
2603 { WM_WINDOWPOSCHANGED
, sent
|wparam
|optional
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
, 0, SWP_NOZORDER
}, /* MDI frame */
2605 { HCBT_MINMAX
, hook
|lparam
, 0, SW_MAXIMIZE
},
2606 { WM_GETMINMAXINFO
, sent
},
2607 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_STATECHANGED
},
2608 { WM_GETMINMAXINFO
, sent
|defwinproc
},
2609 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
2610 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOREDRAW
|SWP_NOCLIENTSIZE
|SWP_STATECHANGED
},
2611 { WM_MOVE
, sent
|defwinproc
},
2612 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_MAXIMIZED
},
2614 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
2615 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
2616 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
2617 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI frame */
2618 { WM_NCCALCSIZE
, sent
|wparam
|optional
, 1 }, /* MDI child */
2619 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI child */
2620 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI child */
2621 /* Win2k sends wparam set to
2622 * MAKEWPARAM(WM_CREATE, MDI_FIRST_CHILD_ID + nTotalCreated),
2623 * while Win9x doesn't bother to set child window id according to
2624 * CLIENTCREATESTRUCT.idFirstChild
2626 { WM_PARENTNOTIFY
, sent
/*|wparam, WM_CREATE*/ }, /* in MDI client */
2629 /* WM_SYSCOMMAND/SC_CLOSE for the 2nd MDI child window, initially visible and maximized */
2630 static const struct message WmDestroyMDIchildVisibleMaxSeq2
[] = {
2631 { WM_SYSCOMMAND
, sent
|wparam
, SC_CLOSE
},
2632 { HCBT_SYSCOMMAND
, hook
},
2633 { WM_CLOSE
, sent
|defwinproc
},
2634 { WM_MDIDESTROY
, sent
}, /* in MDI client */
2636 /* bring the 1st MDI child to top */
2637 { WM_WINDOWPOSCHANGING
, sent
|wparam
|defwinproc
, SWP_NOSIZE
|SWP_NOMOVE
}, /* in the 1st MDI child */
2638 { WM_WINDOWPOSCHANGING
, sent
|wparam
|defwinproc
, SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
}, /* in the 2nd MDI child */
2640 { EVENT_OBJECT_REORDER
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
2642 { WM_CHILDACTIVATE
, sent
|defwinproc
|wparam
|lparam
, 0, 0 }, /* in the 1st MDI child */
2643 { WM_NCACTIVATE
, sent
|wparam
|defwinproc
, 0 }, /* in the 1st MDI child */
2644 { WM_MDIACTIVATE
, sent
|defwinproc
}, /* in the 1st MDI child */
2646 /* maximize the 1st MDI child */
2647 { HCBT_MINMAX
, hook
|lparam
, 0, SW_MAXIMIZE
},
2648 { WM_GETMINMAXINFO
, sent
|defwinproc
},
2649 { WM_WINDOWPOSCHANGING
, sent
|wparam
|defwinproc
, SWP_FRAMECHANGED
|SWP_STATECHANGED
},
2650 { WM_NCCALCSIZE
, sent
|defwinproc
|wparam
, 1 },
2651 { WM_CHILDACTIVATE
, sent
|defwinproc
|wparam
|lparam
, 0, 0 },
2652 { WM_WINDOWPOSCHANGED
, sent
|wparam
|defwinproc
, SWP_FRAMECHANGED
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOREDRAW
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
|SWP_STATECHANGED
},
2653 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_MAXIMIZED
},
2655 /* restore the 2nd MDI child */
2656 { WM_SETREDRAW
, sent
|defwinproc
|wparam
, 0 },
2657 { HCBT_MINMAX
, hook
|lparam
, 0, SW_NORMALNA
},
2658 { WM_WINDOWPOSCHANGING
, sent
|wparam
|defwinproc
, SWP_NOACTIVATE
|SWP_FRAMECHANGED
|SWP_SHOWWINDOW
|SWP_STATECHANGED
},
2659 { WM_NCCALCSIZE
, sent
|defwinproc
|wparam
, 1 },
2661 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, 0, 0 },
2663 { WM_WINDOWPOSCHANGED
, sent
|wparam
|defwinproc
, SWP_NOACTIVATE
|SWP_FRAMECHANGED
|SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOREDRAW
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
|SWP_STATECHANGED
},
2664 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_RESTORED
},
2666 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI frame */
2668 { WM_SETREDRAW
, sent
|defwinproc
|wparam
, 1 },
2670 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
2671 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
2672 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
2673 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI frame */
2674 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI child */
2676 /* bring the 1st MDI child to top */
2677 { WM_WINDOWPOSCHANGING
, sent
|wparam
|defwinproc
, SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
2678 { WM_NCACTIVATE
, sent
|wparam
|defwinproc
, 1 },
2679 { HCBT_SETFOCUS
, hook
},
2680 { WM_KILLFOCUS
, sent
|defwinproc
},
2681 { WM_IME_SETCONTEXT
, sent
|wparam
|defwinproc
|optional
, 0 },
2682 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 1 }, /* in MDI client */
2683 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
2684 { WM_SETFOCUS
, sent
}, /* in MDI client */
2685 { HCBT_SETFOCUS
, hook
},
2686 { WM_KILLFOCUS
, sent
}, /* in MDI client */
2687 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 0 }, /* in MDI client */
2688 { WM_IME_SETCONTEXT
, sent
|wparam
|defwinproc
|optional
, 1 },
2689 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
2690 { WM_SETFOCUS
, sent
|defwinproc
},
2691 { WM_MDIACTIVATE
, sent
|defwinproc
},
2692 { WM_WINDOWPOSCHANGED
, sent
|wparam
|defwinproc
, SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOREDRAW
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
2694 /* apparently ShowWindow(SW_SHOW) on an MDI client */
2695 { WM_SHOWWINDOW
, sent
|wparam
, 1 },
2696 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
2697 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, 0, 0 },
2698 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
2699 { WM_MDIREFRESHMENU
, sent
},
2701 { HCBT_DESTROYWND
, hook
},
2702 /* Win2k sends wparam set to
2703 * MAKEWPARAM(WM_DESTROY, MDI_FIRST_CHILD_ID + nTotalCreated),
2704 * while Win9x doesn't bother to set child window id according to
2705 * CLIENTCREATESTRUCT.idFirstChild
2707 { 0x0090, sent
|defwinproc
|optional
},
2708 { WM_PARENTNOTIFY
, sent
/*|wparam, WM_DESTROY*/ }, /* in MDI client */
2709 { WM_SHOWWINDOW
, sent
|defwinproc
|wparam
, 0 },
2710 { WM_WINDOWPOSCHANGING
, sent
|wparam
|defwinproc
, SWP_HIDEWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
2711 { EVENT_OBJECT_HIDE
, winevent_hook
|wparam
|lparam
, 0, 0 },
2712 { WM_ERASEBKGND
, sent
|parent
|optional
},
2713 { WM_WINDOWPOSCHANGED
, sent
|wparam
|defwinproc
, SWP_HIDEWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
2715 { EVENT_OBJECT_DESTROY
, winevent_hook
|wparam
|lparam
, 0, 0 },
2716 { WM_DESTROY
, sent
|defwinproc
},
2717 { WM_NCDESTROY
, sent
|defwinproc
},
2720 /* WM_MDIDESTROY for the single MDI child window, initially visible and maximized */
2721 static const struct message WmDestroyMDIchildVisibleMaxSeq1
[] = {
2722 { WM_MDIDESTROY
, sent
}, /* in MDI client */
2723 { WM_SHOWWINDOW
, sent
|wparam
, 0 },
2724 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_HIDEWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
2725 { EVENT_OBJECT_HIDE
, winevent_hook
|wparam
|lparam
, 0, 0 },
2726 { WM_ERASEBKGND
, sent
|parent
|optional
},
2727 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_HIDEWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
2729 { HCBT_SETFOCUS
, hook
},
2730 { WM_KILLFOCUS
, sent
},
2731 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 0 },
2732 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 1 }, /* in MDI client */
2733 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
2734 { WM_SETFOCUS
, sent
}, /* in MDI client */
2735 { HCBT_SETFOCUS
, hook
},
2736 { WM_KILLFOCUS
, sent
}, /* in MDI client */
2737 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 0 }, /* in MDI client */
2738 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 1 },
2739 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
2740 { WM_SETFOCUS
, sent
},
2743 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
2744 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
2745 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOREDRAW
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
2746 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI child */
2749 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
2750 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
2751 { 0x0093, sent
|defwinproc
|optional
},
2752 { 0x0093, sent
|defwinproc
|optional
},
2753 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
2754 { WM_MOVE
, sent
|defwinproc
},
2755 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_RESTORED
},
2758 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_NOACTIVATE
},
2759 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
2760 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_NOACTIVATE
|SWP_NOMOVE
|SWP_NOCLIENTMOVE
},
2761 { WM_SIZE
, sent
|wparam
, SIZE_RESTORED
},
2764 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_NOACTIVATE
},
2765 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
2766 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_NOACTIVATE
|SWP_NOMOVE
|SWP_NOREDRAW
|SWP_NOCLIENTMOVE
},
2767 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_MAXIMIZED
},
2770 { WM_WINDOWPOSCHANGING
, sent
|wparam
|defwinproc
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
2771 { WM_NCCALCSIZE
, sent
|wparam
|defwinproc
, 1 },
2772 { WM_WINDOWPOSCHANGED
, sent
|wparam
|defwinproc
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOREDRAW
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
2773 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI child */
2776 { WM_WINDOWPOSCHANGING
, sent
|wparam
|defwinproc
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
2777 { WM_NCCALCSIZE
, sent
|wparam
|defwinproc
, 1 },
2778 { 0x0093, sent
|defwinproc
|optional
},
2779 { 0x0093, sent
|defwinproc
|optional
},
2780 { 0x0093, sent
|defwinproc
|optional
},
2781 { WM_WINDOWPOSCHANGED
, sent
|wparam
|defwinproc
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
2782 { WM_MOVE
, sent
|defwinproc
},
2783 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_RESTORED
},
2786 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_NOACTIVATE
},
2787 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
2788 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_NOACTIVATE
|SWP_NOMOVE
|SWP_NOCLIENTMOVE
},
2789 { WM_SIZE
, sent
|wparam
, SIZE_RESTORED
},
2792 { WM_WINDOWPOSCHANGING
, sent
|wparam
|defwinproc
, SWP_NOACTIVATE
},
2793 { WM_NCCALCSIZE
, sent
|wparam
|defwinproc
, 1 },
2794 { WM_WINDOWPOSCHANGED
, sent
|wparam
|defwinproc
, SWP_NOACTIVATE
|SWP_NOMOVE
|SWP_NOREDRAW
|SWP_NOCLIENTMOVE
},
2795 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_MAXIMIZED
},
2796 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI child */
2797 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI client */
2799 { 0x0093, sent
|defwinproc
|optional
},
2800 { WM_NCCALCSIZE
, sent
|wparam
|defwinproc
|optional
, 1 }, /* XP sends it to MDI frame */
2801 { 0x0093, sent
|defwinproc
|optional
},
2802 { 0x0093, sent
|defwinproc
|optional
},
2803 { 0x0093, sent
|defwinproc
|optional
},
2804 { 0x0093, sent
|optional
},
2806 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI frame */
2807 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI child */
2808 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI client */
2809 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI frame */
2810 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* XP sends a duplicate */
2813 { WM_WINDOWPOSCHANGING
, sent
|wparam
|optional
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
2814 { WM_NCCALCSIZE
, sent
|wparam
|optional
, 1 },
2815 { 0x0093, sent
|defwinproc
|optional
},
2816 { 0x0093, sent
|defwinproc
|optional
},
2817 { 0x0093, sent
|defwinproc
|optional
},
2818 { WM_WINDOWPOSCHANGED
, sent
|wparam
|optional
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
2819 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI frame */
2820 { 0x0093, sent
|optional
},
2822 { WM_NCACTIVATE
, sent
|wparam
, 0 },
2823 { WM_MDIACTIVATE
, sent
},
2825 { HCBT_MINMAX
, hook
|lparam
, 0, SW_SHOWNORMAL
},
2826 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_SHOWWINDOW
|SWP_STATECHANGED
},
2827 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
2829 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, 0, 0 },
2831 { WM_CHILDACTIVATE
, sent
|wparam
|lparam
, 0, 0 },
2832 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_SHOWWINDOW
|SWP_NOMOVE
|SWP_NOCLIENTMOVE
|SWP_STATECHANGED
},
2833 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_RESTORED
},
2836 { WM_WINDOWPOSCHANGING
, sent
|wparam
|defwinproc
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
2837 { WM_NCCALCSIZE
, sent
|wparam
|defwinproc
, 1 },
2838 { WM_WINDOWPOSCHANGED
, sent
|wparam
|defwinproc
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
2839 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI child */
2842 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
2843 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
2844 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
2845 { WM_MOVE
, sent
|defwinproc
},
2846 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_RESTORED
},
2849 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_NOACTIVATE
},
2850 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
2851 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_NOACTIVATE
|SWP_NOMOVE
|SWP_NOCLIENTMOVE
},
2852 { WM_SIZE
, sent
|wparam
, SIZE_RESTORED
},
2853 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI child */
2854 { WM_NCCALCSIZE
, sent
|wparam
|optional
, 1 }, /* XP */
2855 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI client */
2856 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI frame */
2857 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* XP sends a duplicate */
2859 { HCBT_SETFOCUS
, hook
},
2860 { WM_KILLFOCUS
, sent
},
2861 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 0 },
2862 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 1 }, /* in MDI client */
2863 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
2864 { WM_SETFOCUS
, sent
}, /* in MDI client */
2866 { WM_MDIREFRESHMENU
, sent
}, /* in MDI client */
2868 { HCBT_DESTROYWND
, hook
},
2869 /* Win2k sends wparam set to
2870 * MAKEWPARAM(WM_DESTROY, MDI_FIRST_CHILD_ID + nTotalCreated),
2871 * while Win9x doesn't bother to set child window id according to
2872 * CLIENTCREATESTRUCT.idFirstChild
2874 { 0x0090, sent
|optional
},
2875 { WM_PARENTNOTIFY
, sent
/*|wparam, WM_DESTROY*/ }, /* in MDI client */
2877 { WM_SHOWWINDOW
, sent
|wparam
, 0 },
2878 { WM_WINDOWPOSCHANGING
, sent
|wparam
|optional
, SWP_HIDEWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
2879 { EVENT_OBJECT_HIDE
, winevent_hook
|wparam
|lparam
, 0, 0 },
2880 { WM_ERASEBKGND
, sent
|parent
|optional
},
2881 { WM_WINDOWPOSCHANGED
, sent
|wparam
|optional
, SWP_HIDEWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
2883 { EVENT_OBJECT_DESTROY
, winevent_hook
|wparam
|lparam
, 0, 0 },
2884 { WM_DESTROY
, sent
},
2885 { WM_NCDESTROY
, sent
},
2888 /* ShowWindow(SW_MAXIMIZE) for a not visible MDI child window */
2889 static const struct message WmMaximizeMDIchildInvisibleSeq
[] = {
2890 { HCBT_MINMAX
, hook
|lparam
, 0, SW_MAXIMIZE
},
2891 { WM_GETMINMAXINFO
, sent
},
2892 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_FRAMECHANGED
|SWP_STATECHANGED
},
2893 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
2894 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, 0, 0 },
2895 { WM_CHILDACTIVATE
, sent
|wparam
|lparam
, 0, 0 },
2897 { WM_WINDOWPOSCHANGING
, sent
|wparam
|optional
|defwinproc
, SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
2898 { WM_NCACTIVATE
, sent
|wparam
|optional
|defwinproc
, 1 },
2899 { HCBT_SETFOCUS
, hook
|optional
},
2900 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 1 }, /* in MDI client */
2901 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
2902 { WM_SETFOCUS
, sent
|optional
}, /* in MDI client */
2903 { HCBT_SETFOCUS
, hook
|optional
},
2904 { WM_KILLFOCUS
, sent
|optional
}, /* in MDI client */
2905 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 0 }, /* in MDI client */
2906 { WM_IME_SETCONTEXT
, sent
|wparam
|defwinproc
|optional
, 1 },
2907 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
2908 { WM_SETFOCUS
, sent
|optional
|defwinproc
},
2909 { WM_MDIACTIVATE
, sent
|optional
|defwinproc
},
2910 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_FRAMECHANGED
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
|SWP_STATECHANGED
},
2911 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_MAXIMIZED
},
2913 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
2914 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
2915 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
2916 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI frame */
2917 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI child */
2920 /* ShowWindow(SW_MAXIMIZE) for a not visible maximized MDI child window */
2921 static const struct message WmMaximizeMDIchildInvisibleSeq2
[] = {
2922 { HCBT_MINMAX
, hook
|lparam
, 0, SW_MAXIMIZE
},
2923 { WM_GETMINMAXINFO
, sent
},
2924 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_FRAMECHANGED
},
2925 { WM_GETMINMAXINFO
, sent
|defwinproc
},
2926 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
2927 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, 0, 0 },
2928 { WM_CHILDACTIVATE
, sent
|wparam
|lparam
, 0, 0 },
2930 { WM_WINDOWPOSCHANGING
, sent
|wparam
|defwinproc
|optional
, SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
2931 { WM_NCACTIVATE
, sent
|wparam
|defwinproc
|optional
, 1 },
2932 { HCBT_SETFOCUS
, hook
|optional
},
2933 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 1 }, /* in MDI client */
2934 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
2935 { WM_SETFOCUS
, sent
|optional
}, /* in MDI client */
2936 { HCBT_SETFOCUS
, hook
|optional
},
2937 { WM_KILLFOCUS
, sent
|optional
}, /* in MDI client */
2938 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 0 }, /* in MDI client */
2939 { WM_IME_SETCONTEXT
, sent
|wparam
|defwinproc
|optional
, 1 },
2940 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
2941 { WM_SETFOCUS
, sent
|defwinproc
|optional
},
2942 { WM_MDIACTIVATE
, sent
|defwinproc
|optional
},
2943 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_FRAMECHANGED
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
2944 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI child */
2947 /* WM_MDIMAXIMIZE for an MDI child window with invisible parent */
2948 static const struct message WmMaximizeMDIchildInvisibleParentSeq
[] = {
2949 { WM_MDIMAXIMIZE
, sent
}, /* in MDI client */
2950 { HCBT_MINMAX
, hook
|lparam
, 0, SW_MAXIMIZE
},
2951 { WM_GETMINMAXINFO
, sent
},
2952 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_STATECHANGED
},
2953 { WM_GETMINMAXINFO
, sent
|defwinproc
},
2954 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
2955 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
|optional
, 0, 0 }, /* XP doesn't send it */
2956 { WM_CHILDACTIVATE
, sent
|wparam
|lparam
, 0, 0 },
2957 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOREDRAW
|SWP_STATECHANGED
},
2958 { WM_MOVE
, sent
|defwinproc
},
2959 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_MAXIMIZED
},
2961 { WM_WINDOWPOSCHANGING
, sent
|wparam
|defwinproc
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
2962 { WM_NCCALCSIZE
, sent
|wparam
|defwinproc
, 1 },
2963 { WM_WINDOWPOSCHANGED
, sent
|wparam
|defwinproc
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOREDRAW
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
2964 { WM_NCCALCSIZE
, sent
|wparam
|defwinproc
|optional
, 1 },
2965 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
|optional
, 0, 0 }, /* MDI child XP */
2966 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
|optional
, 0, 0 }, /* MDI client XP */
2968 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
2969 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
2970 { 0x0093, sent
|defwinproc
|optional
},
2971 { 0x0094, sent
|defwinproc
|optional
},
2972 { 0x0094, sent
|defwinproc
|optional
},
2973 { 0x0094, sent
|defwinproc
|optional
},
2974 { 0x0094, sent
|defwinproc
|optional
},
2975 { 0x0093, sent
|defwinproc
|optional
},
2976 { 0x0093, sent
|defwinproc
|optional
},
2977 { 0x0091, sent
|defwinproc
|optional
},
2978 { 0x0092, sent
|defwinproc
|optional
},
2979 { 0x0092, sent
|defwinproc
|optional
},
2980 { 0x0092, sent
|defwinproc
|optional
},
2981 { 0x0092, sent
|defwinproc
|optional
},
2982 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
2983 { WM_MOVE
, sent
|defwinproc
},
2984 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_RESTORED
},
2985 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
|optional
, 0, 0 }, /* MDI frame win2000 */
2987 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_NOACTIVATE
},
2988 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
2989 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_NOACTIVATE
|SWP_NOMOVE
|SWP_NOREDRAW
|SWP_NOCLIENTMOVE
},
2990 { WM_SIZE
, sent
|wparam
, SIZE_RESTORED
},
2992 { WM_WINDOWPOSCHANGING
, sent
|wparam
|defwinproc
, SWP_NOACTIVATE
},
2993 { WM_GETMINMAXINFO
, sent
|defwinproc
},
2994 { WM_NCCALCSIZE
, sent
|wparam
|defwinproc
, 1 },
2995 { WM_WINDOWPOSCHANGED
, sent
|wparam
|defwinproc
, SWP_NOACTIVATE
|SWP_NOMOVE
|SWP_NOREDRAW
|SWP_NOCLIENTMOVE
},
2996 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_MAXIMIZED
},
2997 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
|optional
, 0, 0 }, /* MDI child win2000 */
2998 { WM_NCCALCSIZE
, sent
|wparam
|defwinproc
|optional
, 1 },
2999 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
|optional
, 0, 0 }, /* MDI child XP */
3000 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
|optional
, 0, 0 }, /* MDI child XP */
3001 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
|optional
, 0, 0 }, /* MDI client XP */
3003 { 0x0093, sent
|optional
},
3004 { WM_NCCALCSIZE
, sent
|wparam
|optional
, 1 },
3005 { 0x0093, sent
|defwinproc
|optional
},
3006 { 0x0093, sent
|defwinproc
|optional
},
3007 { 0x0093, sent
|defwinproc
|optional
},
3008 { 0x0091, sent
|defwinproc
|optional
},
3009 { 0x0092, sent
|defwinproc
|optional
},
3010 { 0x0092, sent
|defwinproc
|optional
},
3011 { 0x0092, sent
|defwinproc
|optional
},
3012 { 0x0092, sent
|defwinproc
|optional
},
3013 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
|optional
, 0, 0 }, /* MDI frame XP */
3014 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
|optional
, 0, 0 }, /* MDI frame XP */
3015 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
|optional
, 0, 0 }, /* MDI child XP */
3018 /* ShowWindow(SW_MAXIMIZE) for a visible MDI child window */
3019 static const struct message WmMaximizeMDIchildVisibleSeq
[] = {
3020 { HCBT_MINMAX
, hook
|lparam
, 0, SW_MAXIMIZE
},
3021 { WM_GETMINMAXINFO
, sent
},
3022 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_STATECHANGED
},
3023 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
3024 { WM_CHILDACTIVATE
, sent
|wparam
|lparam
, 0, 0 },
3025 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
|SWP_STATECHANGED
},
3026 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_MAXIMIZED
},
3028 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
3029 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
3030 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
3031 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI frame */
3032 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI child */
3035 /* ShowWindow(SW_RESTORE) for a visible maximized MDI child window */
3036 static const struct message WmRestoreMDIchildVisibleSeq
[] = {
3037 { HCBT_MINMAX
, hook
|lparam
, 0, SW_RESTORE
},
3038 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_STATECHANGED
},
3039 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
3040 { WM_CHILDACTIVATE
, sent
|wparam
|lparam
, 0, 0 },
3041 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
|SWP_STATECHANGED
},
3042 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_RESTORED
},
3044 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
3045 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
3046 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
3047 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI frame */
3048 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI child */
3051 /* ShowWindow(SW_RESTORE) for a visible minimized MDI child window */
3052 static const struct message WmRestoreMDIchildVisibleSeq_2
[] = {
3053 { HCBT_MINMAX
, hook
|lparam
, 0, SW_RESTORE
},
3054 { WM_QUERYOPEN
, sent
|wparam
|lparam
, 0, 0 },
3055 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOCOPYBITS
|SWP_STATECHANGED
},
3056 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
3057 { WM_CHILDACTIVATE
, sent
|wparam
|lparam
, 0, 0 },
3058 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOCOPYBITS
|SWP_NOCLIENTSIZE
|SWP_STATECHANGED
},
3059 { WM_MOVE
, sent
|defwinproc
},
3060 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_RESTORED
},
3061 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI child */
3062 { EVENT_SYSTEM_MINIMIZEEND
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI child */
3063 { HCBT_SETFOCUS
, hook
},
3064 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 1 },
3065 { WM_IME_NOTIFY
, sent
|wparam
|defwinproc
|optional
, 2 },
3066 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
3067 { WM_SETFOCUS
, sent
},
3070 /* ShowWindow(SW_MINIMIZE) for a visible restored MDI child window */
3071 static const struct message WmMinimizeMDIchildVisibleSeq
[] = {
3072 { HCBT_MINMAX
, hook
|lparam
, 0, SW_MINIMIZE
},
3073 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOCOPYBITS
|SWP_STATECHANGED
},
3074 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
3075 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOCOPYBITS
|SWP_NOCLIENTSIZE
|SWP_STATECHANGED
},
3076 { WM_MOVE
, sent
|defwinproc
},
3077 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_MINIMIZED
},
3078 { WM_CHILDACTIVATE
, sent
|wparam
|lparam
|defwinproc
, 0, 0 },
3079 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI child */
3080 { EVENT_SYSTEM_MINIMIZESTART
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI child */
3081 /* FIXME: Wine creates an icon/title window while Windows doesn't */
3082 { WM_PARENTNOTIFY
, sent
|parent
|wparam
|optional
, WM_CREATE
}, /* MDI client */
3085 /* ShowWindow(SW_RESTORE) for a not visible MDI child window */
3086 static const struct message WmRestoreMDIchildInisibleSeq
[] = {
3087 { HCBT_MINMAX
, hook
|lparam
, 0, SW_RESTORE
},
3088 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_FRAMECHANGED
|SWP_STATECHANGED
},
3089 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
3090 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, 0, 0 },
3091 { WM_CHILDACTIVATE
, sent
|wparam
|lparam
, 0, 0 },
3092 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_FRAMECHANGED
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
|SWP_STATECHANGED
},
3093 { WM_SIZE
, sent
|defwinproc
|wparam
, SIZE_RESTORED
},
3095 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
3096 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
3097 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
3098 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI frame */
3099 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* MDI child */
3103 static HWND mdi_client
;
3104 static WNDPROC old_mdi_client_proc
;
3106 static LRESULT WINAPI
mdi_client_hook_proc(HWND hwnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
3108 struct recvd_message msg
;
3110 /* do not log painting messages */
3111 if (message
!= WM_PAINT
&&
3112 message
!= WM_NCPAINT
&&
3113 message
!= WM_SYNCPAINT
&&
3114 message
!= WM_ERASEBKGND
&&
3115 message
!= WM_NCHITTEST
&&
3116 message
!= WM_GETTEXT
&&
3117 message
!= WM_MDIGETACTIVE
&&
3118 message
!= WM_GETICON
&&
3119 message
!= WM_DEVICECHANGE
)
3122 msg
.message
= message
;
3123 msg
.flags
= sent
|wparam
|lparam
;
3124 msg
.wParam
= wParam
;
3125 msg
.lParam
= lParam
;
3126 msg
.descr
= "mdi client";
3130 return CallWindowProcA(old_mdi_client_proc
, hwnd
, message
, wParam
, lParam
);
3133 static LRESULT WINAPI
mdi_child_wnd_proc(HWND hwnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
3135 static long defwndproc_counter
= 0;
3137 struct recvd_message msg
;
3139 /* do not log painting messages */
3140 if (message
!= WM_PAINT
&&
3141 message
!= WM_NCPAINT
&&
3142 message
!= WM_SYNCPAINT
&&
3143 message
!= WM_ERASEBKGND
&&
3144 message
!= WM_NCHITTEST
&&
3145 message
!= WM_GETTEXT
&&
3146 message
!= WM_GETICON
&&
3147 message
!= WM_DEVICECHANGE
)
3151 case WM_MDIACTIVATE
:
3153 HWND active
, client
= GetParent(hwnd
);
3155 active
= (HWND
)SendMessageA(client
, WM_MDIGETACTIVE
, 0, 0);
3157 if (hwnd
== (HWND
)lParam
) /* if we are being activated */
3158 ok (active
== (HWND
)lParam
, "new active %p != active %p\n", (HWND
)lParam
, active
);
3160 ok (active
== (HWND
)wParam
, "old active %p != active %p\n", (HWND
)wParam
, active
);
3166 msg
.message
= message
;
3167 msg
.flags
= sent
|wparam
|lparam
;
3168 if (defwndproc_counter
) msg
.flags
|= defwinproc
;
3169 msg
.wParam
= wParam
;
3170 msg
.lParam
= lParam
;
3171 msg
.descr
= "mdi child";
3175 defwndproc_counter
++;
3176 ret
= DefMDIChildProcA(hwnd
, message
, wParam
, lParam
);
3177 defwndproc_counter
--;
3182 static LRESULT WINAPI
mdi_frame_wnd_proc(HWND hwnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
3184 static long defwndproc_counter
= 0;
3186 struct recvd_message msg
;
3188 /* do not log painting messages */
3189 if (message
!= WM_PAINT
&&
3190 message
!= WM_NCPAINT
&&
3191 message
!= WM_SYNCPAINT
&&
3192 message
!= WM_ERASEBKGND
&&
3193 message
!= WM_NCHITTEST
&&
3194 message
!= WM_GETTEXT
&&
3195 message
!= WM_GETICON
&&
3196 message
!= WM_DEVICECHANGE
)
3199 msg
.message
= message
;
3200 msg
.flags
= sent
|wparam
|lparam
;
3201 if (defwndproc_counter
) msg
.flags
|= defwinproc
;
3202 msg
.wParam
= wParam
;
3203 msg
.lParam
= lParam
;
3204 msg
.descr
= "mdi frame";
3208 defwndproc_counter
++;
3209 ret
= DefFrameProcA(hwnd
, mdi_client
, message
, wParam
, lParam
);
3210 defwndproc_counter
--;
3215 static BOOL
mdi_RegisterWindowClasses(void)
3220 cls
.lpfnWndProc
= mdi_frame_wnd_proc
;
3223 cls
.hInstance
= GetModuleHandleA(0);
3225 cls
.hCursor
= LoadCursorA(0, IDC_ARROW
);
3226 cls
.hbrBackground
= GetStockObject(WHITE_BRUSH
);
3227 cls
.lpszMenuName
= NULL
;
3228 cls
.lpszClassName
= "MDI_frame_class";
3229 if (!RegisterClassA(&cls
)) return FALSE
;
3231 cls
.lpfnWndProc
= mdi_child_wnd_proc
;
3232 cls
.lpszClassName
= "MDI_child_class";
3233 if (!RegisterClassA(&cls
)) return FALSE
;
3235 if (!GetClassInfoA(0, "MDIClient", &cls
)) assert(0);
3236 old_mdi_client_proc
= cls
.lpfnWndProc
;
3237 cls
.hInstance
= GetModuleHandleA(0);
3238 cls
.lpfnWndProc
= mdi_client_hook_proc
;
3239 cls
.lpszClassName
= "MDI_client_class";
3240 if (!RegisterClassA(&cls
)) assert(0);
3245 static void test_mdi_messages(void)
3247 MDICREATESTRUCTA mdi_cs
;
3248 CLIENTCREATESTRUCT client_cs
;
3249 HWND mdi_frame
, mdi_child
, mdi_child2
, active_child
;
3251 HMENU hMenu
= CreateMenu();
3253 assert(mdi_RegisterWindowClasses());
3257 trace("creating MDI frame window\n");
3258 mdi_frame
= CreateWindowExA(0, "MDI_frame_class", "MDI frame window",
3259 WS_CAPTION
| WS_SYSMENU
| WS_MINIMIZEBOX
|
3260 WS_MAXIMIZEBOX
| WS_VISIBLE
,
3261 100, 100, CW_USEDEFAULT
, CW_USEDEFAULT
,
3262 GetDesktopWindow(), hMenu
,
3263 GetModuleHandleA(0), NULL
);
3265 ok_sequence(WmCreateMDIframeSeq
, "Create MDI frame window", FALSE
);
3267 ok(GetActiveWindow() == mdi_frame
, "wrong active window %p\n", GetActiveWindow());
3268 ok(GetFocus() == mdi_frame
, "wrong focus window %p\n", GetFocus());
3270 trace("creating MDI client window\n");
3271 client_cs
.hWindowMenu
= 0;
3272 client_cs
.idFirstChild
= MDI_FIRST_CHILD_ID
;
3273 mdi_client
= CreateWindowExA(0, "MDI_client_class",
3275 WS_CHILD
| WS_VISIBLE
| MDIS_ALLCHILDSTYLES
,
3277 mdi_frame
, 0, GetModuleHandleA(0), &client_cs
);
3279 ok_sequence(WmCreateMDIclientSeq
, "Create visible MDI client window", FALSE
);
3281 ok(GetActiveWindow() == mdi_frame
, "wrong active window %p\n", GetActiveWindow());
3282 ok(GetFocus() == mdi_frame
, "input focus should be on MDI frame not on %p\n", GetFocus());
3284 active_child
= (HWND
)SendMessageA(mdi_client
, WM_MDIGETACTIVE
, 0, (LPARAM
)&zoomed
);
3285 ok(!active_child
, "wrong active MDI child %p\n", active_child
);
3286 ok(!zoomed
, "wrong zoomed state %d\n", zoomed
);
3291 trace("creating invisible MDI child window\n");
3292 mdi_child
= CreateWindowExA(WS_EX_MDICHILD
, "MDI_child_class", "MDI child",
3294 0, 0, CW_USEDEFAULT
, CW_USEDEFAULT
,
3295 mdi_client
, 0, GetModuleHandleA(0), NULL
);
3299 ShowWindow(mdi_child
, SW_SHOWNORMAL
);
3300 ok_sequence(WmShowChildSeq
, "ShowWindow(SW_SHOWNORMAL) MDI child window", FALSE
);
3302 ok(GetWindowLongA(mdi_child
, GWL_STYLE
) & WS_VISIBLE
, "MDI child should be visible\n");
3303 ok(IsWindowVisible(mdi_child
), "MDI child should be visible\n");
3305 ok(GetActiveWindow() == mdi_frame
, "wrong active window %p\n", GetActiveWindow());
3306 ok(GetFocus() == 0, "wrong focus window %p\n", GetFocus());
3308 active_child
= (HWND
)SendMessageA(mdi_client
, WM_MDIGETACTIVE
, 0, (LPARAM
)&zoomed
);
3309 ok(!active_child
, "wrong active MDI child %p\n", active_child
);
3310 ok(!zoomed
, "wrong zoomed state %d\n", zoomed
);
3312 ShowWindow(mdi_child
, SW_HIDE
);
3313 ok_sequence(WmHideChildSeq
, "ShowWindow(SW_HIDE) MDI child window", FALSE
);
3316 ShowWindow(mdi_child
, SW_SHOW
);
3317 ok_sequence(WmShowChildSeq
, "ShowWindow(SW_SHOW) MDI child window", FALSE
);
3319 ok(GetWindowLongA(mdi_child
, GWL_STYLE
) & WS_VISIBLE
, "MDI child should be visible\n");
3320 ok(IsWindowVisible(mdi_child
), "MDI child should be visible\n");
3322 ok(GetActiveWindow() == mdi_frame
, "wrong active window %p\n", GetActiveWindow());
3323 ok(GetFocus() == 0, "wrong focus window %p\n", GetFocus());
3325 active_child
= (HWND
)SendMessageA(mdi_client
, WM_MDIGETACTIVE
, 0, (LPARAM
)&zoomed
);
3326 ok(!active_child
, "wrong active MDI child %p\n", active_child
);
3327 ok(!zoomed
, "wrong zoomed state %d\n", zoomed
);
3329 DestroyWindow(mdi_child
);
3332 trace("creating visible MDI child window\n");
3333 mdi_child
= CreateWindowExA(WS_EX_MDICHILD
, "MDI_child_class", "MDI child",
3334 WS_CHILD
| WS_VISIBLE
,
3335 0, 0, CW_USEDEFAULT
, CW_USEDEFAULT
,
3336 mdi_client
, 0, GetModuleHandleA(0), NULL
);
3338 ok_sequence(WmCreateMDIchildVisibleSeq
, "Create visible MDI child window", FALSE
);
3340 ok(GetWindowLongA(mdi_child
, GWL_STYLE
) & WS_VISIBLE
, "MDI child should be visible\n");
3341 ok(IsWindowVisible(mdi_child
), "MDI child should be visible\n");
3343 ok(GetActiveWindow() == mdi_frame
, "wrong active window %p\n", GetActiveWindow());
3344 ok(GetFocus() == mdi_child
, "wrong focus window %p\n", GetFocus());
3346 active_child
= (HWND
)SendMessageA(mdi_client
, WM_MDIGETACTIVE
, 0, (LPARAM
)&zoomed
);
3347 ok(active_child
== mdi_child
, "wrong active MDI child %p\n", active_child
);
3348 ok(!zoomed
, "wrong zoomed state %d\n", zoomed
);
3351 DestroyWindow(mdi_child
);
3352 ok_sequence(WmDestroyMDIchildVisibleSeq
, "Destroy visible MDI child window", TRUE
);
3354 ok(GetActiveWindow() == mdi_frame
, "wrong active window %p\n", GetActiveWindow());
3355 ok(GetFocus() == 0, "wrong focus window %p\n", GetFocus());
3357 /* Win2k: MDI client still returns a just destroyed child as active
3358 * Win9x: MDI client returns 0
3360 active_child
= (HWND
)SendMessageA(mdi_client
, WM_MDIGETACTIVE
, 0, (LPARAM
)&zoomed
);
3361 ok(active_child
== mdi_child
|| /* win2k */
3362 !active_child
, /* win9x */
3363 "wrong active MDI child %p\n", active_child
);
3364 ok(!zoomed
, "wrong zoomed state %d\n", zoomed
);
3368 trace("creating invisible MDI child window\n");
3369 mdi_child2
= CreateWindowExA(WS_EX_MDICHILD
, "MDI_child_class", "MDI child",
3371 0, 0, CW_USEDEFAULT
, CW_USEDEFAULT
,
3372 mdi_client
, 0, GetModuleHandleA(0), NULL
);
3374 ok_sequence(WmCreateMDIchildInvisibleSeq
, "Create invisible MDI child window", FALSE
);
3376 ok(!(GetWindowLongA(mdi_child2
, GWL_STYLE
) & WS_VISIBLE
), "MDI child should not be visible\n");
3377 ok(!IsWindowVisible(mdi_child2
), "MDI child should not be visible\n");
3379 ok(GetActiveWindow() == mdi_frame
, "wrong active window %p\n", GetActiveWindow());
3380 ok(GetFocus() == 0, "wrong focus window %p\n", GetFocus());
3382 /* Win2k: MDI client still returns a just destroyed child as active
3383 * Win9x: MDI client returns mdi_child2
3385 active_child
= (HWND
)SendMessageA(mdi_client
, WM_MDIGETACTIVE
, 0, (LPARAM
)&zoomed
);
3386 ok(active_child
== mdi_child
|| /* win2k */
3387 active_child
== mdi_child2
, /* win9x */
3388 "wrong active MDI child %p\n", active_child
);
3389 ok(!zoomed
, "wrong zoomed state %d\n", zoomed
);
3392 ShowWindow(mdi_child2
, SW_MAXIMIZE
);
3393 ok_sequence(WmMaximizeMDIchildInvisibleSeq
, "ShowWindow(SW_MAXIMIZE):invisible MDI child", FALSE
);
3395 ok(GetWindowLongA(mdi_child2
, GWL_STYLE
) & WS_VISIBLE
, "MDI child should be visible\n");
3396 ok(IsWindowVisible(mdi_child2
), "MDI child should be visible\n");
3398 active_child
= (HWND
)SendMessageA(mdi_client
, WM_MDIGETACTIVE
, 0, (LPARAM
)&zoomed
);
3399 ok(active_child
== mdi_child2
, "wrong active MDI child %p\n", active_child
);
3400 ok(zoomed
, "wrong zoomed state %d\n", zoomed
);
3403 ok(GetActiveWindow() == mdi_frame
, "wrong active window %p\n", GetActiveWindow());
3404 ok(GetFocus() == mdi_child2
|| /* win2k */
3405 GetFocus() == 0, /* win9x */
3406 "wrong focus window %p\n", GetFocus());
3411 ShowWindow(mdi_child2
, SW_HIDE
);
3412 ok_sequence(WmHideChildSeq
, "ShowWindow(SW_HIDE):MDI child", FALSE
);
3414 ShowWindow(mdi_child2
, SW_RESTORE
);
3415 ok_sequence(WmRestoreMDIchildInisibleSeq
, "ShowWindow(SW_RESTORE):invisible MDI child", FALSE
);
3418 ok(GetWindowLongA(mdi_child2
, GWL_STYLE
) & WS_VISIBLE
, "MDI child should be visible\n");
3419 ok(IsWindowVisible(mdi_child2
), "MDI child should be visible\n");
3421 active_child
= (HWND
)SendMessageA(mdi_client
, WM_MDIGETACTIVE
, 0, (LPARAM
)&zoomed
);
3422 ok(active_child
== mdi_child2
, "wrong active MDI child %p\n", active_child
);
3423 ok(!zoomed
, "wrong zoomed state %d\n", zoomed
);
3429 ShowWindow(mdi_child2
, SW_HIDE
);
3430 ok_sequence(WmHideChildSeq
, "ShowWindow(SW_HIDE):MDI child", FALSE
);
3432 ShowWindow(mdi_child2
, SW_SHOW
);
3433 ok_sequence(WmShowChildSeq
, "ShowWindow(SW_SHOW):MDI child", FALSE
);
3435 ok(GetActiveWindow() == mdi_frame
, "wrong active window %p\n", GetActiveWindow());
3436 ok(GetFocus() == 0, "wrong focus window %p\n", GetFocus());
3438 ShowWindow(mdi_child2
, SW_MAXIMIZE
);
3439 ok_sequence(WmMaximizeMDIchildVisibleSeq
, "ShowWindow(SW_MAXIMIZE):MDI child", FALSE
);
3441 ok(GetActiveWindow() == mdi_frame
, "wrong active window %p\n", GetActiveWindow());
3442 ok(GetFocus() == 0, "wrong focus window %p\n", GetFocus());
3444 ShowWindow(mdi_child2
, SW_RESTORE
);
3445 ok_sequence(WmRestoreMDIchildVisibleSeq
, "ShowWindow(SW_RESTORE):maximized MDI child", FALSE
);
3447 ok(GetActiveWindow() == mdi_frame
, "wrong active window %p\n", GetActiveWindow());
3448 ok(GetFocus() == 0, "wrong focus window %p\n", GetFocus());
3450 ShowWindow(mdi_child2
, SW_MINIMIZE
);
3451 ok_sequence(WmMinimizeMDIchildVisibleSeq
, "ShowWindow(SW_MINIMIZE):MDI child", TRUE
);
3453 ok(GetActiveWindow() == mdi_frame
, "wrong active window %p\n", GetActiveWindow());
3454 ok(GetFocus() == 0, "wrong focus window %p\n", GetFocus());
3456 active_child
= (HWND
)SendMessageA(mdi_client
, WM_MDIGETACTIVE
, 0, (LPARAM
)&zoomed
);
3457 ok(active_child
== mdi_child2
, "wrong active MDI child %p\n", active_child
);
3458 ok(!zoomed
, "wrong zoomed state %d\n", zoomed
);
3461 ShowWindow(mdi_child2
, SW_RESTORE
);
3462 ok_sequence(WmRestoreMDIchildVisibleSeq_2
, "ShowWindow(SW_RESTORE):minimized MDI child", TRUE
);
3464 ok(GetActiveWindow() == mdi_frame
, "wrong active window %p\n", GetActiveWindow());
3465 ok(GetFocus() == mdi_child2
, "wrong focus window %p\n", GetFocus());
3467 active_child
= (HWND
)SendMessageA(mdi_client
, WM_MDIGETACTIVE
, 0, (LPARAM
)&zoomed
);
3468 ok(active_child
== mdi_child2
, "wrong active MDI child %p\n", active_child
);
3469 ok(!zoomed
, "wrong zoomed state %d\n", zoomed
);
3475 ShowWindow(mdi_child2
, SW_HIDE
);
3476 ok_sequence(WmHideChildSeq
, "ShowWindow(SW_HIDE):MDI child", FALSE
);
3478 ok(GetActiveWindow() == mdi_frame
, "wrong active window %p\n", GetActiveWindow());
3479 ok(GetFocus() == 0, "wrong focus window %p\n", GetFocus());
3481 DestroyWindow(mdi_child2
);
3482 ok_sequence(WmDestroyMDIchildInvisibleSeq
, "Destroy invisible MDI child window", FALSE
);
3484 ok(GetActiveWindow() == mdi_frame
, "wrong active window %p\n", GetActiveWindow());
3485 ok(GetFocus() == 0, "wrong focus window %p\n", GetFocus());
3487 /* test for maximized MDI children */
3488 trace("creating maximized visible MDI child window 1\n");
3489 mdi_child
= CreateWindowExA(WS_EX_MDICHILD
, "MDI_child_class", "MDI child",
3490 WS_CHILD
| WS_VISIBLE
| WS_MAXIMIZEBOX
| WS_MAXIMIZE
,
3491 0, 0, CW_USEDEFAULT
, CW_USEDEFAULT
,
3492 mdi_client
, 0, GetModuleHandleA(0), NULL
);
3494 ok_sequence(WmCreateMDIchildVisibleMaxSeq1
, "Create maximized visible 1st MDI child window", TRUE
);
3495 ok(IsZoomed(mdi_child
), "1st MDI child should be maximized\n");
3497 ok(GetActiveWindow() == mdi_frame
, "wrong active window %p\n", GetActiveWindow());
3498 ok(GetFocus() == mdi_child
|| /* win2k */
3499 GetFocus() == 0, /* win9x */
3500 "wrong focus window %p\n", GetFocus());
3502 active_child
= (HWND
)SendMessageA(mdi_client
, WM_MDIGETACTIVE
, 0, (LPARAM
)&zoomed
);
3503 ok(active_child
== mdi_child
, "wrong active MDI child %p\n", active_child
);
3504 ok(zoomed
, "wrong zoomed state %d\n", zoomed
);
3507 trace("creating maximized visible MDI child window 2\n");
3508 mdi_child2
= CreateWindowExA(WS_EX_MDICHILD
, "MDI_child_class", "MDI child",
3509 WS_CHILD
| WS_VISIBLE
| WS_MAXIMIZEBOX
| WS_MAXIMIZE
,
3510 0, 0, CW_USEDEFAULT
, CW_USEDEFAULT
,
3511 mdi_client
, 0, GetModuleHandleA(0), NULL
);
3513 ok_sequence(WmCreateMDIchildVisibleMaxSeq2
, "Create maximized visible 2nd MDI child 2 window", TRUE
);
3514 ok(IsZoomed(mdi_child2
), "2nd MDI child should be maximized\n");
3515 ok(!IsZoomed(mdi_child
), "1st MDI child should NOT be maximized\n");
3517 ok(GetActiveWindow() == mdi_frame
, "wrong active window %p\n", GetActiveWindow());
3518 ok(GetFocus() == mdi_child2
, "wrong focus window %p\n", GetFocus());
3520 active_child
= (HWND
)SendMessageA(mdi_client
, WM_MDIGETACTIVE
, 0, (LPARAM
)&zoomed
);
3521 ok(active_child
== mdi_child2
, "wrong active MDI child %p\n", active_child
);
3522 ok(zoomed
, "wrong zoomed state %d\n", zoomed
);
3525 trace("destroying maximized visible MDI child window 2\n");
3526 DestroyWindow(mdi_child2
);
3527 ok_sequence(WmDestroyMDIchildVisibleSeq
, "Destroy visible MDI child window", TRUE
);
3529 ok(!IsZoomed(mdi_child
), "1st MDI child should NOT be maximized\n");
3531 ok(GetActiveWindow() == mdi_frame
, "wrong active window %p\n", GetActiveWindow());
3532 ok(GetFocus() == 0, "wrong focus window %p\n", GetFocus());
3534 /* Win2k: MDI client still returns a just destroyed child as active
3535 * Win9x: MDI client returns 0
3537 active_child
= (HWND
)SendMessageA(mdi_client
, WM_MDIGETACTIVE
, 0, (LPARAM
)&zoomed
);
3538 ok(active_child
== mdi_child2
|| /* win2k */
3539 !active_child
, /* win9x */
3540 "wrong active MDI child %p\n", active_child
);
3543 ShowWindow(mdi_child
, SW_MAXIMIZE
);
3544 ok(IsZoomed(mdi_child
), "1st MDI child should be maximized\n");
3547 ok(GetActiveWindow() == mdi_frame
, "wrong active window %p\n", GetActiveWindow());
3548 ok(GetFocus() == mdi_child
, "wrong focus window %p\n", GetFocus());
3550 trace("re-creating maximized visible MDI child window 2\n");
3551 mdi_child2
= CreateWindowExA(WS_EX_MDICHILD
, "MDI_child_class", "MDI child",
3552 WS_CHILD
| WS_VISIBLE
| WS_MAXIMIZEBOX
| WS_MAXIMIZE
,
3553 0, 0, CW_USEDEFAULT
, CW_USEDEFAULT
,
3554 mdi_client
, 0, GetModuleHandleA(0), NULL
);
3556 ok_sequence(WmCreateMDIchildVisibleMaxSeq2
, "Create maximized visible 2nd MDI child 2 window", TRUE
);
3557 ok(IsZoomed(mdi_child2
), "2nd MDI child should be maximized\n");
3558 ok(!IsZoomed(mdi_child
), "1st MDI child should NOT be maximized\n");
3560 ok(GetActiveWindow() == mdi_frame
, "wrong active window %p\n", GetActiveWindow());
3561 ok(GetFocus() == mdi_child2
, "wrong focus window %p\n", GetFocus());
3563 active_child
= (HWND
)SendMessageA(mdi_client
, WM_MDIGETACTIVE
, 0, (LPARAM
)&zoomed
);
3564 ok(active_child
== mdi_child2
, "wrong active MDI child %p\n", active_child
);
3565 ok(zoomed
, "wrong zoomed state %d\n", zoomed
);
3568 SendMessageA(mdi_child2
, WM_SYSCOMMAND
, SC_CLOSE
, 0);
3569 ok_sequence(WmDestroyMDIchildVisibleMaxSeq2
, "WM_SYSCOMMAND/SC_CLOSE on a visible maximized MDI child window", TRUE
);
3570 ok(!IsWindow(mdi_child2
), "MDI child 2 should be destroyed\n");
3572 ok(IsZoomed(mdi_child
), "1st MDI child should be maximized\n");
3573 ok(GetActiveWindow() == mdi_frame
, "wrong active window %p\n", GetActiveWindow());
3574 ok(GetFocus() == mdi_child
, "wrong focus window %p\n", GetFocus());
3576 active_child
= (HWND
)SendMessageA(mdi_client
, WM_MDIGETACTIVE
, 0, (LPARAM
)&zoomed
);
3577 ok(active_child
== mdi_child
, "wrong active MDI child %p\n", active_child
);
3578 ok(zoomed
, "wrong zoomed state %d\n", zoomed
);
3581 DestroyWindow(mdi_child
);
3582 ok_sequence(WmDestroyMDIchildVisibleSeq
, "Destroy visible MDI child window", TRUE
);
3584 ok(GetActiveWindow() == mdi_frame
, "wrong active window %p\n", GetActiveWindow());
3585 ok(GetFocus() == 0, "wrong focus window %p\n", GetFocus());
3587 /* Win2k: MDI client still returns a just destroyed child as active
3588 * Win9x: MDI client returns 0
3590 active_child
= (HWND
)SendMessageA(mdi_client
, WM_MDIGETACTIVE
, 0, (LPARAM
)&zoomed
);
3591 ok(active_child
== mdi_child
|| /* win2k */
3592 !active_child
, /* win9x */
3593 "wrong active MDI child %p\n", active_child
);
3596 trace("creating maximized invisible MDI child window\n");
3597 mdi_child2
= CreateWindowExA(WS_EX_MDICHILD
, "MDI_child_class", "MDI child",
3598 WS_CHILD
| WS_MAXIMIZE
| WS_CAPTION
| WS_THICKFRAME
,
3599 0, 0, CW_USEDEFAULT
, CW_USEDEFAULT
,
3600 mdi_client
, 0, GetModuleHandleA(0), NULL
);
3602 ok_sequence(WmCreateMDIchildInvisibleMaxSeq4
, "Create maximized invisible MDI child window", FALSE
);
3603 ok(IsZoomed(mdi_child2
), "MDI child should be maximized\n");
3604 ok(!(GetWindowLongA(mdi_child2
, GWL_STYLE
) & WS_VISIBLE
), "MDI child should be not visible\n");
3605 ok(!IsWindowVisible(mdi_child2
), "MDI child should be not visible\n");
3607 /* Win2k: MDI client still returns a just destroyed child as active
3608 * Win9x: MDI client returns 0
3610 active_child
= (HWND
)SendMessageA(mdi_client
, WM_MDIGETACTIVE
, 0, (LPARAM
)&zoomed
);
3611 ok(active_child
== mdi_child
|| /* win2k */
3612 !active_child
, /* win9x */
3613 "wrong active MDI child %p\n", active_child
);
3616 trace("call ShowWindow(mdi_child, SW_MAXIMIZE)\n");
3617 ShowWindow(mdi_child2
, SW_MAXIMIZE
);
3618 ok_sequence(WmMaximizeMDIchildInvisibleSeq2
, "ShowWindow(SW_MAXIMIZE):invisible maximized MDI child", FALSE
);
3619 ok(IsZoomed(mdi_child2
), "MDI child should be maximized\n");
3620 ok(GetWindowLongA(mdi_child2
, GWL_STYLE
) & WS_VISIBLE
, "MDI child should be visible\n");
3621 ok(IsWindowVisible(mdi_child2
), "MDI child should be visible\n");
3623 active_child
= (HWND
)SendMessageA(mdi_client
, WM_MDIGETACTIVE
, 0, (LPARAM
)&zoomed
);
3624 ok(active_child
== mdi_child2
, "wrong active MDI child %p\n", active_child
);
3625 ok(zoomed
, "wrong zoomed state %d\n", zoomed
);
3628 SendMessageA(mdi_client
, WM_MDIDESTROY
, (WPARAM
)mdi_child2
, 0);
3631 /* end of test for maximized MDI children */
3634 trace("creating maximized visible MDI child window 1(Switch test)\n");
3635 mdi_child
= CreateWindowExA(WS_EX_MDICHILD
, "MDI_child_class", "MDI child",
3636 WS_CHILD
| WS_VISIBLE
| WS_MAXIMIZEBOX
| WS_MAXIMIZE
,
3637 0, 0, CW_USEDEFAULT
, CW_USEDEFAULT
,
3638 mdi_client
, 0, GetModuleHandleA(0), NULL
);
3640 ok_sequence(WmCreateMDIchildVisibleMaxSeq1
, "Create maximized visible 1st MDI child window(Switch test)", TRUE
);
3641 ok(IsZoomed(mdi_child
), "1st MDI child should be maximized(Switch test)\n");
3643 ok(GetActiveWindow() == mdi_frame
, "wrong active window %p(Switch test)\n", GetActiveWindow());
3644 ok(GetFocus() == mdi_child
|| /* win2k */
3645 GetFocus() == 0, /* win9x */
3646 "wrong focus window %p(Switch test)\n", GetFocus());
3648 active_child
= (HWND
)SendMessageA(mdi_client
, WM_MDIGETACTIVE
, 0, (LPARAM
)&zoomed
);
3649 ok(active_child
== mdi_child
, "wrong active MDI child %p(Switch test)\n", active_child
);
3650 ok(zoomed
, "wrong zoomed state %d(Switch test)\n", zoomed
);
3653 trace("creating maximized visible MDI child window 2(Switch test)\n");
3654 mdi_child2
= CreateWindowExA(WS_EX_MDICHILD
, "MDI_child_class", "MDI child",
3655 WS_CHILD
| WS_VISIBLE
| WS_MAXIMIZEBOX
| WS_MAXIMIZE
,
3656 0, 0, CW_USEDEFAULT
, CW_USEDEFAULT
,
3657 mdi_client
, 0, GetModuleHandleA(0), NULL
);
3659 ok_sequence(WmCreateMDIchildVisibleMaxSeq2
, "Create maximized visible 2nd MDI child window (Switch test)", TRUE
);
3661 ok(IsZoomed(mdi_child2
), "2nd MDI child should be maximized(Switch test)\n");
3662 ok(!IsZoomed(mdi_child
), "1st MDI child should NOT be maximized(Switch test)\n");
3664 ok(GetActiveWindow() == mdi_frame
, "wrong active window %p(Switch test)\n", GetActiveWindow());
3665 ok(GetFocus() == mdi_child2
, "wrong focus window %p(Switch test)\n", GetFocus());
3667 active_child
= (HWND
)SendMessageA(mdi_client
, WM_MDIGETACTIVE
, 0, (LPARAM
)&zoomed
);
3668 ok(active_child
== mdi_child2
, "wrong active MDI child %p(Switch test)\n", active_child
);
3669 ok(zoomed
, "wrong zoomed state %d(Switch test)\n", zoomed
);
3672 trace("Switch child window.\n");
3673 SendMessageA(mdi_client
, WM_MDIACTIVATE
, (WPARAM
)mdi_child
, 0);
3674 ok_sequence(WmSwitchChild
, "Child did not switch correctly", TRUE
);
3675 trace("end of test for switch maximized MDI children\n");
3678 /* Prepare for switching test of not maximized MDI children */
3679 ShowWindow( mdi_child
, SW_NORMAL
);
3680 ok(!IsZoomed(mdi_child
), "wrong zoomed state for %p(Switch test)\n", mdi_child
);
3681 ok(!IsZoomed(mdi_child2
), "wrong zoomed state for %p(Switch test)\n", mdi_child2
);
3682 active_child
= (HWND
)SendMessageA(mdi_client
, WM_MDIGETACTIVE
, 0, 0);
3683 ok(active_child
== mdi_child
, "wrong active MDI child %p(Switch test)\n", active_child
);
3686 SendMessageA(mdi_client
, WM_MDIACTIVATE
, (WPARAM
)mdi_child2
, 0);
3687 ok_sequence(WmSwitchNotMaximizedChild
, "Not maximized child did not switch correctly", FALSE
);
3688 trace("end of test for switch not maximized MDI children\n");
3691 SendMessageA(mdi_client
, WM_MDIDESTROY
, (WPARAM
)mdi_child
, 0);
3694 SendMessageA(mdi_client
, WM_MDIDESTROY
, (WPARAM
)mdi_child2
, 0);
3699 /* end of tests for switch maximized/not maximized MDI children */
3701 mdi_cs
.szClass
= "MDI_child_Class";
3702 mdi_cs
.szTitle
= "MDI child";
3703 mdi_cs
.hOwner
= GetModuleHandleA(0);
3706 mdi_cs
.cx
= CW_USEDEFAULT
;
3707 mdi_cs
.cy
= CW_USEDEFAULT
;
3708 mdi_cs
.style
= WS_CHILD
| WS_SYSMENU
| WS_VISIBLE
| WS_MAXIMIZEBOX
| WS_MAXIMIZE
;
3710 mdi_child
= (HWND
)SendMessageA(mdi_client
, WM_MDICREATE
, 0, (LPARAM
)&mdi_cs
);
3711 ok(mdi_child
!= 0, "MDI child creation failed\n");
3712 ok_sequence(WmCreateMDIchildVisibleMaxSeq3
, "WM_MDICREATE for maximized visible MDI child window", TRUE
);
3714 ok(GetMenuItemID(hMenu
, GetMenuItemCount(hMenu
) - 1) == SC_CLOSE
, "SC_CLOSE menu item not found\n");
3716 active_child
= (HWND
)SendMessageA(mdi_client
, WM_MDIGETACTIVE
, 0, (LPARAM
)&zoomed
);
3717 ok(active_child
== mdi_child
, "wrong active MDI child %p\n", active_child
);
3719 ok(IsZoomed(mdi_child
), "MDI child should be maximized\n");
3720 ok(GetActiveWindow() == mdi_frame
, "wrong active window %p\n", GetActiveWindow());
3721 ok(GetFocus() == mdi_child
, "wrong focus window %p\n", GetFocus());
3723 active_child
= (HWND
)SendMessageA(mdi_client
, WM_MDIGETACTIVE
, 0, (LPARAM
)&zoomed
);
3724 ok(active_child
== mdi_child
, "wrong active MDI child %p\n", active_child
);
3725 ok(zoomed
, "wrong zoomed state %d\n", zoomed
);
3728 SendMessageA(mdi_client
, WM_MDIDESTROY
, (WPARAM
)mdi_child
, 0);
3729 ok_sequence(WmDestroyMDIchildVisibleMaxSeq1
, "Destroy visible maximized MDI child window", TRUE
);
3731 ok(!IsWindow(mdi_child
), "MDI child should be destroyed\n");
3732 active_child
= (HWND
)SendMessageA(mdi_client
, WM_MDIGETACTIVE
, 0, (LPARAM
)&zoomed
);
3733 ok(!active_child
, "wrong active MDI child %p\n", active_child
);
3738 DestroyWindow(mdi_client
);
3739 ok_sequence(WmDestroyMDIclientSeq
, "Destroy MDI client window", FALSE
);
3741 /* test maximization of MDI child with invisible parent */
3742 client_cs
.hWindowMenu
= 0;
3743 mdi_client
= CreateWindow("MDI_client_class",
3745 WS_CHILD
| WS_CLIPCHILDREN
| WS_VSCROLL
| WS_HSCROLL
| WS_VISIBLE
,
3747 mdi_frame
, 0, GetModuleHandleA(0), &client_cs
);
3748 ok_sequence(WmCreateMDIclientSeq
, "Create MDI client window", FALSE
);
3750 ShowWindow(mdi_client
, SW_HIDE
);
3751 ok_sequence(WmHideMDIclientSeq
, "Hide MDI client window", FALSE
);
3753 mdi_child
= CreateWindowExA(WS_EX_MDICHILD
, "MDI_child_class", "MDI child",
3754 WS_CHILD
| WS_CLIPCHILDREN
| WS_VSCROLL
| WS_HSCROLL
,
3756 mdi_client
, 0, GetModuleHandleA(0), NULL
);
3757 ok_sequence(WmCreateMDIchildInvisibleParentSeq
, "Create MDI child window with invisible parent", FALSE
);
3759 SendMessage(mdi_client
, WM_MDIMAXIMIZE
, (WPARAM
) mdi_child
, 0);
3760 ok_sequence(WmMaximizeMDIchildInvisibleParentSeq
, "Maximize MDI child window with invisible parent", TRUE
);
3761 zoomed
= IsZoomed(mdi_child
);
3762 ok(zoomed
, "wrong zoomed state %d\n", zoomed
);
3764 ShowWindow(mdi_client
, SW_SHOW
);
3765 ok_sequence(WmShowMDIclientSeq
, "Show MDI client window", FALSE
);
3767 DestroyWindow(mdi_child
);
3768 ok_sequence(WmDestroyMDIchildVisibleSeq
, "Destroy visible maximized MDI child window", TRUE
);
3770 /* end of test for maximization of MDI child with invisible parent */
3772 DestroyWindow(mdi_client
);
3773 ok_sequence(WmDestroyMDIclientSeq
, "Destroy MDI client window", FALSE
);
3775 DestroyWindow(mdi_frame
);
3776 ok_sequence(WmDestroyMDIframeSeq
, "Destroy MDI frame window", FALSE
);
3778 /************************* End of MDI test **********************************/
3780 static void test_WM_SETREDRAW(HWND hwnd
)
3782 DWORD style
= GetWindowLongA(hwnd
, GWL_STYLE
);
3787 SendMessageA(hwnd
, WM_SETREDRAW
, FALSE
, 0);
3788 ok_sequence(WmSetRedrawFalseSeq
, "SetRedraw:FALSE", FALSE
);
3790 ok(!(GetWindowLongA(hwnd
, GWL_STYLE
) & WS_VISIBLE
), "WS_VISIBLE should NOT be set\n");
3791 ok(!IsWindowVisible(hwnd
), "IsWindowVisible() should return FALSE\n");
3794 SendMessageA(hwnd
, WM_SETREDRAW
, TRUE
, 0);
3795 ok_sequence(WmSetRedrawTrueSeq
, "SetRedraw:TRUE", FALSE
);
3797 ok(GetWindowLongA(hwnd
, GWL_STYLE
) & WS_VISIBLE
, "WS_VISIBLE should be set\n");
3798 ok(IsWindowVisible(hwnd
), "IsWindowVisible() should return TRUE\n");
3800 /* restore original WS_VISIBLE state */
3801 SetWindowLongA(hwnd
, GWL_STYLE
, style
);
3807 static INT_PTR CALLBACK
TestModalDlgProcA(HWND hwnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
3809 struct recvd_message msg
;
3817 case WM_DEVICECHANGE
:
3824 msg
.message
= message
;
3825 msg
.flags
= sent
|wparam
|lparam
;
3826 msg
.wParam
= wParam
;
3827 msg
.lParam
= lParam
;
3828 msg
.descr
= "dialog";
3831 if (message
== WM_INITDIALOG
) SetTimer( hwnd
, 1, 100, NULL
);
3832 if (message
== WM_TIMER
) EndDialog( hwnd
, 0 );
3836 static void test_hv_scroll_1(HWND hwnd
, INT ctl
, DWORD clear
, DWORD set
, INT min
, INT max
)
3838 DWORD style
, exstyle
;
3842 exstyle
= GetWindowLongA(hwnd
, GWL_EXSTYLE
);
3843 style
= GetWindowLongA(hwnd
, GWL_STYLE
);
3844 /* do not be confused by WS_DLGFRAME set */
3845 if ((style
& WS_CAPTION
) == WS_CAPTION
) style
&= ~WS_CAPTION
;
3847 if (clear
) ok(style
& clear
, "style %08x should be set\n", clear
);
3848 if (set
) ok(!(style
& set
), "style %08x should not be set\n", set
);
3850 ret
= SetScrollRange(hwnd
, ctl
, min
, max
, FALSE
);
3851 ok( ret
, "SetScrollRange(%d) error %d\n", ctl
, GetLastError());
3852 if ((style
& (WS_DLGFRAME
| WS_BORDER
| WS_THICKFRAME
)) || (exstyle
& WS_EX_DLGMODALFRAME
))
3853 ok_sequence(WmSetScrollRangeHV_NC_Seq
, "SetScrollRange(SB_HORZ/SB_VERT) NC", FALSE
);
3855 ok_sequence(WmSetScrollRangeHVSeq
, "SetScrollRange(SB_HORZ/SB_VERT)", FALSE
);
3857 style
= GetWindowLongA(hwnd
, GWL_STYLE
);
3858 if (set
) ok(style
& set
, "style %08x should be set\n", set
);
3859 if (clear
) ok(!(style
& clear
), "style %08x should not be set\n", clear
);
3861 /* a subsequent call should do nothing */
3862 ret
= SetScrollRange(hwnd
, ctl
, min
, max
, FALSE
);
3863 ok( ret
, "SetScrollRange(%d) error %d\n", ctl
, GetLastError());
3864 ok_sequence(WmEmptySeq
, "SetScrollRange(SB_HORZ/SB_VERT) empty sequence", FALSE
);
3868 trace("Ignore GetScrollRange error below if you are on Win9x\n");
3869 ret
= GetScrollRange(hwnd
, ctl
, &xmin
, &xmax
);
3870 ok( ret
, "GetScrollRange(%d) error %d\n", ctl
, GetLastError());
3871 ok_sequence(WmEmptySeq
, "GetScrollRange(SB_HORZ/SB_VERT) empty sequence", FALSE
);
3872 ok(xmin
== min
, "unexpected min scroll value %d\n", xmin
);
3873 ok(xmax
== max
, "unexpected max scroll value %d\n", xmax
);
3876 static void test_hv_scroll_2(HWND hwnd
, INT ctl
, DWORD clear
, DWORD set
, INT min
, INT max
)
3878 DWORD style
, exstyle
;
3882 exstyle
= GetWindowLongA(hwnd
, GWL_EXSTYLE
);
3883 style
= GetWindowLongA(hwnd
, GWL_STYLE
);
3884 /* do not be confused by WS_DLGFRAME set */
3885 if ((style
& WS_CAPTION
) == WS_CAPTION
) style
&= ~WS_CAPTION
;
3887 if (clear
) ok(style
& clear
, "style %08x should be set\n", clear
);
3888 if (set
) ok(!(style
& set
), "style %08x should not be set\n", set
);
3890 si
.cbSize
= sizeof(si
);
3891 si
.fMask
= SIF_RANGE
;
3894 SetScrollInfo(hwnd
, ctl
, &si
, TRUE
);
3895 if ((style
& (WS_DLGFRAME
| WS_BORDER
| WS_THICKFRAME
)) || (exstyle
& WS_EX_DLGMODALFRAME
))
3896 ok_sequence(WmSetScrollRangeHV_NC_Seq
, "SetScrollInfo(SB_HORZ/SB_VERT) NC", FALSE
);
3898 ok_sequence(WmSetScrollRangeHVSeq
, "SetScrollInfo(SB_HORZ/SB_VERT)", FALSE
);
3900 style
= GetWindowLongA(hwnd
, GWL_STYLE
);
3901 if (set
) ok(style
& set
, "style %08x should be set\n", set
);
3902 if (clear
) ok(!(style
& clear
), "style %08x should not be set\n", clear
);
3904 /* a subsequent call should do nothing */
3905 SetScrollInfo(hwnd
, ctl
, &si
, TRUE
);
3906 if (style
& WS_HSCROLL
)
3907 ok_sequence(WmSetScrollRangeHSeq_empty
, "SetScrollInfo(SB_HORZ/SB_VERT) empty sequence", FALSE
);
3908 else if (style
& WS_VSCROLL
)
3909 ok_sequence(WmSetScrollRangeVSeq_empty
, "SetScrollInfo(SB_HORZ/SB_VERT) empty sequence", FALSE
);
3911 ok_sequence(WmEmptySeq
, "SetScrollInfo(SB_HORZ/SB_VERT) empty sequence", FALSE
);
3913 si
.fMask
= SIF_PAGE
;
3915 SetScrollInfo(hwnd
, ctl
, &si
, FALSE
);
3916 ok_sequence(WmEmptySeq
, "SetScrollInfo(SB_HORZ/SB_VERT) empty sequence", FALSE
);
3920 SetScrollInfo(hwnd
, ctl
, &si
, FALSE
);
3921 ok_sequence(WmEmptySeq
, "SetScrollInfo(SB_HORZ/SB_VERT) empty sequence", FALSE
);
3923 si
.fMask
= SIF_RANGE
;
3924 si
.nMin
= 0xdeadbeef;
3925 si
.nMax
= 0xdeadbeef;
3926 ret
= GetScrollInfo(hwnd
, ctl
, &si
);
3927 ok( ret
, "GetScrollInfo error %d\n", GetLastError());
3928 ok_sequence(WmEmptySeq
, "GetScrollRange(SB_HORZ/SB_VERT) empty sequence", FALSE
);
3929 ok(si
.nMin
== min
, "unexpected min scroll value %d\n", si
.nMin
);
3930 ok(si
.nMax
== max
, "unexpected max scroll value %d\n", si
.nMax
);
3933 /* Win9x sends WM_USER+xxx while and NT versions send SBM_xxx messages */
3934 static void test_scroll_messages(HWND hwnd
)
3945 ret
= GetScrollRange(hwnd
, SB_CTL
, &min
, &max
);
3946 ok( ret
, "GetScrollRange error %d\n", GetLastError());
3947 if (sequence
->message
!= WmGetScrollRangeSeq
[0].message
)
3948 trace("GetScrollRange(SB_CTL) generated unknown message %04x\n", sequence
->message
);
3949 /* values of min and max are undefined */
3952 ret
= SetScrollRange(hwnd
, SB_CTL
, 10, 150, FALSE
);
3953 ok( ret
, "SetScrollRange error %d\n", GetLastError());
3954 if (sequence
->message
!= WmSetScrollRangeSeq
[0].message
)
3955 trace("SetScrollRange(SB_CTL) generated unknown message %04x\n", sequence
->message
);
3960 ret
= GetScrollRange(hwnd
, SB_CTL
, &min
, &max
);
3961 ok( ret
, "GetScrollRange error %d\n", GetLastError());
3962 if (sequence
->message
!= WmGetScrollRangeSeq
[0].message
)
3963 trace("GetScrollRange(SB_CTL) generated unknown message %04x\n", sequence
->message
);
3964 /* values of min and max are undefined */
3967 si
.cbSize
= sizeof(si
);
3968 si
.fMask
= SIF_RANGE
;
3971 SetScrollInfo(hwnd
, SB_CTL
, &si
, FALSE
);
3972 if (sequence
->message
!= WmSetScrollRangeSeq
[0].message
)
3973 trace("SetScrollInfo(SB_CTL) generated unknown message %04x\n", sequence
->message
);
3976 si
.fMask
= SIF_PAGE
;
3978 SetScrollInfo(hwnd
, SB_CTL
, &si
, FALSE
);
3979 if (sequence
->message
!= WmSetScrollRangeSeq
[0].message
)
3980 trace("SetScrollInfo(SB_CTL) generated unknown message %04x\n", sequence
->message
);
3985 SetScrollInfo(hwnd
, SB_CTL
, &si
, FALSE
);
3986 if (sequence
->message
!= WmSetScrollRangeSeq
[0].message
)
3987 trace("SetScrollInfo(SB_CTL) generated unknown message %04x\n", sequence
->message
);
3990 si
.fMask
= SIF_RANGE
;
3991 si
.nMin
= 0xdeadbeef;
3992 si
.nMax
= 0xdeadbeef;
3993 ret
= GetScrollInfo(hwnd
, SB_CTL
, &si
);
3994 ok( ret
, "GetScrollInfo error %d\n", GetLastError());
3995 if (sequence
->message
!= WmGetScrollInfoSeq
[0].message
)
3996 trace("GetScrollInfo(SB_CTL) generated unknown message %04x\n", sequence
->message
);
3997 /* values of min and max are undefined */
4000 /* set WS_HSCROLL */
4001 test_hv_scroll_1(hwnd
, SB_HORZ
, 0, WS_HSCROLL
, 10, 150);
4002 /* clear WS_HSCROLL */
4003 test_hv_scroll_1(hwnd
, SB_HORZ
, WS_HSCROLL
, 0, 0, 0);
4005 /* set WS_HSCROLL */
4006 test_hv_scroll_2(hwnd
, SB_HORZ
, 0, WS_HSCROLL
, 10, 150);
4007 /* clear WS_HSCROLL */
4008 test_hv_scroll_2(hwnd
, SB_HORZ
, WS_HSCROLL
, 0, 0, 0);
4010 /* set WS_VSCROLL */
4011 test_hv_scroll_1(hwnd
, SB_VERT
, 0, WS_VSCROLL
, 10, 150);
4012 /* clear WS_VSCROLL */
4013 test_hv_scroll_1(hwnd
, SB_VERT
, WS_VSCROLL
, 0, 0, 0);
4015 /* set WS_VSCROLL */
4016 test_hv_scroll_2(hwnd
, SB_VERT
, 0, WS_VSCROLL
, 10, 150);
4017 /* clear WS_VSCROLL */
4018 test_hv_scroll_2(hwnd
, SB_VERT
, WS_VSCROLL
, 0, 0, 0);
4021 static void test_showwindow(void)
4026 hwnd
= CreateWindowExA(0, "TestWindowClass", "Test overlapped", WS_OVERLAPPEDWINDOW
,
4027 100, 100, 200, 200, 0, 0, 0, NULL
);
4028 ok (hwnd
!= 0, "Failed to create overlapped window\n");
4029 hchild
= CreateWindowExA(0, "TestWindowClass", "Test child", WS_CHILD
,
4030 0, 0, 10, 10, hwnd
, 0, 0, NULL
);
4031 ok (hchild
!= 0, "Failed to create child\n");
4034 /* ShowWindow( SW_SHOWNA) for invisible top level window */
4035 trace("calling ShowWindow( SW_SHOWNA) for invisible top level window\n");
4036 ok( ShowWindow(hwnd
, SW_SHOWNA
) == FALSE
, "ShowWindow: window was visible\n" );
4037 ok_sequence(WmSHOWNATopInvisible
, "ShowWindow(SW_SHOWNA) on invisible top level window", TRUE
);
4039 /* ShowWindow( SW_SHOWNA) for now visible top level window */
4040 trace("calling ShowWindow( SW_SHOWNA) for now visible top level window\n");
4041 ok( ShowWindow(hwnd
, SW_SHOWNA
) != FALSE
, "ShowWindow: window was invisible\n" );
4042 ok_sequence(WmSHOWNATopVisible
, "ShowWindow(SW_SHOWNA) on visible top level window", FALSE
);
4043 /* back to invisible */
4044 ShowWindow(hchild
, SW_HIDE
);
4045 ShowWindow(hwnd
, SW_HIDE
);
4047 /* ShowWindow(SW_SHOWNA) with child and parent invisible */
4048 trace("calling ShowWindow( SW_SHOWNA) for invisible child with invisible parent\n");
4049 ok( ShowWindow(hchild
, SW_SHOWNA
) == FALSE
, "ShowWindow: window was visible\n" );
4050 ok_sequence(WmSHOWNAChildInvisParInvis
, "ShowWindow(SW_SHOWNA) invisible child and parent", FALSE
);
4051 /* ShowWindow(SW_SHOWNA) with child visible and parent invisible */
4052 ok( ShowWindow(hchild
, SW_SHOW
) != FALSE
, "ShowWindow: window was invisible\n" );
4054 trace("calling ShowWindow( SW_SHOWNA) for the visible child and invisible parent\n");
4055 ok( ShowWindow(hchild
, SW_SHOWNA
) != FALSE
, "ShowWindow: window was invisible\n" );
4056 ok_sequence(WmSHOWNAChildVisParInvis
, "ShowWindow(SW_SHOWNA) visible child and invisible parent", FALSE
);
4057 /* ShowWindow(SW_SHOWNA) with child visible and parent visible */
4058 ShowWindow( hwnd
, SW_SHOW
);
4060 trace("calling ShowWindow( SW_SHOWNA) for the visible child and parent\n");
4061 ok( ShowWindow(hchild
, SW_SHOWNA
) != FALSE
, "ShowWindow: window was invisible\n" );
4062 ok_sequence(WmSHOWNAChildVisParVis
, "ShowWindow(SW_SHOWNA) for the visible child and parent", FALSE
);
4064 /* ShowWindow(SW_SHOWNA) with child invisible and parent visible */
4065 ShowWindow( hchild
, SW_HIDE
);
4067 trace("calling ShowWindow( SW_SHOWNA) for the invisible child and visible parent\n");
4068 ok( ShowWindow(hchild
, SW_SHOWNA
) == FALSE
, "ShowWindow: window was visible\n" );
4069 ok_sequence(WmSHOWNAChildInvisParVis
, "ShowWindow(SW_SHOWNA) for the invisible child and visible parent", FALSE
);
4072 ok(GetCapture() == hchild
, "wrong capture window %p\n", GetCapture());
4073 DestroyWindow(hchild
);
4074 ok(!GetCapture(), "wrong capture window %p\n", GetCapture());
4076 DestroyWindow(hwnd
);
4081 * 1. Create invisible maximized popup window.
4082 * 2. Move and resize it.
4083 * 3. Show it maximized.
4085 trace("calling CreateWindowExA( WS_MAXIMIZE ) for invisible maximized popup window\n");
4086 hwnd
= CreateWindowExA(0, "TestWindowClass", "Test popup", WS_POPUP
| WS_MAXIMIZE
,
4087 100, 100, 200, 200, 0, 0, 0, NULL
);
4088 ok (hwnd
!= 0, "Failed to create popup window\n");
4089 ok(IsZoomed(hwnd
), "window should be maximized\n");
4090 ok_sequence(WmCreateInvisibleMaxPopupSeq
, "CreateWindow(WS_MAXIMIZED):popup", FALSE
);
4092 GetWindowRect(hwnd
, &rc
);
4093 ok( rc
.right
-rc
.left
== GetSystemMetrics(SM_CXSCREEN
) &&
4094 rc
.bottom
-rc
.top
== GetSystemMetrics(SM_CYSCREEN
),
4095 "Invalid maximized size before ShowWindow (%d,%d)-(%d,%d)\n",
4096 rc
.left
, rc
.top
, rc
.right
, rc
.bottom
);
4097 /* Reset window's size & position */
4098 SetWindowPos(hwnd
, 0, 10, 10, 200, 200, SWP_NOZORDER
| SWP_NOACTIVATE
);
4099 ok(IsZoomed(hwnd
), "window should be maximized\n");
4102 trace("calling ShowWindow( SW_SHOWMAXIMIZE ) for invisible maximized popup window\n");
4103 ShowWindow(hwnd
, SW_SHOWMAXIMIZED
);
4104 ok(IsZoomed(hwnd
), "window should be maximized\n");
4105 ok_sequence(WmShowMaxPopupResizedSeq
, "ShowWindow(SW_SHOWMAXIMIZED):invisible maximized and resized popup", FALSE
);
4107 GetWindowRect(hwnd
, &rc
);
4108 ok( rc
.right
-rc
.left
== GetSystemMetrics(SM_CXSCREEN
) &&
4109 rc
.bottom
-rc
.top
== GetSystemMetrics(SM_CYSCREEN
),
4110 "Invalid maximized size after ShowWindow (%d,%d)-(%d,%d)\n",
4111 rc
.left
, rc
.top
, rc
.right
, rc
.bottom
);
4112 DestroyWindow(hwnd
);
4116 * 1. Create invisible maximized popup window.
4117 * 2. Show it maximized.
4119 trace("calling CreateWindowExA( WS_MAXIMIZE ) for invisible maximized popup window\n");
4120 hwnd
= CreateWindowExA(0, "TestWindowClass", "Test popup", WS_POPUP
| WS_MAXIMIZE
,
4121 100, 100, 200, 200, 0, 0, 0, NULL
);
4122 ok (hwnd
!= 0, "Failed to create popup window\n");
4123 ok(IsZoomed(hwnd
), "window should be maximized\n");
4124 ok_sequence(WmCreateInvisibleMaxPopupSeq
, "CreateWindow(WS_MAXIMIZED):popup", FALSE
);
4126 trace("calling ShowWindow( SW_SHOWMAXIMIZE ) for invisible maximized popup window\n");
4127 ShowWindow(hwnd
, SW_SHOWMAXIMIZED
);
4128 ok(IsZoomed(hwnd
), "window should be maximized\n");
4129 ok_sequence(WmShowMaxPopupSeq
, "ShowWindow(SW_SHOWMAXIMIZED):invisible maximized popup", FALSE
);
4130 DestroyWindow(hwnd
);
4134 * 1. Create visible maximized popup window.
4136 trace("calling CreateWindowExA( WS_MAXIMIZE ) for maximized popup window\n");
4137 hwnd
= CreateWindowExA(0, "TestWindowClass", "Test popup", WS_POPUP
| WS_MAXIMIZE
| WS_VISIBLE
,
4138 100, 100, 200, 200, 0, 0, 0, NULL
);
4139 ok (hwnd
!= 0, "Failed to create popup window\n");
4140 ok(IsZoomed(hwnd
), "window should be maximized\n");
4141 ok_sequence(WmCreateMaxPopupSeq
, "CreateWindow(WS_MAXIMIZED):popup", FALSE
);
4142 DestroyWindow(hwnd
);
4146 * 1. Create visible popup window.
4149 trace("calling CreateWindowExA( WS_VISIBLE ) for popup window\n");
4150 hwnd
= CreateWindowExA(0, "TestWindowClass", "Test popup", WS_POPUP
| WS_VISIBLE
,
4151 100, 100, 200, 200, 0, 0, 0, NULL
);
4152 ok (hwnd
!= 0, "Failed to create popup window\n");
4153 ok(!IsZoomed(hwnd
), "window should NOT be maximized\n");
4154 ok_sequence(WmCreatePopupSeq
, "CreateWindow(WS_VISIBLE):popup", FALSE
);
4156 trace("calling ShowWindow( SW_SHOWMAXIMIZE ) for visible popup window\n");
4157 ShowWindow(hwnd
, SW_SHOWMAXIMIZED
);
4158 ok(IsZoomed(hwnd
), "window should be maximized\n");
4159 ok_sequence(WmShowVisMaxPopupSeq
, "ShowWindow(SW_SHOWMAXIMIZED):popup", FALSE
);
4160 DestroyWindow(hwnd
);
4164 static void test_sys_menu(void)
4170 hwnd
= CreateWindowExA(0, "TestWindowClass", NULL
, WS_OVERLAPPEDWINDOW
,
4171 100, 100, 200, 200, 0, 0, 0, NULL
);
4172 ok (hwnd
!= 0, "Failed to create overlapped window\n");
4176 /* test existing window without CS_NOCLOSE style */
4177 hmenu
= GetSystemMenu(hwnd
, FALSE
);
4178 ok(hmenu
!= 0, "GetSystemMenu error %d\n", GetLastError());
4180 state
= GetMenuState(hmenu
, SC_CLOSE
, MF_BYCOMMAND
);
4181 ok(state
!= 0xffffffff, "wrong SC_CLOSE state %x\n", state
);
4182 ok(!(state
& (MF_DISABLED
| MF_GRAYED
)), "wrong SC_CLOSE state %x\n", state
);
4184 EnableMenuItem(hmenu
, SC_CLOSE
, MF_BYCOMMAND
| MF_GRAYED
);
4185 ok_sequence(WmEmptySeq
, "WmEnableMenuItem", FALSE
);
4187 state
= GetMenuState(hmenu
, SC_CLOSE
, MF_BYCOMMAND
);
4188 ok(state
!= 0xffffffff, "wrong SC_CLOSE state %x\n", state
);
4189 ok((state
& (MF_DISABLED
| MF_GRAYED
)) == MF_GRAYED
, "wrong SC_CLOSE state %x\n", state
);
4191 EnableMenuItem(hmenu
, SC_CLOSE
, 0);
4192 ok_sequence(WmEmptySeq
, "WmEnableMenuItem", FALSE
);
4194 state
= GetMenuState(hmenu
, SC_CLOSE
, MF_BYCOMMAND
);
4195 ok(state
!= 0xffffffff, "wrong SC_CLOSE state %x\n", state
);
4196 ok(!(state
& (MF_DISABLED
| MF_GRAYED
)), "wrong SC_CLOSE state %x\n", state
);
4198 /* test whether removing WS_SYSMENU destroys a system menu */
4199 SetWindowLongW(hwnd
, GWL_STYLE
, WS_POPUP
);
4200 SetWindowPos(hwnd
, 0, 0, 0, 0, 0, SWP_NOZORDER
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_FRAMECHANGED
);
4202 hmenu
= GetSystemMenu(hwnd
, FALSE
);
4203 ok(hmenu
!= 0, "GetSystemMenu error %d\n", GetLastError());
4205 DestroyWindow(hwnd
);
4207 /* test new window with CS_NOCLOSE style */
4208 hwnd
= CreateWindowExA(0, "NoCloseWindowClass", NULL
, WS_OVERLAPPEDWINDOW
,
4209 100, 100, 200, 200, 0, 0, 0, NULL
);
4210 ok (hwnd
!= 0, "Failed to create overlapped window\n");
4212 hmenu
= GetSystemMenu(hwnd
, FALSE
);
4213 ok(hmenu
!= 0, "GetSystemMenu error %d\n", GetLastError());
4215 state
= GetMenuState(hmenu
, SC_CLOSE
, MF_BYCOMMAND
);
4216 ok(state
== 0xffffffff, "wrong SC_CLOSE state %x\n", state
);
4218 DestroyWindow(hwnd
);
4220 /* test new window without WS_SYSMENU style */
4221 hwnd
= CreateWindowExA(0, "NoCloseWindowClass", NULL
, WS_OVERLAPPEDWINDOW
& ~WS_SYSMENU
,
4222 100, 100, 200, 200, 0, 0, 0, NULL
);
4223 ok(hwnd
!= 0, "Failed to create overlapped window\n");
4225 hmenu
= GetSystemMenu(hwnd
, FALSE
);
4226 ok(!hmenu
, "GetSystemMenu error %d\n", GetLastError());
4228 DestroyWindow(hwnd
);
4231 /* For shown WS_OVERLAPPEDWINDOW */
4232 static const struct message WmSetIcon_1
[] = {
4233 { WM_SETICON
, sent
},
4234 { 0x00AE, sent
|defwinproc
|optional
}, /* XP */
4235 { WM_GETTEXT
, sent
|defwinproc
|optional
},
4236 { WM_GETTEXT
, sent
|defwinproc
|optional
}, /* XP sends a duplicate */
4240 /* For WS_POPUP and hidden WS_OVERLAPPEDWINDOW */
4241 static const struct message WmSetIcon_2
[] = {
4242 { WM_SETICON
, sent
},
4246 /* Sending undocumented 0x3B message with wparam = 0x8000000b */
4247 static const struct message WmInitEndSession
[] = {
4249 { WM_QUERYENDSESSION
, sent
|defwinproc
|wparam
|lparam
, 0, ENDSESSION_LOGOFF
},
4253 /* Sending undocumented 0x3B message with wparam = 0x0000000b */
4254 static const struct message WmInitEndSession_2
[] = {
4256 { WM_QUERYENDSESSION
, sent
|defwinproc
|wparam
|lparam
, 0, 0 },
4260 /* Sending undocumented 0x3B message with wparam = 0x80000008 */
4261 static const struct message WmInitEndSession_3
[] = {
4263 { WM_ENDSESSION
, sent
|defwinproc
|wparam
|lparam
, 0, ENDSESSION_LOGOFF
},
4267 /* Sending undocumented 0x3B message with wparam = 0x00000008 */
4268 static const struct message WmInitEndSession_4
[] = {
4270 { WM_ENDSESSION
, sent
|defwinproc
|wparam
|lparam
, 0, 0 },
4274 /* Sending undocumented 0x3B message with wparam = 0x80000001 */
4275 static const struct message WmInitEndSession_5
[] = {
4277 { WM_ENDSESSION
, sent
|defwinproc
/*|wparam*/|lparam
, 1, ENDSESSION_LOGOFF
},
4281 static const struct message WmOptionalPaint
[] = {
4282 { WM_PAINT
, sent
|optional
},
4283 { WM_NCPAINT
, sent
|beginpaint
|optional
},
4284 { WM_GETTEXT
, sent
|beginpaint
|defwinproc
|optional
},
4285 { WM_ERASEBKGND
, sent
|beginpaint
|optional
},
4289 static const struct message WmZOrder
[] = {
4290 { WM_WINDOWPOSCHANGING
, sent
|wparam
, 0, 0 },
4291 { WM_GETMINMAXINFO
, sent
|defwinproc
|wparam
, 0, 0 },
4292 { HCBT_ACTIVATE
, hook
},
4293 { WM_QUERYNEWPALETTE
, sent
|wparam
|lparam
|optional
, 0, 0 },
4294 { WM_WINDOWPOSCHANGING
, sent
|wparam
, 3, 0 },
4295 { WM_WINDOWPOSCHANGED
, sent
|wparam
|optional
, SWP_NOREDRAW
|SWP_NOMOVE
|SWP_NOSIZE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
, 0 },
4296 { WM_GETTEXT
, sent
|optional
},
4297 { WM_NCCALCSIZE
, sent
|wparam
|optional
, 1 },
4298 { WM_ACTIVATEAPP
, sent
|wparam
, 1, 0 },
4299 { WM_NCACTIVATE
, sent
|wparam
|lparam
, 1, 0 },
4300 { WM_GETTEXT
, sent
|defwinproc
|optional
},
4301 { WM_GETTEXT
, sent
|defwinproc
|optional
},
4302 { WM_ACTIVATE
, sent
|wparam
|lparam
, 1, 0 },
4303 { HCBT_SETFOCUS
, hook
},
4304 { WM_IME_SETCONTEXT
, sent
|wparam
|defwinproc
|optional
, 1 },
4305 { WM_IME_NOTIFY
, sent
|wparam
|defwinproc
|optional
, 2 },
4306 { WM_SETFOCUS
, sent
|wparam
|defwinproc
, 0 },
4307 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOREDRAW
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
4308 { WM_GETTEXT
, sent
|optional
},
4309 { WM_NCCALCSIZE
, sent
|optional
},
4313 static void test_MsgWaitForMultipleObjects(HWND hwnd
)
4318 ret
= MsgWaitForMultipleObjects(0, NULL
, FALSE
, 0, QS_POSTMESSAGE
);
4319 ok(ret
== WAIT_TIMEOUT
, "MsgWaitForMultipleObjects returned %x\n", ret
);
4321 PostMessageA(hwnd
, WM_USER
, 0, 0);
4323 ret
= MsgWaitForMultipleObjects(0, NULL
, FALSE
, 0, QS_POSTMESSAGE
);
4324 ok(ret
== WAIT_OBJECT_0
, "MsgWaitForMultipleObjects returned %x\n", ret
);
4326 ok(PeekMessageA( &msg
, 0, 0, 0, PM_REMOVE
), "PeekMessage should succeed\n");
4327 ok(msg
.message
== WM_USER
, "got %04x instead of WM_USER\n", msg
.message
);
4329 ret
= MsgWaitForMultipleObjects(0, NULL
, FALSE
, 0, QS_POSTMESSAGE
);
4330 ok(ret
== WAIT_TIMEOUT
, "MsgWaitForMultipleObjects returned %x\n", ret
);
4332 PostMessageA(hwnd
, WM_USER
, 0, 0);
4334 ret
= MsgWaitForMultipleObjects(0, NULL
, FALSE
, 0, QS_POSTMESSAGE
);
4335 ok(ret
== WAIT_OBJECT_0
, "MsgWaitForMultipleObjects returned %x\n", ret
);
4337 ok(PeekMessageA( &msg
, 0, 0, 0, PM_NOREMOVE
), "PeekMessage should succeed\n");
4338 ok(msg
.message
== WM_USER
, "got %04x instead of WM_USER\n", msg
.message
);
4340 /* shows QS_POSTMESSAGE flag is cleared in the PeekMessage call */
4341 ret
= MsgWaitForMultipleObjects(0, NULL
, FALSE
, 0, QS_POSTMESSAGE
);
4342 ok(ret
== WAIT_TIMEOUT
, "MsgWaitForMultipleObjects returned %x\n", ret
);
4344 PostMessageA(hwnd
, WM_USER
, 0, 0);
4346 /* new incoming message causes it to become signaled again */
4347 ret
= MsgWaitForMultipleObjects(0, NULL
, FALSE
, 0, QS_POSTMESSAGE
);
4348 ok(ret
== WAIT_OBJECT_0
, "MsgWaitForMultipleObjects returned %x\n", ret
);
4350 ok(PeekMessageA( &msg
, 0, 0, 0, PM_REMOVE
), "PeekMessage should succeed\n");
4351 ok(msg
.message
== WM_USER
, "got %04x instead of WM_USER\n", msg
.message
);
4352 ok(PeekMessageA( &msg
, 0, 0, 0, PM_REMOVE
), "PeekMessage should succeed\n");
4353 ok(msg
.message
== WM_USER
, "got %04x instead of WM_USER\n", msg
.message
);
4356 /* test if we receive the right sequence of messages */
4357 static void test_messages(void)
4359 HWND hwnd
, hparent
, hchild
;
4360 HWND hchild2
, hbutton
;
4367 hwnd
= CreateWindowExA(0, "TestWindowClass", "Test overlapped", WS_OVERLAPPEDWINDOW
,
4368 100, 100, 200, 200, 0, 0, 0, NULL
);
4369 ok (hwnd
!= 0, "Failed to create overlapped window\n");
4370 ok_sequence(WmCreateOverlappedSeq
, "CreateWindow:overlapped", FALSE
);
4372 /* test ShowWindow(SW_HIDE) on a newly created invisible window */
4373 ok( ShowWindow(hwnd
, SW_HIDE
) == FALSE
, "ShowWindow: window was visible\n" );
4374 ok_sequence(WmEmptySeq
, "ShowWindow(SW_HIDE):overlapped, invisible", FALSE
);
4376 /* test WM_SETREDRAW on a not visible top level window */
4377 test_WM_SETREDRAW(hwnd
);
4379 SetWindowPos(hwnd
, 0,0,0,0,0, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
);
4381 ok_sequence(WmSWP_ShowOverlappedSeq
, "SetWindowPos:SWP_SHOWWINDOW:overlapped", FALSE
);
4382 ok(IsWindowVisible(hwnd
), "window should be visible at this point\n");
4384 ok(GetActiveWindow() == hwnd
, "window should be active\n");
4385 ok(GetFocus() == hwnd
, "window should have input focus\n");
4386 ShowWindow(hwnd
, SW_HIDE
);
4388 ok_sequence(WmHideOverlappedSeq
, "ShowWindow(SW_HIDE):overlapped", FALSE
);
4390 ShowWindow(hwnd
, SW_SHOW
);
4392 ok_sequence(WmShowOverlappedSeq
, "ShowWindow(SW_SHOW):overlapped", TRUE
);
4394 ShowWindow(hwnd
, SW_HIDE
);
4396 ok_sequence(WmHideOverlappedSeq
, "ShowWindow(SW_HIDE):overlapped", FALSE
);
4398 ShowWindow(hwnd
, SW_SHOWMAXIMIZED
);
4400 ok_sequence(WmShowMaxOverlappedSeq
, "ShowWindow(SW_SHOWMAXIMIZED):overlapped", TRUE
);
4402 ShowWindow(hwnd
, SW_RESTORE
);
4403 ok_sequence(WmShowRestoreMaxOverlappedSeq
, "ShowWindow(SW_RESTORE):overlapped", FALSE
);
4407 ShowWindow(hwnd
, SW_MINIMIZE
);
4409 ok_sequence(WmShowMinOverlappedSeq
, "ShowWindow(SW_SHOWMINIMIZED):overlapped", TRUE
);
4412 ShowWindow(hwnd
, SW_RESTORE
);
4414 ok_sequence(WmShowRestoreMinOverlappedSeq
, "ShowWindow(SW_RESTORE):overlapped", TRUE
);
4417 ShowWindow(hwnd
, SW_SHOW
);
4419 ok_sequence(WmOptionalPaint
, "ShowWindow(SW_SHOW):overlapped already visible", FALSE
);
4421 ok(GetActiveWindow() == hwnd
, "window should be active\n");
4422 ok(GetFocus() == hwnd
, "window should have input focus\n");
4423 SetWindowPos(hwnd
, 0,0,0,0,0, SWP_HIDEWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
);
4424 ok_sequence(WmSWP_HideOverlappedSeq
, "SetWindowPos:SWP_HIDEWINDOW:overlapped", FALSE
);
4425 ok(!IsWindowVisible(hwnd
), "window should not be visible at this point\n");
4426 ok(GetActiveWindow() == hwnd
, "window should still be active\n");
4428 /* test WM_SETREDRAW on a visible top level window */
4429 ShowWindow(hwnd
, SW_SHOW
);
4431 test_WM_SETREDRAW(hwnd
);
4433 trace("testing scroll APIs on a visible top level window %p\n", hwnd
);
4434 test_scroll_messages(hwnd
);
4436 /* test resizing and moving */
4437 SetWindowPos( hwnd
, 0, 0, 0, 300, 300, SWP_NOMOVE
|SWP_NOACTIVATE
);
4438 ok_sequence(WmSWP_ResizeSeq
, "SetWindowPos:Resize", FALSE
);
4441 SetWindowPos( hwnd
, 0, 200, 200, 0, 0, SWP_NOSIZE
|SWP_NOACTIVATE
);
4442 ok_sequence(WmSWP_MoveSeq
, "SetWindowPos:Move", FALSE
);
4445 SetWindowPos( hwnd
, 0, 200, 200, 250, 250, SWP_NOZORDER
|SWP_NOACTIVATE
);
4446 ok_sequence(WmSWP_ResizeNoZOrder
, "SetWindowPos:WmSWP_ResizeNoZOrder", FALSE
);
4450 /* popups don't get WM_GETMINMAXINFO */
4451 SetWindowLongW( hwnd
, GWL_STYLE
, WS_VISIBLE
|WS_POPUP
);
4452 SetWindowPos( hwnd
, 0, 0, 0, 0, 0, SWP_NOZORDER
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_FRAMECHANGED
);
4454 SetWindowPos( hwnd
, 0, 0, 0, 200, 200, SWP_NOMOVE
|SWP_NOACTIVATE
);
4455 ok_sequence(WmSWP_ResizePopupSeq
, "SetWindowPos:ResizePopup", FALSE
);
4457 DestroyWindow(hwnd
);
4458 ok_sequence(WmDestroyOverlappedSeq
, "DestroyWindow:overlapped", FALSE
);
4460 hparent
= CreateWindowExA(0, "TestParentClass", "Test parent", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
4461 100, 100, 200, 200, 0, 0, 0, NULL
);
4462 ok (hparent
!= 0, "Failed to create parent window\n");
4465 hchild
= CreateWindowExA(0, "TestWindowClass", "Test child", WS_CHILD
| WS_MAXIMIZE
,
4466 0, 0, 10, 10, hparent
, 0, 0, NULL
);
4467 ok (hchild
!= 0, "Failed to create child window\n");
4468 ok_sequence(WmCreateMaximizedChildSeq
, "CreateWindow:maximized child", FALSE
);
4469 DestroyWindow(hchild
);
4472 /* visible child window with a caption */
4473 hchild
= CreateWindowExA(0, "TestWindowClass", "Test child",
4474 WS_CHILD
| WS_VISIBLE
| WS_CAPTION
,
4475 0, 0, 10, 10, hparent
, 0, 0, NULL
);
4476 ok (hchild
!= 0, "Failed to create child window\n");
4477 ok_sequence(WmCreateVisibleChildSeq
, "CreateWindow:visible child", FALSE
);
4479 trace("testing scroll APIs on a visible child window %p\n", hchild
);
4480 test_scroll_messages(hchild
);
4482 SetWindowPos(hchild
, 0,0,0,0,0, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
);
4483 ok_sequence(WmShowChildSeq_4
, "SetWindowPos(SWP_SHOWWINDOW):child with a caption", FALSE
);
4485 DestroyWindow(hchild
);
4488 hchild
= CreateWindowExA(0, "TestWindowClass", "Test child", WS_CHILD
,
4489 0, 0, 10, 10, hparent
, 0, 0, NULL
);
4490 ok (hchild
!= 0, "Failed to create child window\n");
4491 ok_sequence(WmCreateChildSeq
, "CreateWindow:child", FALSE
);
4493 hchild2
= CreateWindowExA(0, "SimpleWindowClass", "Test child2", WS_CHILD
,
4494 100, 100, 50, 50, hparent
, 0, 0, NULL
);
4495 ok (hchild2
!= 0, "Failed to create child2 window\n");
4498 hbutton
= CreateWindowExA(0, "TestWindowClass", "Test button", WS_CHILD
,
4499 0, 100, 50, 50, hchild
, 0, 0, NULL
);
4500 ok (hbutton
!= 0, "Failed to create button window\n");
4502 /* test WM_SETREDRAW on a not visible child window */
4503 test_WM_SETREDRAW(hchild
);
4505 ShowWindow(hchild
, SW_SHOW
);
4506 ok_sequence(WmShowChildSeq
, "ShowWindow(SW_SHOW):child", FALSE
);
4508 /* check parent messages too */
4509 log_all_parent_messages
++;
4510 ShowWindow(hchild
, SW_HIDE
);
4511 ok_sequence(WmHideChildSeq2
, "ShowWindow(SW_HIDE):child", FALSE
);
4512 log_all_parent_messages
--;
4514 ShowWindow(hchild
, SW_SHOW
);
4515 ok_sequence(WmShowChildSeq
, "ShowWindow(SW_SHOW):child", FALSE
);
4517 ShowWindow(hchild
, SW_HIDE
);
4518 ok_sequence(WmHideChildSeq
, "ShowWindow(SW_HIDE):child", FALSE
);
4520 ShowWindow(hchild
, SW_SHOW
);
4521 ok_sequence(WmShowChildSeq
, "ShowWindow(SW_SHOW):child", FALSE
);
4523 /* test WM_SETREDRAW on a visible child window */
4524 test_WM_SETREDRAW(hchild
);
4526 log_all_parent_messages
++;
4527 MoveWindow(hchild
, 10, 10, 20, 20, TRUE
);
4528 ok_sequence(WmResizingChildWithMoveWindowSeq
, "MoveWindow:child", FALSE
);
4529 log_all_parent_messages
--;
4531 ShowWindow(hchild
, SW_HIDE
);
4533 SetWindowPos(hchild
, 0,0,0,0,0, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
);
4534 ok_sequence(WmShowChildSeq_2
, "SetWindowPos:show_child_2", FALSE
);
4536 ShowWindow(hchild
, SW_HIDE
);
4538 SetWindowPos(hchild
, 0,0,0,0,0, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOACTIVATE
);
4539 ok_sequence(WmShowChildSeq_3
, "SetWindowPos:show_child_3", FALSE
);
4541 /* DestroyWindow sequence below expects that a child has focus */
4545 DestroyWindow(hchild
);
4546 ok_sequence(WmDestroyChildSeq
, "DestroyWindow:child", FALSE
);
4547 DestroyWindow(hchild2
);
4548 DestroyWindow(hbutton
);
4551 hchild
= CreateWindowExA(0, "TestWindowClass", "Test Child Popup", WS_CHILD
| WS_POPUP
,
4552 0, 0, 100, 100, hparent
, 0, 0, NULL
);
4553 ok (hchild
!= 0, "Failed to create child popup window\n");
4554 ok_sequence(WmCreateChildPopupSeq
, "CreateWindow:child_popup", FALSE
);
4555 DestroyWindow(hchild
);
4557 /* test what happens to a window which sets WS_VISIBLE in WM_CREATE */
4559 hchild
= CreateWindowExA(0, "TestPopupClass", "Test Popup", WS_POPUP
,
4560 0, 0, 100, 100, hparent
, 0, 0, NULL
);
4561 ok (hchild
!= 0, "Failed to create popup window\n");
4562 ok_sequence(WmCreateInvisiblePopupSeq
, "CreateWindow:invisible_popup", FALSE
);
4563 ok(GetWindowLongA(hchild
, GWL_STYLE
) & WS_VISIBLE
, "WS_VISIBLE should be set\n");
4564 ok(IsWindowVisible(hchild
), "IsWindowVisible() should return TRUE\n");
4566 ShowWindow(hchild
, SW_SHOW
);
4567 ok_sequence(WmEmptySeq
, "ShowWindow:show_visible_popup", FALSE
);
4569 SetWindowPos(hchild
, 0,0,0,0,0, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOACTIVATE
|SWP_NOZORDER
);
4570 ok_sequence(WmShowVisiblePopupSeq_2
, "SetWindowPos:show_visible_popup_2", FALSE
);
4572 SetWindowPos(hchild
, 0,0,0,0,0, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
);
4573 ok_sequence(WmShowVisiblePopupSeq_3
, "SetWindowPos:show_visible_popup_3", FALSE
);
4574 DestroyWindow(hchild
);
4576 /* this time add WS_VISIBLE for CreateWindowEx, but this fact actually
4577 * changes nothing in message sequences.
4580 hchild
= CreateWindowExA(0, "TestPopupClass", "Test Popup", WS_POPUP
| WS_VISIBLE
,
4581 0, 0, 100, 100, hparent
, 0, 0, NULL
);
4582 ok (hchild
!= 0, "Failed to create popup window\n");
4583 ok_sequence(WmCreateInvisiblePopupSeq
, "CreateWindow:invisible_popup", FALSE
);
4584 ok(GetWindowLongA(hchild
, GWL_STYLE
) & WS_VISIBLE
, "WS_VISIBLE should be set\n");
4585 ok(IsWindowVisible(hchild
), "IsWindowVisible() should return TRUE\n");
4587 ShowWindow(hchild
, SW_SHOW
);
4588 ok_sequence(WmEmptySeq
, "ShowWindow:show_visible_popup", FALSE
);
4590 SetWindowPos(hchild
, 0,0,0,0,0, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOACTIVATE
|SWP_NOZORDER
);
4591 ok_sequence(WmShowVisiblePopupSeq_2
, "SetWindowPos:show_visible_popup_2", FALSE
);
4592 DestroyWindow(hchild
);
4595 hwnd
= CreateWindowExA(WS_EX_DLGMODALFRAME
, "TestDialogClass", NULL
, WS_VISIBLE
|WS_CAPTION
|WS_SYSMENU
|WS_DLGFRAME
,
4596 0, 0, 100, 100, hparent
, 0, 0, NULL
);
4597 ok(hwnd
!= 0, "Failed to create custom dialog window\n");
4598 ok_sequence(WmCreateCustomDialogSeq
, "CreateCustomDialog", TRUE
);
4601 trace("testing scroll APIs on a visible dialog %p\n", hwnd);
4602 test_scroll_messages(hwnd);
4608 SendMessage(hwnd
, WM_NULL
, 0, 0);
4611 after_end_dialog
= 1;
4612 EndDialog( hwnd
, 0 );
4613 ok_sequence(WmEndCustomDialogSeq
, "EndCustomDialog", FALSE
);
4615 DestroyWindow(hwnd
);
4616 after_end_dialog
= 0;
4619 hwnd
= CreateWindowExA(0, "TestDialogClass", NULL
, WS_POPUP
,
4620 0, 0, 100, 100, 0, 0, GetModuleHandleA(0), NULL
);
4621 ok(hwnd
!= 0, "Failed to create custom dialog window\n");
4623 trace("call ShowWindow(%p, SW_SHOW)\n", hwnd
);
4624 ShowWindow(hwnd
, SW_SHOW
);
4625 ok_sequence(WmShowCustomDialogSeq
, "ShowCustomDialog", TRUE
);
4626 DestroyWindow(hwnd
);
4629 DialogBoxA( 0, "TEST_DIALOG", hparent
, TestModalDlgProcA
);
4630 ok_sequence(WmModalDialogSeq
, "ModalDialog", TRUE
);
4632 DestroyWindow(hparent
);
4635 /* Message sequence for SetMenu */
4636 ok(!DrawMenuBar(hwnd
), "DrawMenuBar should return FALSE for a window without a menu\n");
4637 ok_sequence(WmEmptySeq
, "DrawMenuBar for a window without a menu", FALSE
);
4639 hmenu
= CreateMenu();
4640 ok (hmenu
!= 0, "Failed to create menu\n");
4641 ok (InsertMenuA(hmenu
, -1, MF_BYPOSITION
, 0x1000, "foo"), "InsertMenu failed\n");
4642 hwnd
= CreateWindowExA(0, "TestWindowClass", "Test overlapped", WS_OVERLAPPEDWINDOW
,
4643 100, 100, 200, 200, 0, hmenu
, 0, NULL
);
4644 ok_sequence(WmCreateOverlappedSeq
, "CreateWindow:overlapped", FALSE
);
4645 ok (SetMenu(hwnd
, 0), "SetMenu\n");
4646 ok_sequence(WmSetMenuNonVisibleSizeChangeSeq
, "SetMenu:NonVisibleSizeChange", FALSE
);
4647 ok (SetMenu(hwnd
, 0), "SetMenu\n");
4648 ok_sequence(WmSetMenuNonVisibleNoSizeChangeSeq
, "SetMenu:NonVisibleNoSizeChange", FALSE
);
4649 ShowWindow(hwnd
, SW_SHOW
);
4650 UpdateWindow( hwnd
);
4653 ok (SetMenu(hwnd
, 0), "SetMenu\n");
4654 ok_sequence(WmSetMenuVisibleNoSizeChangeSeq
, "SetMenu:VisibleNoSizeChange", FALSE
);
4655 ok (SetMenu(hwnd
, hmenu
), "SetMenu\n");
4656 ok_sequence(WmSetMenuVisibleSizeChangeSeq
, "SetMenu:VisibleSizeChange", FALSE
);
4658 UpdateWindow( hwnd
);
4661 ok(DrawMenuBar(hwnd
), "DrawMenuBar\n");
4663 ok_sequence(WmDrawMenuBarSeq
, "DrawMenuBar", FALSE
);
4665 DestroyWindow(hwnd
);
4668 /* Message sequence for EnableWindow */
4669 hparent
= CreateWindowExA(0, "TestWindowClass", "Test parent", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
4670 100, 100, 200, 200, 0, 0, 0, NULL
);
4671 ok (hparent
!= 0, "Failed to create parent window\n");
4672 hchild
= CreateWindowExA(0, "TestWindowClass", "Test child", WS_CHILD
| WS_VISIBLE
,
4673 0, 0, 10, 10, hparent
, 0, 0, NULL
);
4674 ok (hchild
!= 0, "Failed to create child window\n");
4680 EnableWindow(hparent
, FALSE
);
4681 ok_sequence(WmEnableWindowSeq_1
, "EnableWindow(FALSE)", FALSE
);
4683 EnableWindow(hparent
, TRUE
);
4684 ok_sequence(WmEnableWindowSeq_2
, "EnableWindow(TRUE)", FALSE
);
4689 test_MsgWaitForMultipleObjects(hparent
);
4691 /* the following test causes an exception in user.exe under win9x */
4692 if (!PostMessageW( hparent
, WM_USER
, 0, 0 ))
4694 DestroyWindow(hparent
);
4698 PostMessageW( hparent
, WM_USER
+1, 0, 0 );
4699 /* PeekMessage(NULL) fails, but still removes the message */
4700 SetLastError(0xdeadbeef);
4701 ok( !PeekMessageW( NULL
, 0, 0, 0, PM_REMOVE
), "PeekMessage(NULL) should fail\n" );
4702 ok( GetLastError() == ERROR_NOACCESS
|| /* Win2k */
4703 GetLastError() == 0xdeadbeef, /* NT4 */
4704 "last error is %d\n", GetLastError() );
4705 ok( PeekMessageW( &msg
, 0, 0, 0, PM_REMOVE
), "PeekMessage should succeed\n" );
4706 ok( msg
.message
== WM_USER
+1, "got %x instead of WM_USER+1\n", msg
.message
);
4708 DestroyWindow(hchild
);
4709 DestroyWindow(hparent
);
4712 /* Message sequences for WM_SETICON */
4713 trace("testing WM_SETICON\n");
4714 hwnd
= CreateWindowExA(0, "TestWindowClass", NULL
, WS_OVERLAPPEDWINDOW
,
4715 CW_USEDEFAULT
, CW_USEDEFAULT
, 300, 300, 0,
4717 ShowWindow(hwnd
, SW_SHOW
);
4721 SendMessage(hwnd
, WM_SETICON
, ICON_SMALL
, (LPARAM
)LoadIcon(0, IDI_APPLICATION
));
4722 ok_sequence(WmSetIcon_1
, "WM_SETICON for shown window with caption", FALSE
);
4724 ShowWindow(hwnd
, SW_HIDE
);
4727 SendMessage(hwnd
, WM_SETICON
, ICON_SMALL
, (LPARAM
)LoadIcon(0, IDI_APPLICATION
));
4728 ok_sequence(WmSetIcon_2
, "WM_SETICON for hidden window with caption", FALSE
);
4729 DestroyWindow(hwnd
);
4732 hwnd
= CreateWindowExA(0, "TestPopupClass", NULL
, WS_POPUP
,
4733 CW_USEDEFAULT
, CW_USEDEFAULT
, 300, 300, 0,
4735 ShowWindow(hwnd
, SW_SHOW
);
4739 SendMessage(hwnd
, WM_SETICON
, ICON_SMALL
, (LPARAM
)LoadIcon(0, IDI_APPLICATION
));
4740 ok_sequence(WmSetIcon_2
, "WM_SETICON for shown window without caption", FALSE
);
4742 ShowWindow(hwnd
, SW_HIDE
);
4745 SendMessage(hwnd
, WM_SETICON
, ICON_SMALL
, (LPARAM
)LoadIcon(0, IDI_APPLICATION
));
4746 ok_sequence(WmSetIcon_2
, "WM_SETICON for hidden window without caption", FALSE
);
4749 res
= SendMessage(hwnd
, 0x3B, 0x8000000b, 0);
4752 todo_wine
win_skip( "Message 0x3b not supported\n" );
4755 ok_sequence(WmInitEndSession
, "Handling of undocumented 0x3B message by DefWindowProc wparam=0x8000000b", TRUE
);
4756 ok(res
== 1, "SendMessage(hwnd, 0x3B, 0x8000000b, 0) should have returned 1 instead of %ld\n", res
);
4757 res
= SendMessage(hwnd
, 0x3B, 0x0000000b, 0);
4758 ok_sequence(WmInitEndSession_2
, "Handling of undocumented 0x3B message by DefWindowProc wparam=0x0000000b", TRUE
);
4759 ok(res
== 1, "SendMessage(hwnd, 0x3B, 0x0000000b, 0) should have returned 1 instead of %ld\n", res
);
4760 res
= SendMessage(hwnd
, 0x3B, 0x0000000f, 0);
4761 ok_sequence(WmInitEndSession_2
, "Handling of undocumented 0x3B message by DefWindowProc wparam=0x0000000f", TRUE
);
4762 ok(res
== 1, "SendMessage(hwnd, 0x3B, 0x0000000f, 0) should have returned 1 instead of %ld\n", res
);
4765 res
= SendMessage(hwnd
, 0x3B, 0x80000008, 0);
4766 ok_sequence(WmInitEndSession_3
, "Handling of undocumented 0x3B message by DefWindowProc wparam=0x80000008", TRUE
);
4767 ok(res
== 2, "SendMessage(hwnd, 0x3B, 0x80000008, 0) should have returned 2 instead of %ld\n", res
);
4768 res
= SendMessage(hwnd
, 0x3B, 0x00000008, 0);
4769 ok_sequence(WmInitEndSession_4
, "Handling of undocumented 0x3B message by DefWindowProc wparam=0x00000008", TRUE
);
4770 ok(res
== 2, "SendMessage(hwnd, 0x3B, 0x00000008, 0) should have returned 2 instead of %ld\n", res
);
4772 res
= SendMessage(hwnd
, 0x3B, 0x80000004, 0);
4773 ok_sequence(WmInitEndSession_3
, "Handling of undocumented 0x3B message by DefWindowProc wparam=0x80000004", TRUE
);
4774 ok(res
== 2, "SendMessage(hwnd, 0x3B, 0x80000004, 0) should have returned 2 instead of %ld\n", res
);
4776 res
= SendMessage(hwnd
, 0x3B, 0x80000001, 0);
4777 ok_sequence(WmInitEndSession_5
, "Handling of undocumented 0x3B message by DefWindowProc wparam=0x80000001", TRUE
);
4778 ok(res
== 2, "SendMessage(hwnd, 0x3B, 0x80000001, 0) should have returned 2 instead of %ld\n", res
);
4781 DestroyWindow(hwnd
);
4785 static void test_setwindowpos(void)
4790 const INT winX
= 100;
4791 const INT winY
= 100;
4792 const INT sysX
= GetSystemMetrics(SM_CXMINTRACK
);
4794 hwnd
= CreateWindowExA(0, "TestWindowClass", NULL
, 0,
4795 0, 0, winX
, winY
, 0,
4798 GetWindowRect(hwnd
, &rc
);
4799 expect(sysX
, rc
.right
);
4800 expect(winY
, rc
.bottom
);
4804 res
= SetWindowPos(hwnd
, HWND_TOPMOST
, 0, 0, winX
, winY
, 0);
4805 ok_sequence(WmZOrder
, "Z-Order", TRUE
);
4806 ok(res
== TRUE
, "SetWindowPos expected TRUE, got %ld\n", res
);
4808 GetWindowRect(hwnd
, &rc
);
4809 expect(sysX
, rc
.right
);
4810 expect(winY
, rc
.bottom
);
4811 DestroyWindow(hwnd
);
4814 static void invisible_parent_tests(void)
4816 HWND hparent
, hchild
;
4818 hparent
= CreateWindowExA(0, "TestParentClass", "Test parent", WS_OVERLAPPEDWINDOW
,
4819 100, 100, 200, 200, 0, 0, 0, NULL
);
4820 ok (hparent
!= 0, "Failed to create parent window\n");
4823 /* test showing child with hidden parent */
4825 hchild
= CreateWindowExA(0, "TestWindowClass", "Test child", WS_CHILD
,
4826 0, 0, 10, 10, hparent
, 0, 0, NULL
);
4827 ok (hchild
!= 0, "Failed to create child window\n");
4828 ok_sequence(WmCreateChildSeq
, "CreateWindow:child", FALSE
);
4830 ShowWindow( hchild
, SW_MINIMIZE
);
4831 ok_sequence(WmShowChildInvisibleParentSeq_1
, "ShowWindow(SW_MINIMIZE) child with invisible parent", FALSE
);
4832 ok(GetWindowLongA(hchild
, GWL_STYLE
) & WS_VISIBLE
, "WS_VISIBLE should be set\n");
4833 ok(!IsWindowVisible(hchild
), "IsWindowVisible() should return FALSE\n");
4838 ShowWindow( hchild
, SW_MINIMIZE
);
4839 ok_sequence(WmShowChildInvisibleParentSeq_1r
, "ShowWindow(SW_MINIMIZE) child with invisible parent", FALSE
);
4841 DestroyWindow(hchild
);
4842 hchild
= CreateWindowExA(0, "TestWindowClass", "Test child", WS_CHILD
,
4843 0, 0, 10, 10, hparent
, 0, 0, NULL
);
4846 ShowWindow( hchild
, SW_MAXIMIZE
);
4847 ok_sequence(WmShowChildInvisibleParentSeq_2
, "ShowWindow(SW_MAXIMIZE) child with invisible parent", FALSE
);
4848 ok(GetWindowLongA(hchild
, GWL_STYLE
) & WS_VISIBLE
, "WS_VISIBLE should be set\n");
4849 ok(!IsWindowVisible(hchild
), "IsWindowVisible() should return FALSE\n");
4854 ShowWindow( hchild
, SW_MAXIMIZE
);
4855 ok_sequence(WmShowChildInvisibleParentSeq_2r
, "ShowWindow(SW_MAXIMIZE) child with invisible parent", FALSE
);
4857 DestroyWindow(hchild
);
4858 hchild
= CreateWindowExA(0, "TestWindowClass", "Test child", WS_CHILD
,
4859 0, 0, 10, 10, hparent
, 0, 0, NULL
);
4862 ShowWindow( hchild
, SW_RESTORE
);
4863 ok_sequence(WmShowChildInvisibleParentSeq_5
, "ShowWindow(SW_RESTORE) child with invisible parent", FALSE
);
4864 ok(GetWindowLongA(hchild
, GWL_STYLE
) & WS_VISIBLE
, "WS_VISIBLE should be set\n");
4865 ok(!IsWindowVisible(hchild
), "IsWindowVisible() should return FALSE\n");
4867 DestroyWindow(hchild
);
4868 hchild
= CreateWindowExA(0, "TestWindowClass", "Test child", WS_CHILD
,
4869 0, 0, 10, 10, hparent
, 0, 0, NULL
);
4872 ShowWindow( hchild
, SW_SHOWMINIMIZED
);
4873 ok_sequence(WmShowChildInvisibleParentSeq_3
, "ShowWindow(SW_SHOWMINIMIZED) child with invisible parent", FALSE
);
4874 ok(GetWindowLongA(hchild
, GWL_STYLE
) & WS_VISIBLE
, "WS_VISIBLE should be set\n");
4875 ok(!IsWindowVisible(hchild
), "IsWindowVisible() should return FALSE\n");
4880 ShowWindow( hchild
, SW_SHOWMINIMIZED
);
4881 ok_sequence(WmShowChildInvisibleParentSeq_3r
, "ShowWindow(SW_SHOWMINIMIZED) child with invisible parent", FALSE
);
4883 DestroyWindow(hchild
);
4884 hchild
= CreateWindowExA(0, "TestWindowClass", "Test child", WS_CHILD
,
4885 0, 0, 10, 10, hparent
, 0, 0, NULL
);
4888 /* same as ShowWindow( hchild, SW_MAXIMIZE ); */
4889 ShowWindow( hchild
, SW_SHOWMAXIMIZED
);
4890 ok_sequence(WmShowChildInvisibleParentSeq_2
, "ShowWindow(SW_SHOWMAXIMIZED) child with invisible parent", FALSE
);
4891 ok(GetWindowLongA(hchild
, GWL_STYLE
) & WS_VISIBLE
, "WS_VISIBLE should be set\n");
4892 ok(!IsWindowVisible(hchild
), "IsWindowVisible() should return FALSE\n");
4894 DestroyWindow(hchild
);
4895 hchild
= CreateWindowExA(0, "TestWindowClass", "Test child", WS_CHILD
,
4896 0, 0, 10, 10, hparent
, 0, 0, NULL
);
4899 ShowWindow( hchild
, SW_SHOWMINNOACTIVE
);
4900 ok_sequence(WmShowChildInvisibleParentSeq_4
, "ShowWindow(SW_SHOWMINNOACTIVE) child with invisible parent", FALSE
);
4901 ok(GetWindowLongA(hchild
, GWL_STYLE
) & WS_VISIBLE
, "WS_VISIBLE should be set\n");
4902 ok(!IsWindowVisible(hchild
), "IsWindowVisible() should return FALSE\n");
4907 ShowWindow( hchild
, SW_SHOWMINNOACTIVE
);
4908 ok_sequence(WmShowChildInvisibleParentSeq_4r
, "ShowWindow(SW_SHOWMINNOACTIVE) child with invisible parent", FALSE
);
4910 DestroyWindow(hchild
);
4911 hchild
= CreateWindowExA(0, "TestWindowClass", "Test child", WS_CHILD
,
4912 0, 0, 10, 10, hparent
, 0, 0, NULL
);
4915 /* FIXME: looks like XP SP2 doesn't know about SW_FORCEMINIMIZE at all */
4916 ShowWindow( hchild
, SW_FORCEMINIMIZE
);
4917 ok_sequence(WmEmptySeq
, "ShowWindow(SW_FORCEMINIMIZE) child with invisible parent", TRUE
);
4919 ok(!(GetWindowLongA(hchild
, GWL_STYLE
) & WS_VISIBLE
), "WS_VISIBLE should be not set\n");
4921 ok(!IsWindowVisible(hchild
), "IsWindowVisible() should return FALSE\n");
4923 DestroyWindow(hchild
);
4924 hchild
= CreateWindowExA(0, "TestWindowClass", "Test child", WS_CHILD
,
4925 0, 0, 10, 10, hparent
, 0, 0, NULL
);
4928 ShowWindow( hchild
, SW_SHOWNA
);
4929 ok_sequence(WmShowChildInvisibleParentSeq_5
, "ShowWindow(SW_SHOWNA) child with invisible parent", FALSE
);
4930 ok(GetWindowLongA(hchild
, GWL_STYLE
) & WS_VISIBLE
, "WS_VISIBLE should be set\n");
4931 ok(!IsWindowVisible(hchild
), "IsWindowVisible() should return FALSE\n");
4936 ShowWindow( hchild
, SW_SHOWNA
);
4937 ok_sequence(WmShowChildInvisibleParentSeq_5
, "ShowWindow(SW_SHOWNA) child with invisible parent", FALSE
);
4939 DestroyWindow(hchild
);
4940 hchild
= CreateWindowExA(0, "TestWindowClass", "Test child", WS_CHILD
,
4941 0, 0, 10, 10, hparent
, 0, 0, NULL
);
4944 ShowWindow( hchild
, SW_SHOW
);
4945 ok_sequence(WmShowChildInvisibleParentSeq_5
, "ShowWindow(SW_SHOW) child with invisible parent", FALSE
);
4946 ok(GetWindowLongA(hchild
, GWL_STYLE
) & WS_VISIBLE
, "WS_VISIBLE should be set\n");
4947 ok(!IsWindowVisible(hchild
), "IsWindowVisible() should return FALSE\n");
4952 ShowWindow( hchild
, SW_SHOW
);
4953 ok_sequence(WmEmptySeq
, "ShowWindow(SW_SHOW) child with invisible parent", FALSE
);
4955 ShowWindow( hchild
, SW_HIDE
);
4956 ok_sequence(WmHideChildInvisibleParentSeq
, "ShowWindow:hide child with invisible parent", FALSE
);
4957 ok(!(GetWindowLongA(hchild
, GWL_STYLE
) & WS_VISIBLE
), "WS_VISIBLE should be not set\n");
4958 ok(!IsWindowVisible(hchild
), "IsWindowVisible() should return FALSE\n");
4960 SetWindowPos(hchild
, 0,0,0,0,0, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOACTIVATE
|SWP_NOZORDER
);
4961 ok_sequence(WmShowChildInvisibleParentSeq_6
, "SetWindowPos:show child with invisible parent", FALSE
);
4962 ok(GetWindowLongA(hchild
, GWL_STYLE
) & WS_VISIBLE
, "WS_VISIBLE should be set\n");
4963 ok(!IsWindowVisible(hchild
), "IsWindowVisible() should return FALSE\n");
4965 SetWindowPos(hchild
, 0,0,0,0,0, SWP_HIDEWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOACTIVATE
|SWP_NOZORDER
);
4966 ok_sequence(WmHideChildInvisibleParentSeq_2
, "SetWindowPos:hide child with invisible parent", FALSE
);
4967 ok(!(GetWindowLongA(hchild
, GWL_STYLE
) & WS_VISIBLE
), "WS_VISIBLE should not be set\n");
4968 ok(!IsWindowVisible(hchild
), "IsWindowVisible() should return FALSE\n");
4970 SetWindowPos(hchild
, 0,0,0,0,0, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOACTIVATE
|SWP_NOZORDER
);
4972 DestroyWindow(hchild
);
4973 ok_sequence(WmDestroyInvisibleChildSeq
, "DestroyInvisibleChildSeq", FALSE
);
4975 DestroyWindow(hparent
);
4979 /****************** button message test *************************/
4980 static const struct message WmSetFocusButtonSeq
[] =
4982 { HCBT_SETFOCUS
, hook
},
4983 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 1 },
4984 { WM_IME_NOTIFY
, sent
|wparam
|defwinproc
|optional
, 2 },
4985 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
4986 { WM_SETFOCUS
, sent
|wparam
, 0 },
4987 { WM_CTLCOLORBTN
, sent
|defwinproc
},
4990 static const struct message WmKillFocusButtonSeq
[] =
4992 { HCBT_SETFOCUS
, hook
},
4993 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
4994 { WM_KILLFOCUS
, sent
|wparam
, 0 },
4995 { WM_CTLCOLORBTN
, sent
|defwinproc
},
4996 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 0 },
4997 { WM_IME_NOTIFY
, sent
|wparam
|defwinproc
|optional
, 1 },
5000 static const struct message WmSetFocusStaticSeq
[] =
5002 { HCBT_SETFOCUS
, hook
},
5003 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 1 },
5004 { WM_IME_NOTIFY
, sent
|wparam
|defwinproc
|optional
, 2 },
5005 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
5006 { WM_SETFOCUS
, sent
|wparam
, 0 },
5007 { WM_CTLCOLORSTATIC
, sent
|defwinproc
},
5010 static const struct message WmKillFocusStaticSeq
[] =
5012 { HCBT_SETFOCUS
, hook
},
5013 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
5014 { WM_KILLFOCUS
, sent
|wparam
, 0 },
5015 { WM_CTLCOLORSTATIC
, sent
|defwinproc
},
5016 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 0 },
5017 { WM_IME_NOTIFY
, sent
|wparam
|defwinproc
|optional
, 1 },
5020 static const struct message WmLButtonDownSeq
[] =
5022 { WM_LBUTTONDOWN
, sent
|wparam
|lparam
, 0, 0 },
5023 { EVENT_SYSTEM_CAPTURESTART
, winevent_hook
|wparam
|lparam
, 0, 0 },
5024 { HCBT_SETFOCUS
, hook
},
5025 { WM_IME_SETCONTEXT
, sent
|wparam
|defwinproc
|optional
, 1 },
5026 { WM_IME_NOTIFY
, sent
|wparam
|defwinproc
|optional
, 2 },
5027 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
5028 { WM_SETFOCUS
, sent
|wparam
|defwinproc
, 0 },
5029 { WM_CTLCOLORBTN
, sent
|defwinproc
},
5030 { BM_SETSTATE
, sent
|wparam
|defwinproc
, TRUE
},
5031 { WM_CTLCOLORBTN
, sent
|defwinproc
},
5032 { EVENT_OBJECT_STATECHANGE
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
5035 static const struct message WmLButtonUpSeq
[] =
5037 { WM_LBUTTONUP
, sent
|wparam
|lparam
, 0, 0 },
5038 { BM_SETSTATE
, sent
|wparam
|defwinproc
, FALSE
},
5039 { WM_CTLCOLORBTN
, sent
|defwinproc
},
5040 { EVENT_OBJECT_STATECHANGE
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
5041 { EVENT_SYSTEM_CAPTUREEND
, winevent_hook
|wparam
|lparam
, 0, 0 },
5042 { WM_CAPTURECHANGED
, sent
|wparam
|defwinproc
, 0 },
5045 static const struct message WmSetFontButtonSeq
[] =
5047 { WM_SETFONT
, sent
},
5049 { WM_ERASEBKGND
, sent
|defwinproc
|optional
},
5050 { WM_CTLCOLORBTN
, sent
|defwinproc
},
5054 static WNDPROC old_button_proc
;
5056 static LRESULT CALLBACK
button_hook_proc(HWND hwnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
5058 static long defwndproc_counter
= 0;
5060 struct recvd_message msg
;
5064 /* explicitly ignore WM_GETICON message */
5070 ok(GetCapture() == hwnd
, "GetCapture() = %p\n", GetCapture());
5074 msg
.message
= message
;
5075 msg
.flags
= sent
|wparam
|lparam
;
5076 if (defwndproc_counter
) msg
.flags
|= defwinproc
;
5077 msg
.wParam
= wParam
;
5078 msg
.lParam
= lParam
;
5079 msg
.descr
= "button";
5083 defwndproc_counter
++;
5084 ret
= CallWindowProcA(old_button_proc
, hwnd
, message
, wParam
, lParam
);
5085 defwndproc_counter
--;
5090 static void subclass_button(void)
5094 if (!GetClassInfoA(0, "button", &cls
)) assert(0);
5096 old_button_proc
= cls
.lpfnWndProc
;
5098 cls
.hInstance
= GetModuleHandle(0);
5099 cls
.lpfnWndProc
= button_hook_proc
;
5100 cls
.lpszClassName
= "my_button_class";
5101 UnregisterClass(cls
.lpszClassName
, cls
.hInstance
);
5102 if (!RegisterClassA(&cls
)) assert(0);
5105 static void test_button_messages(void)
5111 const struct message
*setfocus
;
5112 const struct message
*killfocus
;
5114 { BS_PUSHBUTTON
, DLGC_BUTTON
| DLGC_UNDEFPUSHBUTTON
,
5115 WmSetFocusButtonSeq
, WmKillFocusButtonSeq
},
5116 { BS_DEFPUSHBUTTON
, DLGC_BUTTON
| DLGC_DEFPUSHBUTTON
,
5117 WmSetFocusButtonSeq
, WmKillFocusButtonSeq
},
5118 { BS_CHECKBOX
, DLGC_BUTTON
,
5119 WmSetFocusStaticSeq
, WmKillFocusStaticSeq
},
5120 { BS_AUTOCHECKBOX
, DLGC_BUTTON
,
5121 WmSetFocusStaticSeq
, WmKillFocusStaticSeq
},
5122 { BS_RADIOBUTTON
, DLGC_BUTTON
| DLGC_RADIOBUTTON
,
5123 WmSetFocusStaticSeq
, WmKillFocusStaticSeq
},
5124 { BS_3STATE
, DLGC_BUTTON
,
5125 WmSetFocusStaticSeq
, WmKillFocusStaticSeq
},
5126 { BS_AUTO3STATE
, DLGC_BUTTON
,
5127 WmSetFocusStaticSeq
, WmKillFocusStaticSeq
},
5128 { BS_GROUPBOX
, DLGC_STATIC
,
5129 WmSetFocusStaticSeq
, WmKillFocusStaticSeq
},
5130 { BS_USERBUTTON
, DLGC_BUTTON
| DLGC_UNDEFPUSHBUTTON
,
5131 WmSetFocusButtonSeq
, WmKillFocusButtonSeq
},
5132 { BS_AUTORADIOBUTTON
, DLGC_BUTTON
| DLGC_RADIOBUTTON
,
5133 WmSetFocusStaticSeq
, WmKillFocusStaticSeq
},
5134 { BS_OWNERDRAW
, DLGC_BUTTON
,
5135 WmSetFocusButtonSeq
, WmKillFocusButtonSeq
}
5144 for (i
= 0; i
< sizeof(button
)/sizeof(button
[0]); i
++)
5146 hwnd
= CreateWindowExA(0, "my_button_class", "test", button
[i
].style
| WS_POPUP
,
5147 0, 0, 50, 14, 0, 0, 0, NULL
);
5148 ok(hwnd
!= 0, "Failed to create button window\n");
5150 dlg_code
= SendMessageA(hwnd
, WM_GETDLGCODE
, 0, 0);
5151 ok(dlg_code
== button
[i
].dlg_code
, "%u: wrong dlg_code %08x\n", i
, dlg_code
);
5153 ShowWindow(hwnd
, SW_SHOW
);
5158 trace("button style %08x\n", button
[i
].style
);
5160 ok_sequence(button
[i
].setfocus
, "SetFocus(hwnd) on a button", FALSE
);
5163 ok_sequence(button
[i
].killfocus
, "SetFocus(0) on a button", FALSE
);
5165 DestroyWindow(hwnd
);
5168 hwnd
= CreateWindowExA(0, "my_button_class", "test", BS_PUSHBUTTON
| WS_POPUP
| WS_VISIBLE
,
5169 0, 0, 50, 14, 0, 0, 0, NULL
);
5170 ok(hwnd
!= 0, "Failed to create button window\n");
5176 SendMessageA(hwnd
, WM_LBUTTONDOWN
, 0, 0);
5177 ok_sequence(WmLButtonDownSeq
, "WM_LBUTTONDOWN on a button", FALSE
);
5179 SendMessageA(hwnd
, WM_LBUTTONUP
, 0, 0);
5180 ok_sequence(WmLButtonUpSeq
, "WM_LBUTTONUP on a button", FALSE
);
5183 zfont
= GetStockObject(SYSTEM_FONT
);
5184 SendMessageA(hwnd
, WM_SETFONT
, (WPARAM
)zfont
, TRUE
);
5186 ok_sequence(WmSetFontButtonSeq
, "WM_SETFONT on a button", FALSE
);
5188 DestroyWindow(hwnd
);
5191 /****************** static message test *************************/
5192 static const struct message WmSetFontStaticSeq
[] =
5194 { WM_SETFONT
, sent
},
5195 { WM_PAINT
, sent
|defwinproc
|optional
},
5196 { WM_ERASEBKGND
, sent
|defwinproc
|optional
},
5197 { WM_CTLCOLORSTATIC
, sent
|defwinproc
|optional
},
5201 static WNDPROC old_static_proc
;
5203 static LRESULT CALLBACK
static_hook_proc(HWND hwnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
5205 static long defwndproc_counter
= 0;
5207 struct recvd_message msg
;
5209 /* explicitly ignore WM_GETICON message */
5210 if (message
== WM_GETICON
) return 0;
5213 msg
.message
= message
;
5214 msg
.flags
= sent
|wparam
|lparam
;
5215 if (defwndproc_counter
) msg
.flags
|= defwinproc
;
5216 msg
.wParam
= wParam
;
5217 msg
.lParam
= lParam
;
5218 msg
.descr
= "static";
5221 defwndproc_counter
++;
5222 ret
= CallWindowProcA(old_static_proc
, hwnd
, message
, wParam
, lParam
);
5223 defwndproc_counter
--;
5228 static void subclass_static(void)
5232 if (!GetClassInfoA(0, "static", &cls
)) assert(0);
5234 old_static_proc
= cls
.lpfnWndProc
;
5236 cls
.hInstance
= GetModuleHandle(0);
5237 cls
.lpfnWndProc
= static_hook_proc
;
5238 cls
.lpszClassName
= "my_static_class";
5239 UnregisterClass(cls
.lpszClassName
, cls
.hInstance
);
5240 if (!RegisterClassA(&cls
)) assert(0);
5243 static void test_static_messages(void)
5245 /* FIXME: make as comprehensive as the button message test */
5250 const struct message
*setfont
;
5252 { SS_LEFT
, DLGC_STATIC
,
5253 WmSetFontStaticSeq
}
5261 for (i
= 0; i
< sizeof(static_ctrl
)/sizeof(static_ctrl
[0]); i
++)
5263 hwnd
= CreateWindowExA(0, "my_static_class", "test", static_ctrl
[i
].style
| WS_POPUP
,
5264 0, 0, 50, 14, 0, 0, 0, NULL
);
5265 ok(hwnd
!= 0, "Failed to create static window\n");
5267 dlg_code
= SendMessageA(hwnd
, WM_GETDLGCODE
, 0, 0);
5268 ok(dlg_code
== static_ctrl
[i
].dlg_code
, "%u: wrong dlg_code %08x\n", i
, dlg_code
);
5270 ShowWindow(hwnd
, SW_SHOW
);
5275 trace("static style %08x\n", static_ctrl
[i
].style
);
5276 SendMessage(hwnd
, WM_SETFONT
, (WPARAM
)GetStockObject(DEFAULT_GUI_FONT
), TRUE
);
5277 ok_sequence(static_ctrl
[i
].setfont
, "WM_SETFONT on a static", FALSE
);
5279 DestroyWindow(hwnd
);
5283 /****************** ComboBox message test *************************/
5284 #define ID_COMBOBOX 0x000f
5286 static const struct message WmKeyDownComboSeq
[] =
5288 { WM_KEYDOWN
, sent
|wparam
|lparam
, VK_DOWN
, 0 },
5289 { WM_COMMAND
, sent
|wparam
|defwinproc
, MAKEWPARAM(1000, LBN_SELCHANGE
) },
5290 { WM_COMMAND
, sent
|wparam
|parent
, MAKEWPARAM(ID_COMBOBOX
, CBN_SELENDOK
) },
5291 { WM_COMMAND
, sent
|wparam
|parent
, MAKEWPARAM(ID_COMBOBOX
, CBN_SELCHANGE
) },
5292 { WM_CTLCOLOREDIT
, sent
|parent
},
5293 { WM_KEYUP
, sent
|wparam
|lparam
, VK_DOWN
, 0 },
5297 static WNDPROC old_combobox_proc
;
5299 static LRESULT CALLBACK
combobox_hook_proc(HWND hwnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
5301 static long defwndproc_counter
= 0;
5303 struct recvd_message msg
;
5305 /* do not log painting messages */
5306 if (message
!= WM_PAINT
&&
5307 message
!= WM_NCPAINT
&&
5308 message
!= WM_SYNCPAINT
&&
5309 message
!= WM_ERASEBKGND
&&
5310 message
!= WM_NCHITTEST
&&
5311 message
!= WM_GETTEXT
&&
5312 message
!= WM_GETICON
&&
5313 message
!= WM_DEVICECHANGE
)
5316 msg
.message
= message
;
5317 msg
.flags
= sent
|wparam
|lparam
;
5318 if (defwndproc_counter
) msg
.flags
|= defwinproc
;
5319 msg
.wParam
= wParam
;
5320 msg
.lParam
= lParam
;
5321 msg
.descr
= "combo";
5325 defwndproc_counter
++;
5326 ret
= CallWindowProcA(old_combobox_proc
, hwnd
, message
, wParam
, lParam
);
5327 defwndproc_counter
--;
5332 static void subclass_combobox(void)
5336 if (!GetClassInfoA(0, "ComboBox", &cls
)) assert(0);
5338 old_combobox_proc
= cls
.lpfnWndProc
;
5340 cls
.hInstance
= GetModuleHandle(0);
5341 cls
.lpfnWndProc
= combobox_hook_proc
;
5342 cls
.lpszClassName
= "my_combobox_class";
5343 UnregisterClass(cls
.lpszClassName
, cls
.hInstance
);
5344 if (!RegisterClassA(&cls
)) assert(0);
5347 static void test_combobox_messages(void)
5352 subclass_combobox();
5354 parent
= CreateWindowExA(0, "TestParentClass", "Test parent", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
5355 100, 100, 200, 200, 0, 0, 0, NULL
);
5356 ok(parent
!= 0, "Failed to create parent window\n");
5359 combo
= CreateWindowEx(0, "my_combobox_class", "test", WS_CHILD
| WS_VISIBLE
| CBS_DROPDOWNLIST
| CBS_HASSTRINGS
,
5360 0, 0, 100, 150, parent
, (HMENU
)ID_COMBOBOX
, 0, NULL
);
5361 ok(combo
!= 0, "Failed to create combobox window\n");
5363 UpdateWindow(combo
);
5365 ret
= SendMessage(combo
, WM_GETDLGCODE
, 0, 0);
5366 ok(ret
== (DLGC_WANTCHARS
| DLGC_WANTARROWS
), "wrong dlg_code %08lx\n", ret
);
5368 ret
= SendMessage(combo
, CB_ADDSTRING
, 0, (LPARAM
)"item 0");
5369 ok(ret
== 0, "expected 0, got %ld\n", ret
);
5370 ret
= SendMessage(combo
, CB_ADDSTRING
, 0, (LPARAM
)"item 1");
5371 ok(ret
== 1, "expected 1, got %ld\n", ret
);
5372 ret
= SendMessage(combo
, CB_ADDSTRING
, 0, (LPARAM
)"item 2");
5373 ok(ret
== 2, "expected 2, got %ld\n", ret
);
5375 SendMessage(combo
, CB_SETCURSEL
, 0, 0);
5379 log_all_parent_messages
++;
5380 SendMessage(combo
, WM_KEYDOWN
, VK_DOWN
, 0);
5381 SendMessage(combo
, WM_KEYUP
, VK_DOWN
, 0);
5382 log_all_parent_messages
--;
5383 ok_sequence(WmKeyDownComboSeq
, "WM_KEYDOWN/VK_DOWN on a ComboBox", FALSE
);
5385 DestroyWindow(combo
);
5386 DestroyWindow(parent
);
5389 /****************** WM_IME_KEYDOWN message test *******************/
5391 static const struct message WmImeKeydownMsgSeq_0
[] =
5393 { WM_IME_KEYDOWN
, wparam
, VK_RETURN
},
5394 { WM_CHAR
, wparam
, 'A' },
5398 static const struct message WmImeKeydownMsgSeq_1
[] =
5400 { WM_KEYDOWN
, optional
|wparam
, VK_RETURN
},
5401 { WM_CHAR
, optional
|wparam
, VK_RETURN
},
5405 static LRESULT WINAPI
wmime_keydown_procA(HWND hwnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
5407 struct recvd_message msg
;
5410 msg
.message
= message
;
5411 msg
.flags
= wparam
|lparam
;
5412 msg
.wParam
= wParam
;
5413 msg
.lParam
= lParam
;
5414 msg
.descr
= "wmime_keydown";
5417 return DefWindowProcA(hwnd
, message
, wParam
, lParam
);
5420 static void register_wmime_keydown_class(void)
5424 ZeroMemory(&cls
, sizeof(WNDCLASSA
));
5425 cls
.lpfnWndProc
= wmime_keydown_procA
;
5426 cls
.hInstance
= GetModuleHandleA(0);
5427 cls
.lpszClassName
= "wmime_keydown_class";
5428 if (!RegisterClassA(&cls
)) assert(0);
5431 static void test_wmime_keydown_message(void)
5436 trace("Message sequences by WM_IME_KEYDOWN\n");
5438 register_wmime_keydown_class();
5439 hwnd
= CreateWindowExA(0, "wmime_keydown_class", NULL
, WS_OVERLAPPEDWINDOW
,
5440 CW_USEDEFAULT
, CW_USEDEFAULT
, 300, 300, 0,
5445 SendMessage(hwnd
, WM_IME_KEYDOWN
, VK_RETURN
, 0x1c0001);
5446 SendMessage(hwnd
, WM_CHAR
, 'A', 1);
5447 ok_sequence(WmImeKeydownMsgSeq_0
, "WM_IME_KEYDOWN 0", FALSE
);
5449 while ( PeekMessage(&msg
, 0, 0, 0, PM_REMOVE
) )
5451 TranslateMessage(&msg
);
5452 DispatchMessage(&msg
);
5454 ok_sequence(WmImeKeydownMsgSeq_1
, "WM_IME_KEYDOWN 1", FALSE
);
5456 DestroyWindow(hwnd
);
5459 /************* painting message test ********************/
5461 void dump_region(HRGN hrgn
)
5464 RGNDATA
*data
= NULL
;
5469 printf( "null region\n" );
5472 if (!(size
= GetRegionData( hrgn
, 0, NULL
))) return;
5473 if (!(data
= HeapAlloc( GetProcessHeap(), 0, size
))) return;
5474 GetRegionData( hrgn
, size
, data
);
5475 printf("%d rects:", data
->rdh
.nCount
);
5476 for (i
= 0, rect
= (RECT
*)data
->Buffer
; i
< data
->rdh
.nCount
; i
++, rect
++)
5477 printf( " (%d,%d)-(%d,%d)", rect
->left
, rect
->top
, rect
->right
, rect
->bottom
);
5479 HeapFree( GetProcessHeap(), 0, data
);
5482 static void check_update_rgn( HWND hwnd
, HRGN hrgn
)
5486 HRGN tmp
= CreateRectRgn( 0, 0, 0, 0 );
5487 HRGN update
= CreateRectRgn( 0, 0, 0, 0 );
5489 ret
= GetUpdateRgn( hwnd
, update
, FALSE
);
5490 ok( ret
!= ERROR
, "GetUpdateRgn failed\n" );
5491 if (ret
== NULLREGION
)
5493 ok( !hrgn
, "Update region shouldn't be empty\n" );
5497 if (CombineRgn( tmp
, hrgn
, update
, RGN_XOR
) != NULLREGION
)
5499 ok( 0, "Regions are different\n" );
5500 if (winetest_debug
> 0)
5502 printf( "Update region: " );
5503 dump_region( update
);
5504 printf( "Wanted region: " );
5505 dump_region( hrgn
);
5509 GetRgnBox( update
, &r1
);
5510 GetUpdateRect( hwnd
, &r2
, FALSE
);
5511 ok( r1
.left
== r2
.left
&& r1
.top
== r2
.top
&& r1
.right
== r2
.right
&& r1
.bottom
== r2
.bottom
,
5512 "Rectangles are different: %d,%d-%d,%d / %d,%d-%d,%d\n",
5513 r1
.left
, r1
.top
, r1
.right
, r1
.bottom
, r2
.left
, r2
.top
, r2
.right
, r2
.bottom
);
5515 DeleteObject( tmp
);
5516 DeleteObject( update
);
5519 static const struct message WmInvalidateRgn
[] = {
5520 { WM_NCPAINT
, sent
},
5521 { WM_GETTEXT
, sent
|defwinproc
|optional
},
5525 static const struct message WmGetUpdateRect
[] = {
5526 { WM_NCPAINT
, sent
},
5527 { WM_GETTEXT
, sent
|defwinproc
|optional
},
5532 static const struct message WmInvalidateFull
[] = {
5533 { WM_NCPAINT
, sent
|wparam
, 1 },
5534 { WM_GETTEXT
, sent
|defwinproc
|optional
},
5538 static const struct message WmInvalidateErase
[] = {
5539 { WM_NCPAINT
, sent
|wparam
, 1 },
5540 { WM_GETTEXT
, sent
|defwinproc
|optional
},
5541 { WM_ERASEBKGND
, sent
},
5545 static const struct message WmInvalidatePaint
[] = {
5547 { WM_NCPAINT
, sent
|wparam
|beginpaint
, 1 },
5548 { WM_GETTEXT
, sent
|beginpaint
|defwinproc
|optional
},
5552 static const struct message WmInvalidateErasePaint
[] = {
5554 { WM_NCPAINT
, sent
|wparam
|beginpaint
, 1 },
5555 { WM_GETTEXT
, sent
|beginpaint
|defwinproc
|optional
},
5556 { WM_ERASEBKGND
, sent
|beginpaint
},
5560 static const struct message WmInvalidateErasePaint2
[] = {
5562 { WM_NCPAINT
, sent
|beginpaint
},
5563 { WM_GETTEXT
, sent
|beginpaint
|defwinproc
|optional
},
5564 { WM_ERASEBKGND
, sent
|beginpaint
|optional
},
5568 static const struct message WmErase
[] = {
5569 { WM_ERASEBKGND
, sent
},
5573 static const struct message WmPaint
[] = {
5578 static const struct message WmParentOnlyPaint
[] = {
5579 { WM_PAINT
, sent
|parent
},
5583 static const struct message WmInvalidateParent
[] = {
5584 { WM_NCPAINT
, sent
|parent
},
5585 { WM_GETTEXT
, sent
|defwinproc
|parent
|optional
},
5586 { WM_ERASEBKGND
, sent
|parent
},
5590 static const struct message WmInvalidateParentChild
[] = {
5591 { WM_NCPAINT
, sent
|parent
},
5592 { WM_GETTEXT
, sent
|defwinproc
|parent
|optional
},
5593 { WM_ERASEBKGND
, sent
|parent
},
5594 { WM_NCPAINT
, sent
},
5595 { WM_GETTEXT
, sent
|defwinproc
|optional
},
5596 { WM_ERASEBKGND
, sent
},
5600 static const struct message WmInvalidateParentChild2
[] = {
5601 { WM_ERASEBKGND
, sent
|parent
},
5602 { WM_NCPAINT
, sent
},
5603 { WM_GETTEXT
, sent
|defwinproc
|optional
},
5604 { WM_ERASEBKGND
, sent
},
5608 static const struct message WmParentPaint
[] = {
5609 { WM_PAINT
, sent
|parent
},
5614 static const struct message WmParentPaintNc
[] = {
5615 { WM_PAINT
, sent
|parent
},
5617 { WM_NCPAINT
, sent
|beginpaint
},
5618 { WM_GETTEXT
, sent
|beginpaint
|defwinproc
|optional
},
5619 { WM_ERASEBKGND
, sent
|beginpaint
|optional
},
5623 static const struct message WmChildPaintNc
[] = {
5625 { WM_NCPAINT
, sent
|beginpaint
},
5626 { WM_GETTEXT
, sent
|beginpaint
|defwinproc
|optional
},
5627 { WM_ERASEBKGND
, sent
|beginpaint
},
5631 static const struct message WmParentErasePaint
[] = {
5632 { WM_PAINT
, sent
|parent
},
5633 { WM_NCPAINT
, sent
|parent
|beginpaint
},
5634 { WM_GETTEXT
, sent
|parent
|beginpaint
|defwinproc
|optional
},
5635 { WM_ERASEBKGND
, sent
|parent
|beginpaint
|optional
},
5637 { WM_NCPAINT
, sent
|beginpaint
},
5638 { WM_GETTEXT
, sent
|beginpaint
|defwinproc
|optional
},
5639 { WM_ERASEBKGND
, sent
|beginpaint
},
5643 static const struct message WmParentOnlyNcPaint
[] = {
5644 { WM_PAINT
, sent
|parent
},
5645 { WM_NCPAINT
, sent
|parent
|beginpaint
},
5646 { WM_GETTEXT
, sent
|parent
|beginpaint
|defwinproc
|optional
},
5650 static const struct message WmSetParentStyle
[] = {
5651 { WM_STYLECHANGING
, sent
|parent
},
5652 { WM_STYLECHANGED
, sent
|parent
},
5656 static void test_paint_messages(void)
5662 HWND hparent
, hchild
;
5663 HRGN hrgn
= CreateRectRgn( 0, 0, 0, 0 );
5664 HRGN hrgn2
= CreateRectRgn( 0, 0, 0, 0 );
5665 HWND hwnd
= CreateWindowExA(0, "TestWindowClass", "Test overlapped", WS_OVERLAPPEDWINDOW
,
5666 100, 100, 200, 200, 0, 0, 0, NULL
);
5667 ok (hwnd
!= 0, "Failed to create overlapped window\n");
5669 ShowWindow( hwnd
, SW_SHOW
);
5670 UpdateWindow( hwnd
);
5674 check_update_rgn( hwnd
, 0 );
5675 SetRectRgn( hrgn
, 10, 10, 20, 20 );
5676 ret
= RedrawWindow( hwnd
, NULL
, hrgn
, RDW_INVALIDATE
);
5677 ok(ret
, "RedrawWindow returned %d instead of TRUE\n", ret
);
5678 check_update_rgn( hwnd
, hrgn
);
5679 SetRectRgn( hrgn2
, 20, 20, 30, 30 );
5680 ret
= RedrawWindow( hwnd
, NULL
, hrgn2
, RDW_INVALIDATE
);
5681 ok(ret
, "RedrawWindow returned %d instead of TRUE\n", ret
);
5682 CombineRgn( hrgn
, hrgn
, hrgn2
, RGN_OR
);
5683 check_update_rgn( hwnd
, hrgn
);
5684 /* validate everything */
5685 ret
= RedrawWindow( hwnd
, NULL
, NULL
, RDW_VALIDATE
);
5686 ok(ret
, "RedrawWindow returned %d instead of TRUE\n", ret
);
5687 check_update_rgn( hwnd
, 0 );
5689 /* test empty region */
5690 SetRectRgn( hrgn
, 10, 10, 10, 15 );
5691 ret
= RedrawWindow( hwnd
, NULL
, hrgn
, RDW_INVALIDATE
);
5692 ok(ret
, "RedrawWindow returned %d instead of TRUE\n", ret
);
5693 check_update_rgn( hwnd
, 0 );
5694 /* test empty rect */
5695 SetRect( &rect
, 10, 10, 10, 15 );
5696 ret
= RedrawWindow( hwnd
, &rect
, NULL
, RDW_INVALIDATE
);
5697 ok(ret
, "RedrawWindow returned %d instead of TRUE\n", ret
);
5698 check_update_rgn( hwnd
, 0 );
5700 /* flush pending messages */
5704 GetClientRect( hwnd
, &rect
);
5705 SetRectRgn( hrgn
, 0, 0, rect
.right
- rect
.left
, rect
.bottom
- rect
.top
);
5706 /* MSDN: if hwnd parameter is NULL, InvalidateRect invalidates and redraws
5707 * all windows and sends WM_ERASEBKGND and WM_NCPAINT.
5709 trace("testing InvalidateRect(0, NULL, FALSE)\n");
5710 SetRectEmpty( &rect
);
5711 ok(InvalidateRect(0, &rect
, FALSE
), "InvalidateRect(0, &rc, FALSE) should fail\n");
5712 check_update_rgn( hwnd
, hrgn
);
5713 ok_sequence( WmInvalidateErase
, "InvalidateErase", FALSE
);
5715 ok_sequence( WmPaint
, "Paint", FALSE
);
5716 RedrawWindow( hwnd
, NULL
, NULL
, RDW_VALIDATE
);
5717 check_update_rgn( hwnd
, 0 );
5719 /* MSDN: if hwnd parameter is NULL, ValidateRect invalidates and redraws
5720 * all windows and sends WM_ERASEBKGND and WM_NCPAINT.
5722 trace("testing ValidateRect(0, NULL)\n");
5723 SetRectEmpty( &rect
);
5724 ok(ValidateRect(0, &rect
), "ValidateRect(0, &rc) should not fail\n");
5725 check_update_rgn( hwnd
, hrgn
);
5726 ok_sequence( WmInvalidateErase
, "InvalidateErase", FALSE
);
5728 ok_sequence( WmPaint
, "Paint", FALSE
);
5729 RedrawWindow( hwnd
, NULL
, NULL
, RDW_VALIDATE
);
5730 check_update_rgn( hwnd
, 0 );
5732 trace("testing InvalidateRgn(0, NULL, FALSE)\n");
5733 SetLastError(0xdeadbeef);
5734 ok(!InvalidateRgn(0, NULL
, FALSE
), "InvalidateRgn(0, NULL, FALSE) should fail\n");
5735 ok(GetLastError() == ERROR_INVALID_WINDOW_HANDLE
|| GetLastError() == 0xdeadbeef,
5736 "wrong error code %d\n", GetLastError());
5737 check_update_rgn( hwnd
, 0 );
5739 ok_sequence( WmEmptySeq
, "WmEmptySeq", FALSE
);
5741 trace("testing ValidateRgn(0, NULL)\n");
5742 SetLastError(0xdeadbeef);
5743 ok(!ValidateRgn(0, NULL
), "ValidateRgn(0, NULL) should fail\n");
5744 ok(GetLastError() == ERROR_INVALID_WINDOW_HANDLE
||
5745 broken( GetLastError() == 0xdeadbeef ) /* win9x */,
5746 "wrong error code %d\n", GetLastError());
5747 check_update_rgn( hwnd
, 0 );
5749 ok_sequence( WmEmptySeq
, "WmEmptySeq", FALSE
);
5751 /* now with frame */
5752 SetRectRgn( hrgn
, -5, -5, 20, 20 );
5754 /* flush pending messages */
5757 RedrawWindow( hwnd
, NULL
, hrgn
, RDW_INVALIDATE
| RDW_FRAME
);
5758 ok_sequence( WmEmptySeq
, "EmptySeq", FALSE
);
5760 SetRectRgn( hrgn
, 0, 0, 20, 20 ); /* GetUpdateRgn clips to client area */
5761 check_update_rgn( hwnd
, hrgn
);
5764 RedrawWindow( hwnd
, NULL
, hrgn
, RDW_INVALIDATE
| RDW_FRAME
| RDW_ERASENOW
);
5765 ok_sequence( WmInvalidateRgn
, "InvalidateRgn", FALSE
);
5768 RedrawWindow( hwnd
, NULL
, NULL
, RDW_INVALIDATE
| RDW_FRAME
| RDW_ERASENOW
);
5769 ok_sequence( WmInvalidateFull
, "InvalidateFull", FALSE
);
5771 GetClientRect( hwnd
, &rect
);
5772 SetRectRgn( hrgn
, rect
.left
, rect
.top
, rect
.right
, rect
.bottom
);
5773 check_update_rgn( hwnd
, hrgn
);
5776 RedrawWindow( hwnd
, NULL
, NULL
, RDW_INVALIDATE
| RDW_FRAME
| RDW_ERASE
| RDW_ERASENOW
);
5777 ok_sequence( WmInvalidateErase
, "InvalidateErase", FALSE
);
5780 RedrawWindow( hwnd
, NULL
, NULL
, RDW_INVALIDATE
| RDW_FRAME
| RDW_ERASENOW
| RDW_UPDATENOW
);
5781 ok_sequence( WmInvalidatePaint
, "InvalidatePaint", FALSE
);
5782 check_update_rgn( hwnd
, 0 );
5785 RedrawWindow( hwnd
, NULL
, NULL
, RDW_INVALIDATE
| RDW_FRAME
| RDW_ERASE
| RDW_UPDATENOW
);
5786 ok_sequence( WmInvalidateErasePaint
, "InvalidateErasePaint", FALSE
);
5787 check_update_rgn( hwnd
, 0 );
5790 SetRectRgn( hrgn
, 0, 0, 100, 100 );
5791 RedrawWindow( hwnd
, NULL
, hrgn
, RDW_INVALIDATE
);
5792 SetRectRgn( hrgn
, 0, 0, 50, 100 );
5793 RedrawWindow( hwnd
, NULL
, hrgn
, RDW_VALIDATE
);
5794 SetRectRgn( hrgn
, 50, 0, 100, 100 );
5795 check_update_rgn( hwnd
, hrgn
);
5796 RedrawWindow( hwnd
, NULL
, hrgn
, RDW_VALIDATE
| RDW_ERASENOW
);
5797 ok_sequence( WmEmptySeq
, "EmptySeq", FALSE
); /* must not generate messages, everything is valid */
5798 check_update_rgn( hwnd
, 0 );
5801 SetRectRgn( hrgn
, 0, 0, 100, 100 );
5802 RedrawWindow( hwnd
, NULL
, hrgn
, RDW_INVALIDATE
| RDW_ERASE
);
5803 SetRectRgn( hrgn
, 0, 0, 100, 50 );
5804 RedrawWindow( hwnd
, NULL
, hrgn
, RDW_VALIDATE
| RDW_ERASENOW
);
5805 ok_sequence( WmErase
, "Erase", FALSE
);
5806 SetRectRgn( hrgn
, 0, 50, 100, 100 );
5807 check_update_rgn( hwnd
, hrgn
);
5810 SetRectRgn( hrgn
, 0, 0, 100, 100 );
5811 RedrawWindow( hwnd
, NULL
, hrgn
, RDW_INVALIDATE
| RDW_ERASE
);
5812 SetRectRgn( hrgn
, 0, 0, 50, 50 );
5813 RedrawWindow( hwnd
, NULL
, hrgn
, RDW_VALIDATE
| RDW_NOERASE
| RDW_UPDATENOW
);
5814 ok_sequence( WmPaint
, "Paint", FALSE
);
5817 SetRectRgn( hrgn
, -4, -4, -2, -2 );
5818 RedrawWindow( hwnd
, NULL
, hrgn
, RDW_INVALIDATE
| RDW_FRAME
);
5819 SetRectRgn( hrgn
, -200, -200, -198, -198 );
5820 RedrawWindow( hwnd
, NULL
, hrgn
, RDW_VALIDATE
| RDW_NOFRAME
| RDW_ERASENOW
);
5821 ok_sequence( WmEmptySeq
, "EmptySeq", FALSE
);
5824 SetRectRgn( hrgn
, -4, -4, -2, -2 );
5825 RedrawWindow( hwnd
, NULL
, hrgn
, RDW_INVALIDATE
| RDW_FRAME
);
5826 SetRectRgn( hrgn
, -4, -4, -3, -3 );
5827 RedrawWindow( hwnd
, NULL
, hrgn
, RDW_VALIDATE
| RDW_NOFRAME
);
5828 SetRectRgn( hrgn
, 0, 0, 1, 1 );
5829 RedrawWindow( hwnd
, NULL
, hrgn
, RDW_INVALIDATE
| RDW_UPDATENOW
);
5830 ok_sequence( WmPaint
, "Paint", FALSE
);
5833 SetRectRgn( hrgn
, -4, -4, -1, -1 );
5834 RedrawWindow( hwnd
, NULL
, hrgn
, RDW_INVALIDATE
| RDW_FRAME
);
5835 RedrawWindow( hwnd
, NULL
, 0, RDW_ERASENOW
);
5836 /* make sure no WM_PAINT was generated */
5838 ok_sequence( WmInvalidateRgn
, "InvalidateRgn", FALSE
);
5841 SetRectRgn( hrgn
, -4, -4, -1, -1 );
5842 RedrawWindow( hwnd
, NULL
, hrgn
, RDW_INVALIDATE
| RDW_FRAME
);
5843 while (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
))
5845 if (msg
.hwnd
== hwnd
&& msg
.message
== WM_PAINT
)
5847 /* GetUpdateRgn must return empty region since only nonclient area is invalidated */
5848 INT ret
= GetUpdateRgn( hwnd
, hrgn
, FALSE
);
5849 ok( ret
== NULLREGION
, "Invalid GetUpdateRgn result %d\n", ret
);
5850 ret
= GetUpdateRect( hwnd
, &rect
, FALSE
);
5851 ok( ret
, "Invalid GetUpdateRect result %d\n", ret
);
5852 /* this will send WM_NCPAINT and validate the non client area */
5853 ret
= GetUpdateRect( hwnd
, &rect
, TRUE
);
5854 ok( !ret
, "Invalid GetUpdateRect result %d\n", ret
);
5856 DispatchMessage( &msg
);
5858 ok_sequence( WmGetUpdateRect
, "GetUpdateRect", FALSE
);
5860 DestroyWindow( hwnd
);
5862 /* now test with a child window */
5864 hparent
= CreateWindowExA(0, "TestParentClass", "Test parent", WS_OVERLAPPEDWINDOW
,
5865 100, 100, 200, 200, 0, 0, 0, NULL
);
5866 ok (hparent
!= 0, "Failed to create parent window\n");
5868 hchild
= CreateWindowExA(0, "TestWindowClass", "Test child", WS_CHILD
| WS_VISIBLE
| WS_BORDER
,
5869 10, 10, 100, 100, hparent
, 0, 0, NULL
);
5870 ok (hchild
!= 0, "Failed to create child window\n");
5872 ShowWindow( hparent
, SW_SHOW
);
5873 UpdateWindow( hparent
);
5874 UpdateWindow( hchild
);
5877 log_all_parent_messages
++;
5879 SetRect( &rect
, 0, 0, 50, 50 );
5880 RedrawWindow( hparent
, &rect
, 0, RDW_INVALIDATE
| RDW_ERASE
| RDW_FRAME
);
5881 RedrawWindow( hparent
, NULL
, 0, RDW_ERASENOW
| RDW_ALLCHILDREN
);
5882 ok_sequence( WmInvalidateParentChild
, "InvalidateParentChild", FALSE
);
5884 RedrawWindow( hparent
, &rect
, 0, RDW_INVALIDATE
| RDW_ERASE
| RDW_FRAME
);
5886 MapWindowPoints( hchild
, hparent
, &pt
, 1 );
5887 SetRectRgn( hrgn
, 0, 0, 50 - pt
.x
, 50 - pt
.y
);
5888 check_update_rgn( hchild
, hrgn
);
5889 SetRectRgn( hrgn
, 0, 0, 50, 50 );
5890 check_update_rgn( hparent
, hrgn
);
5891 RedrawWindow( hparent
, NULL
, 0, RDW_ERASENOW
);
5892 ok_sequence( WmInvalidateParent
, "InvalidateParent", FALSE
);
5893 RedrawWindow( hchild
, NULL
, 0, RDW_ERASENOW
);
5894 ok_sequence( WmEmptySeq
, "EraseNow child", FALSE
);
5897 ok_sequence( WmParentPaintNc
, "WmParentPaintNc", FALSE
);
5899 RedrawWindow( hparent
, &rect
, 0, RDW_INVALIDATE
| RDW_ERASE
| RDW_FRAME
| RDW_ALLCHILDREN
);
5900 RedrawWindow( hparent
, NULL
, 0, RDW_ERASENOW
);
5901 ok_sequence( WmInvalidateParent
, "InvalidateParent2", FALSE
);
5902 RedrawWindow( hchild
, NULL
, 0, RDW_ERASENOW
);
5903 ok_sequence( WmEmptySeq
, "EraseNow child", FALSE
);
5905 RedrawWindow( hparent
, &rect
, 0, RDW_INVALIDATE
| RDW_ERASE
);
5906 RedrawWindow( hparent
, NULL
, 0, RDW_ERASENOW
| RDW_ALLCHILDREN
);
5907 ok_sequence( WmInvalidateParentChild2
, "InvalidateParentChild2", FALSE
);
5909 SetWindowLong( hparent
, GWL_STYLE
, GetWindowLong(hparent
,GWL_STYLE
) | WS_CLIPCHILDREN
);
5911 RedrawWindow( hparent
, &rect
, 0, RDW_INVALIDATE
| RDW_ERASE
| RDW_FRAME
| RDW_ALLCHILDREN
);
5912 RedrawWindow( hparent
, NULL
, 0, RDW_ERASENOW
);
5913 ok_sequence( WmInvalidateParentChild
, "InvalidateParentChild3", FALSE
);
5915 /* flush all paint messages */
5919 /* RDW_UPDATENOW on child with WS_CLIPCHILDREN doesn't change corresponding parent area */
5920 RedrawWindow( hparent
, &rect
, 0, RDW_INVALIDATE
| RDW_ERASE
| RDW_FRAME
| RDW_ALLCHILDREN
);
5921 SetRectRgn( hrgn
, 0, 0, 50, 50 );
5922 check_update_rgn( hparent
, hrgn
);
5923 RedrawWindow( hchild
, NULL
, 0, RDW_UPDATENOW
);
5924 ok_sequence( WmInvalidateErasePaint2
, "WmInvalidateErasePaint2", FALSE
);
5925 SetRectRgn( hrgn
, 0, 0, 50, 50 );
5926 check_update_rgn( hparent
, hrgn
);
5928 /* flush all paint messages */
5930 SetWindowLong( hparent
, GWL_STYLE
, GetWindowLong(hparent
,GWL_STYLE
) & ~WS_CLIPCHILDREN
);
5933 /* RDW_UPDATENOW on child without WS_CLIPCHILDREN will validate corresponding parent area */
5934 RedrawWindow( hparent
, &rect
, 0, RDW_INVALIDATE
| RDW_ERASE
| RDW_FRAME
);
5935 SetRectRgn( hrgn
, 0, 0, 50, 50 );
5936 check_update_rgn( hparent
, hrgn
);
5937 RedrawWindow( hchild
, NULL
, 0, RDW_UPDATENOW
);
5938 ok_sequence( WmInvalidateErasePaint2
, "WmInvalidateErasePaint2", FALSE
);
5939 SetRectRgn( hrgn2
, 10, 10, 50, 50 );
5940 CombineRgn( hrgn
, hrgn
, hrgn2
, RGN_DIFF
);
5941 check_update_rgn( hparent
, hrgn
);
5942 /* flush all paint messages */
5946 /* same as above but parent gets completely validated */
5947 SetRect( &rect
, 20, 20, 30, 30 );
5948 RedrawWindow( hparent
, &rect
, 0, RDW_INVALIDATE
| RDW_ERASE
| RDW_FRAME
);
5949 SetRectRgn( hrgn
, 20, 20, 30, 30 );
5950 check_update_rgn( hparent
, hrgn
);
5951 RedrawWindow( hchild
, NULL
, 0, RDW_UPDATENOW
);
5952 ok_sequence( WmInvalidateErasePaint2
, "WmInvalidateErasePaint2", FALSE
);
5953 check_update_rgn( hparent
, 0 ); /* no update region */
5955 ok_sequence( WmEmptySeq
, "WmEmpty", FALSE
); /* and no paint messages */
5957 /* make sure RDW_VALIDATE on child doesn't have the same effect */
5959 RedrawWindow( hparent
, &rect
, 0, RDW_INVALIDATE
| RDW_ERASE
| RDW_FRAME
);
5960 SetRectRgn( hrgn
, 20, 20, 30, 30 );
5961 check_update_rgn( hparent
, hrgn
);
5962 RedrawWindow( hchild
, NULL
, 0, RDW_VALIDATE
| RDW_NOERASE
);
5963 SetRectRgn( hrgn
, 20, 20, 30, 30 );
5964 check_update_rgn( hparent
, hrgn
);
5966 /* same as above but normal WM_PAINT doesn't validate parent */
5968 SetRect( &rect
, 20, 20, 30, 30 );
5969 RedrawWindow( hparent
, &rect
, 0, RDW_INVALIDATE
| RDW_ERASE
| RDW_FRAME
);
5970 SetRectRgn( hrgn
, 20, 20, 30, 30 );
5971 check_update_rgn( hparent
, hrgn
);
5972 /* no WM_PAINT in child while parent still pending */
5973 while (PeekMessage( &msg
, hchild
, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
5974 ok_sequence( WmEmptySeq
, "No WM_PAINT", FALSE
);
5975 while (PeekMessage( &msg
, hparent
, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
5976 ok_sequence( WmParentErasePaint
, "WmParentErasePaint", FALSE
);
5979 RedrawWindow( hparent
, &rect
, 0, RDW_INVALIDATE
| RDW_ERASE
| RDW_FRAME
);
5980 /* no WM_PAINT in child while parent still pending */
5981 while (PeekMessage( &msg
, hchild
, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
5982 ok_sequence( WmEmptySeq
, "No WM_PAINT", FALSE
);
5983 RedrawWindow( hparent
, &rect
, 0, RDW_VALIDATE
| RDW_NOERASE
| RDW_NOCHILDREN
);
5984 /* now that parent is valid child should get WM_PAINT */
5985 while (PeekMessage( &msg
, hchild
, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
5986 ok_sequence( WmInvalidateErasePaint2
, "WmInvalidateErasePaint2", FALSE
);
5987 while (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
5988 ok_sequence( WmEmptySeq
, "No other message", FALSE
);
5990 /* same thing with WS_CLIPCHILDREN in parent */
5992 SetWindowLong( hparent
, GWL_STYLE
, GetWindowLong(hparent
,GWL_STYLE
) | WS_CLIPCHILDREN
);
5993 ok_sequence( WmSetParentStyle
, "WmSetParentStyle", FALSE
);
5994 /* changing style invalidates non client area, but we need to invalidate something else to see it */
5995 RedrawWindow( hparent
, &rect
, 0, RDW_UPDATENOW
);
5996 ok_sequence( WmEmptySeq
, "No message", FALSE
);
5997 RedrawWindow( hparent
, &rect
, 0, RDW_INVALIDATE
| RDW_UPDATENOW
);
5998 ok_sequence( WmParentOnlyNcPaint
, "WmParentOnlyNcPaint", FALSE
);
6001 RedrawWindow( hparent
, &rect
, 0, RDW_INVALIDATE
| RDW_ERASE
| RDW_ALLCHILDREN
);
6002 SetRectRgn( hrgn
, 20, 20, 30, 30 );
6003 check_update_rgn( hparent
, hrgn
);
6004 /* no WM_PAINT in child while parent still pending */
6005 while (PeekMessage( &msg
, hchild
, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
6006 ok_sequence( WmEmptySeq
, "No WM_PAINT", FALSE
);
6007 /* WM_PAINT in parent first */
6008 while (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
6009 ok_sequence( WmParentPaintNc
, "WmParentPaintNc2", FALSE
);
6011 /* no RDW_ERASE in parent still causes RDW_ERASE and RDW_FRAME in child */
6013 SetRect( &rect
, 0, 0, 30, 30 );
6014 RedrawWindow( hparent
, &rect
, 0, RDW_INVALIDATE
| RDW_ALLCHILDREN
);
6015 SetRectRgn( hrgn
, 0, 0, 30, 30 );
6016 check_update_rgn( hparent
, hrgn
);
6018 ok_sequence( WmParentPaintNc
, "WmParentPaintNc3", FALSE
);
6020 /* validate doesn't cause RDW_NOERASE or RDW_NOFRAME in child */
6022 SetRect( &rect
, -10, 0, 30, 30 );
6023 RedrawWindow( hchild
, &rect
, 0, RDW_INVALIDATE
| RDW_FRAME
| RDW_ERASE
);
6024 SetRect( &rect
, 0, 0, 20, 20 );
6025 RedrawWindow( hparent
, &rect
, 0, RDW_VALIDATE
| RDW_ALLCHILDREN
);
6026 RedrawWindow( hparent
, NULL
, 0, RDW_UPDATENOW
);
6027 ok_sequence( WmChildPaintNc
, "WmChildPaintNc", FALSE
);
6029 /* validate doesn't cause RDW_NOERASE or RDW_NOFRAME in child */
6031 SetRect( &rect
, -10, 0, 30, 30 );
6032 RedrawWindow( hchild
, &rect
, 0, RDW_INVALIDATE
| RDW_FRAME
| RDW_ERASE
);
6033 SetRect( &rect
, 0, 0, 100, 100 );
6034 RedrawWindow( hparent
, &rect
, 0, RDW_VALIDATE
| RDW_ALLCHILDREN
);
6035 RedrawWindow( hparent
, NULL
, 0, RDW_UPDATENOW
);
6036 ok_sequence( WmEmptySeq
, "WmChildPaintNc2", FALSE
);
6037 RedrawWindow( hparent
, NULL
, 0, RDW_ERASENOW
);
6038 ok_sequence( WmEmptySeq
, "WmChildPaintNc3", FALSE
);
6040 /* test RDW_INTERNALPAINT behavior */
6043 RedrawWindow( hparent
, NULL
, 0, RDW_INTERNALPAINT
| RDW_NOCHILDREN
);
6045 ok_sequence( WmParentOnlyPaint
, "WmParentOnlyPaint", FALSE
);
6047 RedrawWindow( hparent
, NULL
, 0, RDW_INTERNALPAINT
| RDW_ALLCHILDREN
);
6049 ok_sequence( WmParentPaint
, "WmParentPaint", FALSE
);
6051 RedrawWindow( hparent
, NULL
, 0, RDW_INTERNALPAINT
);
6053 ok_sequence( WmParentOnlyPaint
, "WmParentOnlyPaint", FALSE
);
6055 assert( GetWindowLong(hparent
, GWL_STYLE
) & WS_CLIPCHILDREN
);
6056 UpdateWindow( hparent
);
6059 trace("testing SWP_FRAMECHANGED on parent with WS_CLIPCHILDREN\n");
6060 RedrawWindow( hchild
, NULL
, 0, RDW_INVALIDATE
| RDW_ERASE
| RDW_FRAME
);
6061 SetWindowPos( hparent
, 0, 0, 0, 0, 0, SWP_NOSIZE
| SWP_NOMOVE
|
6062 SWP_NOACTIVATE
| SWP_NOZORDER
| SWP_FRAMECHANGED
);
6064 ok_sequence(WmSWP_FrameChanged_clip
, "SetWindowPos:FrameChanged_clip", FALSE
);
6066 UpdateWindow( hparent
);
6069 trace("testing SWP_FRAMECHANGED|SWP_DEFERERASE on parent with WS_CLIPCHILDREN\n");
6070 RedrawWindow( hchild
, NULL
, 0, RDW_INVALIDATE
| RDW_ERASE
| RDW_FRAME
);
6071 SetWindowPos( hparent
, 0, 0, 0, 0, 0, SWP_NOSIZE
| SWP_NOMOVE
| SWP_DEFERERASE
|
6072 SWP_NOACTIVATE
| SWP_NOZORDER
| SWP_FRAMECHANGED
);
6074 ok_sequence(WmSWP_FrameChangedDeferErase
, "SetWindowPos:FrameChangedDeferErase", FALSE
);
6076 SetWindowLong( hparent
, GWL_STYLE
, GetWindowLong(hparent
,GWL_STYLE
) & ~WS_CLIPCHILDREN
);
6077 ok_sequence( WmSetParentStyle
, "WmSetParentStyle", FALSE
);
6078 RedrawWindow( hparent
, NULL
, 0, RDW_INTERNALPAINT
);
6080 ok_sequence( WmParentPaint
, "WmParentPaint", FALSE
);
6082 assert( !(GetWindowLong(hparent
, GWL_STYLE
) & WS_CLIPCHILDREN
) );
6083 UpdateWindow( hparent
);
6086 trace("testing SWP_FRAMECHANGED on parent without WS_CLIPCHILDREN\n");
6087 RedrawWindow( hchild
, NULL
, 0, RDW_INVALIDATE
| RDW_ERASE
| RDW_FRAME
);
6088 SetWindowPos( hparent
, 0, 0, 0, 0, 0, SWP_NOSIZE
| SWP_NOMOVE
|
6089 SWP_NOACTIVATE
| SWP_NOZORDER
| SWP_FRAMECHANGED
);
6091 ok_sequence(WmSWP_FrameChanged_noclip
, "SetWindowPos:FrameChanged_noclip", FALSE
);
6093 UpdateWindow( hparent
);
6096 trace("testing SWP_FRAMECHANGED|SWP_DEFERERASE on parent without WS_CLIPCHILDREN\n");
6097 RedrawWindow( hchild
, NULL
, 0, RDW_INVALIDATE
| RDW_ERASE
| RDW_FRAME
);
6098 SetWindowPos( hparent
, 0, 0, 0, 0, 0, SWP_NOSIZE
| SWP_NOMOVE
| SWP_DEFERERASE
|
6099 SWP_NOACTIVATE
| SWP_NOZORDER
| SWP_FRAMECHANGED
);
6101 ok_sequence(WmSWP_FrameChangedDeferErase
, "SetWindowPos:FrameChangedDeferErase", FALSE
);
6103 ok(GetWindowLong( hparent
, GWL_STYLE
) & WS_VISIBLE
, "parent should be visible\n");
6104 ok(GetWindowLong( hchild
, GWL_STYLE
) & WS_VISIBLE
, "child should be visible\n");
6106 UpdateWindow( hparent
);
6109 trace("testing SetWindowPos(-10000, -10000) on child\n");
6110 SetWindowPos( hchild
, 0, -10000, -10000, 0, 0, SWP_NOSIZE
| SWP_NOACTIVATE
| SWP_NOZORDER
);
6111 check_update_rgn( hchild
, 0 );
6114 #if 0 /* this one doesn't pass under Wine yet */
6115 UpdateWindow( hparent
);
6118 trace("testing ShowWindow(SW_MINIMIZE) on child\n");
6119 ShowWindow( hchild
, SW_MINIMIZE
);
6120 check_update_rgn( hchild
, 0 );
6124 UpdateWindow( hparent
);
6127 trace("testing SetWindowPos(-10000, -10000) on parent\n");
6128 SetWindowPos( hparent
, 0, -10000, -10000, 0, 0, SWP_NOSIZE
| SWP_NOACTIVATE
| SWP_NOZORDER
);
6129 check_update_rgn( hparent
, 0 );
6132 log_all_parent_messages
--;
6133 DestroyWindow( hparent
);
6134 ok(!IsWindow(hchild
), "child must be destroyed with its parent\n");
6136 /* tests for moving windows off-screen (needs simple WS_POPUP windows) */
6138 hparent
= CreateWindowExA(0, "TestParentClass", "Test parent", WS_POPUP
| WS_VISIBLE
,
6139 100, 100, 200, 200, 0, 0, 0, NULL
);
6140 ok (hparent
!= 0, "Failed to create parent window\n");
6142 hchild
= CreateWindowExA(0, "TestWindowClass", "Test child", WS_CHILD
| WS_VISIBLE
,
6143 10, 10, 100, 100, hparent
, 0, 0, NULL
);
6144 ok (hchild
!= 0, "Failed to create child window\n");
6146 ShowWindow( hparent
, SW_SHOW
);
6147 UpdateWindow( hparent
);
6148 UpdateWindow( hchild
);
6152 /* moving child outside of parent boundaries changes update region */
6153 SetRect( &rect
, 0, 0, 40, 40 );
6154 RedrawWindow( hchild
, &rect
, 0, RDW_INVALIDATE
| RDW_ERASE
);
6155 SetRectRgn( hrgn
, 0, 0, 40, 40 );
6156 check_update_rgn( hchild
, hrgn
);
6157 MoveWindow( hchild
, -10, 10, 100, 100, FALSE
);
6158 SetRectRgn( hrgn
, 10, 0, 40, 40 );
6159 check_update_rgn( hchild
, hrgn
);
6160 MoveWindow( hchild
, -10, -10, 100, 100, FALSE
);
6161 SetRectRgn( hrgn
, 10, 10, 40, 40 );
6162 check_update_rgn( hchild
, hrgn
);
6164 /* moving parent off-screen does too */
6165 SetRect( &rect
, 0, 0, 100, 100 );
6166 RedrawWindow( hparent
, &rect
, 0, RDW_INVALIDATE
| RDW_ERASE
| RDW_NOCHILDREN
);
6167 SetRectRgn( hrgn
, 0, 0, 100, 100 );
6168 check_update_rgn( hparent
, hrgn
);
6169 SetRectRgn( hrgn
, 10, 10, 40, 40 );
6170 check_update_rgn( hchild
, hrgn
);
6171 MoveWindow( hparent
, -20, -20, 200, 200, FALSE
);
6172 SetRectRgn( hrgn
, 20, 20, 100, 100 );
6173 check_update_rgn( hparent
, hrgn
);
6174 SetRectRgn( hrgn
, 30, 30, 40, 40 );
6175 check_update_rgn( hchild
, hrgn
);
6177 /* invalidated region is cropped by the parent rects */
6178 SetRect( &rect
, 0, 0, 50, 50 );
6179 RedrawWindow( hchild
, &rect
, 0, RDW_INVALIDATE
| RDW_ERASE
);
6180 SetRectRgn( hrgn
, 30, 30, 50, 50 );
6181 check_update_rgn( hchild
, hrgn
);
6183 DestroyWindow( hparent
);
6184 ok(!IsWindow(hchild
), "child must be destroyed with its parent\n");
6187 DeleteObject( hrgn
);
6188 DeleteObject( hrgn2
);
6197 static DWORD WINAPI
thread_proc(void *param
)
6200 struct wnd_event
*wnd_event
= (struct wnd_event
*)param
;
6202 wnd_event
->hwnd
= CreateWindowExA(0, "TestWindowClass", "window caption text", WS_OVERLAPPEDWINDOW
,
6203 100, 100, 200, 200, 0, 0, 0, NULL
);
6204 ok(wnd_event
->hwnd
!= 0, "Failed to create overlapped window\n");
6206 SetEvent(wnd_event
->event
);
6208 while (GetMessage(&msg
, 0, 0, 0))
6210 TranslateMessage(&msg
);
6211 DispatchMessage(&msg
);
6214 ok(IsWindow(wnd_event
->hwnd
), "window should still exist\n");
6219 static void test_interthread_messages(void)
6226 int len
, expected_len
;
6227 struct wnd_event wnd_event
;
6230 wnd_event
.event
= CreateEventW(NULL
, 0, 0, NULL
);
6231 if (!wnd_event
.event
)
6233 trace("skipping interthread message test under win9x\n");
6237 hThread
= CreateThread(NULL
, 0, thread_proc
, &wnd_event
, 0, &tid
);
6238 ok(hThread
!= NULL
, "CreateThread failed, error %d\n", GetLastError());
6240 ok(WaitForSingleObject(wnd_event
.event
, INFINITE
) == WAIT_OBJECT_0
, "WaitForSingleObject failed\n");
6242 CloseHandle(wnd_event
.event
);
6244 SetLastError(0xdeadbeef);
6245 ok(!DestroyWindow(wnd_event
.hwnd
), "DestroyWindow succeded\n");
6246 ok(GetLastError() == ERROR_ACCESS_DENIED
|| GetLastError() == 0xdeadbeef,
6247 "wrong error code %d\n", GetLastError());
6249 proc
= (WNDPROC
)GetWindowLongPtrA(wnd_event
.hwnd
, GWLP_WNDPROC
);
6250 ok(proc
!= NULL
, "GetWindowLongPtrA(GWLP_WNDPROC) error %d\n", GetLastError());
6252 expected_len
= lstrlenA("window caption text");
6253 memset(buf
, 0, sizeof(buf
));
6254 SetLastError(0xdeadbeef);
6255 len
= CallWindowProcA(proc
, wnd_event
.hwnd
, WM_GETTEXT
, sizeof(buf
), (LPARAM
)buf
);
6256 ok(len
== expected_len
, "CallWindowProcA(WM_GETTEXT) error %d, len %d, expected len %d\n", GetLastError(), len
, expected_len
);
6257 ok(!lstrcmpA(buf
, "window caption text"), "window text mismatch\n");
6259 msg
.hwnd
= wnd_event
.hwnd
;
6260 msg
.message
= WM_GETTEXT
;
6261 msg
.wParam
= sizeof(buf
);
6262 msg
.lParam
= (LPARAM
)buf
;
6263 memset(buf
, 0, sizeof(buf
));
6264 SetLastError(0xdeadbeef);
6265 len
= DispatchMessageA(&msg
);
6266 ok((!len
&& GetLastError() == ERROR_MESSAGE_SYNC_ONLY
) || broken(len
), /* nt4 */
6267 "DispatchMessageA(WM_GETTEXT) succeded on another thread window: ret %d, error %d\n", len
, GetLastError());
6269 /* the following test causes an exception in user.exe under win9x */
6270 msg
.hwnd
= wnd_event
.hwnd
;
6271 msg
.message
= WM_TIMER
;
6273 msg
.lParam
= GetWindowLongPtrA(wnd_event
.hwnd
, GWLP_WNDPROC
);
6274 SetLastError(0xdeadbeef);
6275 len
= DispatchMessageA(&msg
);
6276 ok(!len
&& GetLastError() == 0xdeadbeef,
6277 "DispatchMessageA(WM_TIMER) failed on another thread window: ret %d, error %d\n", len
, GetLastError());
6279 ret
= PostMessageA(wnd_event
.hwnd
, WM_QUIT
, 0, 0);
6280 ok( ret
, "PostMessageA(WM_QUIT) error %d\n", GetLastError());
6282 ok(WaitForSingleObject(hThread
, INFINITE
) == WAIT_OBJECT_0
, "WaitForSingleObject failed\n");
6283 CloseHandle(hThread
);
6285 ok(!IsWindow(wnd_event
.hwnd
), "window should be destroyed on thread exit\n");
6289 static const struct message WmVkN
[] = {
6290 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, 'N', 1 }, /* XP */
6291 { WM_KEYDOWN
, wparam
|lparam
, 'N', 1 },
6292 { WM_KEYDOWN
, sent
|wparam
|lparam
, 'N', 1 },
6293 { WM_CHAR
, wparam
|lparam
, 'n', 1 },
6294 { WM_COMMAND
, sent
|wparam
|lparam
, MAKEWPARAM(1002,1), 0 },
6295 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, 'N', 0xc0000001 }, /* XP */
6296 { WM_KEYUP
, wparam
|lparam
, 'N', 0xc0000001 },
6297 { WM_KEYUP
, sent
|wparam
|lparam
, 'N', 0xc0000001 },
6300 static const struct message WmShiftVkN
[] = {
6301 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_SHIFT
, 1 }, /* XP */
6302 { WM_KEYDOWN
, wparam
|lparam
, VK_SHIFT
, 1 },
6303 { WM_KEYDOWN
, sent
|wparam
|lparam
, VK_SHIFT
, 1 },
6304 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, 'N', 1 }, /* XP */
6305 { WM_KEYDOWN
, wparam
|lparam
, 'N', 1 },
6306 { WM_KEYDOWN
, sent
|wparam
|lparam
, 'N', 1 },
6307 { WM_CHAR
, wparam
|lparam
, 'N', 1 },
6308 { WM_COMMAND
, sent
|wparam
|lparam
, MAKEWPARAM(1001,1), 0 },
6309 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, 'N', 0xc0000001 }, /* XP */
6310 { WM_KEYUP
, wparam
|lparam
, 'N', 0xc0000001 },
6311 { WM_KEYUP
, sent
|wparam
|lparam
, 'N', 0xc0000001 },
6312 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_SHIFT
, 0xc0000001 }, /* XP */
6313 { WM_KEYUP
, wparam
|lparam
, VK_SHIFT
, 0xc0000001 },
6314 { WM_KEYUP
, sent
|wparam
|lparam
, VK_SHIFT
, 0xc0000001 },
6317 static const struct message WmCtrlVkN
[] = {
6318 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_CONTROL
, 1 }, /* XP */
6319 { WM_KEYDOWN
, wparam
|lparam
, VK_CONTROL
, 1 },
6320 { WM_KEYDOWN
, sent
|wparam
|lparam
, VK_CONTROL
, 1 },
6321 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, 'N', 1 }, /* XP */
6322 { WM_KEYDOWN
, wparam
|lparam
, 'N', 1 },
6323 { WM_KEYDOWN
, sent
|wparam
|lparam
, 'N', 1 },
6324 { WM_CHAR
, wparam
|lparam
, 0x000e, 1 },
6325 { WM_COMMAND
, sent
|wparam
|lparam
, MAKEWPARAM(1000,1), 0 },
6326 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, 'N', 0xc0000001 }, /* XP */
6327 { WM_KEYUP
, wparam
|lparam
, 'N', 0xc0000001 },
6328 { WM_KEYUP
, sent
|wparam
|lparam
, 'N', 0xc0000001 },
6329 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_CONTROL
, 0xc0000001 }, /* XP */
6330 { WM_KEYUP
, wparam
|lparam
, VK_CONTROL
, 0xc0000001 },
6331 { WM_KEYUP
, sent
|wparam
|lparam
, VK_CONTROL
, 0xc0000001 },
6334 static const struct message WmCtrlVkN_2
[] = {
6335 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_CONTROL
, 1 }, /* XP */
6336 { WM_KEYDOWN
, wparam
|lparam
, VK_CONTROL
, 1 },
6337 { WM_KEYDOWN
, sent
|wparam
|lparam
, VK_CONTROL
, 1 },
6338 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, 'N', 1 }, /* XP */
6339 { WM_KEYDOWN
, wparam
|lparam
, 'N', 1 },
6340 { WM_COMMAND
, sent
|wparam
|lparam
, MAKEWPARAM(1000,1), 0 },
6341 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, 'N', 0xc0000001 }, /* XP */
6342 { WM_KEYUP
, wparam
|lparam
, 'N', 0xc0000001 },
6343 { WM_KEYUP
, sent
|wparam
|lparam
, 'N', 0xc0000001 },
6344 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_CONTROL
, 0xc0000001 }, /* XP */
6345 { WM_KEYUP
, wparam
|lparam
, VK_CONTROL
, 0xc0000001 },
6346 { WM_KEYUP
, sent
|wparam
|lparam
, VK_CONTROL
, 0xc0000001 },
6349 static const struct message WmAltVkN
[] = {
6350 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_MENU
, 0x20000001 }, /* XP */
6351 { WM_SYSKEYDOWN
, wparam
|lparam
, VK_MENU
, 0x20000001 },
6352 { WM_SYSKEYDOWN
, sent
|wparam
|lparam
, VK_MENU
, 0x20000001 },
6353 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, 'N', 0x20000001 }, /* XP */
6354 { WM_SYSKEYDOWN
, wparam
|lparam
, 'N', 0x20000001 },
6355 { WM_SYSKEYDOWN
, sent
|wparam
|lparam
, 'N', 0x20000001 },
6356 { WM_SYSCHAR
, wparam
|lparam
, 'n', 0x20000001 },
6357 { WM_SYSCHAR
, sent
|wparam
|lparam
, 'n', 0x20000001 },
6358 { WM_SYSCOMMAND
, sent
|defwinproc
|wparam
|lparam
, SC_KEYMENU
, 'n' },
6359 { HCBT_SYSCOMMAND
, hook
},
6360 { WM_ENTERMENULOOP
, sent
|defwinproc
|wparam
|lparam
, 0, 0 },
6361 { EVENT_SYSTEM_CAPTURESTART
, winevent_hook
|wparam
|lparam
, 0, 0 },
6362 { 0x00AE, sent
|defwinproc
|optional
}, /* XP */
6363 { WM_GETTEXT
, sent
|defwinproc
|optional
}, /* XP */
6364 { WM_INITMENU
, sent
|defwinproc
},
6365 { EVENT_SYSTEM_MENUSTART
, winevent_hook
|wparam
|lparam
, OBJID_SYSMENU
, 0 },
6366 { WM_MENUCHAR
, sent
|defwinproc
|wparam
, MAKEWPARAM('n',MF_SYSMENU
) },
6367 { EVENT_SYSTEM_CAPTUREEND
, winevent_hook
|wparam
|lparam
, 0, 0 },
6368 { WM_CAPTURECHANGED
, sent
|defwinproc
},
6369 { WM_MENUSELECT
, sent
|defwinproc
|wparam
, MAKEWPARAM(0,0xffff) },
6370 { EVENT_SYSTEM_MENUEND
, winevent_hook
|wparam
|lparam
, OBJID_SYSMENU
, 0 },
6371 { WM_EXITMENULOOP
, sent
|defwinproc
},
6372 { WM_MENUSELECT
, sent
|defwinproc
|wparam
|optional
, MAKEWPARAM(0,0xffff) }, /* Win95 bug */
6373 { WM_EXITMENULOOP
, sent
|defwinproc
|optional
}, /* Win95 bug */
6374 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, 'N', 0xe0000001 }, /* XP */
6375 { WM_SYSKEYUP
, wparam
|lparam
, 'N', 0xe0000001 },
6376 { WM_SYSKEYUP
, sent
|wparam
|lparam
, 'N', 0xe0000001 },
6377 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_MENU
, 0xc0000001 }, /* XP */
6378 { WM_KEYUP
, wparam
|lparam
, VK_MENU
, 0xc0000001 },
6379 { WM_KEYUP
, sent
|wparam
|lparam
, VK_MENU
, 0xc0000001 },
6382 static const struct message WmAltVkN_2
[] = {
6383 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_MENU
, 0x20000001 }, /* XP */
6384 { WM_SYSKEYDOWN
, wparam
|lparam
, VK_MENU
, 0x20000001 },
6385 { WM_SYSKEYDOWN
, sent
|wparam
|lparam
, VK_MENU
, 0x20000001 },
6386 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, 'N', 0x20000001 }, /* XP */
6387 { WM_SYSKEYDOWN
, wparam
|lparam
, 'N', 0x20000001 },
6388 { WM_COMMAND
, sent
|wparam
|lparam
, MAKEWPARAM(1003,1), 0 },
6389 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, 'N', 0xe0000001 }, /* XP */
6390 { WM_SYSKEYUP
, wparam
|lparam
, 'N', 0xe0000001 },
6391 { WM_SYSKEYUP
, sent
|wparam
|lparam
, 'N', 0xe0000001 },
6392 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_MENU
, 0xc0000001 }, /* XP */
6393 { WM_KEYUP
, wparam
|lparam
, VK_MENU
, 0xc0000001 },
6394 { WM_KEYUP
, sent
|wparam
|lparam
, VK_MENU
, 0xc0000001 },
6397 static const struct message WmCtrlAltVkN
[] = {
6398 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_CONTROL
, 1 }, /* XP */
6399 { WM_KEYDOWN
, wparam
|lparam
, VK_CONTROL
, 1 },
6400 { WM_KEYDOWN
, sent
|wparam
|lparam
, VK_CONTROL
, 1 },
6401 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_MENU
, 0x20000001 }, /* XP */
6402 { WM_KEYDOWN
, wparam
|lparam
, VK_MENU
, 0x20000001 },
6403 { WM_KEYDOWN
, sent
|wparam
|lparam
, VK_MENU
, 0x20000001 },
6404 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, 'N', 0x20000001 }, /* XP */
6405 { WM_KEYDOWN
, wparam
|lparam
, 'N', 0x20000001 },
6406 { WM_KEYDOWN
, sent
|wparam
|lparam
, 'N', 0x20000001 },
6407 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, 'N', 0xe0000001 }, /* XP */
6408 { WM_KEYUP
, wparam
|lparam
, 'N', 0xe0000001 },
6409 { WM_KEYUP
, sent
|wparam
|lparam
, 'N', 0xe0000001 },
6410 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_MENU
, 0xc0000001 }, /* XP */
6411 { WM_KEYUP
, wparam
|lparam
, VK_MENU
, 0xc0000001 },
6412 { WM_KEYUP
, sent
|wparam
|lparam
, VK_MENU
, 0xc0000001 },
6413 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_CONTROL
, 0xc0000001 }, /* XP */
6414 { WM_KEYUP
, wparam
|lparam
, VK_CONTROL
, 0xc0000001 },
6415 { WM_KEYUP
, sent
|wparam
|lparam
, VK_CONTROL
, 0xc0000001 },
6418 static const struct message WmCtrlShiftVkN
[] = {
6419 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_CONTROL
, 1 }, /* XP */
6420 { WM_KEYDOWN
, wparam
|lparam
, VK_CONTROL
, 1 },
6421 { WM_KEYDOWN
, sent
|wparam
|lparam
, VK_CONTROL
, 1 },
6422 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_SHIFT
, 1 }, /* XP */
6423 { WM_KEYDOWN
, wparam
|lparam
, VK_SHIFT
, 1 },
6424 { WM_KEYDOWN
, sent
|wparam
|lparam
, VK_SHIFT
, 1 },
6425 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, 'N', 1 }, /* XP */
6426 { WM_KEYDOWN
, wparam
|lparam
, 'N', 1 },
6427 { WM_COMMAND
, sent
|wparam
|lparam
, MAKEWPARAM(1004,1), 0 },
6428 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, 'N', 0xc0000001 }, /* XP */
6429 { WM_KEYUP
, wparam
|lparam
, 'N', 0xc0000001 },
6430 { WM_KEYUP
, sent
|wparam
|lparam
, 'N', 0xc0000001 },
6431 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_SHIFT
, 0xc0000001 }, /* XP */
6432 { WM_KEYUP
, wparam
|lparam
, VK_SHIFT
, 0xc0000001 },
6433 { WM_KEYUP
, sent
|wparam
|lparam
, VK_SHIFT
, 0xc0000001 },
6434 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_CONTROL
, 0xc0000001 }, /* XP */
6435 { WM_KEYUP
, wparam
|lparam
, VK_CONTROL
, 0xc0000001 },
6436 { WM_KEYUP
, sent
|wparam
|lparam
, VK_CONTROL
, 0xc0000001 },
6439 static const struct message WmCtrlAltShiftVkN
[] = {
6440 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_CONTROL
, 1 }, /* XP */
6441 { WM_KEYDOWN
, wparam
|lparam
, VK_CONTROL
, 1 },
6442 { WM_KEYDOWN
, sent
|wparam
|lparam
, VK_CONTROL
, 1 },
6443 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_MENU
, 0x20000001 }, /* XP */
6444 { WM_KEYDOWN
, wparam
|lparam
, VK_MENU
, 0x20000001 },
6445 { WM_KEYDOWN
, sent
|wparam
|lparam
, VK_MENU
, 0x20000001 },
6446 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_SHIFT
, 0x20000001 }, /* XP */
6447 { WM_KEYDOWN
, wparam
|lparam
, VK_SHIFT
, 0x20000001 },
6448 { WM_KEYDOWN
, sent
|wparam
|lparam
, VK_SHIFT
, 0x20000001 },
6449 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, 'N', 0x20000001 }, /* XP */
6450 { WM_KEYDOWN
, wparam
|lparam
, 'N', 0x20000001 },
6451 { WM_COMMAND
, sent
|wparam
|lparam
, MAKEWPARAM(1005,1), 0 },
6452 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, 'N', 0xe0000001 }, /* XP */
6453 { WM_KEYUP
, wparam
|lparam
, 'N', 0xe0000001 },
6454 { WM_KEYUP
, sent
|wparam
|lparam
, 'N', 0xe0000001 },
6455 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_SHIFT
, 0xe0000001 }, /* XP */
6456 { WM_KEYUP
, wparam
|lparam
, VK_SHIFT
, 0xe0000001 },
6457 { WM_KEYUP
, sent
|wparam
|lparam
, VK_SHIFT
, 0xe0000001 },
6458 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_MENU
, 0xc0000001 }, /* XP */
6459 { WM_KEYUP
, wparam
|lparam
, VK_MENU
, 0xc0000001 },
6460 { WM_KEYUP
, sent
|wparam
|lparam
, VK_MENU
, 0xc0000001 },
6461 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_CONTROL
, 0xc0000001 }, /* XP */
6462 { WM_KEYUP
, wparam
|lparam
, VK_CONTROL
, 0xc0000001 },
6463 { WM_KEYUP
, sent
|wparam
|lparam
, VK_CONTROL
, 0xc0000001 },
6466 static const struct message WmAltPressRelease
[] = {
6467 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_MENU
, 0x20000001 }, /* XP */
6468 { WM_SYSKEYDOWN
, wparam
|lparam
, VK_MENU
, 0x20000001 },
6469 { WM_SYSKEYDOWN
, sent
|wparam
|lparam
, VK_MENU
, 0x20000001 },
6470 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_MENU
, 0xc0000001 }, /* XP */
6471 { WM_SYSKEYUP
, wparam
|lparam
, VK_MENU
, 0xc0000001 },
6472 { WM_SYSKEYUP
, sent
|wparam
|lparam
, VK_MENU
, 0xc0000001 },
6473 { WM_SYSCOMMAND
, sent
|defwinproc
|wparam
|lparam
, SC_KEYMENU
, 0 },
6474 { HCBT_SYSCOMMAND
, hook
},
6475 { WM_ENTERMENULOOP
, sent
|defwinproc
|wparam
|lparam
, 0, 0 },
6476 { EVENT_SYSTEM_CAPTURESTART
, winevent_hook
|wparam
|lparam
, 0, 0 },
6477 { WM_INITMENU
, sent
|defwinproc
},
6478 { EVENT_SYSTEM_MENUSTART
, winevent_hook
|wparam
|lparam
, OBJID_SYSMENU
, 0 },
6479 { WM_MENUSELECT
, sent
|defwinproc
|wparam
, MAKEWPARAM(0,MF_SYSMENU
|MF_POPUP
|MF_HILITE
) },
6480 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_SYSMENU
, 1 },
6482 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_MENU
, 0x30000001 }, /* XP */
6484 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_SYSMENU
, 0 },
6485 { EVENT_SYSTEM_CAPTUREEND
, winevent_hook
|wparam
|lparam
, 0, 0, },
6486 { WM_CAPTURECHANGED
, sent
|defwinproc
},
6487 { WM_MENUSELECT
, sent
|defwinproc
|wparam
|optional
, MAKEWPARAM(0,0xffff) },
6488 { EVENT_SYSTEM_MENUEND
, winevent_hook
|wparam
|lparam
, OBJID_SYSMENU
, 0 },
6489 { WM_EXITMENULOOP
, sent
|defwinproc
},
6490 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_MENU
, 0xc0000001 }, /* XP */
6491 { WM_SYSKEYUP
, wparam
|lparam
, VK_MENU
, 0xc0000001 },
6492 { WM_SYSKEYUP
, sent
|wparam
|lparam
, VK_MENU
, 0xc0000001 },
6495 static const struct message WmAltMouseButton
[] = {
6496 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_MENU
, 0x20000001 }, /* XP */
6497 { WM_SYSKEYDOWN
, wparam
|lparam
, VK_MENU
, 0x20000001 },
6498 { WM_SYSKEYDOWN
, sent
|wparam
|lparam
, VK_MENU
, 0x20000001 },
6499 { WM_MOUSEMOVE
, wparam
|optional
, 0, 0 },
6500 { WM_MOUSEMOVE
, sent
|wparam
|optional
, 0, 0 },
6501 { WM_LBUTTONDOWN
, wparam
, MK_LBUTTON
, 0 },
6502 { WM_LBUTTONDOWN
, sent
|wparam
, MK_LBUTTON
, 0 },
6503 { WM_LBUTTONUP
, wparam
, 0, 0 },
6504 { WM_LBUTTONUP
, sent
|wparam
, 0, 0 },
6505 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_MENU
, 0xc0000001 }, /* XP */
6506 { WM_SYSKEYUP
, wparam
|lparam
, VK_MENU
, 0xc0000001 },
6507 { WM_SYSKEYUP
, sent
|wparam
|lparam
, VK_MENU
, 0xc0000001 },
6510 static const struct message WmF1Seq
[] = {
6511 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_F1
, 1 }, /* XP */
6512 { WM_KEYDOWN
, wparam
|lparam
, VK_F1
, 1 },
6513 { WM_KEYDOWN
, sent
|wparam
|lparam
, VK_F1
, 0x00000001 },
6514 { WM_KEYF1
, wparam
|lparam
, 0, 0 },
6515 { WM_KEYF1
, sent
|wparam
|lparam
, 0, 0 },
6516 { WM_HELP
, sent
|defwinproc
},
6517 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_F1
, 0xc0000001 }, /* XP */
6518 { WM_KEYUP
, wparam
|lparam
, VK_F1
, 0xc0000001 },
6519 { WM_KEYUP
, sent
|wparam
|lparam
, VK_F1
, 0xc0000001 },
6522 static const struct message WmVkAppsSeq
[] = {
6523 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_APPS
, 1 }, /* XP */
6524 { WM_KEYDOWN
, wparam
|lparam
, VK_APPS
, 1 },
6525 { WM_KEYDOWN
, sent
|wparam
|lparam
, VK_APPS
, 0x00000001 },
6526 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_APPS
, 0xc0000001 }, /* XP */
6527 { WM_KEYUP
, wparam
|lparam
, VK_APPS
, 0xc0000001 },
6528 { WM_KEYUP
, sent
|wparam
|lparam
, VK_APPS
, 0xc0000001 },
6529 { WM_CONTEXTMENU
, lparam
, /*hwnd*/0, (LPARAM
)-1 },
6530 { WM_CONTEXTMENU
, sent
|lparam
, /*hwnd*/0, (LPARAM
)-1 },
6534 static void pump_msg_loop(HWND hwnd
, HACCEL hAccel
)
6538 while (PeekMessageA(&msg
, 0, 0, 0, PM_REMOVE
))
6540 struct recvd_message log_msg
;
6542 /* ignore some unwanted messages */
6543 if (msg
.message
== WM_MOUSEMOVE
||
6544 msg
.message
== WM_GETICON
||
6545 msg
.message
== WM_TIMER
||
6546 msg
.message
== WM_DEVICECHANGE
)
6549 log_msg
.hwnd
= msg
.hwnd
;
6550 log_msg
.message
= msg
.message
;
6551 log_msg
.flags
= wparam
|lparam
;
6552 log_msg
.wParam
= msg
.wParam
;
6553 log_msg
.lParam
= msg
.lParam
;
6554 log_msg
.descr
= "accel";
6555 add_message(&log_msg
);
6557 if (!hAccel
|| !TranslateAccelerator(hwnd
, hAccel
, &msg
))
6559 TranslateMessage(&msg
);
6560 DispatchMessage(&msg
);
6565 static void test_accelerators(void)
6570 HWND hwnd
= CreateWindowExA(0, "TestWindowClass", NULL
, WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
6571 100, 100, 200, 200, 0, 0, 0, NULL
);
6580 ok(GetFocus() == hwnd
, "wrong focus window %p\n", GetFocus());
6582 state
= GetKeyState(VK_SHIFT
);
6583 ok(!(state
& 0x8000), "wrong Shift state %04x\n", state
);
6584 state
= GetKeyState(VK_CAPITAL
);
6585 ok(state
== 0, "wrong CapsLock state %04x\n", state
);
6587 hAccel
= LoadAccelerators(GetModuleHandleA(0), MAKEINTRESOURCE(1));
6588 assert(hAccel
!= 0);
6591 pump_msg_loop(hwnd
, 0);
6594 trace("testing VK_N press/release\n");
6596 keybd_event('N', 0, 0, 0);
6597 keybd_event('N', 0, KEYEVENTF_KEYUP
, 0);
6598 pump_msg_loop(hwnd
, hAccel
);
6599 ok_sequence(WmVkN
, "VK_N press/release", FALSE
);
6601 trace("testing Shift+VK_N press/release\n");
6603 keybd_event(VK_SHIFT
, 0, 0, 0);
6604 keybd_event('N', 0, 0, 0);
6605 keybd_event('N', 0, KEYEVENTF_KEYUP
, 0);
6606 keybd_event(VK_SHIFT
, 0, KEYEVENTF_KEYUP
, 0);
6607 pump_msg_loop(hwnd
, hAccel
);
6608 ok_sequence(WmShiftVkN
, "Shift+VK_N press/release", FALSE
);
6610 trace("testing Ctrl+VK_N press/release\n");
6612 keybd_event(VK_CONTROL
, 0, 0, 0);
6613 keybd_event('N', 0, 0, 0);
6614 keybd_event('N', 0, KEYEVENTF_KEYUP
, 0);
6615 keybd_event(VK_CONTROL
, 0, KEYEVENTF_KEYUP
, 0);
6616 pump_msg_loop(hwnd
, hAccel
);
6617 ok_sequence(WmCtrlVkN
, "Ctrl+VK_N press/release", FALSE
);
6619 trace("testing Alt+VK_N press/release\n");
6621 keybd_event(VK_MENU
, 0, 0, 0);
6622 keybd_event('N', 0, 0, 0);
6623 keybd_event('N', 0, KEYEVENTF_KEYUP
, 0);
6624 keybd_event(VK_MENU
, 0, KEYEVENTF_KEYUP
, 0);
6625 pump_msg_loop(hwnd
, hAccel
);
6626 ok_sequence(WmAltVkN
, "Alt+VK_N press/release", FALSE
);
6628 trace("testing Ctrl+Alt+VK_N press/release 1\n");
6630 keybd_event(VK_CONTROL
, 0, 0, 0);
6631 keybd_event(VK_MENU
, 0, 0, 0);
6632 keybd_event('N', 0, 0, 0);
6633 keybd_event('N', 0, KEYEVENTF_KEYUP
, 0);
6634 keybd_event(VK_MENU
, 0, KEYEVENTF_KEYUP
, 0);
6635 keybd_event(VK_CONTROL
, 0, KEYEVENTF_KEYUP
, 0);
6636 pump_msg_loop(hwnd
, hAccel
);
6637 ok_sequence(WmCtrlAltVkN
, "Ctrl+Alt+VK_N press/release 1", FALSE
);
6639 ret
= DestroyAcceleratorTable(hAccel
);
6640 ok( ret
, "DestroyAcceleratorTable error %d\n", GetLastError());
6642 hAccel
= LoadAccelerators(GetModuleHandleA(0), MAKEINTRESOURCE(2));
6643 assert(hAccel
!= 0);
6645 trace("testing VK_N press/release\n");
6647 keybd_event('N', 0, 0, 0);
6648 keybd_event('N', 0, KEYEVENTF_KEYUP
, 0);
6649 pump_msg_loop(hwnd
, hAccel
);
6650 ok_sequence(WmVkN
, "VK_N press/release", FALSE
);
6652 trace("testing Shift+VK_N press/release\n");
6654 keybd_event(VK_SHIFT
, 0, 0, 0);
6655 keybd_event('N', 0, 0, 0);
6656 keybd_event('N', 0, KEYEVENTF_KEYUP
, 0);
6657 keybd_event(VK_SHIFT
, 0, KEYEVENTF_KEYUP
, 0);
6658 pump_msg_loop(hwnd
, hAccel
);
6659 ok_sequence(WmShiftVkN
, "Shift+VK_N press/release", FALSE
);
6661 trace("testing Ctrl+VK_N press/release 2\n");
6663 keybd_event(VK_CONTROL
, 0, 0, 0);
6664 keybd_event('N', 0, 0, 0);
6665 keybd_event('N', 0, KEYEVENTF_KEYUP
, 0);
6666 keybd_event(VK_CONTROL
, 0, KEYEVENTF_KEYUP
, 0);
6667 pump_msg_loop(hwnd
, hAccel
);
6668 ok_sequence(WmCtrlVkN_2
, "Ctrl+VK_N press/release 2", FALSE
);
6670 trace("testing Alt+VK_N press/release 2\n");
6672 keybd_event(VK_MENU
, 0, 0, 0);
6673 keybd_event('N', 0, 0, 0);
6674 keybd_event('N', 0, KEYEVENTF_KEYUP
, 0);
6675 keybd_event(VK_MENU
, 0, KEYEVENTF_KEYUP
, 0);
6676 pump_msg_loop(hwnd
, hAccel
);
6677 ok_sequence(WmAltVkN_2
, "Alt+VK_N press/release 2", FALSE
);
6679 trace("testing Ctrl+Alt+VK_N press/release 2\n");
6681 keybd_event(VK_CONTROL
, 0, 0, 0);
6682 keybd_event(VK_MENU
, 0, 0, 0);
6683 keybd_event('N', 0, 0, 0);
6684 keybd_event('N', 0, KEYEVENTF_KEYUP
, 0);
6685 keybd_event(VK_MENU
, 0, KEYEVENTF_KEYUP
, 0);
6686 keybd_event(VK_CONTROL
, 0, KEYEVENTF_KEYUP
, 0);
6687 pump_msg_loop(hwnd
, hAccel
);
6688 ok_sequence(WmCtrlAltVkN
, "Ctrl+Alt+VK_N press/release 2", FALSE
);
6690 trace("testing Ctrl+Shift+VK_N press/release\n");
6692 keybd_event(VK_CONTROL
, 0, 0, 0);
6693 keybd_event(VK_SHIFT
, 0, 0, 0);
6694 keybd_event('N', 0, 0, 0);
6695 keybd_event('N', 0, KEYEVENTF_KEYUP
, 0);
6696 keybd_event(VK_SHIFT
, 0, KEYEVENTF_KEYUP
, 0);
6697 keybd_event(VK_CONTROL
, 0, KEYEVENTF_KEYUP
, 0);
6698 pump_msg_loop(hwnd
, hAccel
);
6699 ok_sequence(WmCtrlShiftVkN
, "Ctrl+Shift+VK_N press/release", FALSE
);
6701 trace("testing Ctrl+Alt+Shift+VK_N press/release\n");
6703 keybd_event(VK_CONTROL
, 0, 0, 0);
6704 keybd_event(VK_MENU
, 0, 0, 0);
6705 keybd_event(VK_SHIFT
, 0, 0, 0);
6706 keybd_event('N', 0, 0, 0);
6707 keybd_event('N', 0, KEYEVENTF_KEYUP
, 0);
6708 keybd_event(VK_SHIFT
, 0, KEYEVENTF_KEYUP
, 0);
6709 keybd_event(VK_MENU
, 0, KEYEVENTF_KEYUP
, 0);
6710 keybd_event(VK_CONTROL
, 0, KEYEVENTF_KEYUP
, 0);
6711 pump_msg_loop(hwnd
, hAccel
);
6712 ok_sequence(WmCtrlAltShiftVkN
, "Ctrl+Alt+Shift+VK_N press/release", FALSE
);
6714 ret
= DestroyAcceleratorTable(hAccel
);
6715 ok( ret
, "DestroyAcceleratorTable error %d\n", GetLastError());
6717 trace("testing Alt press/release\n");
6719 keybd_event(VK_MENU
, 0, 0, 0);
6720 keybd_event(VK_MENU
, 0, KEYEVENTF_KEYUP
, 0);
6721 keybd_event(VK_MENU
, 0, 0, 0);
6722 keybd_event(VK_MENU
, 0, KEYEVENTF_KEYUP
, 0);
6723 pump_msg_loop(hwnd
, 0);
6724 /* this test doesn't pass in Wine for managed windows */
6725 ok_sequence(WmAltPressRelease
, "Alt press/release", TRUE
);
6727 trace("testing Alt+MouseButton press/release\n");
6728 /* first, move mouse pointer inside of the window client area */
6729 GetClientRect(hwnd
, &rc
);
6730 MapWindowPoints(hwnd
, 0, (LPPOINT
)&rc
, 2);
6731 rc
.left
+= (rc
.right
- rc
.left
)/2;
6732 rc
.top
+= (rc
.bottom
- rc
.top
)/2;
6733 SetCursorPos(rc
.left
, rc
.top
);
6737 keybd_event(VK_MENU
, 0, 0, 0);
6738 mouse_event(MOUSEEVENTF_LEFTDOWN
, 0, 0, 0, 0);
6739 mouse_event(MOUSEEVENTF_LEFTUP
, 0, 0, 0, 0);
6740 keybd_event(VK_MENU
, 0, KEYEVENTF_KEYUP
, 0);
6741 pump_msg_loop(hwnd
, 0);
6742 ok_sequence(WmAltMouseButton
, "Alt+MouseButton press/release", FALSE
);
6744 trace("testing VK_F1 press/release\n");
6745 keybd_event(VK_F1
, 0, 0, 0);
6746 keybd_event(VK_F1
, 0, KEYEVENTF_KEYUP
, 0);
6747 pump_msg_loop(hwnd
, 0);
6748 ok_sequence(WmF1Seq
, "F1 press/release", FALSE
);
6750 trace("testing VK_APPS press/release\n");
6751 keybd_event(VK_APPS
, 0, 0, 0);
6752 keybd_event(VK_APPS
, 0, KEYEVENTF_KEYUP
, 0);
6753 pump_msg_loop(hwnd
, 0);
6754 ok_sequence(WmVkAppsSeq
, "VK_APPS press/release", FALSE
);
6756 DestroyWindow(hwnd
);
6759 /************* window procedures ********************/
6761 static LRESULT
MsgCheckProc (BOOL unicode
, HWND hwnd
, UINT message
,
6762 WPARAM wParam
, LPARAM lParam
)
6764 static long defwndproc_counter
= 0;
6765 static long beginpaint_counter
= 0;
6767 struct recvd_message msg
;
6769 /* explicitly ignore WM_GETICON message */
6770 if (message
== WM_GETICON
) return 0;
6772 /* ignore registered messages */
6773 if (message
>= 0xc000) return 0;
6779 LONG style
= GetWindowLongA(hwnd
, GWL_STYLE
);
6780 ok((BOOL
)wParam
== !(style
& WS_DISABLED
),
6781 "wrong WS_DISABLED state: %ld != %d\n", wParam
, !(style
& WS_DISABLED
));
6785 case WM_CAPTURECHANGED
:
6786 if (test_DestroyWindow_flag
)
6788 DWORD style
= GetWindowLongA(hwnd
, GWL_STYLE
);
6789 if (style
& WS_CHILD
)
6790 lParam
= GetWindowLongPtrA(hwnd
, GWLP_ID
);
6791 else if (style
& WS_POPUP
)
6792 lParam
= WND_POPUP_ID
;
6794 lParam
= WND_PARENT_ID
;
6802 ok(!GetWindow(hwnd
, GW_CHILD
), "children should be unlinked at this point\n");
6803 capture
= GetCapture();
6806 ok(capture
== hwnd
, "capture should NOT be released at this point (capture %p)\n", capture
);
6807 trace("current capture %p, releasing...\n", capture
);
6814 ok(pGetAncestor(hwnd
, GA_PARENT
) != 0, "parent should NOT be unlinked at this point\n");
6815 if (test_DestroyWindow_flag
)
6817 DWORD style
= GetWindowLongA(hwnd
, GWL_STYLE
);
6818 if (style
& WS_CHILD
)
6819 lParam
= GetWindowLongPtrA(hwnd
, GWLP_ID
);
6820 else if (style
& WS_POPUP
)
6821 lParam
= WND_POPUP_ID
;
6823 lParam
= WND_PARENT_ID
;
6827 /* test_accelerators() depends on this */
6833 case WM_MOUSEACTIVATE
:
6834 case WM_NCMOUSEMOVE
:
6836 case WM_DEVICECHANGE
:
6841 msg
.message
= message
;
6842 msg
.flags
= sent
|wparam
|lparam
;
6843 if (defwndproc_counter
) msg
.flags
|= defwinproc
;
6844 if (beginpaint_counter
) msg
.flags
|= beginpaint
;
6845 msg
.wParam
= wParam
;
6846 msg
.lParam
= lParam
;
6847 msg
.descr
= "MsgCheckProc";
6850 if (message
== WM_GETMINMAXINFO
&& (GetWindowLongA(hwnd
, GWL_STYLE
) & WS_CHILD
))
6852 HWND parent
= GetParent(hwnd
);
6854 MINMAXINFO
*minmax
= (MINMAXINFO
*)lParam
;
6856 GetClientRect(parent
, &rc
);
6857 trace("parent %p client size = (%d x %d)\n", parent
, rc
.right
, rc
.bottom
);
6858 trace("Reserved=%d,%d MaxSize=%d,%d MaxPos=%d,%d MinTrack=%d,%d MaxTrack=%d,%d\n",
6859 minmax
->ptReserved
.x
, minmax
->ptReserved
.y
,
6860 minmax
->ptMaxSize
.x
, minmax
->ptMaxSize
.y
,
6861 minmax
->ptMaxPosition
.x
, minmax
->ptMaxPosition
.y
,
6862 minmax
->ptMinTrackSize
.x
, minmax
->ptMinTrackSize
.y
,
6863 minmax
->ptMaxTrackSize
.x
, minmax
->ptMaxTrackSize
.y
);
6865 ok(minmax
->ptMaxSize
.x
== rc
.right
, "default width of maximized child %d != %d\n",
6866 minmax
->ptMaxSize
.x
, rc
.right
);
6867 ok(minmax
->ptMaxSize
.y
== rc
.bottom
, "default height of maximized child %d != %d\n",
6868 minmax
->ptMaxSize
.y
, rc
.bottom
);
6871 if (message
== WM_PAINT
)
6874 beginpaint_counter
++;
6875 BeginPaint( hwnd
, &ps
);
6876 beginpaint_counter
--;
6877 EndPaint( hwnd
, &ps
);
6881 defwndproc_counter
++;
6882 ret
= unicode
? DefWindowProcW(hwnd
, message
, wParam
, lParam
)
6883 : DefWindowProcA(hwnd
, message
, wParam
, lParam
);
6884 defwndproc_counter
--;
6889 static LRESULT WINAPI
MsgCheckProcA(HWND hwnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
6891 return MsgCheckProc (FALSE
, hwnd
, message
, wParam
, lParam
);
6894 static LRESULT WINAPI
MsgCheckProcW(HWND hwnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
6896 return MsgCheckProc (TRUE
, hwnd
, message
, wParam
, lParam
);
6899 static LRESULT WINAPI
PopupMsgCheckProcA(HWND hwnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
6901 static long defwndproc_counter
= 0;
6903 struct recvd_message msg
;
6908 /* explicitly ignore WM_GETICON message */
6910 case WM_QUERYENDSESSION
:
6912 lParam
&= ~0x01; /* Vista adds a 0x01 flag */
6917 msg
.message
= message
;
6918 msg
.flags
= sent
|wparam
|lparam
;
6919 if (defwndproc_counter
) msg
.flags
|= defwinproc
;
6920 msg
.wParam
= wParam
;
6921 msg
.lParam
= lParam
;
6922 msg
.descr
= "popup";
6925 if (message
== WM_CREATE
)
6927 DWORD style
= GetWindowLongA(hwnd
, GWL_STYLE
) | WS_VISIBLE
;
6928 SetWindowLongA(hwnd
, GWL_STYLE
, style
);
6931 defwndproc_counter
++;
6932 ret
= DefWindowProcA(hwnd
, message
, wParam
, lParam
);
6933 defwndproc_counter
--;
6938 static LRESULT WINAPI
ParentMsgCheckProcA(HWND hwnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
6940 static long defwndproc_counter
= 0;
6941 static long beginpaint_counter
= 0;
6943 struct recvd_message msg
;
6945 /* explicitly ignore WM_GETICON message */
6946 if (message
== WM_GETICON
) return 0;
6948 /* ignore registered messages */
6949 if (message
>= 0xc000) return 0;
6951 if (log_all_parent_messages
||
6952 message
== WM_PARENTNOTIFY
|| message
== WM_CANCELMODE
||
6953 message
== WM_SETFOCUS
|| message
== WM_KILLFOCUS
||
6954 message
== WM_ENABLE
|| message
== WM_ENTERIDLE
||
6955 message
== WM_DRAWITEM
||
6956 message
== WM_IME_SETCONTEXT
)
6970 INT ret
= GetClipBox((HDC
)wParam
, &rc
);
6972 trace("WM_ERASEBKGND: GetClipBox()=%d, (%d,%d-%d,%d)\n",
6973 ret
, rc
.left
, rc
.top
, rc
.right
, rc
.bottom
);
6979 msg
.message
= message
;
6980 msg
.flags
= sent
|parent
|wparam
|lparam
;
6981 if (defwndproc_counter
) msg
.flags
|= defwinproc
;
6982 if (beginpaint_counter
) msg
.flags
|= beginpaint
;
6983 msg
.wParam
= wParam
;
6984 msg
.lParam
= lParam
;
6985 msg
.descr
= "parent";
6989 if (message
== WM_PAINT
)
6992 beginpaint_counter
++;
6993 BeginPaint( hwnd
, &ps
);
6994 beginpaint_counter
--;
6995 EndPaint( hwnd
, &ps
);
6999 defwndproc_counter
++;
7000 ret
= DefWindowProcA(hwnd
, message
, wParam
, lParam
);
7001 defwndproc_counter
--;
7006 static LRESULT WINAPI
TestDlgProcA(HWND hwnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
7008 static long defwndproc_counter
= 0;
7010 struct recvd_message msg
;
7012 /* explicitly ignore WM_GETICON message */
7013 if (message
== WM_GETICON
) return 0;
7017 DefDlgProcA(hwnd
, DM_SETDEFID
, 1, 0);
7018 ret
= DefDlgProcA(hwnd
, DM_GETDEFID
, 0, 0);
7019 if (after_end_dialog
)
7020 ok( ret
== 0, "DM_GETDEFID should return 0 after EndDialog, got %lx\n", ret
);
7022 ok(HIWORD(ret
) == DC_HASDEFID
, "DM_GETDEFID should return DC_HASDEFID, got %lx\n", ret
);
7026 msg
.message
= message
;
7027 msg
.flags
= sent
|wparam
|lparam
;
7028 if (defwndproc_counter
) msg
.flags
|= defwinproc
;
7029 msg
.wParam
= wParam
;
7030 msg
.lParam
= lParam
;
7031 msg
.descr
= "dialog";
7034 defwndproc_counter
++;
7035 ret
= DefDlgProcA(hwnd
, message
, wParam
, lParam
);
7036 defwndproc_counter
--;
7041 static LRESULT WINAPI
ShowWindowProcA(HWND hwnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
7043 static long defwndproc_counter
= 0;
7045 struct recvd_message msg
;
7047 /* log only specific messages we are interested in */
7050 #if 0 /* probably log these as well */
7058 case WM_GETMINMAXINFO
:
7059 case WM_WINDOWPOSCHANGING
:
7060 case WM_WINDOWPOSCHANGED
:
7063 default: /* ignore */
7064 /*trace("showwindow: %p, %04x, %08x, %08lx\n", hwnd, message, wParam, lParam);*/
7065 return DefWindowProcA(hwnd
, message
, wParam
, lParam
);
7069 msg
.message
= message
;
7070 msg
.flags
= sent
|wparam
|lparam
;
7071 if (defwndproc_counter
) msg
.flags
|= defwinproc
;
7072 msg
.wParam
= wParam
;
7073 msg
.lParam
= lParam
;
7077 defwndproc_counter
++;
7078 ret
= DefWindowProcA(hwnd
, message
, wParam
, lParam
);
7079 defwndproc_counter
--;
7084 static LRESULT WINAPI
PaintLoopProcA(HWND hWnd
, UINT msg
, WPARAM wParam
, LPARAM lParam
)
7088 case WM_CREATE
: return 0;
7097 if (PeekMessageA(&msg2
, 0, 0, 0, 1))
7099 TranslateMessage(&msg2
);
7100 DispatchMessage(&msg2
);
7104 else ok(broken(1), "infinite loop\n");
7106 paint_loop_done
= 1;
7107 return DefWindowProcA(hWnd
,msg
,wParam
,lParam
);
7110 return DefWindowProcA(hWnd
,msg
,wParam
,lParam
);
7113 static BOOL
RegisterWindowClasses(void)
7119 cls
.lpfnWndProc
= MsgCheckProcA
;
7122 cls
.hInstance
= GetModuleHandleA(0);
7124 cls
.hCursor
= LoadCursorA(0, IDC_ARROW
);
7125 cls
.hbrBackground
= GetStockObject(WHITE_BRUSH
);
7126 cls
.lpszMenuName
= NULL
;
7127 cls
.lpszClassName
= "TestWindowClass";
7128 if(!RegisterClassA(&cls
)) return FALSE
;
7130 cls
.lpfnWndProc
= ShowWindowProcA
;
7131 cls
.lpszClassName
= "ShowWindowClass";
7132 if(!RegisterClassA(&cls
)) return FALSE
;
7134 cls
.lpfnWndProc
= PopupMsgCheckProcA
;
7135 cls
.lpszClassName
= "TestPopupClass";
7136 if(!RegisterClassA(&cls
)) return FALSE
;
7138 cls
.lpfnWndProc
= ParentMsgCheckProcA
;
7139 cls
.lpszClassName
= "TestParentClass";
7140 if(!RegisterClassA(&cls
)) return FALSE
;
7142 cls
.lpfnWndProc
= DefWindowProcA
;
7143 cls
.lpszClassName
= "SimpleWindowClass";
7144 if(!RegisterClassA(&cls
)) return FALSE
;
7146 cls
.lpfnWndProc
= PaintLoopProcA
;
7147 cls
.lpszClassName
= "PaintLoopWindowClass";
7148 if(!RegisterClassA(&cls
)) return FALSE
;
7150 cls
.style
= CS_NOCLOSE
;
7151 cls
.lpszClassName
= "NoCloseWindowClass";
7152 if(!RegisterClassA(&cls
)) return FALSE
;
7154 ok(GetClassInfoA(0, "#32770", &cls
), "GetClassInfo failed\n");
7156 cls
.hInstance
= GetModuleHandleA(0);
7157 cls
.hbrBackground
= 0;
7158 cls
.lpfnWndProc
= TestDlgProcA
;
7159 cls
.lpszClassName
= "TestDialogClass";
7160 if(!RegisterClassA(&cls
)) return FALSE
;
7163 clsW
.lpfnWndProc
= MsgCheckProcW
;
7164 clsW
.cbClsExtra
= 0;
7165 clsW
.cbWndExtra
= 0;
7166 clsW
.hInstance
= GetModuleHandleW(0);
7168 clsW
.hCursor
= LoadCursorW(0, (LPWSTR
)IDC_ARROW
);
7169 clsW
.hbrBackground
= GetStockObject(WHITE_BRUSH
);
7170 clsW
.lpszMenuName
= NULL
;
7171 clsW
.lpszClassName
= testWindowClassW
;
7172 RegisterClassW(&clsW
); /* ignore error, this fails on Win9x */
7177 static BOOL
is_our_logged_class(HWND hwnd
)
7181 if (GetClassNameA(hwnd
, buf
, sizeof(buf
)))
7183 if (!lstrcmpiA(buf
, "TestWindowClass") ||
7184 !lstrcmpiA(buf
, "ShowWindowClass") ||
7185 !lstrcmpiA(buf
, "TestParentClass") ||
7186 !lstrcmpiA(buf
, "TestPopupClass") ||
7187 !lstrcmpiA(buf
, "SimpleWindowClass") ||
7188 !lstrcmpiA(buf
, "TestDialogClass") ||
7189 !lstrcmpiA(buf
, "MDI_frame_class") ||
7190 !lstrcmpiA(buf
, "MDI_client_class") ||
7191 !lstrcmpiA(buf
, "MDI_child_class") ||
7192 !lstrcmpiA(buf
, "my_button_class") ||
7193 !lstrcmpiA(buf
, "my_edit_class") ||
7194 !lstrcmpiA(buf
, "static") ||
7195 !lstrcmpiA(buf
, "ListBox") ||
7196 !lstrcmpiA(buf
, "ComboBox") ||
7197 !lstrcmpiA(buf
, "MyDialogClass") ||
7198 !lstrcmpiA(buf
, "#32770") ||
7199 !lstrcmpiA(buf
, "#32768"))
7205 static LRESULT CALLBACK
cbt_hook_proc(int nCode
, WPARAM wParam
, LPARAM lParam
)
7209 ok(cbt_hook_thread_id
== GetCurrentThreadId(), "we didn't ask for events from other threads\n");
7211 if (nCode
== HCBT_CLICKSKIPPED
)
7213 /* ignore this event, XP sends it a lot when switching focus between windows */
7214 return CallNextHookEx(hCBT_hook
, nCode
, wParam
, lParam
);
7217 if (nCode
== HCBT_SYSCOMMAND
|| nCode
== HCBT_KEYSKIPPED
)
7219 struct recvd_message msg
;
7222 msg
.message
= nCode
;
7223 msg
.flags
= hook
|wparam
|lparam
;
7224 msg
.wParam
= wParam
;
7225 msg
.lParam
= lParam
;
7229 return CallNextHookEx(hCBT_hook
, nCode
, wParam
, lParam
);
7232 if (nCode
== HCBT_DESTROYWND
)
7234 if (test_DestroyWindow_flag
)
7236 DWORD style
= GetWindowLongA((HWND
)wParam
, GWL_STYLE
);
7237 if (style
& WS_CHILD
)
7238 lParam
= GetWindowLongPtrA((HWND
)wParam
, GWLP_ID
);
7239 else if (style
& WS_POPUP
)
7240 lParam
= WND_POPUP_ID
;
7242 lParam
= WND_PARENT_ID
;
7246 /* Log also SetFocus(0) calls */
7247 hwnd
= wParam
? (HWND
)wParam
: (HWND
)lParam
;
7249 if (is_our_logged_class(hwnd
))
7251 struct recvd_message msg
;
7254 msg
.message
= nCode
;
7255 msg
.flags
= hook
|wparam
|lparam
;
7256 msg
.wParam
= wParam
;
7257 msg
.lParam
= lParam
;
7261 return CallNextHookEx(hCBT_hook
, nCode
, wParam
, lParam
);
7264 static void CALLBACK
win_event_proc(HWINEVENTHOOK hevent
,
7272 ok(thread_id
== GetCurrentThreadId(), "we didn't ask for events from other threads\n");
7274 /* ignore mouse cursor events */
7275 if (object_id
== OBJID_CURSOR
) return;
7277 if (!hwnd
|| is_our_logged_class(hwnd
))
7279 struct recvd_message msg
;
7282 msg
.message
= event
;
7283 msg
.flags
= winevent_hook
|wparam
|lparam
;
7284 msg
.wParam
= object_id
;
7285 msg
.lParam
= child_id
;
7291 static const WCHAR wszUnicode
[] = {'U','n','i','c','o','d','e',0};
7292 static const WCHAR wszAnsi
[] = {'U',0};
7294 static LRESULT CALLBACK
MsgConversionProcW(HWND hwnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
7298 case CB_FINDSTRINGEXACT
:
7299 trace("String: %p\n", (LPCWSTR
)lParam
);
7300 if (!lstrcmpW((LPCWSTR
)lParam
, wszUnicode
))
7302 if (!lstrcmpW((LPCWSTR
)lParam
, wszAnsi
))
7306 return DefWindowProcW(hwnd
, uMsg
, wParam
, lParam
);
7309 static const struct message WmGetTextLengthAfromW
[] = {
7310 { WM_GETTEXTLENGTH
, sent
},
7311 { WM_GETTEXT
, sent
|optional
},
7315 static const WCHAR dummy_window_text
[] = {'d','u','m','m','y',' ','t','e','x','t',0};
7317 /* dummy window proc for WM_GETTEXTLENGTH test */
7318 static LRESULT CALLBACK
get_text_len_proc( HWND hwnd
, UINT msg
, WPARAM wp
, LPARAM lp
)
7322 case WM_GETTEXTLENGTH
:
7323 return lstrlenW(dummy_window_text
) + 37; /* some random length */
7325 lstrcpynW( (LPWSTR
)lp
, dummy_window_text
, wp
);
7326 return lstrlenW( (LPWSTR
)lp
);
7328 return DefWindowProcW( hwnd
, msg
, wp
, lp
);
7332 static void test_message_conversion(void)
7334 static const WCHAR wszMsgConversionClass
[] =
7335 {'M','s','g','C','o','n','v','e','r','s','i','o','n','C','l','a','s','s',0};
7339 WNDPROC wndproc
, newproc
;
7343 cls
.lpfnWndProc
= MsgConversionProcW
;
7346 cls
.hInstance
= GetModuleHandleW(NULL
);
7348 cls
.hCursor
= LoadCursorW(NULL
, (LPWSTR
)IDC_ARROW
);
7349 cls
.hbrBackground
= (HBRUSH
)(COLOR_BTNFACE
+1);
7350 cls
.lpszMenuName
= NULL
;
7351 cls
.lpszClassName
= wszMsgConversionClass
;
7352 /* this call will fail on Win9x, but that doesn't matter as this test is
7353 * meaningless on those platforms */
7354 if(!RegisterClassW(&cls
)) return;
7356 hwnd
= CreateWindowExW(0, wszMsgConversionClass
, NULL
, WS_OVERLAPPED
,
7357 100, 100, 200, 200, 0, 0, 0, NULL
);
7358 ok(hwnd
!= NULL
, "Window creation failed\n");
7362 wndproc
= (WNDPROC
)GetWindowLongPtrA(hwnd
, GWLP_WNDPROC
);
7363 lRes
= CallWindowProcA(wndproc
, hwnd
, CB_FINDSTRINGEXACT
, 0, (LPARAM
)wszUnicode
);
7364 ok(lRes
== 0, "String should have been converted\n");
7365 lRes
= CallWindowProcW(wndproc
, hwnd
, CB_FINDSTRINGEXACT
, 0, (LPARAM
)wszUnicode
);
7366 ok(lRes
== 1, "String shouldn't have been converted\n");
7370 wndproc
= (WNDPROC
)GetWindowLongPtrW(hwnd
, GWLP_WNDPROC
);
7371 lRes
= CallWindowProcA(wndproc
, hwnd
, CB_FINDSTRINGEXACT
, 0, (LPARAM
)wszUnicode
);
7372 ok(lRes
== 1, "String shouldn't have been converted\n");
7373 lRes
= CallWindowProcW(wndproc
, hwnd
, CB_FINDSTRINGEXACT
, 0, (LPARAM
)wszUnicode
);
7374 ok(lRes
== 1, "String shouldn't have been converted\n");
7376 /* Synchronous messages */
7378 lRes
= SendMessageA(hwnd
, CB_FINDSTRINGEXACT
, 0, (LPARAM
)wszUnicode
);
7379 ok(lRes
== 0, "String should have been converted\n");
7380 lRes
= SendMessageW(hwnd
, CB_FINDSTRINGEXACT
, 0, (LPARAM
)wszUnicode
);
7381 ok(lRes
== 1, "String shouldn't have been converted\n");
7383 /* Asynchronous messages */
7386 lRes
= PostMessageA(hwnd
, CB_FINDSTRINGEXACT
, 0, (LPARAM
)wszUnicode
);
7387 ok(lRes
== 0 && (GetLastError() == ERROR_MESSAGE_SYNC_ONLY
|| GetLastError() == ERROR_INVALID_PARAMETER
),
7388 "PostMessage on sync only message returned %ld, last error %d\n", lRes
, GetLastError());
7390 lRes
= PostMessageW(hwnd
, CB_FINDSTRINGEXACT
, 0, (LPARAM
)wszUnicode
);
7391 ok(lRes
== 0 && (GetLastError() == ERROR_MESSAGE_SYNC_ONLY
|| GetLastError() == ERROR_INVALID_PARAMETER
),
7392 "PostMessage on sync only message returned %ld, last error %d\n", lRes
, GetLastError());
7394 lRes
= PostThreadMessageA(GetCurrentThreadId(), CB_FINDSTRINGEXACT
, 0, (LPARAM
)wszUnicode
);
7395 ok(lRes
== 0 && (GetLastError() == ERROR_MESSAGE_SYNC_ONLY
|| GetLastError() == ERROR_INVALID_PARAMETER
),
7396 "PosThreadtMessage on sync only message returned %ld, last error %d\n", lRes
, GetLastError());
7398 lRes
= PostThreadMessageW(GetCurrentThreadId(), CB_FINDSTRINGEXACT
, 0, (LPARAM
)wszUnicode
);
7399 ok(lRes
== 0 && (GetLastError() == ERROR_MESSAGE_SYNC_ONLY
|| GetLastError() == ERROR_INVALID_PARAMETER
),
7400 "PosThreadtMessage on sync only message returned %ld, last error %d\n", lRes
, GetLastError());
7402 lRes
= SendNotifyMessageA(hwnd
, CB_FINDSTRINGEXACT
, 0, (LPARAM
)wszUnicode
);
7403 ok(lRes
== 0 && (GetLastError() == ERROR_MESSAGE_SYNC_ONLY
|| GetLastError() == ERROR_INVALID_PARAMETER
),
7404 "SendNotifyMessage on sync only message returned %ld, last error %d\n", lRes
, GetLastError());
7406 lRes
= SendNotifyMessageW(hwnd
, CB_FINDSTRINGEXACT
, 0, (LPARAM
)wszUnicode
);
7407 ok(lRes
== 0 && (GetLastError() == ERROR_MESSAGE_SYNC_ONLY
|| GetLastError() == ERROR_INVALID_PARAMETER
),
7408 "SendNotifyMessage on sync only message returned %ld, last error %d\n", lRes
, GetLastError());
7410 lRes
= SendMessageCallbackA(hwnd
, CB_FINDSTRINGEXACT
, 0, (LPARAM
)wszUnicode
, NULL
, 0);
7411 ok(lRes
== 0 && (GetLastError() == ERROR_MESSAGE_SYNC_ONLY
|| GetLastError() == ERROR_INVALID_PARAMETER
),
7412 "SendMessageCallback on sync only message returned %ld, last error %d\n", lRes
, GetLastError());
7414 lRes
= SendMessageCallbackW(hwnd
, CB_FINDSTRINGEXACT
, 0, (LPARAM
)wszUnicode
, NULL
, 0);
7415 ok(lRes
== 0 && (GetLastError() == ERROR_MESSAGE_SYNC_ONLY
|| GetLastError() == ERROR_INVALID_PARAMETER
),
7416 "SendMessageCallback on sync only message returned %ld, last error %d\n", lRes
, GetLastError());
7418 /* Check WM_GETTEXTLENGTH A->W behaviour, whether WM_GETTEXT is also sent or not */
7420 hwnd
= CreateWindowW (testWindowClassW
, wszUnicode
,
7421 WS_OVERLAPPEDWINDOW
,
7422 100, 100, 200, 200, 0, 0, 0, NULL
);
7425 lRes
= SendMessageA (hwnd
, WM_GETTEXTLENGTH
, 0, 0);
7426 ok_sequence(WmGetTextLengthAfromW
, "ANSI WM_GETTEXTLENGTH to Unicode window", FALSE
);
7427 ok( lRes
== WideCharToMultiByte( CP_ACP
, 0, wszUnicode
, lstrlenW(wszUnicode
), NULL
, 0, NULL
, NULL
),
7428 "got bad length %ld\n", lRes
);
7431 lRes
= CallWindowProcA( (WNDPROC
)GetWindowLongPtrA( hwnd
, GWLP_WNDPROC
),
7432 hwnd
, WM_GETTEXTLENGTH
, 0, 0);
7433 ok_sequence(WmGetTextLengthAfromW
, "ANSI WM_GETTEXTLENGTH to Unicode window", FALSE
);
7434 ok( lRes
== WideCharToMultiByte( CP_ACP
, 0, wszUnicode
, lstrlenW(wszUnicode
), NULL
, 0, NULL
, NULL
),
7435 "got bad length %ld\n", lRes
);
7437 wndproc
= (WNDPROC
)SetWindowLongPtrW( hwnd
, GWLP_WNDPROC
, (LONG_PTR
)get_text_len_proc
);
7438 newproc
= (WNDPROC
)GetWindowLongPtrA( hwnd
, GWLP_WNDPROC
);
7439 lRes
= CallWindowProcA( newproc
, hwnd
, WM_GETTEXTLENGTH
, 0, 0 );
7440 ok( lRes
== WideCharToMultiByte( CP_ACP
, 0, dummy_window_text
, lstrlenW(dummy_window_text
),
7441 NULL
, 0, NULL
, NULL
) ||
7442 broken(lRes
== lstrlenW(dummy_window_text
) + 37),
7443 "got bad length %ld\n", lRes
);
7445 SetWindowLongPtrW( hwnd
, GWLP_WNDPROC
, (LONG_PTR
)wndproc
); /* restore old wnd proc */
7446 lRes
= CallWindowProcA( newproc
, hwnd
, WM_GETTEXTLENGTH
, 0, 0 );
7447 ok( lRes
== WideCharToMultiByte( CP_ACP
, 0, dummy_window_text
, lstrlenW(dummy_window_text
),
7448 NULL
, 0, NULL
, NULL
) ||
7449 broken(lRes
== lstrlenW(dummy_window_text
) + 37),
7450 "got bad length %ld\n", lRes
);
7452 ret
= DestroyWindow(hwnd
);
7453 ok( ret
, "DestroyWindow() error %d\n", GetLastError());
7463 static VOID CALLBACK
tfunc(HWND hwnd
, UINT uMsg
, UINT_PTR id
, DWORD dwTime
)
7467 #define TIMER_ID 0x19
7469 static DWORD WINAPI
timer_thread_proc(LPVOID x
)
7471 struct timer_info
*info
= x
;
7474 r
= KillTimer(info
->hWnd
, 0x19);
7475 ok(r
,"KillTimer failed in thread\n");
7476 r
= SetTimer(info
->hWnd
,TIMER_ID
,10000,tfunc
);
7477 ok(r
,"SetTimer failed in thread\n");
7478 ok(r
==TIMER_ID
,"SetTimer id different\n");
7479 r
= SetEvent(info
->handles
[0]);
7480 ok(r
,"SetEvent failed in thread\n");
7484 static void test_timers(void)
7486 struct timer_info info
;
7489 info
.hWnd
= CreateWindow ("TestWindowClass", NULL
,
7490 WS_OVERLAPPEDWINDOW
,
7491 CW_USEDEFAULT
, CW_USEDEFAULT
, 300, 300, 0,
7494 info
.id
= SetTimer(info
.hWnd
,TIMER_ID
,10000,tfunc
);
7495 ok(info
.id
, "SetTimer failed\n");
7496 ok(info
.id
==TIMER_ID
, "SetTimer timer ID different\n");
7497 info
.handles
[0] = CreateEvent(NULL
,0,0,NULL
);
7498 info
.handles
[1] = CreateThread(NULL
,0,timer_thread_proc
,&info
,0,&id
);
7500 WaitForMultipleObjects(2, info
.handles
, FALSE
, INFINITE
);
7502 WaitForSingleObject(info
.handles
[1], INFINITE
);
7504 CloseHandle(info
.handles
[0]);
7505 CloseHandle(info
.handles
[1]);
7507 ok( KillTimer(info
.hWnd
, TIMER_ID
), "KillTimer failed\n");
7509 ok(DestroyWindow(info
.hWnd
), "failed to destroy window\n");
7512 static int count
= 0;
7513 static VOID CALLBACK
callback_count(
7523 static void test_timers_no_wnd(void)
7529 id
= SetTimer(NULL
, 0, 100, callback_count
);
7530 ok(id
!= 0, "did not get id from SetTimer.\n");
7531 id2
= SetTimer(NULL
, id
, 200, callback_count
);
7532 ok(id2
== id
, "did not get same id from SetTimer when replacing (%li expected %li).\n", id2
, id
);
7534 while (PeekMessage(&msg
, NULL
, 0, 0, PM_REMOVE
)) DispatchMessage(&msg
);
7535 ok(count
== 0, "did not get zero count as expected (%i).\n", count
);
7537 while (PeekMessage(&msg
, NULL
, 0, 0, PM_REMOVE
)) DispatchMessage(&msg
);
7538 ok(count
== 1, "did not get one count as expected (%i).\n", count
);
7539 KillTimer(NULL
, id
);
7541 while (PeekMessage(&msg
, NULL
, 0, 0, PM_REMOVE
)) DispatchMessage(&msg
);
7542 ok(count
== 1, "killing replaced timer did not work (%i).\n", count
);
7545 /* Various win events with arbitrary parameters */
7546 static const struct message WmWinEventsSeq
[] = {
7547 { EVENT_SYSTEM_SOUND
, winevent_hook
|wparam
|lparam
, OBJID_WINDOW
, 0 },
7548 { EVENT_SYSTEM_ALERT
, winevent_hook
|wparam
|lparam
, OBJID_SYSMENU
, 1 },
7549 { EVENT_SYSTEM_FOREGROUND
, winevent_hook
|wparam
|lparam
, OBJID_TITLEBAR
, 2 },
7550 { EVENT_SYSTEM_MENUSTART
, winevent_hook
|wparam
|lparam
, OBJID_MENU
, 3 },
7551 { EVENT_SYSTEM_MENUEND
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 4 },
7552 { EVENT_SYSTEM_MENUPOPUPSTART
, winevent_hook
|wparam
|lparam
, OBJID_VSCROLL
, 5 },
7553 { EVENT_SYSTEM_MENUPOPUPEND
, winevent_hook
|wparam
|lparam
, OBJID_HSCROLL
, 6 },
7554 { EVENT_SYSTEM_CAPTURESTART
, winevent_hook
|wparam
|lparam
, OBJID_SIZEGRIP
, 7 },
7555 { EVENT_SYSTEM_CAPTUREEND
, winevent_hook
|wparam
|lparam
, OBJID_CARET
, 8 },
7556 /* our win event hook ignores OBJID_CURSOR events */
7557 /*{ EVENT_SYSTEM_MOVESIZESTART, winevent_hook|wparam|lparam, OBJID_CURSOR, 9 },*/
7558 { EVENT_SYSTEM_MOVESIZEEND
, winevent_hook
|wparam
|lparam
, OBJID_ALERT
, 10 },
7559 { EVENT_SYSTEM_CONTEXTHELPSTART
, winevent_hook
|wparam
|lparam
, OBJID_SOUND
, 11 },
7560 { EVENT_SYSTEM_CONTEXTHELPEND
, winevent_hook
|wparam
|lparam
, OBJID_QUERYCLASSNAMEIDX
, 12 },
7561 { EVENT_SYSTEM_DRAGDROPSTART
, winevent_hook
|wparam
|lparam
, OBJID_NATIVEOM
, 13 },
7562 { EVENT_SYSTEM_DRAGDROPEND
, winevent_hook
|wparam
|lparam
, OBJID_WINDOW
, 0 },
7563 { EVENT_SYSTEM_DIALOGSTART
, winevent_hook
|wparam
|lparam
, OBJID_SYSMENU
, 1 },
7564 { EVENT_SYSTEM_DIALOGEND
, winevent_hook
|wparam
|lparam
, OBJID_TITLEBAR
, 2 },
7565 { EVENT_SYSTEM_SCROLLINGSTART
, winevent_hook
|wparam
|lparam
, OBJID_MENU
, 3 },
7566 { EVENT_SYSTEM_SCROLLINGEND
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 4 },
7567 { EVENT_SYSTEM_SWITCHSTART
, winevent_hook
|wparam
|lparam
, OBJID_VSCROLL
, 5 },
7568 { EVENT_SYSTEM_SWITCHEND
, winevent_hook
|wparam
|lparam
, OBJID_HSCROLL
, 6 },
7569 { EVENT_SYSTEM_MINIMIZESTART
, winevent_hook
|wparam
|lparam
, OBJID_SIZEGRIP
, 7 },
7570 { EVENT_SYSTEM_MINIMIZEEND
, winevent_hook
|wparam
|lparam
, OBJID_CARET
, 8 },
7573 static const struct message WmWinEventCaretSeq
[] = {
7574 { EVENT_OBJECT_CREATE
, winevent_hook
|wparam
|lparam
, OBJID_CARET
, 0 }, /* hook 1 */
7575 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, OBJID_CARET
, 0 }, /* hook 1 */
7576 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, OBJID_CARET
, 0 }, /* hook 2 */
7577 { EVENT_OBJECT_NAMECHANGE
, winevent_hook
|wparam
|lparam
, OBJID_CARET
, 0 }, /* hook 1 */
7580 static const struct message WmWinEventCaretSeq_2
[] = {
7581 { EVENT_OBJECT_CREATE
, winevent_hook
|wparam
|lparam
, OBJID_CARET
, 0 }, /* hook 1/2 */
7582 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, OBJID_CARET
, 0 }, /* hook 1/2 */
7583 { EVENT_OBJECT_NAMECHANGE
, winevent_hook
|wparam
|lparam
, OBJID_CARET
, 0 }, /* hook 1/2 */
7586 static const struct message WmWinEventAlertSeq
[] = {
7587 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, OBJID_ALERT
, 0 },
7590 static const struct message WmWinEventAlertSeq_2
[] = {
7591 /* create window in the thread proc */
7592 { EVENT_OBJECT_CREATE
, winevent_hook
|wparam
|lparam
, OBJID_WINDOW
, 2 },
7593 /* our test event */
7594 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, OBJID_ALERT
, 2 },
7597 static const struct message WmGlobalHookSeq_1
[] = {
7598 /* create window in the thread proc */
7599 { HCBT_CREATEWND
, hook
|lparam
, 0, 2 },
7600 /* our test events */
7601 { HCBT_SYSCOMMAND
, hook
|wparam
|lparam
, SC_PREVWINDOW
, 2 },
7602 { HCBT_SYSCOMMAND
, hook
|wparam
|lparam
, SC_NEXTWINDOW
, 2 },
7605 static const struct message WmGlobalHookSeq_2
[] = {
7606 { HCBT_SYSCOMMAND
, hook
|wparam
|lparam
, SC_NEXTWINDOW
, 0 }, /* old local hook */
7607 { HCBT_SYSCOMMAND
, hook
|wparam
|lparam
, SC_NEXTWINDOW
, 2 }, /* new global hook */
7608 { HCBT_SYSCOMMAND
, hook
|wparam
|lparam
, SC_PREVWINDOW
, 0 }, /* old local hook */
7609 { HCBT_SYSCOMMAND
, hook
|wparam
|lparam
, SC_PREVWINDOW
, 2 }, /* new global hook */
7613 static const struct message WmMouseLLHookSeq
[] = {
7614 { WM_MOUSEMOVE
, hook
},
7615 { WM_LBUTTONUP
, hook
},
7616 { WM_MOUSEMOVE
, hook
},
7620 static void CALLBACK
win_event_global_hook_proc(HWINEVENTHOOK hevent
,
7630 if (GetClassNameA(hwnd
, buf
, sizeof(buf
)))
7632 if (!lstrcmpiA(buf
, "TestWindowClass") ||
7633 !lstrcmpiA(buf
, "static"))
7635 struct recvd_message msg
;
7638 msg
.message
= event
;
7639 msg
.flags
= winevent_hook
|wparam
|lparam
;
7640 msg
.wParam
= object_id
;
7641 msg
.lParam
= (thread_id
== GetCurrentThreadId()) ? child_id
: (child_id
+ 2);
7642 msg
.descr
= "WEH_2";
7648 static HHOOK hCBT_global_hook
;
7649 static DWORD cbt_global_hook_thread_id
;
7651 static LRESULT CALLBACK
cbt_global_hook_proc(int nCode
, WPARAM wParam
, LPARAM lParam
)
7656 if (nCode
== HCBT_SYSCOMMAND
)
7658 struct recvd_message msg
;
7661 msg
.message
= nCode
;
7662 msg
.flags
= hook
|wparam
|lparam
;
7663 msg
.wParam
= wParam
;
7664 msg
.lParam
= (cbt_global_hook_thread_id
== GetCurrentThreadId()) ? 1 : 2;
7665 msg
.descr
= "CBT_2";
7668 return CallNextHookEx(hCBT_global_hook
, nCode
, wParam
, lParam
);
7670 /* WH_MOUSE_LL hook */
7671 if (nCode
== HC_ACTION
)
7673 MSLLHOOKSTRUCT
*mhll
= (MSLLHOOKSTRUCT
*)lParam
;
7675 /* we can't test for real mouse events */
7676 if (mhll
->flags
& LLMHF_INJECTED
)
7678 struct recvd_message msg
;
7680 memset (&msg
, 0, sizeof (msg
));
7681 msg
.message
= wParam
;
7683 msg
.descr
= "CBT_2";
7686 return CallNextHookEx(hCBT_global_hook
, nCode
, wParam
, lParam
);
7689 /* Log also SetFocus(0) calls */
7690 hwnd
= wParam
? (HWND
)wParam
: (HWND
)lParam
;
7692 if (GetClassNameA(hwnd
, buf
, sizeof(buf
)))
7694 if (!lstrcmpiA(buf
, "TestWindowClass") ||
7695 !lstrcmpiA(buf
, "static"))
7697 struct recvd_message msg
;
7700 msg
.message
= nCode
;
7701 msg
.flags
= hook
|wparam
|lparam
;
7702 msg
.wParam
= wParam
;
7703 msg
.lParam
= (cbt_global_hook_thread_id
== GetCurrentThreadId()) ? 1 : 2;
7704 msg
.descr
= "CBT_2";
7708 return CallNextHookEx(hCBT_global_hook
, nCode
, wParam
, lParam
);
7711 static DWORD WINAPI
win_event_global_thread_proc(void *param
)
7715 HANDLE hevent
= *(HANDLE
*)param
;
7717 assert(pNotifyWinEvent
);
7719 hwnd
= CreateWindowExA(0, "static", NULL
, WS_POPUP
, 0,0,0,0,0,0,0, NULL
);
7721 trace("created thread window %p\n", hwnd
);
7723 *(HWND
*)param
= hwnd
;
7726 /* this event should be received only by our new hook proc,
7727 * an old one does not expect an event from another thread.
7729 pNotifyWinEvent(EVENT_OBJECT_LOCATIONCHANGE
, hwnd
, OBJID_ALERT
, 0);
7732 while (GetMessage(&msg
, 0, 0, 0))
7734 TranslateMessage(&msg
);
7735 DispatchMessage(&msg
);
7740 static DWORD WINAPI
cbt_global_hook_thread_proc(void *param
)
7744 HANDLE hevent
= *(HANDLE
*)param
;
7747 /* these events should be received only by our new hook proc,
7748 * an old one does not expect an event from another thread.
7751 hwnd
= CreateWindowExA(0, "static", NULL
, WS_POPUP
, 0,0,0,0,0,0,0, NULL
);
7753 trace("created thread window %p\n", hwnd
);
7755 *(HWND
*)param
= hwnd
;
7757 /* Windows doesn't like when a thread plays games with the focus,
7758 that leads to all kinds of misbehaviours and failures to activate
7759 a window. So, better keep next lines commented out.
7763 DefWindowProcA(hwnd
, WM_SYSCOMMAND
, SC_PREVWINDOW
, 0);
7764 DefWindowProcA(hwnd
, WM_SYSCOMMAND
, SC_NEXTWINDOW
, 0);
7768 while (GetMessage(&msg
, 0, 0, 0))
7770 TranslateMessage(&msg
);
7771 DispatchMessage(&msg
);
7776 static DWORD WINAPI
mouse_ll_global_thread_proc(void *param
)
7780 HANDLE hevent
= *(HANDLE
*)param
;
7782 hwnd
= CreateWindowExA(0, "static", NULL
, WS_POPUP
, 0,0,0,0,0,0,0, NULL
);
7784 trace("created thread window %p\n", hwnd
);
7786 *(HWND
*)param
= hwnd
;
7790 /* Windows doesn't like when a thread plays games with the focus,
7791 * that leads to all kinds of misbehaviours and failures to activate
7792 * a window. So, better don't generate a mouse click message below.
7794 mouse_event(MOUSEEVENTF_MOVE
, -1, 0, 0, 0);
7795 mouse_event(MOUSEEVENTF_LEFTUP
, 0, 0, 0, 0);
7796 mouse_event(MOUSEEVENTF_MOVE
, 1, 0, 0, 0);
7799 while (GetMessage(&msg
, 0, 0, 0))
7801 TranslateMessage(&msg
);
7802 DispatchMessage(&msg
);
7807 static void test_winevents(void)
7813 HANDLE hthread
, hevent
;
7815 HWINEVENTHOOK hhook
;
7816 const struct message
*events
= WmWinEventsSeq
;
7818 hwnd
= CreateWindowExA(0, "TestWindowClass", NULL
,
7819 WS_OVERLAPPEDWINDOW
,
7820 CW_USEDEFAULT
, CW_USEDEFAULT
, 300, 300, 0,
7824 /****** start of global hook test *************/
7825 hCBT_global_hook
= SetWindowsHookExA(WH_CBT
, cbt_global_hook_proc
, GetModuleHandleA(0), 0);
7826 if (!hCBT_global_hook
)
7828 ok(DestroyWindow(hwnd
), "failed to destroy window\n");
7829 skip( "cannot set global hook\n" );
7833 hevent
= CreateEventA(NULL
, 0, 0, NULL
);
7835 hwnd2
= (HWND
)hevent
;
7837 hthread
= CreateThread(NULL
, 0, cbt_global_hook_thread_proc
, &hwnd2
, 0, &tid
);
7838 ok(hthread
!= NULL
, "CreateThread failed, error %d\n", GetLastError());
7840 ok(WaitForSingleObject(hevent
, INFINITE
) == WAIT_OBJECT_0
, "WaitForSingleObject failed\n");
7842 ok_sequence(WmGlobalHookSeq_1
, "global hook 1", FALSE
);
7845 /* this one should be received only by old hook proc */
7846 DefWindowProcA(hwnd
, WM_SYSCOMMAND
, SC_NEXTWINDOW
, 0);
7847 /* this one should be received only by old hook proc */
7848 DefWindowProcA(hwnd
, WM_SYSCOMMAND
, SC_PREVWINDOW
, 0);
7850 ok_sequence(WmGlobalHookSeq_2
, "global hook 2", FALSE
);
7852 ret
= UnhookWindowsHookEx(hCBT_global_hook
);
7853 ok( ret
, "UnhookWindowsHookEx error %d\n", GetLastError());
7855 PostThreadMessageA(tid
, WM_QUIT
, 0, 0);
7856 ok(WaitForSingleObject(hthread
, INFINITE
) == WAIT_OBJECT_0
, "WaitForSingleObject failed\n");
7857 CloseHandle(hthread
);
7858 CloseHandle(hevent
);
7859 ok(!IsWindow(hwnd2
), "window should be destroyed on thread exit\n");
7860 /****** end of global hook test *************/
7862 if (!pSetWinEventHook
|| !pNotifyWinEvent
|| !pUnhookWinEvent
)
7864 ok(DestroyWindow(hwnd
), "failed to destroy window\n");
7872 /* this test doesn't pass under Win9x */
7873 /* win2k ignores events with hwnd == 0 */
7874 SetLastError(0xdeadbeef);
7875 pNotifyWinEvent(events
[0].message
, 0, events
[0].wParam
, events
[0].lParam
);
7876 ok(GetLastError() == ERROR_INVALID_WINDOW_HANDLE
|| /* Win2k */
7877 GetLastError() == 0xdeadbeef, /* Win9x */
7878 "unexpected error %d\n", GetLastError());
7879 ok_sequence(WmEmptySeq
, "empty notify winevents", FALSE
);
7882 for (i
= 0; i
< sizeof(WmWinEventsSeq
)/sizeof(WmWinEventsSeq
[0]); i
++)
7883 pNotifyWinEvent(events
[i
].message
, hwnd
, events
[i
].wParam
, events
[i
].lParam
);
7885 ok_sequence(WmWinEventsSeq
, "notify winevents", FALSE
);
7887 /****** start of event filtering test *************/
7888 hhook
= (HWINEVENTHOOK
)pSetWinEventHook(
7889 EVENT_OBJECT_SHOW
, /* 0x8002 */
7890 EVENT_OBJECT_LOCATIONCHANGE
, /* 0x800B */
7891 GetModuleHandleA(0), win_event_global_hook_proc
,
7892 GetCurrentProcessId(), 0,
7893 WINEVENT_INCONTEXT
);
7894 ok(hhook
!= 0, "SetWinEventHook error %d\n", GetLastError());
7896 hevent
= CreateEventA(NULL
, 0, 0, NULL
);
7898 hwnd2
= (HWND
)hevent
;
7900 hthread
= CreateThread(NULL
, 0, win_event_global_thread_proc
, &hwnd2
, 0, &tid
);
7901 ok(hthread
!= NULL
, "CreateThread failed, error %d\n", GetLastError());
7903 ok(WaitForSingleObject(hevent
, INFINITE
) == WAIT_OBJECT_0
, "WaitForSingleObject failed\n");
7905 ok_sequence(WmWinEventAlertSeq
, "alert winevent", FALSE
);
7908 /* this one should be received only by old hook proc */
7909 pNotifyWinEvent(EVENT_OBJECT_CREATE
, hwnd
, OBJID_CARET
, 0); /* 0x8000 */
7910 pNotifyWinEvent(EVENT_OBJECT_SHOW
, hwnd
, OBJID_CARET
, 0); /* 0x8002 */
7911 /* this one should be received only by old hook proc */
7912 pNotifyWinEvent(EVENT_OBJECT_NAMECHANGE
, hwnd
, OBJID_CARET
, 0); /* 0x800C */
7914 ok_sequence(WmWinEventCaretSeq
, "caret winevent", FALSE
);
7916 ret
= pUnhookWinEvent(hhook
);
7917 ok( ret
, "UnhookWinEvent error %d\n", GetLastError());
7919 PostThreadMessageA(tid
, WM_QUIT
, 0, 0);
7920 ok(WaitForSingleObject(hthread
, INFINITE
) == WAIT_OBJECT_0
, "WaitForSingleObject failed\n");
7921 CloseHandle(hthread
);
7922 CloseHandle(hevent
);
7923 ok(!IsWindow(hwnd2
), "window should be destroyed on thread exit\n");
7924 /****** end of event filtering test *************/
7926 /****** start of out of context event test *************/
7927 hhook
= (HWINEVENTHOOK
)pSetWinEventHook(
7928 EVENT_MIN
, EVENT_MAX
,
7929 0, win_event_global_hook_proc
,
7930 GetCurrentProcessId(), 0,
7931 WINEVENT_OUTOFCONTEXT
);
7932 ok(hhook
!= 0, "SetWinEventHook error %d\n", GetLastError());
7934 hevent
= CreateEventA(NULL
, 0, 0, NULL
);
7936 hwnd2
= (HWND
)hevent
;
7940 hthread
= CreateThread(NULL
, 0, win_event_global_thread_proc
, &hwnd2
, 0, &tid
);
7941 ok(hthread
!= NULL
, "CreateThread failed, error %d\n", GetLastError());
7943 ok(WaitForSingleObject(hevent
, INFINITE
) == WAIT_OBJECT_0
, "WaitForSingleObject failed\n");
7945 ok_sequence(WmEmptySeq
, "empty notify winevents", FALSE
);
7946 /* process pending winevent messages */
7947 ok(!PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
), "msg queue should be empty\n");
7948 ok_sequence(WmWinEventAlertSeq_2
, "alert winevent for out of context proc", FALSE
);
7951 /* this one should be received only by old hook proc */
7952 pNotifyWinEvent(EVENT_OBJECT_CREATE
, hwnd
, OBJID_CARET
, 0); /* 0x8000 */
7953 pNotifyWinEvent(EVENT_OBJECT_SHOW
, hwnd
, OBJID_CARET
, 0); /* 0x8002 */
7954 /* this one should be received only by old hook proc */
7955 pNotifyWinEvent(EVENT_OBJECT_NAMECHANGE
, hwnd
, OBJID_CARET
, 0); /* 0x800C */
7957 ok_sequence(WmWinEventCaretSeq_2
, "caret winevent for incontext proc", FALSE
);
7958 /* process pending winevent messages */
7959 ok(!PeekMessageA(&msg
, 0, 0, 0, PM_NOREMOVE
), "msg queue should be empty\n");
7960 ok_sequence(WmWinEventCaretSeq_2
, "caret winevent for out of context proc", FALSE
);
7962 ret
= pUnhookWinEvent(hhook
);
7963 ok( ret
, "UnhookWinEvent error %d\n", GetLastError());
7965 PostThreadMessageA(tid
, WM_QUIT
, 0, 0);
7966 ok(WaitForSingleObject(hthread
, INFINITE
) == WAIT_OBJECT_0
, "WaitForSingleObject failed\n");
7967 CloseHandle(hthread
);
7968 CloseHandle(hevent
);
7969 ok(!IsWindow(hwnd2
), "window should be destroyed on thread exit\n");
7970 /****** end of out of context event test *************/
7972 /****** start of MOUSE_LL hook test *************/
7973 hCBT_global_hook
= SetWindowsHookExA(WH_MOUSE_LL
, cbt_global_hook_proc
, GetModuleHandleA(0), 0);
7974 /* WH_MOUSE_LL is not supported on Win9x platforms */
7975 if (!hCBT_global_hook
)
7977 trace("Skipping WH_MOUSE_LL test on this platform\n");
7978 goto skip_mouse_ll_hook_test
;
7981 hevent
= CreateEventA(NULL
, 0, 0, NULL
);
7983 hwnd2
= (HWND
)hevent
;
7985 hthread
= CreateThread(NULL
, 0, mouse_ll_global_thread_proc
, &hwnd2
, 0, &tid
);
7986 ok(hthread
!= NULL
, "CreateThread failed, error %d\n", GetLastError());
7988 while (WaitForSingleObject(hevent
, 100) == WAIT_TIMEOUT
)
7989 while (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage( &msg
);
7991 ok_sequence(WmMouseLLHookSeq
, "MOUSE_LL hook other thread", FALSE
);
7994 mouse_event(MOUSEEVENTF_MOVE
, -1, 0, 0, 0);
7995 mouse_event(MOUSEEVENTF_LEFTUP
, 0, 0, 0, 0);
7996 mouse_event(MOUSEEVENTF_MOVE
, 1, 0, 0, 0);
7998 ok_sequence(WmMouseLLHookSeq
, "MOUSE_LL hook same thread", FALSE
);
8000 ret
= UnhookWindowsHookEx(hCBT_global_hook
);
8001 ok( ret
, "UnhookWindowsHookEx error %d\n", GetLastError());
8003 PostThreadMessageA(tid
, WM_QUIT
, 0, 0);
8004 ok(WaitForSingleObject(hthread
, INFINITE
) == WAIT_OBJECT_0
, "WaitForSingleObject failed\n");
8005 CloseHandle(hthread
);
8006 CloseHandle(hevent
);
8007 ok(!IsWindow(hwnd2
), "window should be destroyed on thread exit\n");
8008 /****** end of MOUSE_LL hook test *************/
8009 skip_mouse_ll_hook_test
:
8011 ok(DestroyWindow(hwnd
), "failed to destroy window\n");
8014 static void test_set_hook(void)
8018 HWINEVENTHOOK hwinevent_hook
;
8020 hhook
= SetWindowsHookExA(WH_CBT
, cbt_hook_proc
, GetModuleHandleA(0), GetCurrentThreadId());
8021 ok(hhook
!= 0, "local hook does not require hModule set to 0\n");
8022 UnhookWindowsHookEx(hhook
);
8026 /* this test doesn't pass under Win9x: BUG! */
8027 SetLastError(0xdeadbeef);
8028 hhook
= SetWindowsHookExA(WH_CBT
, cbt_hook_proc
, 0, 0);
8029 ok(!hhook
, "global hook requires hModule != 0\n");
8030 ok(GetLastError() == ERROR_HOOK_NEEDS_HMOD
, "unexpected error %d\n", GetLastError());
8033 SetLastError(0xdeadbeef);
8034 hhook
= SetWindowsHookExA(WH_CBT
, 0, GetModuleHandleA(0), GetCurrentThreadId());
8035 ok(!hhook
, "SetWinEventHook with invalid proc should fail\n");
8036 ok(GetLastError() == ERROR_INVALID_FILTER_PROC
|| /* Win2k */
8037 GetLastError() == 0xdeadbeef, /* Win9x */
8038 "unexpected error %d\n", GetLastError());
8040 SetLastError(0xdeadbeef);
8041 ok(!UnhookWindowsHookEx((HHOOK
)0xdeadbeef), "UnhookWindowsHookEx succeeded\n");
8042 ok(GetLastError() == ERROR_INVALID_HOOK_HANDLE
|| /* Win2k */
8043 GetLastError() == 0xdeadbeef, /* Win9x */
8044 "unexpected error %d\n", GetLastError());
8046 if (!pSetWinEventHook
|| !pUnhookWinEvent
) return;
8048 /* even process local incontext hooks require hmodule */
8049 SetLastError(0xdeadbeef);
8050 hwinevent_hook
= (HWINEVENTHOOK
)pSetWinEventHook(EVENT_MIN
, EVENT_MAX
,
8051 0, win_event_proc
, GetCurrentProcessId(), 0, WINEVENT_INCONTEXT
);
8052 ok(!hwinevent_hook
, "WINEVENT_INCONTEXT requires hModule != 0\n");
8053 ok(GetLastError() == ERROR_HOOK_NEEDS_HMOD
|| /* Win2k */
8054 GetLastError() == 0xdeadbeef, /* Win9x */
8055 "unexpected error %d\n", GetLastError());
8057 /* even thread local incontext hooks require hmodule */
8058 SetLastError(0xdeadbeef);
8059 hwinevent_hook
= (HWINEVENTHOOK
)pSetWinEventHook(EVENT_MIN
, EVENT_MAX
,
8060 0, win_event_proc
, GetCurrentProcessId(), GetCurrentThreadId(), WINEVENT_INCONTEXT
);
8061 ok(!hwinevent_hook
, "WINEVENT_INCONTEXT requires hModule != 0\n");
8062 ok(GetLastError() == ERROR_HOOK_NEEDS_HMOD
|| /* Win2k */
8063 GetLastError() == 0xdeadbeef, /* Win9x */
8064 "unexpected error %d\n", GetLastError());
8068 /* these 3 tests don't pass under Win9x */
8069 SetLastError(0xdeadbeef);
8070 hwinevent_hook
= (HWINEVENTHOOK
)pSetWinEventHook(1, 0,
8071 0, win_event_proc
, GetCurrentProcessId(), 0, WINEVENT_OUTOFCONTEXT
);
8072 ok(!hwinevent_hook
, "SetWinEventHook with invalid event range should fail\n");
8073 ok(GetLastError() == ERROR_INVALID_HOOK_FILTER
, "unexpected error %d\n", GetLastError());
8075 SetLastError(0xdeadbeef);
8076 hwinevent_hook
= (HWINEVENTHOOK
)pSetWinEventHook(-1, 1,
8077 0, win_event_proc
, GetCurrentProcessId(), 0, WINEVENT_OUTOFCONTEXT
);
8078 ok(!hwinevent_hook
, "SetWinEventHook with invalid event range should fail\n");
8079 ok(GetLastError() == ERROR_INVALID_HOOK_FILTER
, "unexpected error %d\n", GetLastError());
8081 SetLastError(0xdeadbeef);
8082 hwinevent_hook
= (HWINEVENTHOOK
)pSetWinEventHook(EVENT_MIN
, EVENT_MAX
,
8083 0, win_event_proc
, 0, 0xdeadbeef, WINEVENT_OUTOFCONTEXT
);
8084 ok(!hwinevent_hook
, "SetWinEventHook with invalid tid should fail\n");
8085 ok(GetLastError() == ERROR_INVALID_THREAD_ID
, "unexpected error %d\n", GetLastError());
8088 SetLastError(0xdeadbeef);
8089 hwinevent_hook
= (HWINEVENTHOOK
)pSetWinEventHook(0, 0,
8090 0, win_event_proc
, GetCurrentProcessId(), 0, WINEVENT_OUTOFCONTEXT
);
8091 ok(hwinevent_hook
!= 0, "SetWinEventHook error %d\n", GetLastError());
8092 ok(GetLastError() == 0xdeadbeef, "unexpected error %d\n", GetLastError());
8093 ret
= pUnhookWinEvent(hwinevent_hook
);
8094 ok( ret
, "UnhookWinEvent error %d\n", GetLastError());
8097 /* This call succeeds under win2k SP4, but fails under Wine.
8098 Does win2k test/use passed process id? */
8099 SetLastError(0xdeadbeef);
8100 hwinevent_hook
= (HWINEVENTHOOK
)pSetWinEventHook(EVENT_MIN
, EVENT_MAX
,
8101 0, win_event_proc
, 0xdeadbeef, 0, WINEVENT_OUTOFCONTEXT
);
8102 ok(hwinevent_hook
!= 0, "SetWinEventHook error %d\n", GetLastError());
8103 ok(GetLastError() == 0xdeadbeef, "unexpected error %d\n", GetLastError());
8104 ret
= pUnhookWinEvent(hwinevent_hook
);
8105 ok( ret
, "UnhookWinEvent error %d\n", GetLastError());
8108 SetLastError(0xdeadbeef);
8109 ok(!pUnhookWinEvent((HWINEVENTHOOK
)0xdeadbeef), "UnhookWinEvent succeeded\n");
8110 ok(GetLastError() == ERROR_INVALID_HANDLE
|| /* Win2k */
8111 GetLastError() == 0xdeadbeef, /* Win9x */
8112 "unexpected error %d\n", GetLastError());
8115 static const struct message ScrollWindowPaint1
[] = {
8117 { WM_ERASEBKGND
, sent
|beginpaint
},
8121 static const struct message ScrollWindowPaint2
[] = {
8126 static void test_scrollwindowex(void)
8129 RECT rect
={0,0,130,130};
8131 hwnd
= CreateWindowExA(0, "TestWindowClass", "Test Scroll",
8132 WS_VISIBLE
|WS_OVERLAPPEDWINDOW
,
8133 100, 100, 200, 200, 0, 0, 0, NULL
);
8134 ok (hwnd
!= 0, "Failed to create overlapped window\n");
8135 hchild
= CreateWindowExA(0, "TestWindowClass", "Test child",
8136 WS_VISIBLE
|WS_CAPTION
|WS_CHILD
,
8137 10, 10, 150, 150, hwnd
, 0, 0, NULL
);
8138 ok (hchild
!= 0, "Failed to create child\n");
8143 /* scroll without the child window */
8144 trace("start scroll\n");
8145 ScrollWindowEx( hwnd
, 10, 10, &rect
, NULL
, NULL
, NULL
,
8146 SW_ERASE
|SW_INVALIDATE
);
8147 ok_sequence(WmEmptySeq
, "ScrollWindowEx", 0);
8148 trace("end scroll\n");
8151 ok_sequence(ScrollWindowPaint1
, "ScrollWindowEx", 0);
8155 /* Now without the SW_ERASE flag */
8156 trace("start scroll\n");
8157 ScrollWindowEx( hwnd
, 10, 10, &rect
, NULL
, NULL
, NULL
, SW_INVALIDATE
);
8158 ok_sequence(WmEmptySeq
, "ScrollWindowEx", 0);
8159 trace("end scroll\n");
8162 ok_sequence(ScrollWindowPaint2
, "ScrollWindowEx", 0);
8166 /* now scroll the child window as well */
8167 trace("start scroll\n");
8168 ScrollWindowEx( hwnd
, 10, 10, &rect
, NULL
, NULL
, NULL
,
8169 SW_SCROLLCHILDREN
|SW_ERASE
|SW_INVALIDATE
);
8170 /* wine sends WM_POSCHANGING, WM_POSCHANGED messages */
8171 /* windows sometimes a WM_MOVE */
8172 ok_sequence(WmEmptySeq
, "ScrollWindowEx", TRUE
);
8173 trace("end scroll\n");
8176 ok_sequence(ScrollWindowPaint1
, "ScrollWindowEx", 0);
8180 /* now scroll with ScrollWindow() */
8181 trace("start scroll with ScrollWindow\n");
8182 ScrollWindow( hwnd
, 5, 5, NULL
, NULL
);
8183 trace("end scroll\n");
8186 ok_sequence(ScrollWindowPaint1
, "ScrollWindow", 0);
8188 ok(DestroyWindow(hchild
), "failed to destroy window\n");
8189 ok(DestroyWindow(hwnd
), "failed to destroy window\n");
8193 static const struct message destroy_window_with_children
[] = {
8194 { EVENT_SYSTEM_CAPTURESTART
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* popup */
8195 { HCBT_DESTROYWND
, hook
|lparam
, 0, WND_PARENT_ID
}, /* parent */
8196 { 0x0090, sent
|optional
},
8197 { HCBT_DESTROYWND
, hook
|lparam
, 0, WND_POPUP_ID
}, /* popup */
8198 { 0x0090, sent
|optional
},
8199 { EVENT_OBJECT_DESTROY
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* popup */
8200 { WM_DESTROY
, sent
|wparam
|lparam
, 0, WND_POPUP_ID
}, /* popup */
8201 { WM_CAPTURECHANGED
, sent
|wparam
|lparam
, 0, WND_POPUP_ID
}, /* popup */
8202 { WM_NCDESTROY
, sent
|wparam
|lparam
, 0, WND_POPUP_ID
}, /* popup */
8203 { EVENT_OBJECT_DESTROY
, winevent_hook
|wparam
|lparam
, 0, 0 }, /* parent */
8204 { WM_DESTROY
, sent
|wparam
|lparam
, 0, WND_PARENT_ID
}, /* parent */
8205 { WM_DESTROY
, sent
|wparam
|lparam
, 0, WND_CHILD_ID
+ 2 }, /* child2 */
8206 { WM_DESTROY
, sent
|wparam
|lparam
, 0, WND_CHILD_ID
+ 1 }, /* child1 */
8207 { WM_DESTROY
, sent
|wparam
|lparam
, 0, WND_CHILD_ID
+ 3 }, /* child3 */
8208 { WM_NCDESTROY
, sent
|wparam
|lparam
, 0, WND_CHILD_ID
+ 2 }, /* child2 */
8209 { WM_NCDESTROY
, sent
|wparam
|lparam
, 0, WND_CHILD_ID
+ 3 }, /* child3 */
8210 { WM_NCDESTROY
, sent
|wparam
|lparam
, 0, WND_CHILD_ID
+ 1 }, /* child1 */
8211 { WM_NCDESTROY
, sent
|wparam
|lparam
, 0, WND_PARENT_ID
}, /* parent */
8215 static void test_DestroyWindow(void)
8218 HWND parent
, child1
, child2
, child3
, child4
, test
;
8219 UINT_PTR child_id
= WND_CHILD_ID
+ 1;
8221 parent
= CreateWindowExA(0, "TestWindowClass", NULL
, WS_OVERLAPPEDWINDOW
,
8222 100, 100, 200, 200, 0, 0, 0, NULL
);
8223 assert(parent
!= 0);
8224 child1
= CreateWindowExA(0, "TestWindowClass", NULL
, WS_CHILD
,
8225 0, 0, 50, 50, parent
, (HMENU
)child_id
++, 0, NULL
);
8226 assert(child1
!= 0);
8227 child2
= CreateWindowExA(0, "TestWindowClass", NULL
, WS_CHILD
,
8228 0, 0, 50, 50, GetDesktopWindow(), (HMENU
)child_id
++, 0, NULL
);
8229 assert(child2
!= 0);
8230 child3
= CreateWindowExA(0, "TestWindowClass", NULL
, WS_CHILD
,
8231 0, 0, 50, 50, child1
, (HMENU
)child_id
++, 0, NULL
);
8232 assert(child3
!= 0);
8233 child4
= CreateWindowExA(0, "TestWindowClass", NULL
, WS_POPUP
,
8234 0, 0, 50, 50, parent
, 0, 0, NULL
);
8235 assert(child4
!= 0);
8237 /* test owner/parent of child2 */
8238 test
= GetParent(child2
);
8239 ok(test
== GetDesktopWindow(), "wrong parent %p\n", test
);
8240 ok(!IsChild(parent
, child2
), "wrong parent/child %p/%p\n", parent
, child2
);
8242 test
= pGetAncestor(child2
, GA_PARENT
);
8243 ok(test
== GetDesktopWindow(), "wrong parent %p\n", test
);
8245 test
= GetWindow(child2
, GW_OWNER
);
8246 ok(!test
, "wrong owner %p\n", test
);
8248 test
= SetParent(child2
, parent
);
8249 ok(test
== GetDesktopWindow(), "wrong old parent %p\n", test
);
8251 /* test owner/parent of the parent */
8252 test
= GetParent(parent
);
8253 ok(!test
, "wrong parent %p\n", test
);
8254 ok(!IsChild(GetDesktopWindow(), parent
), "wrong parent/child %p/%p\n", GetDesktopWindow(), parent
);
8256 test
= pGetAncestor(parent
, GA_PARENT
);
8257 ok(test
== GetDesktopWindow(), "wrong parent %p\n", test
);
8259 test
= GetWindow(parent
, GW_OWNER
);
8260 ok(!test
, "wrong owner %p\n", test
);
8262 /* test owner/parent of child1 */
8263 test
= GetParent(child1
);
8264 ok(test
== parent
, "wrong parent %p\n", test
);
8265 ok(IsChild(parent
, child1
), "wrong parent/child %p/%p\n", parent
, child1
);
8267 test
= pGetAncestor(child1
, GA_PARENT
);
8268 ok(test
== parent
, "wrong parent %p\n", test
);
8270 test
= GetWindow(child1
, GW_OWNER
);
8271 ok(!test
, "wrong owner %p\n", test
);
8273 /* test owner/parent of child2 */
8274 test
= GetParent(child2
);
8275 ok(test
== parent
, "wrong parent %p\n", test
);
8276 ok(IsChild(parent
, child2
), "wrong parent/child %p/%p\n", parent
, child2
);
8278 test
= pGetAncestor(child2
, GA_PARENT
);
8279 ok(test
== parent
, "wrong parent %p\n", test
);
8281 test
= GetWindow(child2
, GW_OWNER
);
8282 ok(!test
, "wrong owner %p\n", test
);
8284 /* test owner/parent of child3 */
8285 test
= GetParent(child3
);
8286 ok(test
== child1
, "wrong parent %p\n", test
);
8287 ok(IsChild(parent
, child3
), "wrong parent/child %p/%p\n", parent
, child3
);
8289 test
= pGetAncestor(child3
, GA_PARENT
);
8290 ok(test
== child1
, "wrong parent %p\n", test
);
8292 test
= GetWindow(child3
, GW_OWNER
);
8293 ok(!test
, "wrong owner %p\n", test
);
8295 /* test owner/parent of child4 */
8296 test
= GetParent(child4
);
8297 ok(test
== parent
, "wrong parent %p\n", test
);
8298 ok(!IsChild(parent
, child4
), "wrong parent/child %p/%p\n", parent
, child4
);
8300 test
= pGetAncestor(child4
, GA_PARENT
);
8301 ok(test
== GetDesktopWindow(), "wrong parent %p\n", test
);
8303 test
= GetWindow(child4
, GW_OWNER
);
8304 ok(test
== parent
, "wrong owner %p\n", test
);
8308 trace("parent %p, child1 %p, child2 %p, child3 %p, child4 %p\n",
8309 parent
, child1
, child2
, child3
, child4
);
8312 test
= GetCapture();
8313 ok(test
== child4
, "wrong capture window %p\n", test
);
8315 test_DestroyWindow_flag
= TRUE
;
8316 ret
= DestroyWindow(parent
);
8317 ok( ret
, "DestroyWindow() error %d\n", GetLastError());
8318 test_DestroyWindow_flag
= FALSE
;
8319 ok_sequence(destroy_window_with_children
, "destroy window with children", 0);
8321 ok(!IsWindow(parent
), "parent still exists\n");
8322 ok(!IsWindow(child1
), "child1 still exists\n");
8323 ok(!IsWindow(child2
), "child2 still exists\n");
8324 ok(!IsWindow(child3
), "child3 still exists\n");
8325 ok(!IsWindow(child4
), "child4 still exists\n");
8327 test
= GetCapture();
8328 ok(!test
, "wrong capture window %p\n", test
);
8332 static const struct message WmDispatchPaint
[] = {
8333 { WM_NCPAINT
, sent
},
8334 { WM_GETTEXT
, sent
|defwinproc
|optional
},
8335 { WM_GETTEXT
, sent
|defwinproc
|optional
},
8336 { WM_ERASEBKGND
, sent
},
8340 static LRESULT WINAPI
DispatchMessageCheckProc(HWND hwnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
8342 if (message
== WM_PAINT
) return 0;
8343 return MsgCheckProcA( hwnd
, message
, wParam
, lParam
);
8346 static void test_DispatchMessage(void)
8351 HWND hwnd
= CreateWindowA( "TestWindowClass", NULL
, WS_OVERLAPPEDWINDOW
,
8352 100, 100, 200, 200, 0, 0, 0, NULL
);
8353 ShowWindow( hwnd
, SW_SHOW
);
8354 UpdateWindow( hwnd
);
8357 SetWindowLongPtrA( hwnd
, GWLP_WNDPROC
, (LONG_PTR
)DispatchMessageCheckProc
);
8359 SetRect( &rect
, -5, -5, 5, 5 );
8360 RedrawWindow( hwnd
, &rect
, 0, RDW_INVALIDATE
|RDW_ERASE
|RDW_FRAME
);
8362 while (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
))
8364 if (msg
.message
!= WM_PAINT
) DispatchMessage( &msg
);
8368 DispatchMessage( &msg
);
8369 /* DispatchMessage will send WM_NCPAINT if non client area is still invalid after WM_PAINT */
8370 if (!count
) ok_sequence( WmDispatchPaint
, "WmDispatchPaint", FALSE
);
8371 else ok_sequence( WmEmptySeq
, "WmEmpty", FALSE
);
8372 if (++count
> 10) break;
8375 ok( msg
.message
== WM_PAINT
&& count
> 10, "WM_PAINT messages stopped\n" );
8377 trace("now without DispatchMessage\n");
8379 RedrawWindow( hwnd
, &rect
, 0, RDW_INVALIDATE
|RDW_ERASE
|RDW_FRAME
);
8381 while (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
))
8383 if (msg
.message
!= WM_PAINT
) DispatchMessage( &msg
);
8386 HRGN hrgn
= CreateRectRgn( 0, 0, 0, 0 );
8388 /* this will send WM_NCCPAINT just like DispatchMessage does */
8389 GetUpdateRgn( hwnd
, hrgn
, TRUE
);
8390 ok_sequence( WmDispatchPaint
, "WmDispatchPaint", FALSE
);
8391 DeleteObject( hrgn
);
8392 GetClientRect( hwnd
, &rect
);
8393 ValidateRect( hwnd
, &rect
); /* this will stop WM_PAINTs */
8394 ok( !count
, "Got multiple WM_PAINTs\n" );
8395 if (++count
> 10) break;
8398 DestroyWindow(hwnd
);
8402 static const struct message WmUser
[] = {
8414 static DWORD CALLBACK
send_msg_thread( LPVOID arg
)
8416 struct sendmsg_info
*info
= arg
;
8417 SetLastError( 0xdeadbeef );
8418 info
->ret
= SendMessageTimeoutA( info
->hwnd
, WM_USER
, 0, 0, 0, info
->timeout
, NULL
);
8419 if (!info
->ret
) ok( GetLastError() == ERROR_TIMEOUT
||
8420 broken(GetLastError() == 0), /* win9x */
8421 "unexpected error %d\n", GetLastError());
8425 static void wait_for_thread( HANDLE thread
)
8427 while (MsgWaitForMultipleObjects(1, &thread
, FALSE
, INFINITE
, QS_SENDMESSAGE
) != WAIT_OBJECT_0
)
8430 while (PeekMessageA( &msg
, 0, 0, 0, PM_REMOVE
)) DispatchMessage(&msg
);
8434 static LRESULT WINAPI
send_msg_delay_proc(HWND hwnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
8436 if (message
== WM_USER
) Sleep(200);
8437 return MsgCheckProcA( hwnd
, message
, wParam
, lParam
);
8440 static void test_SendMessageTimeout(void)
8443 struct sendmsg_info info
;
8447 info
.hwnd
= CreateWindowA( "TestWindowClass", NULL
, WS_OVERLAPPEDWINDOW
,
8448 100, 100, 200, 200, 0, 0, 0, NULL
);
8452 info
.timeout
= 1000;
8453 info
.ret
= 0xdeadbeef;
8454 thread
= CreateThread( NULL
, 0, send_msg_thread
, &info
, 0, &tid
);
8455 wait_for_thread( thread
);
8456 CloseHandle( thread
);
8457 ok( info
.ret
== 1, "SendMessageTimeout failed\n" );
8458 ok_sequence( WmUser
, "WmUser", FALSE
);
8461 info
.ret
= 0xdeadbeef;
8462 thread
= CreateThread( NULL
, 0, send_msg_thread
, &info
, 0, &tid
);
8463 Sleep(100); /* SendMessageTimeout should time out here */
8464 wait_for_thread( thread
);
8465 CloseHandle( thread
);
8466 ok( info
.ret
== 0, "SendMessageTimeout succeeded\n" );
8467 ok_sequence( WmEmptySeq
, "WmEmptySeq", FALSE
);
8469 /* 0 means infinite timeout (but not on win9x) */
8471 info
.ret
= 0xdeadbeef;
8472 thread
= CreateThread( NULL
, 0, send_msg_thread
, &info
, 0, &tid
);
8474 wait_for_thread( thread
);
8475 CloseHandle( thread
);
8476 is_win9x
= !info
.ret
;
8477 if (is_win9x
) ok_sequence( WmEmptySeq
, "WmEmptySeq", FALSE
);
8478 else ok_sequence( WmUser
, "WmUser", FALSE
);
8480 /* timeout is treated as signed despite the prototype (but not on win9x) */
8481 info
.timeout
= 0x7fffffff;
8482 info
.ret
= 0xdeadbeef;
8483 thread
= CreateThread( NULL
, 0, send_msg_thread
, &info
, 0, &tid
);
8485 wait_for_thread( thread
);
8486 CloseHandle( thread
);
8487 ok( info
.ret
== 1, "SendMessageTimeout failed\n" );
8488 ok_sequence( WmUser
, "WmUser", FALSE
);
8490 info
.timeout
= 0x80000000;
8491 info
.ret
= 0xdeadbeef;
8492 thread
= CreateThread( NULL
, 0, send_msg_thread
, &info
, 0, &tid
);
8494 wait_for_thread( thread
);
8495 CloseHandle( thread
);
8498 ok( info
.ret
== 1, "SendMessageTimeout failed\n" );
8499 ok_sequence( WmUser
, "WmUser", FALSE
);
8503 ok( info
.ret
== 0, "SendMessageTimeout succeeded\n" );
8504 ok_sequence( WmEmptySeq
, "WmEmptySeq", FALSE
);
8507 /* now check for timeout during message processing */
8508 SetWindowLongPtrA( info
.hwnd
, GWLP_WNDPROC
, (LONG_PTR
)send_msg_delay_proc
);
8510 info
.ret
= 0xdeadbeef;
8511 thread
= CreateThread( NULL
, 0, send_msg_thread
, &info
, 0, &tid
);
8512 wait_for_thread( thread
);
8513 CloseHandle( thread
);
8514 /* we should time out but still get the message */
8515 ok( info
.ret
== 0, "SendMessageTimeout failed\n" );
8516 ok_sequence( WmUser
, "WmUser", FALSE
);
8518 DestroyWindow( info
.hwnd
);
8522 /****************** edit message test *************************/
8523 #define ID_EDIT 0x1234
8524 static const struct message sl_edit_setfocus
[] =
8526 { HCBT_SETFOCUS
, hook
},
8527 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 1 },
8528 { WM_IME_NOTIFY
, sent
|wparam
|defwinproc
|optional
, 2 },
8529 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
8530 { WM_SETFOCUS
, sent
|wparam
, 0 },
8531 { WM_IME_NOTIFY
, sent
|wparam
|defwinproc
|optional
, 10 },
8532 { WM_IME_NOTIFY
, sent
|wparam
|defwinproc
|optional
, 15 },
8533 { WM_CTLCOLOREDIT
, sent
|parent
},
8534 { WM_IME_NOTIFY
, sent
|wparam
|defwinproc
|optional
, 11 },
8535 { EVENT_OBJECT_CREATE
, winevent_hook
|wparam
|lparam
, OBJID_CARET
, 0 },
8536 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, OBJID_CARET
, 0 },
8537 { WM_COMMAND
, sent
|parent
|wparam
, MAKEWPARAM(ID_EDIT
, EN_SETFOCUS
) },
8540 static const struct message ml_edit_setfocus
[] =
8542 { HCBT_SETFOCUS
, hook
},
8543 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 1 },
8544 { WM_IME_NOTIFY
, sent
|wparam
|defwinproc
|optional
, 2 },
8545 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
8546 { WM_SETFOCUS
, sent
|wparam
, 0 },
8547 { WM_IME_NOTIFY
, sent
|wparam
|defwinproc
|optional
, 10 },
8548 { WM_IME_NOTIFY
, sent
|wparam
|defwinproc
|optional
, 11 },
8549 { EVENT_OBJECT_CREATE
, winevent_hook
|wparam
|lparam
, OBJID_CARET
, 0 },
8550 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, OBJID_CARET
, 0 },
8551 { WM_COMMAND
, sent
|parent
|wparam
, MAKEWPARAM(ID_EDIT
, EN_SETFOCUS
) },
8554 static const struct message sl_edit_killfocus
[] =
8556 { HCBT_SETFOCUS
, hook
},
8557 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
8558 { WM_KILLFOCUS
, sent
|wparam
, 0 },
8559 { EVENT_OBJECT_HIDE
, winevent_hook
|wparam
|lparam
, OBJID_CARET
, 0 },
8560 { EVENT_OBJECT_DESTROY
, winevent_hook
|wparam
|lparam
, OBJID_CARET
, 0 },
8561 { WM_COMMAND
, sent
|parent
|wparam
, MAKEWPARAM(ID_EDIT
, EN_KILLFOCUS
) },
8562 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 0 },
8563 { WM_IME_NOTIFY
, sent
|wparam
|defwinproc
|optional
, 1 },
8566 static const struct message sl_edit_lbutton_dblclk
[] =
8568 { WM_LBUTTONDBLCLK
, sent
},
8569 { EVENT_SYSTEM_CAPTURESTART
, winevent_hook
|wparam
|lparam
, 0, 0 },
8572 static const struct message sl_edit_lbutton_down
[] =
8574 { WM_LBUTTONDOWN
, sent
|wparam
|lparam
, 0, 0 },
8575 { HCBT_SETFOCUS
, hook
},
8576 { WM_IME_SETCONTEXT
, sent
|wparam
|defwinproc
|optional
, 1 },
8577 { WM_IME_NOTIFY
, sent
|wparam
|defwinproc
|optional
, 2 },
8578 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
8579 { WM_SETFOCUS
, sent
|wparam
|defwinproc
, 0 },
8580 { WM_IME_NOTIFY
, sent
|wparam
|defwinproc
|optional
, 10 },
8581 { WM_CTLCOLOREDIT
, sent
|parent
},
8582 { WM_IME_NOTIFY
, sent
|wparam
|defwinproc
|optional
, 11 },
8583 { EVENT_OBJECT_CREATE
, winevent_hook
|wparam
|lparam
, OBJID_CARET
, 0 },
8584 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, OBJID_CARET
, 0 },
8585 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, OBJID_CARET
, 0 },
8586 { WM_COMMAND
, sent
|parent
|wparam
, MAKEWPARAM(ID_EDIT
, EN_SETFOCUS
) },
8587 { EVENT_SYSTEM_CAPTURESTART
, winevent_hook
|wparam
|lparam
, 0, 0 },
8588 { EVENT_OBJECT_HIDE
, winevent_hook
|wparam
|lparam
, OBJID_CARET
, 0 },
8589 { WM_CTLCOLOREDIT
, sent
|parent
|optional
},
8590 { WM_IME_NOTIFY
, sent
|wparam
|defwinproc
|optional
, 11 },
8591 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, OBJID_CARET
, 0 },
8592 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, OBJID_CARET
, 0 },
8595 static const struct message ml_edit_lbutton_down
[] =
8597 { WM_LBUTTONDOWN
, sent
|wparam
|lparam
, 0, 0 },
8598 { EVENT_SYSTEM_CAPTURESTART
, winevent_hook
|wparam
|lparam
, 0, 0 },
8599 { HCBT_SETFOCUS
, hook
},
8600 { WM_IME_SETCONTEXT
, sent
|wparam
|defwinproc
|optional
, 1 },
8601 { WM_IME_NOTIFY
, sent
|wparam
|defwinproc
|optional
, 2 },
8602 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
8603 { WM_SETFOCUS
, sent
|wparam
|defwinproc
, 0 },
8604 { WM_IME_NOTIFY
, sent
|wparam
|defwinproc
|optional
, 10 },
8605 { WM_IME_NOTIFY
, sent
|wparam
|defwinproc
|optional
, 11 },
8606 { EVENT_OBJECT_CREATE
, winevent_hook
|wparam
|lparam
, OBJID_CARET
, 0 },
8607 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, OBJID_CARET
, 0 },
8608 { WM_COMMAND
, sent
|parent
|wparam
, MAKEWPARAM(ID_EDIT
, EN_SETFOCUS
) },
8611 static const struct message sl_edit_lbutton_up
[] =
8613 { WM_LBUTTONUP
, sent
|wparam
|lparam
, 0, 0 },
8614 { EVENT_OBJECT_HIDE
, winevent_hook
|wparam
|lparam
, OBJID_CARET
, 0 },
8615 { EVENT_SYSTEM_CAPTUREEND
, winevent_hook
|wparam
|lparam
, 0, 0 },
8616 { WM_CAPTURECHANGED
, sent
|defwinproc
},
8617 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, OBJID_CARET
, 0 },
8620 static const struct message ml_edit_lbutton_up
[] =
8622 { WM_LBUTTONUP
, sent
|wparam
|lparam
, 0, 0 },
8623 { EVENT_SYSTEM_CAPTUREEND
, winevent_hook
|wparam
|lparam
, 0, 0 },
8624 { WM_CAPTURECHANGED
, sent
|defwinproc
},
8628 static WNDPROC old_edit_proc
;
8630 static LRESULT CALLBACK
edit_hook_proc(HWND hwnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
8632 static long defwndproc_counter
= 0;
8634 struct recvd_message msg
;
8636 /* explicitly ignore WM_GETICON message */
8637 if (message
== WM_GETICON
) return 0;
8640 msg
.message
= message
;
8641 msg
.flags
= sent
|wparam
|lparam
;
8642 if (defwndproc_counter
) msg
.flags
|= defwinproc
;
8643 msg
.wParam
= wParam
;
8644 msg
.lParam
= lParam
;
8648 defwndproc_counter
++;
8649 ret
= CallWindowProcA(old_edit_proc
, hwnd
, message
, wParam
, lParam
);
8650 defwndproc_counter
--;
8655 static void subclass_edit(void)
8659 if (!GetClassInfoA(0, "edit", &cls
)) assert(0);
8661 old_edit_proc
= cls
.lpfnWndProc
;
8663 cls
.hInstance
= GetModuleHandle(0);
8664 cls
.lpfnWndProc
= edit_hook_proc
;
8665 cls
.lpszClassName
= "my_edit_class";
8666 UnregisterClass(cls
.lpszClassName
, cls
.hInstance
);
8667 if (!RegisterClassA(&cls
)) assert(0);
8670 static void test_edit_messages(void)
8676 log_all_parent_messages
++;
8678 parent
= CreateWindowExA(0, "TestParentClass", "Test parent", WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
8679 100, 100, 200, 200, 0, 0, 0, NULL
);
8680 ok (parent
!= 0, "Failed to create parent window\n");
8682 /* test single line edit */
8683 hwnd
= CreateWindowExA(0, "my_edit_class", "test", WS_CHILD
,
8684 0, 0, 80, 20, parent
, (HMENU
)ID_EDIT
, 0, NULL
);
8685 ok(hwnd
!= 0, "Failed to create edit window\n");
8687 dlg_code
= SendMessageA(hwnd
, WM_GETDLGCODE
, 0, 0);
8688 ok(dlg_code
== (DLGC_WANTCHARS
|DLGC_HASSETSEL
|DLGC_WANTARROWS
), "wrong dlg_code %08x\n", dlg_code
);
8690 ShowWindow(hwnd
, SW_SHOW
);
8696 ok_sequence(sl_edit_setfocus
, "SetFocus(hwnd) on an edit", FALSE
);
8699 ok_sequence(sl_edit_killfocus
, "SetFocus(0) on an edit", FALSE
);
8705 SendMessageA(hwnd
, WM_LBUTTONDBLCLK
, 0, 0);
8706 ok_sequence(sl_edit_lbutton_dblclk
, "WM_LBUTTONDBLCLK on an edit", FALSE
);
8712 SendMessageA(hwnd
, WM_LBUTTONDOWN
, 0, 0);
8713 ok_sequence(sl_edit_lbutton_down
, "WM_LBUTTONDOWN on an edit", FALSE
);
8715 SendMessageA(hwnd
, WM_LBUTTONUP
, 0, 0);
8716 ok_sequence(sl_edit_lbutton_up
, "WM_LBUTTONUP on an edit", FALSE
);
8718 DestroyWindow(hwnd
);
8720 /* test multiline edit */
8721 hwnd
= CreateWindowExA(0, "my_edit_class", "test", WS_CHILD
| ES_MULTILINE
,
8722 0, 0, 80, 20, parent
, (HMENU
)ID_EDIT
, 0, NULL
);
8723 ok(hwnd
!= 0, "Failed to create edit window\n");
8725 dlg_code
= SendMessageA(hwnd
, WM_GETDLGCODE
, 0, 0);
8726 ok(dlg_code
== (DLGC_WANTCHARS
|DLGC_HASSETSEL
|DLGC_WANTARROWS
|DLGC_WANTALLKEYS
),
8727 "wrong dlg_code %08x\n", dlg_code
);
8729 ShowWindow(hwnd
, SW_SHOW
);
8735 ok_sequence(ml_edit_setfocus
, "SetFocus(hwnd) on multiline edit", FALSE
);
8738 ok_sequence(sl_edit_killfocus
, "SetFocus(0) on multiline edit", FALSE
);
8744 SendMessageA(hwnd
, WM_LBUTTONDBLCLK
, 0, 0);
8745 ok_sequence(sl_edit_lbutton_dblclk
, "WM_LBUTTONDBLCLK on multiline edit", FALSE
);
8751 SendMessageA(hwnd
, WM_LBUTTONDOWN
, 0, 0);
8752 ok_sequence(ml_edit_lbutton_down
, "WM_LBUTTONDOWN on multiline edit", FALSE
);
8754 SendMessageA(hwnd
, WM_LBUTTONUP
, 0, 0);
8755 ok_sequence(ml_edit_lbutton_up
, "WM_LBUTTONUP on multiline edit", FALSE
);
8757 DestroyWindow(hwnd
);
8758 DestroyWindow(parent
);
8760 log_all_parent_messages
--;
8763 /**************************** End of Edit test ******************************/
8765 static const struct message WmKeyDownSkippedSeq
[] =
8767 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, 'N', 1 }, /* XP */
8770 static const struct message WmKeyDownWasDownSkippedSeq
[] =
8772 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, 'N', 0x40000001 }, /* XP */
8775 static const struct message WmKeyUpSkippedSeq
[] =
8777 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, 'N', 0xc0000001 }, /* XP */
8780 static const struct message WmUserKeyUpSkippedSeq
[] =
8783 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, 'N', 0xc0000001 }, /* XP */
8788 #define EV_SENDMSG 1
8794 HANDLE hevent
[3]; /* 0 - start/stop, 1 - SendMessage, 2 - ack */
8797 static DWORD CALLBACK
send_msg_thread_2(void *param
)
8800 struct peekmsg_info
*info
= param
;
8802 trace("thread: looping\n");
8803 SetEvent(info
->hevent
[EV_ACK
]);
8807 ret
= WaitForMultipleObjects(2, info
->hevent
, FALSE
, INFINITE
);
8811 case WAIT_OBJECT_0
+ EV_STOP
:
8812 trace("thread: exiting\n");
8815 case WAIT_OBJECT_0
+ EV_SENDMSG
:
8816 trace("thread: sending message\n");
8817 ok( SendNotifyMessageA(info
->hwnd
, WM_USER
, 0, 0),
8818 "SendNotifyMessageA failed error %u\n", GetLastError());
8819 SetEvent(info
->hevent
[EV_ACK
]);
8823 trace("unexpected return: %04x\n", ret
);
8831 static void test_PeekMessage(void)
8836 UINT qs_all_input
= QS_ALLINPUT
;
8837 UINT qs_input
= QS_INPUT
;
8839 struct peekmsg_info info
;
8841 info
.hwnd
= CreateWindowA("TestWindowClass", NULL
, WS_OVERLAPPEDWINDOW
,
8842 100, 100, 200, 200, 0, 0, 0, NULL
);
8844 ShowWindow(info
.hwnd
, SW_SHOW
);
8845 UpdateWindow(info
.hwnd
);
8846 SetFocus(info
.hwnd
);
8848 info
.hevent
[EV_STOP
] = CreateEventA(NULL
, 0, 0, NULL
);
8849 info
.hevent
[EV_SENDMSG
] = CreateEventA(NULL
, 0, 0, NULL
);
8850 info
.hevent
[EV_ACK
] = CreateEventA(NULL
, 0, 0, NULL
);
8852 hthread
= CreateThread(NULL
, 0, send_msg_thread_2
, &info
, 0, &tid
);
8853 WaitForSingleObject(info
.hevent
[EV_ACK
], 10000);
8858 SetLastError(0xdeadbeef);
8859 qstatus
= GetQueueStatus(qs_all_input
);
8860 if (GetLastError() == ERROR_INVALID_FLAGS
)
8862 trace("QS_RAWINPUT not supported on this platform\n");
8863 qs_all_input
&= ~QS_RAWINPUT
;
8864 qs_input
&= ~QS_RAWINPUT
;
8866 ok(qstatus
== 0, "wrong qstatus %08x\n", qstatus
);
8868 trace("signalling to send message\n");
8869 SetEvent(info
.hevent
[EV_SENDMSG
]);
8870 WaitForSingleObject(info
.hevent
[EV_ACK
], INFINITE
);
8872 /* pass invalid QS_xxxx flags */
8873 SetLastError(0xdeadbeef);
8874 qstatus
= GetQueueStatus(0xffffffff);
8875 ok(qstatus
== 0 || broken(qstatus
) /* win9x */, "GetQueueStatus should fail: %08x\n", qstatus
);
8878 ok(GetLastError() == ERROR_INVALID_FLAGS
, "wrong error %d\n", GetLastError());
8879 qstatus
= GetQueueStatus(qs_all_input
);
8881 ok(qstatus
== MAKELONG(QS_SENDMESSAGE
, QS_SENDMESSAGE
),
8882 "wrong qstatus %08x\n", qstatus
);
8885 ret
= PeekMessageA(&msg
, 0, 0, 0, PM_REMOVE
);
8887 "PeekMessageA should have returned FALSE instead of msg %04x\n",
8889 ok_sequence(WmUser
, "WmUser", FALSE
);
8891 qstatus
= GetQueueStatus(qs_all_input
);
8892 ok(qstatus
== 0, "wrong qstatus %08x\n", qstatus
);
8894 keybd_event('N', 0, 0, 0);
8895 keybd_event('N', 0, KEYEVENTF_KEYUP
, 0);
8896 qstatus
= GetQueueStatus(qs_all_input
);
8897 ok(qstatus
== MAKELONG(QS_KEY
, QS_KEY
),
8898 "wrong qstatus %08x\n", qstatus
);
8900 PostMessageA(info
.hwnd
, WM_CHAR
, 'z', 0);
8901 qstatus
= GetQueueStatus(qs_all_input
);
8902 ok(qstatus
== MAKELONG(QS_POSTMESSAGE
, QS_POSTMESSAGE
|QS_KEY
),
8903 "wrong qstatus %08x\n", qstatus
);
8905 InvalidateRect(info
.hwnd
, NULL
, FALSE
);
8906 qstatus
= GetQueueStatus(qs_all_input
);
8907 ok(qstatus
== MAKELONG(QS_PAINT
, QS_PAINT
|QS_POSTMESSAGE
|QS_KEY
),
8908 "wrong qstatus %08x\n", qstatus
);
8910 trace("signalling to send message\n");
8911 SetEvent(info
.hevent
[EV_SENDMSG
]);
8912 WaitForSingleObject(info
.hevent
[EV_ACK
], INFINITE
);
8914 qstatus
= GetQueueStatus(qs_all_input
);
8915 ok(qstatus
== MAKELONG(QS_SENDMESSAGE
, QS_SENDMESSAGE
|QS_PAINT
|QS_POSTMESSAGE
|QS_KEY
),
8916 "wrong qstatus %08x\n", qstatus
);
8919 ret
= PeekMessageA(&msg
, 0, 0, 0, PM_REMOVE
| (qs_input
<< 16));
8920 if (ret
&& msg
.message
== WM_CHAR
)
8922 win_skip( "PM_QS_* flags not supported in PeekMessage\n" );
8926 "PeekMessageA should have returned FALSE instead of msg %04x\n",
8928 if (!sequence_cnt
) /* nt4 doesn't fetch anything with PM_QS_* flags */
8930 win_skip( "PM_QS_* flags not supported in PeekMessage\n" );
8933 ok_sequence(WmUser
, "WmUser", FALSE
);
8935 qstatus
= GetQueueStatus(qs_all_input
);
8936 ok(qstatus
== MAKELONG(0, QS_PAINT
|QS_POSTMESSAGE
|QS_KEY
),
8937 "wrong qstatus %08x\n", qstatus
);
8939 trace("signalling to send message\n");
8940 SetEvent(info
.hevent
[EV_SENDMSG
]);
8941 WaitForSingleObject(info
.hevent
[EV_ACK
], INFINITE
);
8943 qstatus
= GetQueueStatus(qs_all_input
);
8944 ok(qstatus
== MAKELONG(QS_SENDMESSAGE
, QS_SENDMESSAGE
|QS_PAINT
|QS_POSTMESSAGE
|QS_KEY
),
8945 "wrong qstatus %08x\n", qstatus
);
8948 ret
= PeekMessageA(&msg
, 0, 0, 0, PM_REMOVE
| PM_QS_POSTMESSAGE
);
8950 "PeekMessageA should have returned FALSE instead of msg %04x\n",
8952 ok_sequence(WmUser
, "WmUser", FALSE
);
8954 qstatus
= GetQueueStatus(qs_all_input
);
8955 ok(qstatus
== MAKELONG(0, QS_PAINT
|QS_POSTMESSAGE
|QS_KEY
),
8956 "wrong qstatus %08x\n", qstatus
);
8959 ret
= PeekMessageA(&msg
, 0, 0, 0, PM_REMOVE
| PM_QS_POSTMESSAGE
);
8960 ok(ret
&& msg
.message
== WM_CHAR
&& msg
.wParam
== 'z',
8961 "got %d and %04x wParam %08lx instead of TRUE and WM_CHAR wParam 'z'\n",
8962 ret
, msg
.message
, msg
.wParam
);
8963 ok_sequence(WmEmptySeq
, "WmEmptySeq", FALSE
);
8965 qstatus
= GetQueueStatus(qs_all_input
);
8966 ok(qstatus
== MAKELONG(0, QS_PAINT
|QS_KEY
),
8967 "wrong qstatus %08x\n", qstatus
);
8970 ret
= PeekMessageA(&msg
, 0, 0, 0, PM_REMOVE
| PM_QS_POSTMESSAGE
);
8972 "PeekMessageA should have returned FALSE instead of msg %04x\n",
8974 ok_sequence(WmEmptySeq
, "WmEmptySeq", FALSE
);
8976 qstatus
= GetQueueStatus(qs_all_input
);
8977 ok(qstatus
== MAKELONG(0, QS_PAINT
|QS_KEY
),
8978 "wrong qstatus %08x\n", qstatus
);
8981 ret
= PeekMessageA(&msg
, 0, 0, 0, PM_REMOVE
| PM_QS_PAINT
);
8982 ok(ret
&& msg
.message
== WM_PAINT
,
8983 "got %d and %04x instead of TRUE and WM_PAINT\n", ret
, msg
.message
);
8984 DispatchMessageA(&msg
);
8985 ok_sequence(WmPaint
, "WmPaint", FALSE
);
8987 qstatus
= GetQueueStatus(qs_all_input
);
8988 ok(qstatus
== MAKELONG(0, QS_KEY
),
8989 "wrong qstatus %08x\n", qstatus
);
8992 ret
= PeekMessageA(&msg
, 0, 0, 0, PM_REMOVE
| PM_QS_PAINT
);
8994 "PeekMessageA should have returned FALSE instead of msg %04x\n",
8996 ok_sequence(WmEmptySeq
, "WmEmptySeq", FALSE
);
8998 qstatus
= GetQueueStatus(qs_all_input
);
8999 ok(qstatus
== MAKELONG(0, QS_KEY
),
9000 "wrong qstatus %08x\n", qstatus
);
9002 trace("signalling to send message\n");
9003 SetEvent(info
.hevent
[EV_SENDMSG
]);
9004 WaitForSingleObject(info
.hevent
[EV_ACK
], INFINITE
);
9006 qstatus
= GetQueueStatus(qs_all_input
);
9007 ok(qstatus
== MAKELONG(QS_SENDMESSAGE
, QS_SENDMESSAGE
|QS_KEY
),
9008 "wrong qstatus %08x\n", qstatus
);
9010 PostMessageA(info
.hwnd
, WM_CHAR
, 'z', 0);
9012 qstatus
= GetQueueStatus(qs_all_input
);
9013 ok(qstatus
== MAKELONG(QS_POSTMESSAGE
, QS_SENDMESSAGE
|QS_POSTMESSAGE
|QS_KEY
),
9014 "wrong qstatus %08x\n", qstatus
);
9017 ret
= PeekMessageA(&msg
, 0, WM_CHAR
, WM_CHAR
, PM_REMOVE
);
9018 ok(ret
&& msg
.message
== WM_CHAR
&& msg
.wParam
== 'z',
9019 "got %d and %04x wParam %08lx instead of TRUE and WM_CHAR wParam 'z'\n",
9020 ret
, msg
.message
, msg
.wParam
);
9021 ok_sequence(WmUser
, "WmUser", FALSE
);
9023 qstatus
= GetQueueStatus(qs_all_input
);
9024 ok(qstatus
== MAKELONG(0, QS_KEY
),
9025 "wrong qstatus %08x\n", qstatus
);
9028 ret
= PeekMessageA(&msg
, 0, WM_CHAR
, WM_CHAR
, PM_REMOVE
);
9030 "PeekMessageA should have returned FALSE instead of msg %04x\n",
9032 ok_sequence(WmEmptySeq
, "WmEmptySeq", FALSE
);
9034 qstatus
= GetQueueStatus(qs_all_input
);
9035 ok(qstatus
== MAKELONG(0, QS_KEY
),
9036 "wrong qstatus %08x\n", qstatus
);
9038 PostMessageA(info
.hwnd
, WM_CHAR
, 'z', 0);
9040 qstatus
= GetQueueStatus(qs_all_input
);
9041 ok(qstatus
== MAKELONG(QS_POSTMESSAGE
, QS_POSTMESSAGE
|QS_KEY
),
9042 "wrong qstatus %08x\n", qstatus
);
9044 trace("signalling to send message\n");
9045 SetEvent(info
.hevent
[EV_SENDMSG
]);
9046 WaitForSingleObject(info
.hevent
[EV_ACK
], INFINITE
);
9048 qstatus
= GetQueueStatus(qs_all_input
);
9049 ok(qstatus
== MAKELONG(QS_SENDMESSAGE
, QS_SENDMESSAGE
|QS_POSTMESSAGE
|QS_KEY
),
9050 "wrong qstatus %08x\n", qstatus
);
9053 ret
= PeekMessageA(&msg
, 0, 0, 0, PM_REMOVE
| (QS_KEY
<< 16));
9055 "PeekMessageA should have returned FALSE instead of msg %04x\n",
9057 ok_sequence(WmUser
, "WmUser", FALSE
);
9059 qstatus
= GetQueueStatus(qs_all_input
);
9060 ok(qstatus
== MAKELONG(0, QS_POSTMESSAGE
|QS_KEY
),
9061 "wrong qstatus %08x\n", qstatus
);
9064 if (qs_all_input
& QS_RAWINPUT
) /* use QS_RAWINPUT only if supported */
9065 ret
= PeekMessageA(&msg
, 0, 0, 0, PM_REMOVE
| (QS_RAWINPUT
<< 16));
9066 else /* workaround for a missing QS_RAWINPUT support */
9067 ret
= PeekMessageA(&msg
, 0, WM_KEYDOWN
, WM_KEYDOWN
, PM_REMOVE
);
9068 ok(ret
&& msg
.message
== WM_KEYDOWN
&& msg
.wParam
== 'N',
9069 "got %d and %04x wParam %08lx instead of TRUE and WM_KEYDOWN wParam 'N'\n",
9070 ret
, msg
.message
, msg
.wParam
);
9071 ok_sequence(WmKeyDownSkippedSeq
, "WmKeyDownSkippedSeq", FALSE
);
9073 qstatus
= GetQueueStatus(qs_all_input
);
9074 ok(qstatus
== MAKELONG(0, QS_POSTMESSAGE
|QS_KEY
),
9075 "wrong qstatus %08x\n", qstatus
);
9078 if (qs_all_input
& QS_RAWINPUT
) /* use QS_RAWINPUT only if supported */
9079 ret
= PeekMessageA(&msg
, 0, 0, 0, PM_REMOVE
| (QS_RAWINPUT
<< 16));
9080 else /* workaround for a missing QS_RAWINPUT support */
9081 ret
= PeekMessageA(&msg
, 0, WM_KEYUP
, WM_KEYUP
, PM_REMOVE
);
9082 ok(ret
&& msg
.message
== WM_KEYUP
&& msg
.wParam
== 'N',
9083 "got %d and %04x wParam %08lx instead of TRUE and WM_KEYUP wParam 'N'\n",
9084 ret
, msg
.message
, msg
.wParam
);
9085 ok_sequence(WmKeyUpSkippedSeq
, "WmKeyUpSkippedSeq", FALSE
);
9087 qstatus
= GetQueueStatus(qs_all_input
);
9088 ok(qstatus
== MAKELONG(0, QS_POSTMESSAGE
),
9089 "wrong qstatus %08x\n", qstatus
);
9092 ret
= PeekMessageA(&msg
, 0, 0, 0, PM_REMOVE
| PM_QS_SENDMESSAGE
);
9094 "PeekMessageA should have returned FALSE instead of msg %04x\n",
9096 ok_sequence(WmEmptySeq
, "WmEmptySeq", FALSE
);
9098 qstatus
= GetQueueStatus(qs_all_input
);
9099 ok(qstatus
== MAKELONG(0, QS_POSTMESSAGE
),
9100 "wrong qstatus %08x\n", qstatus
);
9103 ret
= PeekMessageA(&msg
, 0, 0, 0, PM_REMOVE
);
9104 ok(ret
&& msg
.message
== WM_CHAR
&& msg
.wParam
== 'z',
9105 "got %d and %04x wParam %08lx instead of TRUE and WM_CHAR wParam 'z'\n",
9106 ret
, msg
.message
, msg
.wParam
);
9107 ok_sequence(WmEmptySeq
, "WmEmptySeq", FALSE
);
9109 qstatus
= GetQueueStatus(qs_all_input
);
9111 "wrong qstatus %08x\n", qstatus
);
9114 ret
= PeekMessageA(&msg
, 0, 0, 0, PM_REMOVE
);
9116 "PeekMessageA should have returned FALSE instead of msg %04x\n",
9118 ok_sequence(WmEmptySeq
, "WmEmptySeq", FALSE
);
9120 qstatus
= GetQueueStatus(qs_all_input
);
9122 "wrong qstatus %08x\n", qstatus
);
9124 /* test whether presence of the quit flag in the queue affects
9127 PostQuitMessage(0x1234abcd);
9129 qstatus
= GetQueueStatus(qs_all_input
);
9130 ok(qstatus
== MAKELONG(QS_POSTMESSAGE
, QS_POSTMESSAGE
),
9131 "wrong qstatus %08x\n", qstatus
);
9133 PostMessageA(info
.hwnd
, WM_USER
, 0, 0);
9135 qstatus
= GetQueueStatus(qs_all_input
);
9136 ok(qstatus
== MAKELONG(QS_POSTMESSAGE
, QS_POSTMESSAGE
),
9137 "wrong qstatus %08x\n", qstatus
);
9140 ret
= PeekMessageA(&msg
, 0, 0, 0, PM_REMOVE
);
9141 ok(ret
&& msg
.message
== WM_USER
,
9142 "got %d and %04x instead of TRUE and WM_USER\n", ret
, msg
.message
);
9143 ok_sequence(WmEmptySeq
, "WmEmptySeq", FALSE
);
9145 qstatus
= GetQueueStatus(qs_all_input
);
9146 ok(qstatus
== MAKELONG(0, QS_POSTMESSAGE
),
9147 "wrong qstatus %08x\n", qstatus
);
9150 ret
= PeekMessageA(&msg
, 0, 0, 0, PM_REMOVE
);
9151 ok(ret
&& msg
.message
== WM_QUIT
,
9152 "got %d and %04x instead of TRUE and WM_QUIT\n", ret
, msg
.message
);
9153 ok(msg
.wParam
== 0x1234abcd, "got wParam %08lx instead of 0x1234abcd\n", msg
.wParam
);
9154 ok(msg
.lParam
== 0, "got lParam %08lx instead of 0\n", msg
.lParam
);
9155 ok_sequence(WmEmptySeq
, "WmEmptySeq", FALSE
);
9157 qstatus
= GetQueueStatus(qs_all_input
);
9159 ok(qstatus
== MAKELONG(0, QS_POSTMESSAGE
),
9160 "wrong qstatus %08x\n", qstatus
);
9164 ret
= PeekMessageA(&msg
, 0, 0, 0, PM_REMOVE
);
9166 "PeekMessageA should have returned FALSE instead of msg %04x\n",
9168 ok_sequence(WmEmptySeq
, "WmEmptySeq", FALSE
);
9170 qstatus
= GetQueueStatus(qs_all_input
);
9172 "wrong qstatus %08x\n", qstatus
);
9174 /* some GetMessage tests */
9176 keybd_event('N', 0, 0, 0);
9177 qstatus
= GetQueueStatus(qs_all_input
);
9178 ok(qstatus
== MAKELONG(QS_KEY
, QS_KEY
), "wrong qstatus %08x\n", qstatus
);
9180 PostMessageA(info
.hwnd
, WM_CHAR
, 'z', 0);
9181 qstatus
= GetQueueStatus(qs_all_input
);
9182 ok(qstatus
== MAKELONG(QS_POSTMESSAGE
, QS_POSTMESSAGE
|QS_KEY
), "wrong qstatus %08x\n", qstatus
);
9186 ret
= GetMessageA( &msg
, 0, 0, 0 );
9187 ok(ret
&& msg
.message
== WM_CHAR
&& msg
.wParam
== 'z',
9188 "got %d and %04x wParam %08lx instead of TRUE and WM_CHAR wParam 'z'\n",
9189 ret
, msg
.message
, msg
.wParam
);
9190 qstatus
= GetQueueStatus(qs_all_input
);
9191 ok(qstatus
== MAKELONG(0, QS_KEY
), "wrong qstatus %08x\n", qstatus
);
9196 ret
= GetMessageA( &msg
, 0, 0, 0 );
9197 ok(ret
&& msg
.message
== WM_KEYDOWN
&& msg
.wParam
== 'N',
9198 "got %d and %04x wParam %08lx instead of TRUE and WM_KEYDOWN wParam 'N'\n",
9199 ret
, msg
.message
, msg
.wParam
);
9200 ok_sequence(WmKeyDownSkippedSeq
, "WmKeyDownSkippedSeq", FALSE
);
9201 qstatus
= GetQueueStatus(qs_all_input
);
9202 ok(qstatus
== 0, "wrong qstatus %08x\n", qstatus
);
9205 keybd_event('N', 0, 0, 0);
9206 qstatus
= GetQueueStatus(qs_all_input
);
9207 ok(qstatus
== MAKELONG(QS_KEY
, QS_KEY
), "wrong qstatus %08x\n", qstatus
);
9209 PostMessageA(info
.hwnd
, WM_CHAR
, 'z', 0);
9210 qstatus
= GetQueueStatus(qs_all_input
);
9211 ok(qstatus
== MAKELONG(QS_POSTMESSAGE
, QS_POSTMESSAGE
|QS_KEY
), "wrong qstatus %08x\n", qstatus
);
9213 if (qstatus
& (QS_KEY
<< 16))
9215 ret
= GetMessageA( &msg
, 0, WM_KEYDOWN
, WM_KEYUP
);
9216 ok(ret
&& msg
.message
== WM_KEYDOWN
&& msg
.wParam
== 'N',
9217 "got %d and %04x wParam %08lx instead of TRUE and WM_KEYDOWN wParam 'N'\n",
9218 ret
, msg
.message
, msg
.wParam
);
9219 ok_sequence(WmKeyDownWasDownSkippedSeq
, "WmKeyDownWasDownSkippedSeq", FALSE
);
9220 qstatus
= GetQueueStatus(qs_all_input
);
9221 ok(qstatus
== MAKELONG(0, QS_POSTMESSAGE
), "wrong qstatus %08x\n", qstatus
);
9226 ret
= GetMessageA( &msg
, 0, WM_CHAR
, WM_CHAR
);
9227 ok(ret
&& msg
.message
== WM_CHAR
&& msg
.wParam
== 'z',
9228 "got %d and %04x wParam %08lx instead of TRUE and WM_CHAR wParam 'z'\n",
9229 ret
, msg
.message
, msg
.wParam
);
9230 qstatus
= GetQueueStatus(qs_all_input
);
9231 ok(qstatus
== 0, "wrong qstatus %08x\n", qstatus
);
9234 keybd_event('N', 0, KEYEVENTF_KEYUP
, 0);
9235 qstatus
= GetQueueStatus(qs_all_input
);
9236 ok(qstatus
== MAKELONG(QS_KEY
, QS_KEY
), "wrong qstatus %08x\n", qstatus
);
9238 PostMessageA(info
.hwnd
, WM_CHAR
, 'z', 0);
9239 qstatus
= GetQueueStatus(qs_all_input
);
9240 ok(qstatus
== MAKELONG(QS_POSTMESSAGE
, QS_POSTMESSAGE
|QS_KEY
), "wrong qstatus %08x\n", qstatus
);
9242 trace("signalling to send message\n");
9243 SetEvent(info
.hevent
[EV_SENDMSG
]);
9244 WaitForSingleObject(info
.hevent
[EV_ACK
], INFINITE
);
9245 qstatus
= GetQueueStatus(qs_all_input
);
9246 ok(qstatus
== MAKELONG(QS_SENDMESSAGE
, QS_SENDMESSAGE
|QS_POSTMESSAGE
|QS_KEY
),
9247 "wrong qstatus %08x\n", qstatus
);
9249 if (qstatus
& (QS_KEY
<< 16))
9251 ret
= GetMessageA( &msg
, 0, WM_KEYDOWN
, WM_KEYUP
);
9252 ok(ret
&& msg
.message
== WM_KEYUP
&& msg
.wParam
== 'N',
9253 "got %d and %04x wParam %08lx instead of TRUE and WM_KEYDOWN wParam 'N'\n",
9254 ret
, msg
.message
, msg
.wParam
);
9255 ok_sequence(WmUserKeyUpSkippedSeq
, "WmUserKeyUpSkippedSeq", FALSE
);
9256 qstatus
= GetQueueStatus(qs_all_input
);
9257 ok(qstatus
== MAKELONG(0, QS_POSTMESSAGE
), "wrong qstatus %08x\n", qstatus
);
9262 ret
= GetMessageA( &msg
, 0, WM_CHAR
, WM_CHAR
);
9263 ok(ret
&& msg
.message
== WM_CHAR
&& msg
.wParam
== 'z',
9264 "got %d and %04x wParam %08lx instead of TRUE and WM_CHAR wParam 'z'\n",
9265 ret
, msg
.message
, msg
.wParam
);
9266 qstatus
= GetQueueStatus(qs_all_input
);
9267 ok(qstatus
== 0, "wrong qstatus %08x\n", qstatus
);
9270 trace("signalling to exit\n");
9271 SetEvent(info
.hevent
[EV_STOP
]);
9273 WaitForSingleObject(hthread
, INFINITE
);
9275 CloseHandle(hthread
);
9276 CloseHandle(info
.hevent
[0]);
9277 CloseHandle(info
.hevent
[1]);
9278 CloseHandle(info
.hevent
[2]);
9280 DestroyWindow(info
.hwnd
);
9283 static void wait_move_event(HWND hwnd
, int x
, int y
)
9290 time
= GetTickCount();
9291 while (GetTickCount() - time
< 200 && !go
) {
9292 ret
= PeekMessageA(&msg
, hwnd
, WM_MOUSEMOVE
, WM_MOUSEMOVE
, PM_NOREMOVE
);
9293 go
= ret
&& msg
.pt
.x
> x
&& msg
.pt
.y
> y
;
9294 if (ret
&& !go
) PeekMessageA(&msg
, hwnd
, WM_MOUSEMOVE
, WM_MOUSEMOVE
, PM_REMOVE
);
9299 static void test_PeekMessage2(void)
9305 DWORD time1
, time2
, time3
;
9306 int x1
, y1
, x2
, y2
, x3
, y3
;
9309 time1
= time2
= time3
= 0;
9310 x1
= y1
= x2
= y2
= x3
= y3
= 0;
9312 /* Initialise window and make sure it is ready for events */
9313 hwnd
= CreateWindow("TestWindowClass", "PeekMessage2", WS_OVERLAPPEDWINDOW
,
9314 10, 10, 800, 800, NULL
, NULL
, NULL
, NULL
);
9316 trace("Window for test_PeekMessage2 %p\n", hwnd
);
9317 ShowWindow(hwnd
, SW_SHOW
);
9321 SetCursorPos(100, 100);
9322 mouse_event(MOUSEEVENTF_MOVE
, -STEP
, -STEP
, 0, 0);
9325 /* Do initial mousemove, wait until we can see it
9326 and then do our test peek with PM_NOREMOVE. */
9327 mouse_event(MOUSEEVENTF_MOVE
, STEP
, STEP
, 0, 0);
9328 wait_move_event(hwnd
, 80, 80);
9330 ret
= PeekMessageA(&msg
, hwnd
, WM_MOUSEMOVE
, WM_MOUSEMOVE
, PM_NOREMOVE
);
9331 ok(ret
, "no message available\n");
9333 trace("1st move event: %04x %x %d %d\n", msg
.message
, msg
.time
, msg
.pt
.x
, msg
.pt
.y
);
9334 message
= msg
.message
;
9338 ok(message
== WM_MOUSEMOVE
, "message not WM_MOUSEMOVE, %04x instead\n", message
);
9339 PeekMessageA(&msg
, hwnd
, WM_MOUSEMOVE
, WM_MOUSEMOVE
, PM_REMOVE
);
9342 /* Allow time to advance a bit, and then simulate the user moving their
9343 * mouse around. After that we peek again with PM_NOREMOVE.
9344 * Although the previous mousemove message was never removed, the
9345 * mousemove we now peek should reflect the recent mouse movements
9346 * because the input queue will merge the move events. */
9348 mouse_event(MOUSEEVENTF_MOVE
, STEP
, STEP
, 0, 0);
9349 wait_move_event(hwnd
, x1
, y1
);
9351 ret
= PeekMessageA(&msg
, hwnd
, WM_MOUSEMOVE
, WM_MOUSEMOVE
, PM_NOREMOVE
);
9352 ok(ret
, "no message available\n");
9354 trace("2nd move event: %04x %x %d %d\n", msg
.message
, msg
.time
, msg
.pt
.x
, msg
.pt
.y
);
9355 message
= msg
.message
;
9359 ok(message
== WM_MOUSEMOVE
, "message not WM_MOUSEMOVE, %04x instead\n", message
);
9360 ok(time2
> time1
, "message time not advanced: %x %x\n", time1
, time2
);
9361 ok(x2
!= x1
&& y2
!= y1
, "coords not changed: (%d %d) (%d %d)\n", x1
, y1
, x2
, y2
);
9362 PeekMessageA(&msg
, hwnd
, WM_MOUSEMOVE
, WM_MOUSEMOVE
, PM_REMOVE
);
9365 /* Have another go, to drive the point home */
9367 mouse_event(MOUSEEVENTF_MOVE
, STEP
, STEP
, 0, 0);
9368 wait_move_event(hwnd
, x2
, y2
);
9370 ret
= PeekMessageA(&msg
, hwnd
, WM_MOUSEMOVE
, WM_MOUSEMOVE
, PM_NOREMOVE
);
9371 ok(ret
, "no message available\n");
9373 trace("3rd move event: %04x %x %d %d\n", msg
.message
, msg
.time
, msg
.pt
.x
, msg
.pt
.y
);
9374 message
= msg
.message
;
9378 ok(message
== WM_MOUSEMOVE
, "message not WM_MOUSEMOVE, %04x instead\n", message
);
9379 ok(time3
> time2
, "message time not advanced: %x %x\n", time2
, time3
);
9380 ok(x3
!= x2
&& y3
!= y2
, "coords not changed: (%d %d) (%d %d)\n", x2
, y2
, x3
, y3
);
9383 DestroyWindow(hwnd
);
9384 SetCursorPos(pos
.x
, pos
.y
);
9388 static void test_quit_message(void)
9393 /* test using PostQuitMessage */
9395 PostQuitMessage(0xbeef);
9397 ret
= PeekMessage(&msg
, NULL
, 0, 0, PM_NOREMOVE
);
9398 ok(ret
, "PeekMessage failed with error %d\n", GetLastError());
9399 ok(msg
.message
== WM_QUIT
, "Received message 0x%04x instead of WM_QUIT\n", msg
.message
);
9400 ok(msg
.wParam
== 0xbeef, "wParam was 0x%lx instead of 0xbeef\n", msg
.wParam
);
9402 ret
= PostThreadMessage(GetCurrentThreadId(), WM_USER
, 0, 0);
9403 ok(ret
, "PostMessage failed with error %d\n", GetLastError());
9405 ret
= GetMessage(&msg
, NULL
, 0, 0);
9406 ok(ret
> 0, "GetMessage failed with error %d\n", GetLastError());
9407 ok(msg
.message
== WM_USER
, "Received message 0x%04x instead of WM_USER\n", msg
.message
);
9409 /* note: WM_QUIT message received after WM_USER message */
9410 ret
= GetMessage(&msg
, NULL
, 0, 0);
9411 ok(!ret
, "GetMessage return %d with error %d instead of FALSE\n", ret
, GetLastError());
9412 ok(msg
.message
== WM_QUIT
, "Received message 0x%04x instead of WM_QUIT\n", msg
.message
);
9413 ok(msg
.wParam
== 0xbeef, "wParam was 0x%lx instead of 0xbeef\n", msg
.wParam
);
9415 ret
= PeekMessage(&msg
, NULL
, 0, 0, PM_REMOVE
);
9416 ok( !ret
|| msg
.message
!= WM_QUIT
, "Received WM_QUIT again\n" );
9418 /* now test with PostThreadMessage - different behaviour! */
9419 PostThreadMessage(GetCurrentThreadId(), WM_QUIT
, 0xdead, 0);
9421 ret
= PeekMessage(&msg
, NULL
, 0, 0, PM_NOREMOVE
);
9422 ok(ret
, "PeekMessage failed with error %d\n", GetLastError());
9423 ok(msg
.message
== WM_QUIT
, "Received message 0x%04x instead of WM_QUIT\n", msg
.message
);
9424 ok(msg
.wParam
== 0xdead, "wParam was 0x%lx instead of 0xdead\n", msg
.wParam
);
9426 ret
= PostThreadMessage(GetCurrentThreadId(), WM_USER
, 0, 0);
9427 ok(ret
, "PostMessage failed with error %d\n", GetLastError());
9429 /* note: we receive the WM_QUIT message first this time */
9430 ret
= GetMessage(&msg
, NULL
, 0, 0);
9431 ok(!ret
, "GetMessage return %d with error %d instead of FALSE\n", ret
, GetLastError());
9432 ok(msg
.message
== WM_QUIT
, "Received message 0x%04x instead of WM_QUIT\n", msg
.message
);
9433 ok(msg
.wParam
== 0xdead, "wParam was 0x%lx instead of 0xdead\n", msg
.wParam
);
9435 ret
= GetMessage(&msg
, NULL
, 0, 0);
9436 ok(ret
> 0, "GetMessage failed with error %d\n", GetLastError());
9437 ok(msg
.message
== WM_USER
, "Received message 0x%04x instead of WM_USER\n", msg
.message
);
9440 static const struct message WmMouseHoverSeq
[] = {
9441 { WM_MOUSEACTIVATE
, sent
|optional
}, /* we can get those when moving the mouse in focus-follow-mouse mode under X11 */
9442 { WM_MOUSEACTIVATE
, sent
|optional
},
9443 { WM_TIMER
, sent
|optional
}, /* XP sends it */
9444 { WM_SYSTIMER
, sent
},
9445 { WM_MOUSEHOVER
, sent
|wparam
, 0 },
9449 static void pump_msg_loop_timeout(DWORD timeout
, BOOL inject_mouse_move
)
9452 DWORD start_ticks
, end_ticks
;
9454 start_ticks
= GetTickCount();
9455 /* add some deviation (50%) to cover not expected delays */
9456 start_ticks
+= timeout
/ 2;
9460 while (PeekMessage(&msg
, 0, 0, 0, PM_REMOVE
))
9462 /* Timer proc messages are not dispatched to the window proc,
9463 * and therefore not logged.
9465 if (msg
.message
== WM_TIMER
|| msg
.message
== WM_SYSTIMER
)
9467 struct recvd_message s_msg
;
9469 s_msg
.hwnd
= msg
.hwnd
;
9470 s_msg
.message
= msg
.message
;
9471 s_msg
.flags
= sent
|wparam
|lparam
;
9472 s_msg
.wParam
= msg
.wParam
;
9473 s_msg
.lParam
= msg
.lParam
;
9474 s_msg
.descr
= "msg_loop";
9475 add_message(&s_msg
);
9477 DispatchMessage(&msg
);
9480 end_ticks
= GetTickCount();
9482 /* inject WM_MOUSEMOVE to see how it changes tracking */
9483 if (inject_mouse_move
&& start_ticks
+ timeout
/ 2 >= end_ticks
)
9485 mouse_event(MOUSEEVENTF_MOVE
, -1, 0, 0, 0);
9486 mouse_event(MOUSEEVENTF_MOVE
, 1, 0, 0, 0);
9488 inject_mouse_move
= FALSE
;
9490 } while (start_ticks
+ timeout
>= end_ticks
);
9493 static void test_TrackMouseEvent(void)
9495 TRACKMOUSEEVENT tme
;
9498 RECT rc_parent
, rc_child
;
9499 UINT default_hover_time
, hover_width
= 0, hover_height
= 0;
9501 #define track_hover(track_hwnd, track_hover_time) \
9502 tme.cbSize = sizeof(tme); \
9503 tme.dwFlags = TME_HOVER; \
9504 tme.hwndTrack = track_hwnd; \
9505 tme.dwHoverTime = track_hover_time; \
9506 SetLastError(0xdeadbeef); \
9507 ret = pTrackMouseEvent(&tme); \
9508 ok(ret, "TrackMouseEvent(TME_HOVER) error %d\n", GetLastError())
9510 #define track_query(expected_track_flags, expected_track_hwnd, expected_hover_time) \
9511 tme.cbSize = sizeof(tme); \
9512 tme.dwFlags = TME_QUERY; \
9513 tme.hwndTrack = (HWND)0xdeadbeef; \
9514 tme.dwHoverTime = 0xdeadbeef; \
9515 SetLastError(0xdeadbeef); \
9516 ret = pTrackMouseEvent(&tme); \
9517 ok(ret, "TrackMouseEvent(TME_QUERY) error %d\n", GetLastError());\
9518 ok(tme.cbSize == sizeof(tme), "wrong tme.cbSize %u\n", tme.cbSize); \
9519 ok(tme.dwFlags == (expected_track_flags), \
9520 "wrong tme.dwFlags %08x, expected %08x\n", tme.dwFlags, (expected_track_flags)); \
9521 ok(tme.hwndTrack == (expected_track_hwnd), \
9522 "wrong tme.hwndTrack %p, expected %p\n", tme.hwndTrack, (expected_track_hwnd)); \
9523 ok(tme.dwHoverTime == (expected_hover_time), \
9524 "wrong tme.dwHoverTime %u, expected %u\n", tme.dwHoverTime, (expected_hover_time))
9526 #define track_hover_cancel(track_hwnd) \
9527 tme.cbSize = sizeof(tme); \
9528 tme.dwFlags = TME_HOVER | TME_CANCEL; \
9529 tme.hwndTrack = track_hwnd; \
9530 tme.dwHoverTime = 0xdeadbeef; \
9531 SetLastError(0xdeadbeef); \
9532 ret = pTrackMouseEvent(&tme); \
9533 ok(ret, "TrackMouseEvent(TME_HOVER | TME_CANCEL) error %d\n", GetLastError())
9535 default_hover_time
= 0xdeadbeef;
9536 SetLastError(0xdeadbeef);
9537 ret
= SystemParametersInfo(SPI_GETMOUSEHOVERTIME
, 0, &default_hover_time
, 0);
9538 ok(ret
|| broken(GetLastError() == 0xdeadbeef), /* win9x */
9539 "SystemParametersInfo(SPI_GETMOUSEHOVERTIME) error %u\n", GetLastError());
9540 if (!ret
) default_hover_time
= 400;
9541 trace("SPI_GETMOUSEHOVERTIME returned %u ms\n", default_hover_time
);
9543 SetLastError(0xdeadbeef);
9544 ret
= SystemParametersInfo(SPI_GETMOUSEHOVERWIDTH
, 0, &hover_width
, 0);
9545 ok(ret
|| broken(GetLastError() == 0xdeadbeef), /* win9x */
9546 "SystemParametersInfo(SPI_GETMOUSEHOVERWIDTH) error %u\n", GetLastError());
9547 if (!ret
) hover_width
= 4;
9548 SetLastError(0xdeadbeef);
9549 ret
= SystemParametersInfo(SPI_GETMOUSEHOVERHEIGHT
, 0, &hover_height
, 0);
9550 ok(ret
|| broken(GetLastError() == 0xdeadbeef), /* win9x */
9551 "SystemParametersInfo(SPI_GETMOUSEHOVERHEIGHT) error %u\n", GetLastError());
9552 if (!ret
) hover_height
= 4;
9553 trace("hover rect is %u x %d\n", hover_width
, hover_height
);
9555 hwnd
= CreateWindowEx(0, "TestWindowClass", NULL
,
9556 WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
9557 CW_USEDEFAULT
, CW_USEDEFAULT
, 300, 300, 0,
9561 hchild
= CreateWindowEx(0, "TestWindowClass", NULL
,
9562 WS_CHILD
| WS_BORDER
| WS_VISIBLE
,
9563 50, 50, 200, 200, hwnd
,
9567 SetWindowPos( hwnd
, HWND_TOPMOST
, 0, 0, 0, 0, SWP_NOSIZE
|SWP_NOMOVE
);
9572 tme
.dwFlags
= TME_QUERY
;
9573 tme
.hwndTrack
= (HWND
)0xdeadbeef;
9574 tme
.dwHoverTime
= 0xdeadbeef;
9575 SetLastError(0xdeadbeef);
9576 ret
= pTrackMouseEvent(&tme
);
9577 ok(!ret
, "TrackMouseEvent should fail\n");
9578 ok(GetLastError() == ERROR_INVALID_PARAMETER
|| broken(GetLastError() == 0xdeadbeef),
9579 "not expected error %u\n", GetLastError());
9581 tme
.cbSize
= sizeof(tme
);
9582 tme
.dwFlags
= TME_HOVER
;
9583 tme
.hwndTrack
= (HWND
)0xdeadbeef;
9584 tme
.dwHoverTime
= 0xdeadbeef;
9585 SetLastError(0xdeadbeef);
9586 ret
= pTrackMouseEvent(&tme
);
9587 ok(!ret
, "TrackMouseEvent should fail\n");
9588 ok(GetLastError() == ERROR_INVALID_WINDOW_HANDLE
|| broken(GetLastError() == 0xdeadbeef),
9589 "not expected error %u\n", GetLastError());
9591 tme
.cbSize
= sizeof(tme
);
9592 tme
.dwFlags
= TME_HOVER
| TME_CANCEL
;
9593 tme
.hwndTrack
= (HWND
)0xdeadbeef;
9594 tme
.dwHoverTime
= 0xdeadbeef;
9595 SetLastError(0xdeadbeef);
9596 ret
= pTrackMouseEvent(&tme
);
9597 ok(!ret
, "TrackMouseEvent should fail\n");
9598 ok(GetLastError() == ERROR_INVALID_WINDOW_HANDLE
|| broken(GetLastError() == 0xdeadbeef),
9599 "not expected error %u\n", GetLastError());
9601 GetWindowRect(hwnd
, &rc_parent
);
9602 GetWindowRect(hchild
, &rc_child
);
9603 SetCursorPos(rc_child
.left
- 10, rc_child
.top
- 10);
9605 /* Process messages so that the system updates its internal current
9606 * window and hittest, otherwise TrackMouseEvent calls don't have any
9612 track_query(0, NULL
, 0);
9613 track_hover(hchild
, 0);
9614 track_query(0, NULL
, 0);
9619 track_hover(hwnd
, 0);
9620 track_query(TME_HOVER
, hwnd
, default_hover_time
);
9622 pump_msg_loop_timeout(default_hover_time
, FALSE
);
9623 ok_sequence(WmMouseHoverSeq
, "WmMouseHoverSeq", FALSE
);
9625 track_query(0, NULL
, 0);
9627 track_hover(hwnd
, HOVER_DEFAULT
);
9628 track_query(TME_HOVER
, hwnd
, default_hover_time
);
9630 Sleep(default_hover_time
/ 2);
9631 mouse_event(MOUSEEVENTF_MOVE
, -1, 0, 0, 0);
9632 mouse_event(MOUSEEVENTF_MOVE
, 1, 0, 0, 0);
9634 track_query(TME_HOVER
, hwnd
, default_hover_time
);
9636 pump_msg_loop_timeout(default_hover_time
/ 2, FALSE
);
9637 ok_sequence(WmMouseHoverSeq
, "WmMouseHoverSeq", FALSE
);
9639 track_query(0, NULL
, 0);
9641 track_hover(hwnd
, HOVER_DEFAULT
);
9642 track_query(TME_HOVER
, hwnd
, default_hover_time
);
9644 pump_msg_loop_timeout(default_hover_time
, TRUE
);
9645 ok_sequence(WmMouseHoverSeq
, "WmMouseHoverSeq", FALSE
);
9647 track_query(0, NULL
, 0);
9649 track_hover(hwnd
, HOVER_DEFAULT
);
9650 track_query(TME_HOVER
, hwnd
, default_hover_time
);
9651 track_hover_cancel(hwnd
);
9653 DestroyWindow(hwnd
);
9657 #undef track_hover_cancel
9661 static const struct message WmSetWindowRgn
[] = {
9662 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
|SWP_NOACTIVATE
|SWP_FRAMECHANGED
|SWP_NOSIZE
|SWP_NOMOVE
},
9663 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
9664 { WM_NCPAINT
, sent
|optional
}, /* wparam != 1 */
9665 { WM_GETTEXT
, sent
|defwinproc
|optional
},
9666 { WM_ERASEBKGND
, sent
|optional
},
9667 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
|SWP_NOACTIVATE
|SWP_FRAMECHANGED
|SWP_NOSIZE
|SWP_NOMOVE
},
9668 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
9672 static const struct message WmSetWindowRgn_no_redraw
[] = {
9673 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
|SWP_NOACTIVATE
|SWP_FRAMECHANGED
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOREDRAW
},
9674 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
9675 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
|SWP_NOACTIVATE
|SWP_FRAMECHANGED
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOREDRAW
},
9676 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
9680 static const struct message WmSetWindowRgn_clear
[] = {
9681 { WM_WINDOWPOSCHANGING
, sent
/*|wparam*/, SWP_NOACTIVATE
|SWP_FRAMECHANGED
|SWP_NOSIZE
|SWP_NOMOVE
/*|SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE only on some Windows versions */ },
9682 { WM_NCCALCSIZE
, sent
|wparam
, 1 },
9683 { WM_NCPAINT
, sent
|optional
},
9684 { WM_GETTEXT
, sent
|defwinproc
|optional
},
9685 { WM_ERASEBKGND
, sent
|optional
}, /* FIXME: remove optional once Wine is fixed */
9686 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
|SWP_NOACTIVATE
|SWP_FRAMECHANGED
|SWP_NOSIZE
|SWP_NOMOVE
},
9687 { WM_NCCALCSIZE
, sent
|wparam
|optional
, 1 },
9688 { WM_NCPAINT
, sent
|optional
},
9689 { WM_GETTEXT
, sent
|defwinproc
|optional
},
9690 { WM_ERASEBKGND
, sent
|optional
},
9691 { WM_WINDOWPOSCHANGING
, sent
|optional
},
9692 { WM_NCCALCSIZE
, sent
|optional
|wparam
, 1 },
9693 { WM_NCPAINT
, sent
|optional
},
9694 { WM_GETTEXT
, sent
|defwinproc
|optional
},
9695 { WM_ERASEBKGND
, sent
|optional
},
9696 { WM_WINDOWPOSCHANGED
, sent
|optional
|wparam
, SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
|SWP_NOACTIVATE
|SWP_FRAMECHANGED
|SWP_NOSIZE
|SWP_NOMOVE
},
9697 { WM_NCCALCSIZE
, sent
|optional
|wparam
, 1 },
9698 { WM_NCPAINT
, sent
|optional
},
9699 { WM_GETTEXT
, sent
|defwinproc
|optional
},
9700 { WM_ERASEBKGND
, sent
|optional
},
9701 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
9702 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, 0, 0 },
9706 static void test_SetWindowRgn(void)
9709 HWND hwnd
= CreateWindowExA(0, "TestWindowClass", "Test overlapped", WS_OVERLAPPEDWINDOW
,
9710 100, 100, 200, 200, 0, 0, 0, NULL
);
9711 ok( hwnd
!= 0, "Failed to create overlapped window\n" );
9713 ShowWindow( hwnd
, SW_SHOW
);
9714 UpdateWindow( hwnd
);
9718 trace("testing SetWindowRgn\n");
9719 hrgn
= CreateRectRgn( 0, 0, 150, 150 );
9720 SetWindowRgn( hwnd
, hrgn
, TRUE
);
9721 ok_sequence( WmSetWindowRgn
, "WmSetWindowRgn", FALSE
);
9723 hrgn
= CreateRectRgn( 30, 30, 160, 160 );
9724 SetWindowRgn( hwnd
, hrgn
, FALSE
);
9725 ok_sequence( WmSetWindowRgn_no_redraw
, "WmSetWindowRgn_no_redraw", FALSE
);
9727 hrgn
= CreateRectRgn( 0, 0, 180, 180 );
9728 SetWindowRgn( hwnd
, hrgn
, TRUE
);
9729 ok_sequence( WmSetWindowRgn
, "WmSetWindowRgn2", FALSE
);
9731 SetWindowRgn( hwnd
, 0, TRUE
);
9732 ok_sequence( WmSetWindowRgn_clear
, "WmSetWindowRgn_clear", FALSE
);
9734 DestroyWindow( hwnd
);
9737 /*************************** ShowWindow() test ******************************/
9738 static const struct message WmShowNormal
[] = {
9739 { WM_SHOWWINDOW
, sent
|wparam
, 1 },
9740 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
},
9741 { HCBT_ACTIVATE
, hook
},
9742 { WM_WINDOWPOSCHANGING
, sent
|wparam
|optional
, SWP_NOSIZE
|SWP_NOMOVE
}, /* win2003 doesn't send it */
9743 { HCBT_SETFOCUS
, hook
},
9744 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
9747 static const struct message WmShow
[] = {
9748 { WM_SHOWWINDOW
, sent
|wparam
, 1 },
9749 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
},
9750 { HCBT_ACTIVATE
, hook
|optional
}, /* win2000 doesn't send it */
9751 { WM_WINDOWPOSCHANGING
, sent
|wparam
|optional
, SWP_NOSIZE
|SWP_NOMOVE
}, /* win2000 doesn't send it */
9752 { HCBT_SETFOCUS
, hook
|optional
}, /* win2000 doesn't send it */
9753 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
9756 static const struct message WmShowNoActivate_1
[] = {
9757 { HCBT_MINMAX
, hook
|lparam
, 0, SW_SHOWNOACTIVATE
},
9758 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOACTIVATE
|SWP_FRAMECHANGED
|SWP_STATECHANGED
, 0, SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
|SWP_NOSIZE
|SWP_NOMOVE
},
9759 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOACTIVATE
|SWP_FRAMECHANGED
|SWP_STATECHANGED
, 0, SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
|SWP_NOSIZE
|SWP_NOMOVE
},
9760 { WM_MOVE
, sent
|defwinproc
|optional
},
9761 { WM_SIZE
, sent
|wparam
|defwinproc
, SIZE_RESTORED
},
9764 static const struct message WmShowNoActivate_2
[] = {
9765 { HCBT_MINMAX
, hook
|lparam
, 0, SW_SHOWNOACTIVATE
},
9766 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOACTIVATE
|SWP_FRAMECHANGED
|SWP_NOCOPYBITS
|SWP_STATECHANGED
},
9767 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOACTIVATE
|SWP_FRAMECHANGED
|SWP_NOCOPYBITS
|SWP_STATECHANGED
},
9768 { WM_MOVE
, sent
|defwinproc
},
9769 { WM_SIZE
, sent
|wparam
|defwinproc
, SIZE_RESTORED
},
9770 { HCBT_SETFOCUS
, hook
|optional
},
9771 { HCBT_ACTIVATE
, hook
|optional
}, /* win2003 doesn't send it */
9772 { WM_WINDOWPOSCHANGING
, sent
|wparam
|optional
, SWP_NOSIZE
|SWP_NOMOVE
}, /* win2003 doesn't send it */
9773 { HCBT_SETFOCUS
, hook
|optional
}, /* win2003 doesn't send it */
9776 static const struct message WmShowNA_1
[] = {
9777 { WM_SHOWWINDOW
, sent
|wparam
, 1 },
9778 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
9779 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
9782 static const struct message WmShowNA_2
[] = {
9783 { WM_SHOWWINDOW
, sent
|wparam
, 1 },
9784 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
9787 static const struct message WmRestore_1
[] = {
9788 { HCBT_MINMAX
, hook
|lparam
, 0, SW_RESTORE
},
9789 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_FRAMECHANGED
|SWP_NOCOPYBITS
|SWP_STATECHANGED
},
9790 { HCBT_ACTIVATE
, hook
|optional
}, /* win2000 doesn't send it */
9791 { WM_WINDOWPOSCHANGING
, sent
|wparam
|optional
, SWP_NOSIZE
|SWP_NOMOVE
}, /* win2000 doesn't send it */
9792 { HCBT_SETFOCUS
, hook
|optional
}, /* win2000 doesn't send it */
9793 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_FRAMECHANGED
|SWP_NOCOPYBITS
|SWP_STATECHANGED
},
9794 { WM_MOVE
, sent
|defwinproc
},
9795 { WM_SIZE
, sent
|wparam
|defwinproc
, SIZE_RESTORED
},
9796 { HCBT_SETFOCUS
, hook
|optional
}, /* win2000 sends it */
9799 static const struct message WmRestore_2
[] = {
9800 { WM_SHOWWINDOW
, sent
|wparam
, 1 },
9801 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
},
9802 { HCBT_ACTIVATE
, hook
|optional
}, /* win2000 doesn't send it */
9803 { WM_WINDOWPOSCHANGING
, sent
|wparam
|optional
, SWP_NOSIZE
|SWP_NOMOVE
}, /* win2000 doesn't send it */
9804 { HCBT_SETFOCUS
, hook
|optional
}, /* win2000 doesn't send it */
9805 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
9808 static const struct message WmRestore_3
[] = {
9809 { HCBT_MINMAX
, hook
|lparam
, 0, SW_RESTORE
},
9810 { WM_GETMINMAXINFO
, sent
},
9811 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOCOPYBITS
|SWP_STATECHANGED
},
9812 { HCBT_ACTIVATE
, hook
|optional
}, /* win2003 doesn't send it */
9813 { WM_WINDOWPOSCHANGING
, sent
|wparam
|optional
, SWP_NOSIZE
|SWP_NOMOVE
}, /* win2003 doesn't send it */
9814 { HCBT_SETFOCUS
, hook
|optional
}, /* win2003 doesn't send it */
9815 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOCOPYBITS
|SWP_STATECHANGED
},
9816 { WM_MOVE
, sent
|defwinproc
},
9817 { WM_SIZE
, sent
|wparam
|defwinproc
, SIZE_MAXIMIZED
},
9818 { HCBT_SETFOCUS
, hook
|optional
}, /* win2003 sends it */
9821 static const struct message WmRestore_4
[] = {
9822 { HCBT_MINMAX
, hook
|lparam
, 0, SW_RESTORE
},
9823 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_STATECHANGED
, 0, SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
|SWP_NOSIZE
|SWP_NOMOVE
},
9824 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_STATECHANGED
, 0, SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
|SWP_NOSIZE
|SWP_NOMOVE
},
9825 { WM_MOVE
, sent
|defwinproc
|optional
},
9826 { WM_SIZE
, sent
|wparam
|defwinproc
, SIZE_RESTORED
},
9829 static const struct message WmRestore_5
[] = {
9830 { HCBT_MINMAX
, hook
|lparam
, 0, SW_SHOWNORMAL
},
9831 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_STATECHANGED
, 0, SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
|SWP_NOSIZE
|SWP_NOMOVE
},
9832 { HCBT_ACTIVATE
, hook
|optional
},
9833 { HCBT_SETFOCUS
, hook
|optional
},
9834 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_STATECHANGED
, 0, SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
|SWP_NOSIZE
|SWP_NOMOVE
},
9835 { WM_MOVE
, sent
|defwinproc
|optional
},
9836 { WM_SIZE
, sent
|wparam
|defwinproc
, SIZE_RESTORED
},
9839 static const struct message WmHide_1
[] = {
9840 { WM_SHOWWINDOW
, sent
|wparam
, 0 },
9841 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_HIDEWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
},
9842 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_HIDEWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
9843 { HCBT_SETFOCUS
, hook
|optional
}, /* win2000 sends it */
9846 static const struct message WmHide_2
[] = {
9847 { WM_SHOWWINDOW
, sent
|wparam
, 0 },
9848 { WM_WINDOWPOSCHANGING
, sent
/*|wparam, SWP_HIDEWINDOW|SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOMOVE*/ }, /* win2000 doesn't add SWP_NOACTIVATE */
9849 { WM_WINDOWPOSCHANGED
, sent
/*|wparam, SWP_HIDEWINDOW|SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOMOVE|SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE*/ }, /* win2000 doesn't add SWP_NOACTIVATE */
9852 static const struct message WmHide_3
[] = {
9853 { WM_SHOWWINDOW
, sent
|wparam
, 0 },
9854 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_HIDEWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
},
9855 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_HIDEWINDOW
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
9856 { HCBT_SETFOCUS
, hook
|optional
},
9857 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
9860 static const struct message WmShowMinimized_1
[] = {
9861 { HCBT_MINMAX
, hook
|lparam
, 0, SW_SHOWMINIMIZED
},
9862 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_FRAMECHANGED
|SWP_NOCOPYBITS
|SWP_STATECHANGED
},
9863 { HCBT_ACTIVATE
, hook
|optional
}, /* win2000 doesn't send it */
9864 { WM_WINDOWPOSCHANGING
, sent
|wparam
|optional
, SWP_NOSIZE
|SWP_NOMOVE
}, /* win2000 doesn't send it */
9865 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_FRAMECHANGED
|SWP_NOCOPYBITS
|SWP_STATECHANGED
},
9866 { WM_MOVE
, sent
|defwinproc
},
9867 { WM_SIZE
, sent
|wparam
|defwinproc
, SIZE_MINIMIZED
},
9870 static const struct message WmMinimize_1
[] = {
9871 { HCBT_MINMAX
, hook
|lparam
, 0, SW_MINIMIZE
},
9872 { HCBT_SETFOCUS
, hook
|optional
}, /* win2000 doesn't send it */
9873 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
9874 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOACTIVATE
|SWP_FRAMECHANGED
|SWP_NOCOPYBITS
|SWP_STATECHANGED
},
9875 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_NOACTIVATE
|SWP_FRAMECHANGED
|SWP_NOCOPYBITS
|SWP_STATECHANGED
},
9876 { WM_MOVE
, sent
|defwinproc
},
9877 { WM_SIZE
, sent
|wparam
|defwinproc
, SIZE_MINIMIZED
},
9880 static const struct message WmMinimize_2
[] = {
9881 { HCBT_MINMAX
, hook
|lparam
, 0, SW_MINIMIZE
},
9882 { HCBT_SETFOCUS
, hook
|optional
},
9883 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOACTIVATE
|SWP_FRAMECHANGED
|SWP_NOCOPYBITS
|SWP_STATECHANGED
},
9884 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_NOACTIVATE
|SWP_FRAMECHANGED
|SWP_NOCOPYBITS
|SWP_STATECHANGED
},
9885 { WM_MOVE
, sent
|defwinproc
},
9886 { WM_SIZE
, sent
|wparam
|defwinproc
, SIZE_MINIMIZED
},
9889 static const struct message WmMinimize_3
[] = {
9890 { HCBT_MINMAX
, hook
|lparam
, 0, SW_MINIMIZE
},
9891 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOACTIVATE
|SWP_FRAMECHANGED
|SWP_NOCOPYBITS
|SWP_STATECHANGED
},
9892 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOACTIVATE
|SWP_FRAMECHANGED
|SWP_NOCOPYBITS
|SWP_STATECHANGED
},
9893 { WM_MOVE
, sent
|defwinproc
},
9894 { WM_SIZE
, sent
|wparam
|defwinproc
, SIZE_MINIMIZED
},
9897 static const struct message WmShowMinNoActivate
[] = {
9898 { HCBT_MINMAX
, hook
|lparam
, 0, SW_SHOWMINNOACTIVE
},
9899 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
},
9900 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_NOACTIVATE
|SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
9903 static const struct message WmMinMax_1
[] = {
9904 { HCBT_MINMAX
, hook
|lparam
, 0, SW_SHOWMINIMIZED
},
9907 static const struct message WmMinMax_2
[] = {
9908 { HCBT_MINMAX
, hook
|lparam
, 0, SW_SHOWMAXIMIZED
},
9909 { WM_GETMINMAXINFO
, sent
|optional
},
9910 { WM_WINDOWPOSCHANGING
, sent
|wparam
|optional
, SWP_FRAMECHANGED
|SWP_STATECHANGED
},
9911 { HCBT_ACTIVATE
, hook
|optional
},
9912 { WM_WINDOWPOSCHANGING
, sent
|wparam
|optional
, SWP_NOSIZE
|SWP_NOMOVE
},
9913 { HCBT_SETFOCUS
, hook
|optional
},
9914 { WM_WINDOWPOSCHANGED
, sent
|wparam
|optional
, SWP_FRAMECHANGED
|SWP_STATECHANGED
, 0, SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
9915 { WM_MOVE
, sent
|defwinproc
|optional
},
9916 { WM_SIZE
, sent
|wparam
|defwinproc
|optional
, SIZE_MAXIMIZED
},
9917 { HCBT_SETFOCUS
, hook
|optional
},
9920 static const struct message WmMinMax_3
[] = {
9921 { HCBT_MINMAX
, hook
|lparam
, 0, SW_MINIMIZE
},
9924 static const struct message WmMinMax_4
[] = {
9925 { HCBT_MINMAX
, hook
|lparam
, 0, SW_SHOWMINNOACTIVE
},
9928 static const struct message WmShowMaximized_1
[] = {
9929 { HCBT_MINMAX
, hook
|lparam
, 0, SW_SHOWMAXIMIZED
},
9930 { WM_GETMINMAXINFO
, sent
},
9931 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_FRAMECHANGED
|SWP_NOCOPYBITS
|SWP_STATECHANGED
},
9932 { HCBT_ACTIVATE
, hook
|optional
}, /* win2000 doesn't send it */
9933 { WM_WINDOWPOSCHANGING
, sent
|wparam
|optional
, SWP_NOSIZE
|SWP_NOMOVE
}, /* win2000 doesn't send it */
9934 { HCBT_SETFOCUS
, hook
|optional
}, /* win2000 doesn't send it */
9935 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_SHOWWINDOW
|SWP_FRAMECHANGED
|SWP_NOCOPYBITS
|SWP_STATECHANGED
},
9936 { WM_MOVE
, sent
|defwinproc
},
9937 { WM_SIZE
, sent
|wparam
|defwinproc
, SIZE_MAXIMIZED
},
9938 { HCBT_SETFOCUS
, hook
|optional
}, /* win2003 sends it */
9941 static const struct message WmShowMaximized_2
[] = {
9942 { HCBT_MINMAX
, hook
|lparam
, 0, SW_SHOWMAXIMIZED
},
9943 { WM_GETMINMAXINFO
, sent
},
9944 { WM_WINDOWPOSCHANGING
, sent
|optional
},
9945 { HCBT_ACTIVATE
, hook
|optional
},
9946 { WM_WINDOWPOSCHANGED
, sent
|optional
},
9947 { WM_MOVE
, sent
|optional
}, /* Win9x doesn't send it */
9948 { WM_SIZE
, sent
|wparam
|optional
, SIZE_MAXIMIZED
}, /* Win9x doesn't send it */
9949 { WM_WINDOWPOSCHANGING
, sent
},
9950 { HCBT_SETFOCUS
, hook
|optional
},
9951 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_NOCOPYBITS
|SWP_STATECHANGED
},
9952 { WM_MOVE
, sent
|defwinproc
},
9953 { WM_SIZE
, sent
|wparam
|defwinproc
, SIZE_MAXIMIZED
},
9954 { HCBT_SETFOCUS
, hook
|optional
},
9957 static const struct message WmShowMaximized_3
[] = {
9958 { HCBT_MINMAX
, hook
|lparam
, 0, SW_SHOWMAXIMIZED
},
9959 { WM_GETMINMAXINFO
, sent
},
9960 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_STATECHANGED
, 0, SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
|SWP_NOSIZE
|SWP_NOMOVE
},
9961 { HCBT_ACTIVATE
, hook
|optional
}, /* win2000 doesn't send it */
9962 { WM_WINDOWPOSCHANGING
, sent
|wparam
|optional
, SWP_NOSIZE
|SWP_NOMOVE
}, /* win2000 doesn't send it */
9963 { HCBT_SETFOCUS
, hook
|optional
}, /* win2000 doesn't send it */
9964 { WM_WINDOWPOSCHANGED
, sent
|wparam
, SWP_FRAMECHANGED
|SWP_STATECHANGED
, 0, SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
|SWP_NOSIZE
|SWP_NOMOVE
},
9965 { WM_MOVE
, sent
|defwinproc
|optional
},
9966 { WM_SIZE
, sent
|wparam
|defwinproc
, SIZE_MAXIMIZED
},
9970 static void test_ShowWindow(void)
9972 /* ShowWindow commands in random order */
9975 INT cmd
; /* ShowWindow command */
9976 LPARAM ret
; /* ShowWindow return value */
9977 DWORD style
; /* window style after the command */
9978 const struct message
*msg
; /* message sequence the command produces */
9979 BOOL todo_msg
; /* message sequence doesn't match what Wine does */
9982 /* 1 */ { SW_SHOWNORMAL
, FALSE
, WS_VISIBLE
, WmShowNormal
, FALSE
},
9983 /* 2 */ { SW_SHOWNORMAL
, TRUE
, WS_VISIBLE
, WmEmptySeq
, FALSE
},
9984 /* 3 */ { SW_HIDE
, TRUE
, 0, WmHide_1
, FALSE
},
9985 /* 4 */ { SW_HIDE
, FALSE
, 0, WmEmptySeq
, FALSE
},
9986 /* 5 */ { SW_SHOWMINIMIZED
, FALSE
, WS_VISIBLE
|WS_MINIMIZE
, WmShowMinimized_1
, FALSE
},
9987 /* 6 */ { SW_SHOWMINIMIZED
, TRUE
, WS_VISIBLE
|WS_MINIMIZE
, WmMinMax_1
, FALSE
},
9988 /* 7 */ { SW_HIDE
, TRUE
, WS_MINIMIZE
, WmHide_1
, FALSE
},
9989 /* 8 */ { SW_HIDE
, FALSE
, WS_MINIMIZE
, WmEmptySeq
, FALSE
},
9990 /* 9 */ { SW_SHOWMAXIMIZED
, FALSE
, WS_VISIBLE
|WS_MAXIMIZE
, WmShowMaximized_1
, FALSE
},
9991 /* 10 */ { SW_SHOWMAXIMIZED
, TRUE
, WS_VISIBLE
|WS_MAXIMIZE
, WmMinMax_2
, FALSE
},
9992 /* 11 */ { SW_HIDE
, TRUE
, WS_MAXIMIZE
, WmHide_1
, FALSE
},
9993 /* 12 */ { SW_HIDE
, FALSE
, WS_MAXIMIZE
, WmEmptySeq
, FALSE
},
9994 /* 13 */ { SW_SHOWNOACTIVATE
, FALSE
, WS_VISIBLE
, WmShowNoActivate_1
, FALSE
},
9995 /* 14 */ { SW_SHOWNOACTIVATE
, TRUE
, WS_VISIBLE
, WmEmptySeq
, FALSE
},
9996 /* 15 */ { SW_HIDE
, TRUE
, 0, WmHide_2
, FALSE
},
9997 /* 16 */ { SW_HIDE
, FALSE
, 0, WmEmptySeq
, FALSE
},
9998 /* 17 */ { SW_SHOW
, FALSE
, WS_VISIBLE
, WmShow
, FALSE
},
9999 /* 18 */ { SW_SHOW
, TRUE
, WS_VISIBLE
, WmEmptySeq
, FALSE
},
10000 /* 19 */ { SW_MINIMIZE
, TRUE
, WS_VISIBLE
|WS_MINIMIZE
, WmMinimize_1
, FALSE
},
10001 /* 20 */ { SW_MINIMIZE
, TRUE
, WS_VISIBLE
|WS_MINIMIZE
, WmMinMax_3
, FALSE
},
10002 /* 21 */ { SW_HIDE
, TRUE
, WS_MINIMIZE
, WmHide_2
, FALSE
},
10003 /* 22 */ { SW_SHOWMINNOACTIVE
, FALSE
, WS_VISIBLE
|WS_MINIMIZE
, WmShowMinNoActivate
, TRUE
},
10004 /* 23 */ { SW_SHOWMINNOACTIVE
, TRUE
, WS_VISIBLE
|WS_MINIMIZE
, WmMinMax_4
, FALSE
},
10005 /* 24 */ { SW_HIDE
, TRUE
, WS_MINIMIZE
, WmHide_2
, FALSE
},
10006 /* 25 */ { SW_HIDE
, FALSE
, WS_MINIMIZE
, WmEmptySeq
, FALSE
},
10007 /* 26 */ { SW_SHOWNA
, FALSE
, WS_VISIBLE
|WS_MINIMIZE
, WmShowNA_1
, FALSE
},
10008 /* 27 */ { SW_SHOWNA
, TRUE
, WS_VISIBLE
|WS_MINIMIZE
, WmShowNA_2
, FALSE
},
10009 /* 28 */ { SW_HIDE
, TRUE
, WS_MINIMIZE
, WmHide_2
, FALSE
},
10010 /* 29 */ { SW_HIDE
, FALSE
, WS_MINIMIZE
, WmEmptySeq
, FALSE
},
10011 /* 30 */ { SW_RESTORE
, FALSE
, WS_VISIBLE
, WmRestore_1
, FALSE
},
10012 /* 31 */ { SW_RESTORE
, TRUE
, WS_VISIBLE
, WmEmptySeq
, FALSE
},
10013 /* 32 */ { SW_HIDE
, TRUE
, 0, WmHide_3
, FALSE
},
10014 /* 33 */ { SW_HIDE
, FALSE
, 0, WmEmptySeq
, FALSE
},
10015 /* 34 */ { SW_NORMALNA
, FALSE
, 0, WmEmptySeq
, FALSE
}, /* what does this mean?! */
10016 /* 35 */ { SW_NORMALNA
, FALSE
, 0, WmEmptySeq
, FALSE
},
10017 /* 36 */ { SW_HIDE
, FALSE
, 0, WmEmptySeq
, FALSE
},
10018 /* 37 */ { SW_RESTORE
, FALSE
, WS_VISIBLE
, WmRestore_2
, FALSE
},
10019 /* 38 */ { SW_RESTORE
, TRUE
, WS_VISIBLE
, WmEmptySeq
, FALSE
},
10020 /* 39 */ { SW_SHOWNOACTIVATE
, TRUE
, WS_VISIBLE
, WmEmptySeq
, FALSE
},
10021 /* 40 */ { SW_MINIMIZE
, TRUE
, WS_VISIBLE
|WS_MINIMIZE
, WmMinimize_2
, FALSE
},
10022 /* 41 */ { SW_MINIMIZE
, TRUE
, WS_VISIBLE
|WS_MINIMIZE
, WmMinMax_3
, FALSE
},
10023 /* 42 */ { SW_SHOWMAXIMIZED
, TRUE
, WS_VISIBLE
|WS_MAXIMIZE
, WmShowMaximized_2
, TRUE
},
10024 /* 43 */ { SW_SHOWMAXIMIZED
, TRUE
, WS_VISIBLE
|WS_MAXIMIZE
, WmMinMax_2
, FALSE
},
10025 /* 44 */ { SW_MINIMIZE
, TRUE
, WS_VISIBLE
|WS_MINIMIZE
, WmMinimize_1
, FALSE
},
10026 /* 45 */ { SW_MINIMIZE
, TRUE
, WS_VISIBLE
|WS_MINIMIZE
, WmMinMax_3
, FALSE
},
10027 /* 46 */ { SW_RESTORE
, TRUE
, WS_VISIBLE
|WS_MAXIMIZE
, WmRestore_3
, FALSE
},
10028 /* 47 */ { SW_RESTORE
, TRUE
, WS_VISIBLE
, WmRestore_4
, FALSE
},
10029 /* 48 */ { SW_SHOWMAXIMIZED
, TRUE
, WS_VISIBLE
|WS_MAXIMIZE
, WmShowMaximized_3
, FALSE
},
10030 /* 49 */ { SW_SHOW
, TRUE
, WS_VISIBLE
|WS_MAXIMIZE
, WmEmptySeq
, FALSE
},
10031 /* 50 */ { SW_SHOWNORMAL
, TRUE
, WS_VISIBLE
, WmRestore_5
, FALSE
},
10032 /* 51 */ { SW_SHOWNORMAL
, TRUE
, WS_VISIBLE
, WmEmptySeq
, FALSE
},
10033 /* 52 */ { SW_HIDE
, TRUE
, 0, WmHide_1
, FALSE
},
10034 /* 53 */ { SW_HIDE
, FALSE
, 0, WmEmptySeq
, FALSE
},
10035 /* 54 */ { SW_MINIMIZE
, FALSE
, WS_VISIBLE
|WS_MINIMIZE
, WmMinimize_3
, FALSE
},
10036 /* 55 */ { SW_HIDE
, TRUE
, WS_MINIMIZE
, WmHide_2
, FALSE
},
10037 /* 56 */ { SW_SHOWNOACTIVATE
, FALSE
, WS_VISIBLE
, WmShowNoActivate_2
, FALSE
},
10038 /* 57 */ { SW_SHOW
, TRUE
, WS_VISIBLE
, WmEmptySeq
, FALSE
}
10045 #define WS_BASE (WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX|WS_MAXIMIZEBOX|WS_POPUP|WS_CLIPSIBLINGS)
10046 hwnd
= CreateWindowEx(0, "ShowWindowClass", NULL
, WS_BASE
,
10051 style
= GetWindowLong(hwnd
, GWL_STYLE
) & ~WS_BASE
;
10052 ok(style
== 0, "expected style 0, got %08x\n", style
);
10057 for (i
= 0; i
< sizeof(sw
)/sizeof(sw
[0]); i
++)
10059 static const char * const sw_cmd_name
[13] =
10061 "SW_HIDE", "SW_SHOWNORMAL", "SW_SHOWMINIMIZED", "SW_SHOWMAXIMIZED",
10062 "SW_SHOWNOACTIVATE", "SW_SHOW", "SW_MINIMIZE", "SW_SHOWMINNOACTIVE",
10063 "SW_SHOWNA", "SW_RESTORE", "SW_SHOWDEFAULT", "SW_FORCEMINIMIZE",
10064 "SW_NORMALNA" /* 0xCC */
10067 INT idx
; /* index into the above array of names */
10069 idx
= (sw
[i
].cmd
== SW_NORMALNA
) ? 12 : sw
[i
].cmd
;
10071 style
= GetWindowLong(hwnd
, GWL_STYLE
);
10072 trace("%d: sending %s, current window style %08x\n", i
+1, sw_cmd_name
[idx
], style
);
10073 ret
= ShowWindow(hwnd
, sw
[i
].cmd
);
10074 ok(!ret
== !sw
[i
].ret
, "%d: cmd %s: expected ret %lu, got %lu\n", i
+1, sw_cmd_name
[idx
], sw
[i
].ret
, ret
);
10075 style
= GetWindowLong(hwnd
, GWL_STYLE
) & ~WS_BASE
;
10076 ok(style
== sw
[i
].style
, "%d: expected style %08x, got %08x\n", i
+1, sw
[i
].style
, style
);
10078 sprintf(comment
, "%d: ShowWindow(%s)", i
+1, sw_cmd_name
[idx
]);
10079 ok_sequence(sw
[i
].msg
, comment
, sw
[i
].todo_msg
);
10085 DestroyWindow(hwnd
);
10088 static INT_PTR WINAPI
test_dlg_proc(HWND hwnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
10090 struct recvd_message msg
;
10094 /* explicitly ignore WM_GETICON message */
10100 msg
.message
= message
;
10101 msg
.flags
= sent
|wparam
|lparam
;
10102 msg
.wParam
= wParam
;
10103 msg
.lParam
= lParam
;
10104 msg
.descr
= "dialog";
10107 /* calling DefDlgProc leads to a recursion under XP */
10111 case WM_INITDIALOG
:
10112 case WM_GETDLGCODE
:
10118 static const struct message WmDefDlgSetFocus_1
[] = {
10119 { WM_GETDLGCODE
, sent
|wparam
|lparam
, 0, 0 },
10120 { WM_GETTEXTLENGTH
, sent
|wparam
|lparam
|optional
, 0, 0 }, /* XP */
10121 { WM_GETTEXT
, sent
|wparam
|optional
, 6 }, /* XP */
10122 { WM_GETTEXT
, sent
|wparam
|optional
, 12 }, /* XP */
10123 { EM_SETSEL
, sent
|wparam
, 0 }, /* XP sets lparam to text length, Win9x to -2 */
10124 { HCBT_SETFOCUS
, hook
},
10125 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 1 },
10126 { WM_IME_NOTIFY
, sent
|wparam
|defwinproc
|optional
, 2 },
10127 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
10128 { WM_SETFOCUS
, sent
|wparam
, 0 },
10129 { WM_IME_NOTIFY
, sent
|wparam
|defwinproc
|optional
, 10 },
10130 { WM_CTLCOLOREDIT
, sent
},
10131 { WM_IME_NOTIFY
, sent
|wparam
|defwinproc
|optional
, 11 },
10132 { EVENT_OBJECT_CREATE
, winevent_hook
|wparam
|lparam
, OBJID_CARET
, 0 },
10133 { EVENT_OBJECT_LOCATIONCHANGE
, winevent_hook
|wparam
|lparam
, OBJID_CARET
, 0 },
10134 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, OBJID_CARET
, 0 },
10135 { WM_COMMAND
, sent
|wparam
, MAKEWPARAM(1, EN_SETFOCUS
) },
10138 static const struct message WmDefDlgSetFocus_2
[] = {
10139 { WM_GETDLGCODE
, sent
|wparam
|lparam
, 0, 0 },
10140 { WM_GETTEXTLENGTH
, sent
|wparam
|lparam
|optional
, 0, 0 }, /* XP */
10141 { WM_GETTEXT
, sent
|wparam
|optional
, 6 }, /* XP */
10142 { WM_GETTEXT
, sent
|wparam
|optional
, 12 }, /* XP */
10143 { EM_SETSEL
, sent
|wparam
, 0 }, /* XP sets lparam to text length, Win9x to -2 */
10144 { EVENT_OBJECT_HIDE
, winevent_hook
|wparam
|lparam
, OBJID_CARET
, 0 },
10145 { WM_CTLCOLOREDIT
, sent
|optional
}, /* XP */
10146 { EVENT_OBJECT_SHOW
, winevent_hook
|wparam
|lparam
, OBJID_CARET
, 0 },
10149 /* Creation of a dialog */
10150 static const struct message WmCreateDialogParamSeq_1
[] = {
10151 { HCBT_CREATEWND
, hook
},
10152 { WM_NCCREATE
, sent
},
10153 { WM_NCCALCSIZE
, sent
|wparam
, 0 },
10154 { WM_CREATE
, sent
},
10155 { EVENT_OBJECT_CREATE
, winevent_hook
|wparam
|lparam
, 0, 0 },
10156 { WM_SIZE
, sent
|wparam
, SIZE_RESTORED
},
10158 { WM_SETFONT
, sent
},
10159 { WM_INITDIALOG
, sent
},
10160 { WM_CHANGEUISTATE
, sent
|optional
},
10163 /* Creation of a dialog */
10164 static const struct message WmCreateDialogParamSeq_2
[] = {
10165 { HCBT_CREATEWND
, hook
},
10166 { WM_NCCREATE
, sent
},
10167 { WM_NCCALCSIZE
, sent
|wparam
, 0 },
10168 { WM_CREATE
, sent
},
10169 { EVENT_OBJECT_CREATE
, winevent_hook
|wparam
|lparam
, 0, 0 },
10170 { WM_SIZE
, sent
|wparam
, SIZE_RESTORED
},
10172 { WM_CHANGEUISTATE
, sent
|optional
},
10176 static void test_dialog_messages(void)
10179 HWND hdlg
, hedit1
, hedit2
, hfocus
;
10182 #define set_selection(hctl, start, end) \
10183 ret = SendMessage(hctl, EM_SETSEL, start, end); \
10184 ok(ret == 1, "EM_SETSEL returned %ld\n", ret);
10186 #define check_selection(hctl, start, end) \
10187 ret = SendMessage(hctl, EM_GETSEL, 0, 0); \
10188 ok(ret == MAKELRESULT(start, end), "wrong selection (%d - %d)\n", LOWORD(ret), HIWORD(ret));
10192 hdlg
= CreateWindowEx(WS_EX_DLGMODALFRAME
, "TestDialogClass", NULL
,
10193 WS_VISIBLE
|WS_CAPTION
|WS_SYSMENU
|WS_DLGFRAME
,
10194 0, 0, 100, 100, 0, 0, 0, NULL
);
10195 ok(hdlg
!= 0, "Failed to create custom dialog window\n");
10197 hedit1
= CreateWindowEx(0, "my_edit_class", NULL
,
10198 WS_CHILD
|WS_BORDER
|WS_VISIBLE
|WS_TABSTOP
,
10199 0, 0, 80, 20, hdlg
, (HMENU
)1, 0, NULL
);
10200 ok(hedit1
!= 0, "Failed to create edit control\n");
10201 hedit2
= CreateWindowEx(0, "my_edit_class", NULL
,
10202 WS_CHILD
|WS_BORDER
|WS_VISIBLE
|WS_TABSTOP
,
10203 0, 40, 80, 20, hdlg
, (HMENU
)2, 0, NULL
);
10204 ok(hedit2
!= 0, "Failed to create edit control\n");
10206 SendMessage(hedit1
, WM_SETTEXT
, 0, (LPARAM
)"hello");
10207 SendMessage(hedit2
, WM_SETTEXT
, 0, (LPARAM
)"bye");
10209 hfocus
= GetFocus();
10210 ok(hfocus
== hdlg
, "wrong focus %p\n", hfocus
);
10213 hfocus
= GetFocus();
10214 ok(hfocus
== hedit2
, "wrong focus %p\n", hfocus
);
10216 check_selection(hedit1
, 0, 0);
10217 check_selection(hedit2
, 0, 0);
10219 set_selection(hedit2
, 0, -1);
10220 check_selection(hedit2
, 0, 3);
10223 hfocus
= GetFocus();
10224 ok(hfocus
== 0, "wrong focus %p\n", hfocus
);
10227 ret
= DefDlgProc(hdlg
, WM_SETFOCUS
, 0, 0);
10228 ok(ret
== 0, "WM_SETFOCUS returned %ld\n", ret
);
10229 ok_sequence(WmDefDlgSetFocus_1
, "DefDlgProc(WM_SETFOCUS) 1", FALSE
);
10231 hfocus
= GetFocus();
10232 ok(hfocus
== hedit1
, "wrong focus %p\n", hfocus
);
10234 check_selection(hedit1
, 0, 5);
10235 check_selection(hedit2
, 0, 3);
10238 ret
= DefDlgProc(hdlg
, WM_SETFOCUS
, 0, 0);
10239 ok(ret
== 0, "WM_SETFOCUS returned %ld\n", ret
);
10240 ok_sequence(WmDefDlgSetFocus_2
, "DefDlgProc(WM_SETFOCUS) 2", FALSE
);
10242 hfocus
= GetFocus();
10243 ok(hfocus
== hedit1
, "wrong focus %p\n", hfocus
);
10245 check_selection(hedit1
, 0, 5);
10246 check_selection(hedit2
, 0, 3);
10248 EndDialog(hdlg
, 0);
10249 DestroyWindow(hedit1
);
10250 DestroyWindow(hedit2
);
10251 DestroyWindow(hdlg
);
10254 #undef set_selection
10255 #undef check_selection
10257 ok(GetClassInfo(0, "#32770", &cls
), "GetClassInfo failed\n");
10258 cls
.lpszClassName
= "MyDialogClass";
10259 cls
.hInstance
= GetModuleHandle(0);
10260 /* need a cast since a dlgproc is used as a wndproc */
10261 cls
.lpfnWndProc
= (WNDPROC
)test_dlg_proc
;
10262 if (!RegisterClass(&cls
)) assert(0);
10264 hdlg
= CreateDialogParam(0, "CLASS_TEST_DIALOG_2", 0, test_dlg_proc
, 0);
10265 ok(IsWindow(hdlg
), "CreateDialogParam failed\n");
10266 ok_sequence(WmCreateDialogParamSeq_1
, "CreateDialogParam_1", FALSE
);
10267 EndDialog(hdlg
, 0);
10268 DestroyWindow(hdlg
);
10271 hdlg
= CreateDialogParam(0, "CLASS_TEST_DIALOG_2", 0, NULL
, 0);
10272 ok(IsWindow(hdlg
), "CreateDialogParam failed\n");
10273 ok_sequence(WmCreateDialogParamSeq_2
, "CreateDialogParam_2", FALSE
);
10274 EndDialog(hdlg
, 0);
10275 DestroyWindow(hdlg
);
10278 UnregisterClass(cls
.lpszClassName
, cls
.hInstance
);
10281 static void test_nullCallback(void)
10285 hwnd
= CreateWindowExA(0, "TestWindowClass", "Test overlapped", WS_OVERLAPPEDWINDOW
,
10286 100, 100, 200, 200, 0, 0, 0, NULL
);
10287 ok (hwnd
!= 0, "Failed to create overlapped window\n");
10289 SendMessageCallbackA(hwnd
,WM_NULL
,0,0,NULL
,0);
10291 DestroyWindow(hwnd
);
10294 /* SetActiveWindow( 0 ) hwnd visible */
10295 static const struct message SetActiveWindowSeq0
[] =
10297 { HCBT_ACTIVATE
, hook
},
10298 { WM_NCACTIVATE
, sent
|wparam
, 0 },
10299 { WM_GETTEXT
, sent
|defwinproc
|optional
},
10300 { WM_ACTIVATE
, sent
|wparam
, 0 },
10301 { WM_QUERYNEWPALETTE
, sent
|wparam
|lparam
|optional
, 0, 0 },
10302 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOACTIVATE
},
10303 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_NOSIZE
|SWP_NOMOVE
},
10304 { WM_NCACTIVATE
, sent
|wparam
, 1 },
10305 { WM_GETTEXT
, sent
|defwinproc
|optional
},
10306 { WM_ACTIVATE
, sent
|wparam
, 1 },
10307 { HCBT_SETFOCUS
, hook
},
10308 { WM_KILLFOCUS
, sent
|defwinproc
},
10309 { WM_IME_SETCONTEXT
, sent
|wparam
|defwinproc
|optional
, 0 },
10310 { WM_IME_SETCONTEXT
, sent
|wparam
|defwinproc
|optional
, 1 },
10311 { WM_IME_NOTIFY
, sent
|wparam
|defwinproc
|optional
, 1 },
10312 { WM_IME_NOTIFY
, sent
|wparam
|defwinproc
|optional
, 2 },
10313 { WM_SETFOCUS
, sent
|defwinproc
},
10314 { WM_GETTEXT
, sent
|optional
},
10317 /* SetActiveWindow( hwnd ) hwnd visible */
10318 static const struct message SetActiveWindowSeq1
[] =
10320 { WM_QUERYNEWPALETTE
, sent
|wparam
|lparam
|optional
, 0, 0 },
10323 /* SetActiveWindow( popup ) hwnd visible, popup visible */
10324 static const struct message SetActiveWindowSeq2
[] =
10326 { HCBT_ACTIVATE
, hook
},
10327 { WM_NCACTIVATE
, sent
|wparam
, 0 },
10328 { WM_GETTEXT
, sent
|defwinproc
|optional
},
10329 { WM_ACTIVATE
, sent
|wparam
, 0 },
10330 { WM_QUERYNEWPALETTE
, sent
|wparam
|lparam
|optional
, 0, 0 },
10331 { WM_WINDOWPOSCHANGING
, sent
|wparam
|optional
, SWP_NOSIZE
|SWP_NOMOVE
},
10332 { WM_WINDOWPOSCHANGING
, sent
|wparam
|optional
, SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOACTIVATE
},
10333 { WM_NCPAINT
, sent
|optional
},
10334 { WM_GETTEXT
, sent
|defwinproc
|optional
},
10335 { WM_ERASEBKGND
, sent
|optional
},
10336 { WM_WINDOWPOSCHANGED
, sent
|wparam
|optional
, SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
10337 { WM_NCACTIVATE
, sent
|wparam
, 1 },
10338 { WM_GETTEXT
, sent
|defwinproc
|optional
},
10339 { WM_ACTIVATE
, sent
|wparam
, 1 },
10340 { HCBT_SETFOCUS
, hook
},
10341 { WM_KILLFOCUS
, sent
|defwinproc
},
10342 { WM_IME_SETCONTEXT
, sent
|wparam
|defwinproc
|optional
, 0 },
10343 { WM_IME_SETCONTEXT
, sent
|wparam
|defwinproc
|optional
, 1 },
10344 { WM_IME_NOTIFY
, sent
|wparam
|defwinproc
|optional
, 1 },
10345 { WM_IME_NOTIFY
, sent
|wparam
|defwinproc
|optional
, 2 },
10346 { WM_SETFOCUS
, sent
|defwinproc
},
10347 { WM_GETTEXT
, sent
|optional
},
10351 /* SetActiveWindow( hwnd ) hwnd not visible */
10352 static const struct message SetActiveWindowSeq3
[] =
10354 { HCBT_ACTIVATE
, hook
},
10355 { WM_QUERYNEWPALETTE
, sent
|wparam
|lparam
|optional
, 0, 0 },
10356 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOACTIVATE
},
10357 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_NOSIZE
|SWP_NOMOVE
},
10358 { WM_WINDOWPOSCHANGED
, sent
|wparam
|optional
, SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOREDRAW
|SWP_NOACTIVATE
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
10359 { WM_WINDOWPOSCHANGED
, sent
|wparam
|optional
, SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOREDRAW
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
10360 { WM_ACTIVATEAPP
, sent
|wparam
, 1 },
10361 { WM_ACTIVATEAPP
, sent
|wparam
, 1 },
10362 { WM_NCACTIVATE
, sent
|wparam
, 1 },
10363 { WM_ACTIVATE
, sent
|wparam
, 1 },
10364 { HCBT_SETFOCUS
, hook
},
10365 { WM_IME_SETCONTEXT
, sent
|wparam
|defwinproc
|optional
, 1 },
10366 { WM_IME_NOTIFY
, sent
|wparam
|defwinproc
|optional
, 2 },
10367 { WM_SETFOCUS
, sent
|defwinproc
},
10370 /* SetActiveWindow( popup ) hwnd not visible, popup not visible */
10371 static const struct message SetActiveWindowSeq4
[] =
10373 { HCBT_ACTIVATE
, hook
},
10374 { WM_NCACTIVATE
, sent
|wparam
, 0 },
10375 { WM_GETTEXT
, sent
|defwinproc
|optional
},
10376 { WM_ACTIVATE
, sent
|wparam
, 0 },
10377 { WM_QUERYNEWPALETTE
, sent
|wparam
|lparam
|optional
, 0, 0 },
10378 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_NOSIZE
|SWP_NOMOVE
},
10379 { WM_WINDOWPOSCHANGING
, sent
|wparam
, SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOACTIVATE
},
10380 { WM_WINDOWPOSCHANGED
, sent
|wparam
|optional
, SWP_NOSIZE
|SWP_NOMOVE
|SWP_NOREDRAW
|SWP_NOCLIENTSIZE
|SWP_NOCLIENTMOVE
},
10381 { WM_NCACTIVATE
, sent
|wparam
, 1 },
10382 { WM_GETTEXT
, sent
|defwinproc
|optional
},
10383 { WM_ACTIVATE
, sent
|wparam
, 1 },
10384 { HCBT_SETFOCUS
, hook
},
10385 { WM_KILLFOCUS
, sent
|defwinproc
},
10386 { WM_IME_SETCONTEXT
, sent
|wparam
|defwinproc
|optional
, 0 },
10387 { WM_IME_SETCONTEXT
, sent
|wparam
|defwinproc
|optional
, 1 },
10388 { WM_IME_NOTIFY
, sent
|wparam
|defwinproc
|optional
, 1 },
10389 { WM_IME_NOTIFY
, sent
|wparam
|defwinproc
|optional
, 2 },
10390 { WM_SETFOCUS
, sent
|defwinproc
},
10395 static void test_SetActiveWindow(void)
10397 HWND hwnd
, popup
, ret
;
10399 hwnd
= CreateWindowExA(0, "TestWindowClass", "Test SetActiveWindow",
10400 WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
10401 100, 100, 200, 200, 0, 0, 0, NULL
);
10403 popup
= CreateWindowExA(0, "TestWindowClass", "Test SetActiveWindow",
10404 WS_OVERLAPPEDWINDOW
| WS_VISIBLE
| WS_POPUP
,
10405 100, 100, 200, 200, hwnd
, 0, 0, NULL
);
10407 ok(hwnd
!= 0, "Failed to create overlapped window\n");
10408 ok(popup
!= 0, "Failed to create popup window\n");
10409 SetForegroundWindow( popup
);
10412 trace("SetActiveWindow(0)\n");
10413 ret
= SetActiveWindow(0);
10414 ok( ret
== popup
, "Failed to SetActiveWindow(0)\n");
10415 ok_sequence(SetActiveWindowSeq0
, "SetActiveWindow(0)", TRUE
);
10418 trace("SetActiveWindow(hwnd), hwnd visible\n");
10419 ret
= SetActiveWindow(hwnd
);
10422 ok( ret
== hwnd
, "Failed to SetActiveWindow(hwnd), hwnd visible\n");
10424 ok_sequence(SetActiveWindowSeq1
, "SetActiveWindow(hwnd), hwnd visible", TRUE
);
10427 trace("SetActiveWindow(popup), hwnd visible, popup visible\n");
10428 ret
= SetActiveWindow(popup
);
10429 ok( ret
== hwnd
, "Failed to SetActiveWindow(popup), popup visible\n");
10430 ok_sequence(SetActiveWindowSeq2
, "SetActiveWindow(popup), hwnd visible, popup visible", FALSE
);
10433 ShowWindow(hwnd
, SW_HIDE
);
10434 ShowWindow(popup
, SW_HIDE
);
10437 trace("SetActiveWindow(hwnd), hwnd not visible\n");
10438 ret
= SetActiveWindow(hwnd
);
10439 ok( ret
== NULL
, "SetActiveWindow(hwnd), hwnd not visible, previous is %p\n", ret
);
10440 ok_sequence(SetActiveWindowSeq3
, "SetActiveWindow(hwnd), hwnd not visible", TRUE
);
10443 trace("SetActiveWindow(popup), hwnd not visible, popup not visible\n");
10444 ret
= SetActiveWindow(popup
);
10445 ok( ret
== hwnd
, "Failed to SetActiveWindow(popup)\n");
10446 ok_sequence(SetActiveWindowSeq4
, "SetActiveWindow(popup), hwnd not visible, popup not visible", TRUE
);
10451 DestroyWindow(hwnd
);
10454 static const struct message SetForegroundWindowSeq
[] =
10456 { WM_NCACTIVATE
, sent
|wparam
, 0 },
10457 { WM_GETTEXT
, sent
|defwinproc
|optional
},
10458 { WM_ACTIVATE
, sent
|wparam
, 0 },
10459 { WM_ACTIVATEAPP
, sent
|wparam
, 0 },
10460 { WM_KILLFOCUS
, sent
},
10461 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
, 0 },
10462 { WM_IME_NOTIFY
, sent
|wparam
|optional
|defwinproc
, 1 },
10466 static void test_SetForegroundWindow(void)
10470 hwnd
= CreateWindowExA(0, "TestWindowClass", "Test SetForegroundWindow",
10471 WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
10472 100, 100, 200, 200, 0, 0, 0, NULL
);
10473 ok (hwnd
!= 0, "Failed to create overlapped window\n");
10476 trace("SetForegroundWindow( 0 )\n");
10477 SetForegroundWindow( 0 );
10478 ok_sequence(WmEmptySeq
, "SetForegroundWindow( 0 ) away from foreground top level window", FALSE
);
10479 trace("SetForegroundWindow( GetDesktopWindow() )\n");
10480 SetForegroundWindow( GetDesktopWindow() );
10481 ok_sequence(SetForegroundWindowSeq
, "SetForegroundWindow( desktop ) away from "
10482 "foreground top level window", FALSE
);
10485 DestroyWindow(hwnd
);
10488 static void test_dbcs_wm_char(void)
10491 WCHAR wch
, bad_wch
;
10499 struct message wmCharSeq
[2];
10501 if (!pGetCPInfoExA
)
10503 skip("GetCPInfoExA is not available\n");
10507 pGetCPInfoExA( CP_ACP
, 0, &cpinfo
);
10508 if (cpinfo
.MaxCharSize
!= 2)
10510 skip( "Skipping DBCS WM_CHAR test in SBCS codepage '%s'\n", cpinfo
.CodePageName
);
10514 dbch
[0] = dbch
[1] = 0;
10516 bad_wch
= cpinfo
.UnicodeDefaultChar
;
10517 for (i
= 0; !wch
&& i
< MAX_LEADBYTES
&& cpinfo
.LeadByte
[i
]; i
+= 2)
10518 for (j
= cpinfo
.LeadByte
[i
]; !wch
&& j
<= cpinfo
.LeadByte
[i
+1]; j
++)
10519 for (k
= 128; k
<= 255; k
++)
10525 if (MultiByteToWideChar( CP_ACP
, 0, str
, 2, wstr
, 2 ) == 1 &&
10526 WideCharToMultiByte( CP_ACP
, 0, wstr
, 1, str
, 2, NULL
, NULL
) == 2 &&
10527 (BYTE
)str
[0] == j
&& (BYTE
)str
[1] == k
&&
10528 HIBYTE(wstr
[0]) && HIBYTE(wstr
[0]) != 0xff)
10539 skip( "Skipping DBCS WM_CHAR test, no appropriate char found\n" );
10542 trace( "using dbcs char %02x,%02x wchar %04x bad wchar %04x codepage '%s'\n",
10543 dbch
[0], dbch
[1], wch
, bad_wch
, cpinfo
.CodePageName
);
10545 hwnd
= CreateWindowExW(0, testWindowClassW
, NULL
,
10546 WS_OVERLAPPEDWINDOW
, 100, 100, 200, 200, 0, 0, 0, NULL
);
10547 hwnd2
= CreateWindowExW(0, testWindowClassW
, NULL
,
10548 WS_OVERLAPPEDWINDOW
, 100, 100, 200, 200, 0, 0, 0, NULL
);
10549 ok (hwnd
!= 0, "Failed to create overlapped window\n");
10550 ok (hwnd2
!= 0, "Failed to create overlapped window\n");
10553 memset( wmCharSeq
, 0, sizeof(wmCharSeq
) );
10554 wmCharSeq
[0].message
= WM_CHAR
;
10555 wmCharSeq
[0].flags
= sent
|wparam
;
10556 wmCharSeq
[0].wParam
= wch
;
10558 /* posted message */
10559 PostMessageA( hwnd
, WM_CHAR
, dbch
[0], 0 );
10560 ok( !PeekMessageW( &msg
, hwnd
, 0, 0, PM_REMOVE
), "got message %x\n", msg
.message
);
10561 PostMessageA( hwnd
, WM_CHAR
, dbch
[1], 0 );
10562 ok( PeekMessageW( &msg
, hwnd
, 0, 0, PM_REMOVE
), "no message\n" );
10563 ok( msg
.message
== WM_CHAR
, "unexpected message %x\n", msg
.message
);
10564 ok( msg
.wParam
== wch
, "bad wparam %lx/%x\n", msg
.wParam
, wch
);
10565 ok( !PeekMessageW( &msg
, hwnd
, 0, 0, PM_REMOVE
), "got message %x\n", msg
.message
);
10567 /* posted thread message */
10568 PostThreadMessageA( GetCurrentThreadId(), WM_CHAR
, dbch
[0], 0 );
10569 ok( !PeekMessageW( &msg
, hwnd
, 0, 0, PM_REMOVE
), "got message %x\n", msg
.message
);
10570 PostMessageA( hwnd
, WM_CHAR
, dbch
[1], 0 );
10571 ok( PeekMessageW( &msg
, hwnd
, 0, 0, PM_REMOVE
), "no message\n" );
10572 ok( msg
.message
== WM_CHAR
, "unexpected message %x\n", msg
.message
);
10573 ok( msg
.wParam
== wch
, "bad wparam %lx/%x\n", msg
.wParam
, wch
);
10574 ok( !PeekMessageW( &msg
, hwnd
, 0, 0, PM_REMOVE
), "got message %x\n", msg
.message
);
10578 SendMessageA( hwnd
, WM_CHAR
, dbch
[0], 0 );
10579 ok_sequence( WmEmptySeq
, "no messages", FALSE
);
10580 SendMessageA( hwnd
, WM_CHAR
, dbch
[1], 0 );
10581 ok_sequence( wmCharSeq
, "Unicode WM_CHAR", FALSE
);
10582 ok( !PeekMessageW( &msg
, hwnd
, 0, 0, PM_REMOVE
), "got message %x\n", msg
.message
);
10584 /* sent message with timeout */
10586 SendMessageTimeoutA( hwnd
, WM_CHAR
, dbch
[0], 0, SMTO_NORMAL
, 0, &res
);
10587 ok_sequence( WmEmptySeq
, "no messages", FALSE
);
10588 SendMessageTimeoutA( hwnd
, WM_CHAR
, dbch
[1], 0, SMTO_NORMAL
, 0, &res
);
10589 ok_sequence( wmCharSeq
, "Unicode WM_CHAR", FALSE
);
10590 ok( !PeekMessageW( &msg
, hwnd
, 0, 0, PM_REMOVE
), "got message %x\n", msg
.message
);
10592 /* sent message with timeout and callback */
10594 SendMessageTimeoutA( hwnd
, WM_CHAR
, dbch
[0], 0, SMTO_NORMAL
, 0, &res
);
10595 ok_sequence( WmEmptySeq
, "no messages", FALSE
);
10596 SendMessageCallbackA( hwnd
, WM_CHAR
, dbch
[1], 0, NULL
, 0 );
10597 ok_sequence( wmCharSeq
, "Unicode WM_CHAR", FALSE
);
10598 ok( !PeekMessageW( &msg
, hwnd
, 0, 0, PM_REMOVE
), "got message %x\n", msg
.message
);
10600 /* sent message with callback */
10602 SendNotifyMessageA( hwnd
, WM_CHAR
, dbch
[0], 0 );
10603 ok_sequence( WmEmptySeq
, "no messages", FALSE
);
10604 SendMessageCallbackA( hwnd
, WM_CHAR
, dbch
[1], 0, NULL
, 0 );
10605 ok_sequence( wmCharSeq
, "Unicode WM_CHAR", FALSE
);
10606 ok( !PeekMessageW( &msg
, hwnd
, 0, 0, PM_REMOVE
), "got message %x\n", msg
.message
);
10608 /* direct window proc call */
10610 CallWindowProcA( (WNDPROC
)GetWindowLongPtrA( hwnd
, GWLP_WNDPROC
), hwnd
, WM_CHAR
, dbch
[0], 0 );
10611 ok_sequence( WmEmptySeq
, "no messages", FALSE
);
10612 CallWindowProcA( (WNDPROC
)GetWindowLongPtrA( hwnd
, GWLP_WNDPROC
), hwnd
, WM_CHAR
, dbch
[1], 0 );
10613 ok_sequence( wmCharSeq
, "Unicode WM_CHAR", FALSE
);
10615 /* dispatch message */
10617 msg
.message
= WM_CHAR
;
10618 msg
.wParam
= dbch
[0];
10620 DispatchMessageA( &msg
);
10621 ok_sequence( WmEmptySeq
, "no messages", FALSE
);
10622 msg
.wParam
= dbch
[1];
10623 DispatchMessageA( &msg
);
10624 ok_sequence( wmCharSeq
, "Unicode WM_CHAR", FALSE
);
10626 /* window handle is irrelevant */
10628 SendMessageA( hwnd2
, WM_CHAR
, dbch
[0], 0 );
10629 ok_sequence( WmEmptySeq
, "no messages", FALSE
);
10630 SendMessageA( hwnd
, WM_CHAR
, dbch
[1], 0 );
10631 ok_sequence( wmCharSeq
, "Unicode WM_CHAR", FALSE
);
10632 ok( !PeekMessageW( &msg
, hwnd
, 0, 0, PM_REMOVE
), "got message %x\n", msg
.message
);
10634 /* interleaved post and send */
10636 PostMessageA( hwnd2
, WM_CHAR
, dbch
[0], 0 );
10637 SendMessageA( hwnd2
, WM_CHAR
, dbch
[0], 0 );
10638 ok_sequence( WmEmptySeq
, "no messages", FALSE
);
10639 ok( !PeekMessageW( &msg
, hwnd
, 0, 0, PM_REMOVE
), "got message %x\n", msg
.message
);
10640 PostMessageA( hwnd
, WM_CHAR
, dbch
[1], 0 );
10641 ok_sequence( WmEmptySeq
, "no messages", FALSE
);
10642 ok( PeekMessageW( &msg
, hwnd
, 0, 0, PM_REMOVE
), "no message\n" );
10643 ok( msg
.message
== WM_CHAR
, "unexpected message %x\n", msg
.message
);
10644 ok( msg
.wParam
== wch
, "bad wparam %lx/%x\n", msg
.wParam
, wch
);
10645 ok( !PeekMessageW( &msg
, hwnd
, 0, 0, PM_REMOVE
), "got message %x\n", msg
.message
);
10646 SendMessageA( hwnd
, WM_CHAR
, dbch
[1], 0 );
10647 ok_sequence( wmCharSeq
, "Unicode WM_CHAR", FALSE
);
10648 ok( !PeekMessageW( &msg
, hwnd
, 0, 0, PM_REMOVE
), "got message %x\n", msg
.message
);
10650 /* interleaved sent message and winproc */
10652 SendMessageA( hwnd
, WM_CHAR
, dbch
[0], 0 );
10653 CallWindowProcA( (WNDPROC
)GetWindowLongPtrA( hwnd
, GWLP_WNDPROC
), hwnd
, WM_CHAR
, dbch
[0], 0 );
10654 ok_sequence( WmEmptySeq
, "no messages", FALSE
);
10655 SendMessageA( hwnd
, WM_CHAR
, dbch
[1], 0 );
10656 ok_sequence( wmCharSeq
, "Unicode WM_CHAR", FALSE
);
10657 CallWindowProcA( (WNDPROC
)GetWindowLongPtrA( hwnd
, GWLP_WNDPROC
), hwnd
, WM_CHAR
, dbch
[1], 0 );
10658 ok_sequence( wmCharSeq
, "Unicode WM_CHAR", FALSE
);
10660 /* interleaved winproc and dispatch */
10662 msg
.message
= WM_CHAR
;
10663 msg
.wParam
= dbch
[0];
10665 CallWindowProcA( (WNDPROC
)GetWindowLongPtrA( hwnd
, GWLP_WNDPROC
), hwnd
, WM_CHAR
, dbch
[0], 0 );
10666 DispatchMessageA( &msg
);
10667 ok_sequence( WmEmptySeq
, "no messages", FALSE
);
10668 msg
.wParam
= dbch
[1];
10669 DispatchMessageA( &msg
);
10670 ok_sequence( wmCharSeq
, "Unicode WM_CHAR", FALSE
);
10671 CallWindowProcA( (WNDPROC
)GetWindowLongPtrA( hwnd
, GWLP_WNDPROC
), hwnd
, WM_CHAR
, dbch
[1], 0 );
10672 ok_sequence( wmCharSeq
, "Unicode WM_CHAR", FALSE
);
10674 /* interleaved sends */
10676 SendMessageA( hwnd
, WM_CHAR
, dbch
[0], 0 );
10677 SendMessageCallbackA( hwnd
, WM_CHAR
, dbch
[0], 0, NULL
, 0 );
10678 ok_sequence( WmEmptySeq
, "no messages", FALSE
);
10679 SendMessageTimeoutA( hwnd
, WM_CHAR
, dbch
[1], 0, SMTO_NORMAL
, 0, &res
);
10680 ok_sequence( wmCharSeq
, "Unicode WM_CHAR", FALSE
);
10681 SendMessageA( hwnd
, WM_CHAR
, dbch
[1], 0 );
10682 ok_sequence( wmCharSeq
, "Unicode WM_CHAR", FALSE
);
10686 SendMessageA( hwnd2
, WM_CHAR
, (dbch
[1] << 8) | dbch
[0], 0 );
10687 ok_sequence( wmCharSeq
, "Unicode WM_CHAR", FALSE
);
10688 ok( !PeekMessageW( &msg
, hwnd
, 0, 0, PM_REMOVE
), "got message %x\n", msg
.message
);
10690 /* other char messages are not magic */
10691 PostMessageA( hwnd
, WM_SYSCHAR
, dbch
[0], 0 );
10692 ok( PeekMessageW( &msg
, hwnd
, 0, 0, PM_REMOVE
), "no message\n" );
10693 ok( msg
.message
== WM_SYSCHAR
, "unexpected message %x\n", msg
.message
);
10694 ok( msg
.wParam
== bad_wch
, "bad wparam %lx/%x\n", msg
.wParam
, bad_wch
);
10695 ok( !PeekMessageW( &msg
, hwnd
, 0, 0, PM_REMOVE
), "got message %x\n", msg
.message
);
10696 PostMessageA( hwnd
, WM_DEADCHAR
, dbch
[0], 0 );
10697 ok( PeekMessageW( &msg
, hwnd
, 0, 0, PM_REMOVE
), "no message\n" );
10698 ok( msg
.message
== WM_DEADCHAR
, "unexpected message %x\n", msg
.message
);
10699 ok( msg
.wParam
== bad_wch
, "bad wparam %lx/%x\n", msg
.wParam
, bad_wch
);
10700 ok( !PeekMessageW( &msg
, hwnd
, 0, 0, PM_REMOVE
), "got message %x\n", msg
.message
);
10702 /* test retrieving messages */
10704 PostMessageW( hwnd
, WM_CHAR
, wch
, 0 );
10705 ok( PeekMessageA( &msg
, hwnd
, 0, 0, PM_REMOVE
), "no message\n" );
10706 ok( msg
.hwnd
== hwnd
, "unexpected hwnd %p\n", msg
.hwnd
);
10707 ok( msg
.message
== WM_CHAR
, "unexpected message %x\n", msg
.message
);
10708 ok( msg
.wParam
== dbch
[0], "bad wparam %lx/%x\n", msg
.wParam
, dbch
[0] );
10709 ok( PeekMessageA( &msg
, hwnd
, 0, 0, PM_REMOVE
), "no message\n" );
10710 ok( msg
.hwnd
== hwnd
, "unexpected hwnd %p\n", msg
.hwnd
);
10711 ok( msg
.message
== WM_CHAR
, "unexpected message %x\n", msg
.message
);
10712 ok( msg
.wParam
== dbch
[1], "bad wparam %lx/%x\n", msg
.wParam
, dbch
[0] );
10713 ok( !PeekMessageA( &msg
, hwnd
, 0, 0, PM_REMOVE
), "got message %x\n", msg
.message
);
10715 /* message filters */
10716 PostMessageW( hwnd
, WM_CHAR
, wch
, 0 );
10717 ok( PeekMessageA( &msg
, hwnd
, 0, 0, PM_REMOVE
), "no message\n" );
10718 ok( msg
.hwnd
== hwnd
, "unexpected hwnd %p\n", msg
.hwnd
);
10719 ok( msg
.message
== WM_CHAR
, "unexpected message %x\n", msg
.message
);
10720 ok( msg
.wParam
== dbch
[0], "bad wparam %lx/%x\n", msg
.wParam
, dbch
[0] );
10721 /* message id is filtered, hwnd is not */
10722 ok( !PeekMessageA( &msg
, hwnd
, WM_MOUSEFIRST
, WM_MOUSELAST
, PM_REMOVE
), "no message\n" );
10723 ok( PeekMessageA( &msg
, hwnd2
, 0, 0, PM_REMOVE
), "no message\n" );
10724 ok( msg
.hwnd
== hwnd
, "unexpected hwnd %p\n", msg
.hwnd
);
10725 ok( msg
.message
== WM_CHAR
, "unexpected message %x\n", msg
.message
);
10726 ok( msg
.wParam
== dbch
[1], "bad wparam %lx/%x\n", msg
.wParam
, dbch
[0] );
10727 ok( !PeekMessageA( &msg
, hwnd
, 0, 0, PM_REMOVE
), "got message %x\n", msg
.message
);
10729 /* mixing GetMessage and PostMessage */
10730 PostMessageW( hwnd
, WM_CHAR
, wch
, 0xbeef );
10731 ok( GetMessageA( &msg
, hwnd
, 0, 0 ), "no message\n" );
10732 ok( msg
.hwnd
== hwnd
, "unexpected hwnd %p\n", msg
.hwnd
);
10733 ok( msg
.message
== WM_CHAR
, "unexpected message %x\n", msg
.message
);
10734 ok( msg
.wParam
== dbch
[0], "bad wparam %lx/%x\n", msg
.wParam
, dbch
[0] );
10735 ok( msg
.lParam
== 0xbeef, "bad lparam %lx\n", msg
.lParam
);
10738 ok( time
- GetTickCount() <= 100, "bad time %x\n", msg
.time
);
10739 ok( PeekMessageA( &msg
, 0, 0, 0, PM_REMOVE
), "no message\n" );
10740 ok( msg
.hwnd
== hwnd
, "unexpected hwnd %p\n", msg
.hwnd
);
10741 ok( msg
.message
== WM_CHAR
, "unexpected message %x\n", msg
.message
);
10742 ok( msg
.wParam
== dbch
[1], "bad wparam %lx/%x\n", msg
.wParam
, dbch
[0] );
10743 ok( msg
.lParam
== 0xbeef, "bad lparam %lx\n", msg
.lParam
);
10744 ok( msg
.time
== time
, "bad time %x/%x\n", msg
.time
, time
);
10745 ok( msg
.pt
.x
== pt
.x
&& msg
.pt
.y
== pt
.y
, "bad point %u,%u/%u,%u\n", msg
.pt
.x
, msg
.pt
.y
, pt
.x
, pt
.y
);
10746 ok( !PeekMessageA( &msg
, hwnd
, 0, 0, PM_REMOVE
), "got message %x\n", msg
.message
);
10748 /* without PM_REMOVE */
10749 PostMessageW( hwnd
, WM_CHAR
, wch
, 0 );
10750 ok( PeekMessageA( &msg
, 0, 0, 0, PM_NOREMOVE
), "no message\n" );
10751 ok( msg
.hwnd
== hwnd
, "unexpected hwnd %p\n", msg
.hwnd
);
10752 ok( msg
.message
== WM_CHAR
, "unexpected message %x\n", msg
.message
);
10753 ok( msg
.wParam
== dbch
[0], "bad wparam %lx/%x\n", msg
.wParam
, dbch
[0] );
10754 ok( PeekMessageA( &msg
, 0, 0, 0, PM_REMOVE
), "no message\n" );
10755 ok( msg
.hwnd
== hwnd
, "unexpected hwnd %p\n", msg
.hwnd
);
10756 ok( msg
.message
== WM_CHAR
, "unexpected message %x\n", msg
.message
);
10757 ok( msg
.wParam
== dbch
[0], "bad wparam %lx/%x\n", msg
.wParam
, dbch
[0] );
10758 ok( PeekMessageA( &msg
, 0, 0, 0, PM_NOREMOVE
), "no message\n" );
10759 ok( msg
.hwnd
== hwnd
, "unexpected hwnd %p\n", msg
.hwnd
);
10760 ok( msg
.message
== WM_CHAR
, "unexpected message %x\n", msg
.message
);
10761 ok( msg
.wParam
== dbch
[1], "bad wparam %lx/%x\n", msg
.wParam
, dbch
[0] );
10762 ok( PeekMessageA( &msg
, 0, 0, 0, PM_REMOVE
), "no message\n" );
10763 ok( msg
.hwnd
== hwnd
, "unexpected hwnd %p\n", msg
.hwnd
);
10764 ok( msg
.message
== WM_CHAR
, "unexpected message %x\n", msg
.message
);
10765 ok( msg
.wParam
== dbch
[1], "bad wparam %lx/%x\n", msg
.wParam
, dbch
[0] );
10766 ok( !PeekMessageA( &msg
, hwnd
, 0, 0, PM_REMOVE
), "got message %x\n", msg
.message
);
10768 DestroyWindow(hwnd
);
10771 #define ID_LISTBOX 0x000f
10773 static const struct message wm_lb_setcursel_0
[] =
10775 { LB_SETCURSEL
, sent
|wparam
|lparam
, 0, 0 },
10776 { WM_CTLCOLORLISTBOX
, sent
|parent
},
10777 { WM_DRAWITEM
, sent
|wparam
|lparam
|parent
, ID_LISTBOX
, 0x000120f2 },
10778 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 1 },
10779 { EVENT_OBJECT_SELECTION
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 1 },
10782 static const struct message wm_lb_setcursel_1
[] =
10784 { LB_SETCURSEL
, sent
|wparam
|lparam
, 1, 0 },
10785 { WM_CTLCOLORLISTBOX
, sent
|parent
},
10786 { WM_DRAWITEM
, sent
|wparam
|lparam
|parent
, ID_LISTBOX
, 0x000020f2 },
10787 { WM_CTLCOLORLISTBOX
, sent
|parent
},
10788 { WM_DRAWITEM
, sent
|wparam
|lparam
|parent
, ID_LISTBOX
, 0x000121f2 },
10789 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 2 },
10790 { EVENT_OBJECT_SELECTION
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 2 },
10793 static const struct message wm_lb_setcursel_2
[] =
10795 { LB_SETCURSEL
, sent
|wparam
|lparam
, 2, 0 },
10796 { WM_CTLCOLORLISTBOX
, sent
|parent
},
10797 { WM_DRAWITEM
, sent
|wparam
|lparam
|parent
, ID_LISTBOX
, 0x000021f2 },
10798 { WM_CTLCOLORLISTBOX
, sent
|parent
},
10799 { WM_DRAWITEM
, sent
|wparam
|lparam
|parent
, ID_LISTBOX
, 0x000122f2 },
10800 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 3 },
10801 { EVENT_OBJECT_SELECTION
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 3 },
10804 static const struct message wm_lb_click_0
[] =
10806 { WM_LBUTTONDOWN
, sent
|wparam
|lparam
, 0, MAKELPARAM(1,1) },
10807 { HCBT_SETFOCUS
, hook
},
10808 { WM_KILLFOCUS
, sent
|parent
},
10809 { WM_IME_SETCONTEXT
, sent
|wparam
|optional
|parent
, 0 },
10810 { WM_IME_SETCONTEXT
, sent
|wparam
|defwinproc
|optional
, 1 },
10811 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 0 },
10812 { WM_SETFOCUS
, sent
|defwinproc
},
10814 { WM_DRAWITEM
, sent
|wparam
|lparam
|parent
, ID_LISTBOX
, 0x001142f2 },
10815 { WM_COMMAND
, sent
|wparam
|parent
, MAKEWPARAM(ID_LISTBOX
, LBN_SETFOCUS
) },
10816 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 3 },
10817 { WM_LBTRACKPOINT
, sent
|wparam
|lparam
|parent
, 0, MAKELPARAM(1,1) },
10818 { EVENT_SYSTEM_CAPTURESTART
, winevent_hook
|wparam
|lparam
, 0, 0 },
10820 { WM_DRAWITEM
, sent
|wparam
|lparam
|parent
, ID_LISTBOX
, 0x000142f2 },
10821 { WM_CTLCOLORLISTBOX
, sent
|parent
},
10822 { WM_DRAWITEM
, sent
|wparam
|lparam
|parent
, ID_LISTBOX
, 0x000022f2 },
10823 { WM_CTLCOLORLISTBOX
, sent
|parent
},
10824 { WM_DRAWITEM
, sent
|wparam
|lparam
|parent
, ID_LISTBOX
, 0x000120f2 },
10825 { WM_DRAWITEM
, sent
|wparam
|lparam
|parent
, ID_LISTBOX
, 0x001140f2 },
10827 { EVENT_OBJECT_FOCUS
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 1 },
10828 { EVENT_OBJECT_SELECTION
, winevent_hook
|wparam
|lparam
, OBJID_CLIENT
, 1 },
10830 { WM_LBUTTONUP
, sent
|wparam
|lparam
, 0, 0 },
10831 { EVENT_SYSTEM_CAPTUREEND
, winevent_hook
|wparam
|lparam
, 0, 0 },
10832 { WM_CAPTURECHANGED
, sent
|wparam
|lparam
|defwinproc
, 0, 0 },
10833 { WM_COMMAND
, sent
|wparam
|parent
, MAKEWPARAM(ID_LISTBOX
, LBN_SELCHANGE
) },
10837 #define check_lb_state(a1, a2, a3, a4, a5) check_lb_state_dbg(a1, a2, a3, a4, a5, __LINE__)
10839 static LRESULT (WINAPI
*listbox_orig_proc
)(HWND
, UINT
, WPARAM
, LPARAM
);
10841 static LRESULT WINAPI
listbox_hook_proc(HWND hwnd
, UINT message
, WPARAM wp
, LPARAM lp
)
10843 static long defwndproc_counter
= 0;
10845 struct recvd_message msg
;
10847 /* do not log painting messages */
10848 if (message
!= WM_PAINT
&&
10849 message
!= WM_NCPAINT
&&
10850 message
!= WM_SYNCPAINT
&&
10851 message
!= WM_ERASEBKGND
&&
10852 message
!= WM_NCHITTEST
&&
10853 message
!= WM_GETTEXT
&&
10854 message
!= WM_GETICON
&&
10855 message
!= WM_DEVICECHANGE
)
10858 msg
.message
= message
;
10859 msg
.flags
= sent
|wparam
|lparam
;
10860 if (defwndproc_counter
) msg
.flags
|= defwinproc
;
10863 msg
.descr
= "listbox";
10867 defwndproc_counter
++;
10868 ret
= CallWindowProcA(listbox_orig_proc
, hwnd
, message
, wp
, lp
);
10869 defwndproc_counter
--;
10874 static void check_lb_state_dbg(HWND listbox
, int count
, int cur_sel
,
10875 int caret_index
, int top_index
, int line
)
10879 /* calling an orig proc helps to avoid unnecessary message logging */
10880 ret
= CallWindowProcA(listbox_orig_proc
, listbox
, LB_GETCOUNT
, 0, 0);
10881 ok_(__FILE__
, line
)(ret
== count
, "expected count %d, got %ld\n", count
, ret
);
10882 ret
= CallWindowProcA(listbox_orig_proc
, listbox
, LB_GETCURSEL
, 0, 0);
10883 ok_(__FILE__
, line
)(ret
== cur_sel
, "expected cur sel %d, got %ld\n", cur_sel
, ret
);
10884 ret
= CallWindowProcA(listbox_orig_proc
, listbox
, LB_GETCARETINDEX
, 0, 0);
10885 ok_(__FILE__
, line
)(ret
== caret_index
, "expected caret index %d, got %ld\n", caret_index
, ret
);
10886 ret
= CallWindowProcA(listbox_orig_proc
, listbox
, LB_GETTOPINDEX
, 0, 0);
10887 ok_(__FILE__
, line
)(ret
== top_index
, "expected top index %d, got %ld\n", top_index
, ret
);
10890 static void test_listbox_messages(void)
10892 HWND parent
, listbox
;
10895 parent
= CreateWindowExA(0, "TestParentClass", NULL
, WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
10896 100, 100, 200, 200, 0, 0, 0, NULL
);
10897 listbox
= CreateWindowExA(WS_EX_NOPARENTNOTIFY
, "ListBox", NULL
,
10898 WS_CHILD
| LBS_NOTIFY
| LBS_OWNERDRAWVARIABLE
| LBS_HASSTRINGS
| WS_VISIBLE
,
10899 10, 10, 80, 80, parent
, (HMENU
)ID_LISTBOX
, 0, NULL
);
10900 listbox_orig_proc
= (WNDPROC
)SetWindowLongPtrA(listbox
, GWLP_WNDPROC
, (ULONG_PTR
)listbox_hook_proc
);
10902 check_lb_state(listbox
, 0, LB_ERR
, 0, 0);
10904 ret
= SendMessage(listbox
, LB_ADDSTRING
, 0, (LPARAM
)"item 0");
10905 ok(ret
== 0, "expected 0, got %ld\n", ret
);
10906 ret
= SendMessage(listbox
, LB_ADDSTRING
, 0, (LPARAM
)"item 1");
10907 ok(ret
== 1, "expected 1, got %ld\n", ret
);
10908 ret
= SendMessage(listbox
, LB_ADDSTRING
, 0, (LPARAM
)"item 2");
10909 ok(ret
== 2, "expected 2, got %ld\n", ret
);
10911 check_lb_state(listbox
, 3, LB_ERR
, 0, 0);
10915 log_all_parent_messages
++;
10917 trace("selecting item 0\n");
10918 ret
= SendMessage(listbox
, LB_SETCURSEL
, 0, 0);
10919 ok(ret
== 0, "expected 0, got %ld\n", ret
);
10920 ok_sequence(wm_lb_setcursel_0
, "LB_SETCURSEL 0", FALSE
);
10921 check_lb_state(listbox
, 3, 0, 0, 0);
10924 trace("selecting item 1\n");
10925 ret
= SendMessage(listbox
, LB_SETCURSEL
, 1, 0);
10926 ok(ret
== 1, "expected 1, got %ld\n", ret
);
10927 ok_sequence(wm_lb_setcursel_1
, "LB_SETCURSEL 1", FALSE
);
10928 check_lb_state(listbox
, 3, 1, 1, 0);
10930 trace("selecting item 2\n");
10931 ret
= SendMessage(listbox
, LB_SETCURSEL
, 2, 0);
10932 ok(ret
== 2, "expected 2, got %ld\n", ret
);
10933 ok_sequence(wm_lb_setcursel_2
, "LB_SETCURSEL 2", FALSE
);
10934 check_lb_state(listbox
, 3, 2, 2, 0);
10936 trace("clicking on item 0\n");
10937 ret
= SendMessage(listbox
, WM_LBUTTONDOWN
, 0, MAKELPARAM(1, 1));
10938 ok(ret
== LB_OKAY
, "expected LB_OKAY, got %ld\n", ret
);
10939 ret
= SendMessage(listbox
, WM_LBUTTONUP
, 0, 0);
10940 ok(ret
== LB_OKAY
, "expected LB_OKAY, got %ld\n", ret
);
10941 ok_sequence(wm_lb_click_0
, "WM_LBUTTONDOWN 0", FALSE
);
10942 check_lb_state(listbox
, 3, 0, 0, 0);
10945 log_all_parent_messages
--;
10947 DestroyWindow(listbox
);
10948 DestroyWindow(parent
);
10951 /*************************** Menu test ******************************/
10952 static const struct message wm_popup_menu_1
[] =
10954 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_MENU
, 0x20000001 },
10955 { WM_SYSKEYDOWN
, sent
|wparam
|lparam
, VK_MENU
, 0x20000001 },
10956 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, 'E', 0x20000001 },
10957 { WM_SYSKEYDOWN
, sent
|wparam
|lparam
, 'E', 0x20000001 },
10958 { WM_SYSCHAR
, sent
|wparam
|lparam
, 'e', 0x20000001 },
10959 { HCBT_SYSCOMMAND
, hook
|wparam
|lparam
, SC_KEYMENU
, 'e' },
10960 { WM_ENTERMENULOOP
, sent
|wparam
|lparam
, 0, 0 },
10961 { WM_INITMENU
, sent
|lparam
, 0, 0 },
10962 { WM_MENUSELECT
, sent
|wparam
, MAKEWPARAM(1,MF_HILITE
|MF_POPUP
) },
10963 { WM_INITMENUPOPUP
, sent
|lparam
, 0, 1 },
10964 { HCBT_CREATEWND
, hook
|optional
}, /* Win9x doesn't create a window */
10965 { WM_MENUSELECT
, sent
|wparam
, MAKEWPARAM(200,MF_HILITE
) },
10966 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, 'E', 0xf0000001 },
10967 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_MENU
, 0xd0000001 },
10968 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_RETURN
, 0x10000001 },
10969 { HCBT_DESTROYWND
, hook
|optional
}, /* Win9x doesn't create a window */
10970 { WM_UNINITMENUPOPUP
, sent
|lparam
, 0, 0 },
10971 { WM_MENUSELECT
, sent
|wparam
|lparam
, MAKEWPARAM(0,0xffff), 0 },
10972 { WM_EXITMENULOOP
, sent
|wparam
|lparam
, 0, 0 },
10973 { WM_MENUCOMMAND
, sent
}, /* |wparam, 200 - Win9x */
10974 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_RETURN
, 0xc0000001 },
10975 { WM_KEYUP
, sent
|wparam
|lparam
, VK_RETURN
, 0xc0000001 },
10978 static const struct message wm_popup_menu_2
[] =
10980 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_MENU
, 0x20000001 },
10981 { WM_SYSKEYDOWN
, sent
|wparam
|lparam
, VK_MENU
, 0x20000001 },
10982 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, 'F', 0x20000001 },
10983 { WM_SYSKEYDOWN
, sent
|wparam
|lparam
, 'F', 0x20000001 },
10984 { WM_SYSCHAR
, sent
|wparam
|lparam
, 'f', 0x20000001 },
10985 { HCBT_SYSCOMMAND
, hook
|wparam
|lparam
, SC_KEYMENU
, 'f' },
10986 { WM_ENTERMENULOOP
, sent
|wparam
|lparam
, 0, 0 },
10987 { WM_INITMENU
, sent
|lparam
, 0, 0 },
10988 { WM_MENUSELECT
, sent
|wparam
, MAKEWPARAM(0,MF_HILITE
|MF_POPUP
) },
10989 { WM_INITMENUPOPUP
, sent
|lparam
, 0, 0 },
10990 { WM_MENUSELECT
, sent
|wparam
|optional
, MAKEWPARAM(0,MF_HILITE
|MF_POPUP
) }, /* Win9x */
10991 { WM_INITMENUPOPUP
, sent
|lparam
|optional
, 0, 0 }, /* Win9x */
10992 { HCBT_CREATEWND
, hook
},
10993 { WM_MENUSELECT
, sent
}, /*|wparam, MAKEWPARAM(0,MF_HILITE|MF_POPUP) - XP
10994 |wparam, MAKEWPARAM(100,MF_HILITE) - Win9x */
10995 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, 'F', 0xf0000001 },
10996 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_MENU
, 0xd0000001 },
10997 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_RIGHT
, 0x10000001 },
10998 { WM_INITMENUPOPUP
, sent
|lparam
|optional
, 0, 0 }, /* Win9x doesn't send it */
10999 { HCBT_CREATEWND
, hook
|optional
}, /* Win9x doesn't send it */
11000 { WM_MENUSELECT
, sent
|wparam
|optional
, MAKEWPARAM(100,MF_HILITE
) },
11001 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_RIGHT
, 0xd0000001 },
11002 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_RETURN
, 0x10000001 },
11003 { HCBT_DESTROYWND
, hook
},
11004 { WM_UNINITMENUPOPUP
, sent
|lparam
, 0, 0 },
11005 { HCBT_DESTROYWND
, hook
|optional
}, /* Win9x doesn't send it */
11006 { WM_UNINITMENUPOPUP
, sent
|lparam
, 0, 0 },
11007 { WM_MENUSELECT
, sent
|wparam
|lparam
, MAKEWPARAM(0,0xffff), 0 },
11008 { WM_EXITMENULOOP
, sent
|wparam
|lparam
, 0, 0 },
11009 { WM_MENUCOMMAND
, sent
}, /* |wparam, 100 - Win9x */
11010 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_RETURN
, 0xc0000001 },
11011 { WM_KEYUP
, sent
|wparam
|lparam
, VK_RETURN
, 0xc0000001 },
11014 static const struct message wm_popup_menu_3
[] =
11016 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_MENU
, 0x20000001 },
11017 { WM_SYSKEYDOWN
, sent
|wparam
|lparam
, VK_MENU
, 0x20000001 },
11018 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, 'F', 0x20000001 },
11019 { WM_SYSKEYDOWN
, sent
|wparam
|lparam
, 'F', 0x20000001 },
11020 { WM_SYSCHAR
, sent
|wparam
|lparam
, 'f', 0x20000001 },
11021 { HCBT_SYSCOMMAND
, hook
|wparam
|lparam
, SC_KEYMENU
, 'f' },
11022 { WM_ENTERMENULOOP
, sent
|wparam
|lparam
, 0, 0 },
11023 { WM_INITMENU
, sent
|lparam
, 0, 0 },
11024 { WM_MENUSELECT
, sent
|wparam
, MAKEWPARAM(0,MF_HILITE
|MF_POPUP
) },
11025 { WM_INITMENUPOPUP
, sent
|lparam
, 0, 0 },
11026 { WM_MENUSELECT
, sent
|wparam
|optional
, MAKEWPARAM(0,MF_HILITE
|MF_POPUP
) }, /* Win9x */
11027 { WM_INITMENUPOPUP
, sent
|lparam
|optional
, 0, 0 }, /* Win9x */
11028 { HCBT_CREATEWND
, hook
},
11029 { WM_MENUSELECT
, sent
}, /*|wparam, MAKEWPARAM(0,MF_HILITE|MF_POPUP) - XP
11030 |wparam, MAKEWPARAM(100,MF_HILITE) - Win9x */
11031 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, 'F', 0xf0000001 },
11032 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_MENU
, 0xd0000001 },
11033 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_RIGHT
, 0x10000001 },
11034 { WM_INITMENUPOPUP
, sent
|lparam
|optional
, 0, 0 }, /* Win9x doesn't send it */
11035 { HCBT_CREATEWND
, hook
|optional
}, /* Win9x doesn't send it */
11036 { WM_MENUSELECT
, sent
|wparam
|optional
, MAKEWPARAM(100,MF_HILITE
) },
11037 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_RIGHT
, 0xd0000001 },
11038 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_RETURN
, 0x10000001 },
11039 { HCBT_DESTROYWND
, hook
},
11040 { WM_UNINITMENUPOPUP
, sent
|lparam
, 0, 0 },
11041 { HCBT_DESTROYWND
, hook
|optional
}, /* Win9x doesn't send it */
11042 { WM_UNINITMENUPOPUP
, sent
|lparam
, 0, 0 },
11043 { WM_MENUSELECT
, sent
|wparam
|lparam
, MAKEWPARAM(0,0xffff), 0 },
11044 { WM_EXITMENULOOP
, sent
|wparam
|lparam
, 0, 0 },
11045 { WM_COMMAND
, sent
|wparam
|lparam
, 100, 0 },
11046 { HCBT_KEYSKIPPED
, hook
|wparam
|lparam
|optional
, VK_RETURN
, 0xc0000001 },
11047 { WM_KEYUP
, sent
|wparam
|lparam
, VK_RETURN
, 0xc0000001 },
11051 static LRESULT WINAPI
parent_menu_proc(HWND hwnd
, UINT message
, WPARAM wp
, LPARAM lp
)
11053 if (message
== WM_ENTERIDLE
||
11054 message
== WM_INITMENU
||
11055 message
== WM_INITMENUPOPUP
||
11056 message
== WM_MENUSELECT
||
11057 message
== WM_PARENTNOTIFY
||
11058 message
== WM_ENTERMENULOOP
||
11059 message
== WM_EXITMENULOOP
||
11060 message
== WM_UNINITMENUPOPUP
||
11061 message
== WM_KEYDOWN
||
11062 message
== WM_KEYUP
||
11063 message
== WM_CHAR
||
11064 message
== WM_SYSKEYDOWN
||
11065 message
== WM_SYSKEYUP
||
11066 message
== WM_SYSCHAR
||
11067 message
== WM_COMMAND
||
11068 message
== WM_MENUCOMMAND
)
11070 struct recvd_message msg
;
11073 msg
.message
= message
;
11074 msg
.flags
= sent
|wparam
|lparam
;
11077 msg
.descr
= "parent_menu_proc";
11081 return DefWindowProcA(hwnd
, message
, wp
, lp
);
11084 static void set_menu_style(HMENU hmenu
, DWORD style
)
11089 mi
.cbSize
= sizeof(mi
);
11090 mi
.fMask
= MIM_STYLE
;
11091 mi
.dwStyle
= style
;
11092 SetLastError(0xdeadbeef);
11093 ret
= pSetMenuInfo(hmenu
, &mi
);
11094 ok(ret
, "SetMenuInfo error %u\n", GetLastError());
11097 static DWORD
get_menu_style(HMENU hmenu
)
11102 mi
.cbSize
= sizeof(mi
);
11103 mi
.fMask
= MIM_STYLE
;
11105 SetLastError(0xdeadbeef);
11106 ret
= pGetMenuInfo(hmenu
, &mi
);
11107 ok(ret
, "GetMenuInfo error %u\n", GetLastError());
11112 static void test_menu_messages(void)
11116 HMENU hmenu
, hmenu_popup
;
11120 if (!pGetMenuInfo
|| !pSetMenuInfo
)
11122 skip("GetMenuInfo and/or SetMenuInfo are not available\n");
11126 cls
.lpfnWndProc
= parent_menu_proc
;
11127 cls
.cbClsExtra
= 0;
11128 cls
.cbWndExtra
= 0;
11129 cls
.hInstance
= GetModuleHandleA(0);
11131 cls
.hCursor
= LoadCursorA(0, IDC_ARROW
);
11132 cls
.hbrBackground
= GetStockObject(WHITE_BRUSH
);
11133 cls
.lpszMenuName
= NULL
;
11134 cls
.lpszClassName
= "TestMenuClass";
11135 UnregisterClass(cls
.lpszClassName
, cls
.hInstance
);
11136 if (!RegisterClassA(&cls
)) assert(0);
11138 SetLastError(0xdeadbeef);
11139 hwnd
= CreateWindowExA(0, "TestMenuClass", NULL
, WS_OVERLAPPEDWINDOW
| WS_VISIBLE
,
11140 100, 100, 200, 200, 0, 0, 0, NULL
);
11141 ok(hwnd
!= 0, "LoadMenuA error %u\n", GetLastError());
11143 SetLastError(0xdeadbeef);
11144 hmenu
= LoadMenuA(GetModuleHandle(0), MAKEINTRESOURCE(1));
11145 ok(hmenu
!= 0, "LoadMenuA error %u\n", GetLastError());
11147 SetMenu(hwnd
, hmenu
);
11148 SetForegroundWindow( hwnd
);
11150 set_menu_style(hmenu
, MNS_NOTIFYBYPOS
);
11151 style
= get_menu_style(hmenu
);
11152 ok(style
== MNS_NOTIFYBYPOS
, "expected MNS_NOTIFYBYPOS, got %u\n", style
);
11154 hmenu_popup
= GetSubMenu(hmenu
, 0);
11155 ok(hmenu_popup
!= 0, "GetSubMenu returned 0 for submenu 0\n");
11156 style
= get_menu_style(hmenu_popup
);
11157 ok(style
== 0, "expected 0, got %u\n", style
);
11159 hmenu_popup
= GetSubMenu(hmenu_popup
, 0);
11160 ok(hmenu_popup
!= 0, "GetSubMenu returned 0 for submenu 0\n");
11161 style
= get_menu_style(hmenu_popup
);
11162 ok(style
== 0, "expected 0, got %u\n", style
);
11165 trace("testing a popup menu command\n");
11167 keybd_event(VK_MENU
, 0, 0, 0);
11168 keybd_event('E', 0, 0, 0);
11169 keybd_event('E', 0, KEYEVENTF_KEYUP
, 0);
11170 keybd_event(VK_MENU
, 0, KEYEVENTF_KEYUP
, 0);
11171 keybd_event(VK_RETURN
, 0, 0, 0);
11172 keybd_event(VK_RETURN
, 0, KEYEVENTF_KEYUP
, 0);
11173 while (PeekMessage(&msg
, 0, 0, 0, PM_REMOVE
))
11175 TranslateMessage(&msg
);
11176 DispatchMessage(&msg
);
11178 ok_sequence(wm_popup_menu_1
, "popup menu command", FALSE
);
11180 /* Alt+F, Right, Enter */
11181 trace("testing submenu of a popup menu command\n");
11183 keybd_event(VK_MENU
, 0, 0, 0);
11184 keybd_event('F', 0, 0, 0);
11185 keybd_event('F', 0, KEYEVENTF_KEYUP
, 0);
11186 keybd_event(VK_MENU
, 0, KEYEVENTF_KEYUP
, 0);
11187 keybd_event(VK_RIGHT
, 0, 0, 0);
11188 keybd_event(VK_RIGHT
, 0, KEYEVENTF_KEYUP
, 0);
11189 keybd_event(VK_RETURN
, 0, 0, 0);
11190 keybd_event(VK_RETURN
, 0, KEYEVENTF_KEYUP
, 0);
11191 while (PeekMessage(&msg
, 0, 0, 0, PM_REMOVE
))
11193 TranslateMessage(&msg
);
11194 DispatchMessage(&msg
);
11196 ok_sequence(wm_popup_menu_2
, "submenu of a popup menu command", FALSE
);
11198 set_menu_style(hmenu
, 0);
11199 style
= get_menu_style(hmenu
);
11200 ok(style
== 0, "expected 0, got %u\n", style
);
11202 hmenu_popup
= GetSubMenu(hmenu
, 0);
11203 ok(hmenu_popup
!= 0, "GetSubMenu returned 0 for submenu 0\n");
11204 set_menu_style(hmenu_popup
, MNS_NOTIFYBYPOS
);
11205 style
= get_menu_style(hmenu_popup
);
11206 ok(style
== MNS_NOTIFYBYPOS
, "expected MNS_NOTIFYBYPOS, got %u\n", style
);
11208 hmenu_popup
= GetSubMenu(hmenu_popup
, 0);
11209 ok(hmenu_popup
!= 0, "GetSubMenu returned 0 for submenu 0\n");
11210 style
= get_menu_style(hmenu_popup
);
11211 ok(style
== 0, "expected 0, got %u\n", style
);
11213 /* Alt+F, Right, Enter */
11214 trace("testing submenu of a popup menu command\n");
11216 keybd_event(VK_MENU
, 0, 0, 0);
11217 keybd_event('F', 0, 0, 0);
11218 keybd_event('F', 0, KEYEVENTF_KEYUP
, 0);
11219 keybd_event(VK_MENU
, 0, KEYEVENTF_KEYUP
, 0);
11220 keybd_event(VK_RIGHT
, 0, 0, 0);
11221 keybd_event(VK_RIGHT
, 0, KEYEVENTF_KEYUP
, 0);
11222 keybd_event(VK_RETURN
, 0, 0, 0);
11223 keybd_event(VK_RETURN
, 0, KEYEVENTF_KEYUP
, 0);
11224 while (PeekMessage(&msg
, 0, 0, 0, PM_REMOVE
))
11226 TranslateMessage(&msg
);
11227 DispatchMessage(&msg
);
11229 ok_sequence(wm_popup_menu_3
, "submenu of a popup menu command", FALSE
);
11231 DestroyWindow(hwnd
);
11232 DestroyMenu(hmenu
);
11236 static void test_paintingloop(void)
11240 paint_loop_done
= 0;
11241 hwnd
= CreateWindowExA(0x0,"PaintLoopWindowClass",
11242 "PaintLoopWindowClass",WS_OVERLAPPEDWINDOW
,
11243 100, 100, 100, 100, 0, 0, 0, NULL
);
11244 ok(hwnd
!= 0, "PaintLoop window error %u\n", GetLastError());
11245 ShowWindow(hwnd
,SW_NORMAL
);
11248 while (!paint_loop_done
)
11251 if (PeekMessageA(&msg
, 0, 0, 0, 1))
11253 TranslateMessage(&msg
);
11254 DispatchMessage(&msg
);
11257 DestroyWindow(hwnd
);
11263 FARPROC pIsWinEventHookInstalled
= 0;/*GetProcAddress(user32, "IsWinEventHookInstalled");*/
11267 if (!RegisterWindowClasses()) assert(0);
11269 if (pSetWinEventHook
)
11271 hEvent_hook
= (HWINEVENTHOOK
)pSetWinEventHook(EVENT_MIN
, EVENT_MAX
,
11272 GetModuleHandleA(0),
11275 GetCurrentThreadId(),
11276 WINEVENT_INCONTEXT
);
11277 assert(hEvent_hook
);
11279 if (pIsWinEventHookInstalled
)
11282 for (event
= EVENT_MIN
; event
<= EVENT_MAX
; event
++)
11283 ok(pIsWinEventHookInstalled(event
), "IsWinEventHookInstalled(%u) failed\n", event
);
11287 cbt_hook_thread_id
= GetCurrentThreadId();
11288 hCBT_hook
= SetWindowsHookExA(WH_CBT
, cbt_hook_proc
, 0, GetCurrentThreadId());
11289 if (!hCBT_hook
) skip( "cannot set global hook, will skip hook tests\n" );
11293 /* Fix message sequences before removing 4 lines below */
11295 if (pUnhookWinEvent
&& hEvent_hook
)
11297 ret
= pUnhookWinEvent(hEvent_hook
);
11298 ok( ret
, "UnhookWinEvent error %d\n", GetLastError());
11299 pUnhookWinEvent
= 0;
11305 test_PeekMessage();
11306 test_PeekMessage2();
11307 test_scrollwindowex();
11309 test_setwindowpos();
11311 invisible_parent_tests();
11312 test_mdi_messages();
11313 test_button_messages();
11314 test_static_messages();
11315 test_listbox_messages();
11316 test_combobox_messages();
11317 test_wmime_keydown_message();
11318 test_paint_messages();
11319 test_interthread_messages();
11320 test_message_conversion();
11321 test_accelerators();
11323 test_timers_no_wnd();
11325 test_DestroyWindow();
11326 test_DispatchMessage();
11327 test_SendMessageTimeout();
11328 test_edit_messages();
11329 test_quit_message();
11330 test_SetActiveWindow();
11332 if (!pTrackMouseEvent
)
11333 skip("TrackMouseEvent is not available\n");
11335 test_TrackMouseEvent();
11337 test_SetWindowRgn();
11339 test_dialog_messages();
11340 test_nullCallback();
11341 test_dbcs_wm_char();
11342 test_menu_messages();
11343 test_paintingloop();
11344 /* keep it the last test, under Windows it tends to break the tests
11345 * which rely on active/foreground windows being correct.
11347 test_SetForegroundWindow();
11349 UnhookWindowsHookEx(hCBT_hook
);
11350 if (pUnhookWinEvent
)
11352 ret
= pUnhookWinEvent(hEvent_hook
);
11353 ok( ret
, "UnhookWinEvent error %d\n", GetLastError());
11354 SetLastError(0xdeadbeef);
11355 ok(!pUnhookWinEvent(hEvent_hook
), "UnhookWinEvent succeeded\n");
11356 ok(GetLastError() == ERROR_INVALID_HANDLE
|| /* Win2k */
11357 GetLastError() == 0xdeadbeef, /* Win9x */
11358 "unexpected error %d\n", GetLastError());
11361 skip("UnhookWinEvent is not available\n");