ReactOS 0.4.15-dev-7788-g1ad9096
msg.c
Go to the documentation of this file.
1/*
2 * Unit tests for window message handling
3 *
4 * Copyright 1999 Ove Kaaven
5 * Copyright 2003 Dimitrie O. Paun
6 * Copyright 2004,2005,2016 Dmitry Timoshkov
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 */
22
23#include <assert.h>
24#include <limits.h>
25#include <stdarg.h>
26#include <stdio.h>
27
28#include "windef.h"
29#include "winbase.h"
30#include "wingdi.h"
31#include "winuser.h"
32#include "winnls.h"
33#include "dbt.h"
34
35#include "wine/test.h"
36
37#define MDI_FIRST_CHILD_ID 2004
38
39/* undocumented SWP flags - from SDK 3.1 */
40#define SWP_NOCLIENTSIZE 0x0800
41#define SWP_NOCLIENTMOVE 0x1000
42#define SWP_STATECHANGED 0x8000
43
44#define SW_NORMALNA 0xCC /* undoc. flag in MinMaximize */
45
46#ifndef WM_KEYF1
47#define WM_KEYF1 0x004d
48#endif
49
50#ifndef WM_SYSTIMER
51#define WM_SYSTIMER 0x0118
52#endif
53
54#define WND_PARENT_ID 1
55#define WND_POPUP_ID 2
56#define WND_CHILD_ID 3
57
58#ifndef WM_LBTRACKPOINT
59#define WM_LBTRACKPOINT 0x0131
60#endif
61
62#ifdef __i386__
63#define ARCH "x86"
64#elif defined __x86_64__
65#define ARCH "amd64"
66#elif defined __arm__
67#define ARCH "arm"
68#elif defined __aarch64__
69#define ARCH "arm64"
70#else
71#define ARCH "none"
72#endif
73
74static BOOL (WINAPI *pActivateActCtx)(HANDLE,ULONG_PTR*);
75static HANDLE (WINAPI *pCreateActCtxW)(PCACTCTXW);
76static BOOL (WINAPI *pDeactivateActCtx)(DWORD,ULONG_PTR);
77static BOOL (WINAPI *pGetCurrentActCtx)(HANDLE *);
78static BOOL (WINAPI *pQueryActCtxW)(DWORD,HANDLE,void*,ULONG,void*,SIZE_T,SIZE_T*);
79static void (WINAPI *pReleaseActCtx)(HANDLE);
80
81/* encoded DRAWITEMSTRUCT into an LPARAM */
82typedef struct
83{
84 union
85 {
86 struct
87 {
88 UINT type : 4; /* ODT_* flags */
89 UINT ctl_id : 4; /* Control ID */
90 UINT item_id : 4; /* Menu item ID */
91 UINT action : 4; /* ODA_* flags */
92 UINT state : 16; /* ODS_* flags */
95 } u;
97
98/* encoded MEASUREITEMSTRUCT into a WPARAM */
99typedef struct
100{
101 union
102 {
103 struct
104 {
105 UINT CtlType : 4;
106 UINT CtlID : 4;
107 UINT itemID : 4;
108 UINT wParam : 20;
110 WPARAM wp;
111 } u;
113
117static HHOOK hKBD_hook;
118static HHOOK hCBT_hook;
120
121static const WCHAR testWindowClassW[] =
122{ 'T','e','s','t','W','i','n','d','o','w','C','l','a','s','s','W',0 };
123
125
126/*
127FIXME: add tests for these
128Window Edge Styles (Win31/Win95/98 look), in order of precedence:
129 WS_EX_DLGMODALFRAME: double border, WS_CAPTION allowed
130 WS_THICKFRAME: thick border
131 WS_DLGFRAME: double border, WS_CAPTION not allowed (but possibly shown anyway)
132 WS_BORDER (default for overlapped windows): single black border
133 none (default for child (and popup?) windows): no border
134*/
135
136typedef enum {
137 sent=0x1,
141 lparam=0x10,
145 hook=0x100,
147 kbd_hook=0x400
149
150struct message {
151 UINT message; /* the WM_* code */
152 msg_flags_t flags; /* message props */
153 WPARAM wParam; /* expected value of wParam */
154 LPARAM lParam; /* expected value of lParam */
155 WPARAM wp_mask; /* mask for wParam checks */
156 LPARAM lp_mask; /* mask for lParam checks */
157};
158
159struct recvd_message {
160 UINT message; /* the WM_* code */
161 msg_flags_t flags; /* message props */
162 HWND hwnd; /* window that received the message */
163 WPARAM wParam; /* expected value of wParam */
164 LPARAM lParam; /* expected value of lParam */
165 int line; /* source line where logged */
166 const char *descr; /* description for trace output */
167 char output[512]; /* trace output */
168};
169
170/* Empty message sequence */
171static const struct message WmEmptySeq[] =
172{
173 { 0 }
174};
175/* CreateWindow (for overlapped window, not initially visible) (16/32) */
176static const struct message WmCreateOverlappedSeq[] = {
177 { HCBT_CREATEWND, hook },
179 { WM_NCCREATE, sent },
180 { WM_NCCALCSIZE, sent|wparam, 0 },
181 { 0x0093, sent|defwinproc|optional },
182 { 0x0094, sent|defwinproc|optional },
183 { EVENT_OBJECT_REORDER, winevent_hook|wparam|lparam, 0, 0 },
184 { WM_CREATE, sent },
185 { EVENT_OBJECT_CREATE, winevent_hook|wparam|lparam, 0, 0 },
186 { 0 }
187};
188/* SetWindowPos(SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE)
189 * for a not visible overlapped window.
190 */
191static const struct message WmSWP_ShowOverlappedSeq[] = {
193 { EVENT_OBJECT_SHOW, winevent_hook|wparam|lparam, 0, 0 },
197 { HCBT_ACTIVATE, hook },
198 { EVENT_SYSTEM_FOREGROUND, winevent_hook|wparam|lparam, 0, 0 },
199 { WM_NOTIFYFORMAT, sent|optional },
200 { WM_QUERYUISTATE, sent|optional },
202 { WM_WINDOWPOSCHANGING, sent|wparam|optional, SWP_NOSIZE|SWP_NOMOVE }, /* Win9x: SWP_NOSENDCHANGING */
203 { WM_ACTIVATEAPP, sent|wparam, 1 },
204 { WM_NCACTIVATE, sent },
206 { WM_ACTIVATE, sent|wparam, 1 },
207 { HCBT_SETFOCUS, hook },
210 { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
216 /* Win9x adds SWP_NOZORDER below */
222 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 },
229 { 0 }
230};
231/* SetWindowPos(SWP_HIDEWINDOW|SWP_NOSIZE|SWP_NOMOVE)
232 * for a visible overlapped window.
233 */
234static const struct message WmSWP_HideOverlappedSeq[] = {
236 { EVENT_OBJECT_HIDE, winevent_hook|wparam|lparam, 0, 0 },
243 { 0 }
244};
245
246/* SetWindowPos(SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOMOVE)
247 * for a visible overlapped window.
248 */
249static const struct message WmSWP_ResizeSeq[] = {
262 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 },
263 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam|optional, 0, 0 }, /* XP sends a duplicate */
264 { 0 }
265};
266
267/* SetWindowPos(SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOMOVE)
268 * for a visible popup window.
269 */
270static const struct message WmSWP_ResizePopupSeq[] = {
272 { WM_GETMINMAXINFO, sent|defwinproc|optional }, /* Win9x */
283 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 },
284 { 0 }
285};
286
287/* SetWindowPos(SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOSIZE)
288 * for a visible overlapped window.
289 */
290static const struct message WmSWP_MoveSeq[] = {
297 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 },
298 { 0 }
299};
300/* Resize with SetWindowPos(SWP_NOZORDER)
301 * for a visible overlapped window
302 * SWP_NOZORDER is stripped by the logging code
303 */
304static const struct message WmSWP_ResizeNoZOrder[] = {
305 { WM_WINDOWPOSCHANGING, sent|wparam, /*SWP_NOZORDER|*/SWP_NOACTIVATE },
311 { WM_WINDOWPOSCHANGED, sent|wparam|optional, /*SWP_NOZORDER|*/SWP_NOACTIVATE, 0,
315 { WM_NCCALCSIZE, sent|wparam|optional, 1 }, /* Win9x doesn't send it */
316 { WM_NCPAINT, sent|optional }, /* Win9x doesn't send it */
317 { WM_GETTEXT, sent|defwinproc|optional }, /* Win9x doesn't send it */
318 { WM_ERASEBKGND, sent|optional }, /* Win9x doesn't send it */
319 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 },
320 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 },
321 { 0 }
322};
323
324/* Switch visible mdi children */
325static const struct message WmSwitchChild[] = {
326 /* Switch MDI child */
327 { WM_MDIACTIVATE, sent },/* in the MDI client */
328 { WM_WINDOWPOSCHANGING, sent|wparam,SWP_NOSIZE|SWP_NOMOVE },/* in the 1st MDI child */
329 { EVENT_OBJECT_REORDER, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
330 { WM_CHILDACTIVATE, sent },/* in the 1st MDI child */
331 /* Deactivate 2nd MDI child */
332 { WM_NCACTIVATE, sent|wparam|defwinproc, 0 }, /* in the 2nd MDI child */
333 { WM_MDIACTIVATE, sent|defwinproc }, /* in the 2nd MDI child */
335 /* Preparing for maximize and maximize the 1st MDI child */
336 { WM_GETMINMAXINFO, sent|defwinproc }, /* in the 1st MDI child */
338 { WM_NCCALCSIZE, sent|wparam|defwinproc, 1 }, /* in the 1st MDI child */
339 { WM_CHILDACTIVATE, sent|defwinproc }, /* in the 1st MDI child */
341 { WM_SIZE, sent|defwinproc|wparam, SIZE_MAXIMIZED }, /* in the 1st MDI child */
342 /* Lock redraw 2nd MDI child */
343 { WM_SETREDRAW, sent|wparam|defwinproc, 0 }, /* in the 2nd MDI child */
345 /* Restore 2nd MDI child */
347 { WM_NCCALCSIZE, sent|wparam|defwinproc, 1 },/* in the 2nd MDI child */
348 { EVENT_OBJECT_SHOW, winevent_hook|wparam|lparam, 0, 0 }, /* in the 2nd MDI child */
350 { WM_SIZE, sent|defwinproc|wparam, SIZE_RESTORED }, /* in the 2nd MDI child */
351 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, /* in the 2nd MDI child */
352 /* Redraw 2nd MDI child */
353 { WM_SETREDRAW, sent|wparam|defwinproc, 1 },/* in the 2nd MDI child */
354 /* Redraw MDI frame */
356 { WM_NCCALCSIZE, sent|wparam, 1 },/* in MDI frame */
358 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, /* in MDI frame */
359 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, /* in the 1st MDI child */
361 { WM_NCACTIVATE, sent|wparam|defwinproc, 1 }, /* in the 1st MDI child */
362 { HCBT_SETFOCUS, hook },
363 { WM_KILLFOCUS, sent|defwinproc }, /* in the 2nd MDI child */
364 { WM_IME_SETCONTEXT, sent|wparam|defwinproc|optional, 0 },/* in the 1st MDI child */
365 { WM_IME_SETCONTEXT, sent|wparam|optional, 1 }, /* in MDI client */
366 { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
367 { WM_SETFOCUS, sent },/* in the MDI client */
368 { HCBT_SETFOCUS, hook },
369 { WM_KILLFOCUS, sent },/* in the MDI client */
370 { WM_IME_SETCONTEXT, sent|wparam|optional, 0 }, /* in MDI client */
371 { WM_IME_SETCONTEXT, sent|wparam|defwinproc|optional, 1 }, /* in the 1st MDI child */
372 { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
373 { WM_SETFOCUS, sent|defwinproc }, /* in the 1st MDI child */
374 { WM_MDIACTIVATE, sent|defwinproc },/* in the 1st MDI child */
376 { 0 }
377};
378
379/* Switch visible not maximized mdi children */
380static const struct message WmSwitchNotMaximizedChild[] = {
381 /* Switch not maximized MDI child */
382 { WM_MDIACTIVATE, sent },/* in the MDI client */
383 { WM_WINDOWPOSCHANGING, sent|wparam,SWP_NOSIZE|SWP_NOMOVE },/* in the 2nd MDI child */
384 { EVENT_OBJECT_REORDER, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
385 { WM_CHILDACTIVATE, sent },/* in the 2nd MDI child */
386 /* Deactivate 1st MDI child */
387 { WM_NCACTIVATE, sent|wparam|defwinproc, 0 }, /* in the 1st MDI child */
388 { WM_MDIACTIVATE, sent|defwinproc }, /* in the 1st MDI child */
389 /* Activate 2nd MDI child */
391 { WM_NCACTIVATE, sent|wparam|defwinproc, 1 }, /* in the 2nd MDI child */
392 { HCBT_SETFOCUS, hook }, /* in the 1st MDI child */
393 { WM_KILLFOCUS, sent|defwinproc }, /* in the 1st MDI child */
394 { WM_IME_SETCONTEXT, sent|defwinproc|optional }, /* in the 1st MDI child */
395 { WM_IME_SETCONTEXT, sent|optional }, /* in the MDI client */
396 { WM_SETFOCUS, sent, 0 }, /* in the MDI client */
397 { HCBT_SETFOCUS, hook },
398 { WM_KILLFOCUS, sent }, /* in the MDI client */
399 { WM_IME_SETCONTEXT, sent|optional }, /* in the MDI client */
400 { WM_IME_SETCONTEXT, sent|defwinproc|optional }, /* in the 1st MDI child */
401 { WM_SETFOCUS, sent|defwinproc }, /* in the 2nd MDI child */
402 { WM_MDIACTIVATE, sent|defwinproc }, /* in the 2nd MDI child */
404 { 0 }
405};
406
407
408/* SetWindowPos(SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE|
409 SWP_NOZORDER|SWP_FRAMECHANGED)
410 * for a visible overlapped window with WS_CLIPCHILDREN style set.
411 */
412static const struct message WmSWP_FrameChanged_clip[] = {
415 { WM_NCPAINT, sent|parent|optional }, /* wparam != 1 */
417 { WM_ERASEBKGND, sent|parent|optional }, /* FIXME: remove optional once Wine is fixed */
418 { WM_NCPAINT, sent }, /* wparam != 1 */
419 { WM_ERASEBKGND, sent },
421 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 },
422 { WM_PAINT, sent },
423 { 0 }
424};
425/* SetWindowPos(SWP_NOSIZE|SWP_NOMOVE|SWP_DEFERERASE|SWP_NOACTIVATE|
426 SWP_NOZORDER|SWP_FRAMECHANGED)
427 * for a visible overlapped window.
428 */
429static const struct message WmSWP_FrameChangedDeferErase[] = {
433 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 },
435 { WM_NCPAINT, sent|beginpaint|parent|optional }, /* wparam != 1 */
437 { WM_PAINT, sent },
438 { WM_NCPAINT, sent|beginpaint }, /* wparam != 1 */
440 { 0 }
441};
442
443/* SetWindowPos(SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE|
444 SWP_NOZORDER|SWP_FRAMECHANGED)
445 * for a visible overlapped window without WS_CLIPCHILDREN style set.
446 */
447static const struct message WmSWP_FrameChanged_noclip[] = {
450 { WM_NCPAINT, sent|parent|optional }, /* wparam != 1 */
454 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 },
455 { WM_PAINT, sent },
456 { WM_NCPAINT, sent|beginpaint }, /* wparam != 1 */
458 { 0 }
459};
460
461/* ShowWindow(SW_SHOW) for a not visible overlapped window */
462static const struct message WmShowOverlappedSeq[] = {
463 { WM_SHOWWINDOW, sent|wparam, 1 },
466 { EVENT_OBJECT_SHOW, winevent_hook|wparam|lparam, 0, 0 },
471 { EVENT_SYSTEM_FOREGROUND, winevent_hook|wparam|lparam, 0, 0 },
482 { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
488 /* Win9x adds SWP_NOZORDER below */
495#if 0 /* CreateWindow/ShowWindow(SW_SHOW) also generates WM_SIZE/WM_MOVE
496 * messages. Does that mean that CreateWindow doesn't set initial
497 * window dimensions for overlapped windows?
498 */
499 { WM_SIZE, sent },
500 { WM_MOVE, sent },
501#endif
504 { 0 }
505};
506/* ShowWindow(SW_SHOWMAXIMIZED) for a not visible overlapped window */
507static const struct message WmShowMaxOverlappedSeq[] = {
513 { EVENT_OBJECT_SHOW, winevent_hook|wparam|lparam, 0, 0 },
515 { EVENT_SYSTEM_FOREGROUND, winevent_hook|wparam|lparam, 0, 0 },
525 { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
531 /* Win9x adds SWP_NOZORDER below */
539 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 },
540 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 },
546 { 0 }
547};
548/* ShowWindow(SW_RESTORE) for a not visible maximized overlapped window */
549static const struct message WmShowRestoreMaxOverlappedSeq[] = {
569 { 0 }
570};
571/* ShowWindow(SW_RESTORE) for a not visible minimized overlapped window */
572static const struct message WmShowRestoreMinOverlappedSeq[] = {
577 { WM_WINDOWPOSCHANGING, sent|optional }, /* SWP_NOSIZE|SWP_NOMOVE */
580 { WM_MOVE, sent|optional },
600 { WM_ERASEBKGND, sent },
611 { WM_ACTIVATE, sent|wparam, 1 },
617 { 0 }
618};
619/* ShowWindow(SW_SHOWMINIMIZED) for a not visible overlapped window */
620static const struct message WmShowMinOverlappedSeq[] = {
623 { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
631 { EVENT_OBJECT_REORDER, winevent_hook|wparam|lparam, 0, 0 },
638 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 },
639 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 },
640 { EVENT_SYSTEM_MINIMIZESTART, winevent_hook|wparam|lparam, 0, 0 },
645
646 /* Vista sometimes restores the window right away... */
672
676 { 0 }
677};
678/* ShowWindow(SW_HIDE) for a visible overlapped window */
679static const struct message WmHideOverlappedSeq[] = {
680 { WM_SHOWWINDOW, sent|wparam, 0 },
682 { EVENT_OBJECT_HIDE, winevent_hook|wparam|lparam, 0, 0 },
684 { WM_SIZE, sent|optional }, /* XP doesn't send it */
685 { WM_MOVE, sent|optional }, /* XP doesn't send it */
693 { 0 }
694};
695/* DestroyWindow for a visible overlapped window */
696static const struct message WmDestroyOverlappedSeq[] = {
698 { 0x0090, sent|optional },
700 { EVENT_OBJECT_HIDE, winevent_hook|wparam|lparam, 0, 0 },
701 { 0x0090, sent|optional },
709 { EVENT_OBJECT_DESTROY, winevent_hook|wparam|lparam, 0, 0 },
710 { WM_DESTROY, sent },
711 { WM_NCDESTROY, sent },
712 { 0 }
713};
714/* CreateWindow(WS_MAXIMIZE|WS_VISIBLE) for popup window */
715static const struct message WmCreateMaxPopupSeq[] = {
716 { HCBT_CREATEWND, hook },
717 { WM_NCCREATE, sent },
718 { WM_NCCALCSIZE, sent|wparam, 0 },
719 { WM_CREATE, sent },
720 { EVENT_OBJECT_CREATE, winevent_hook|wparam|lparam, 0, 0 },
722 { WM_MOVE, sent },
730 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 },
731 { WM_SHOWWINDOW, sent|wparam, 1 },
733 { EVENT_OBJECT_SHOW, winevent_hook|wparam|lparam, 0, 0 },
734 { HCBT_ACTIVATE, hook },
735 { EVENT_SYSTEM_FOREGROUND, winevent_hook|wparam|lparam, 0, 0 },
741 { WM_ACTIVATEAPP, sent|wparam, 1 },
742 { WM_NCACTIVATE, sent },
743 { WM_ACTIVATE, sent|wparam, 1 },
744 { HCBT_SETFOCUS, hook },
747 { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
756 { 0 }
757};
758/* CreateWindow(WS_MAXIMIZE) for popup window, not initially visible */
759static const struct message WmCreateInvisibleMaxPopupSeq[] = {
760 { HCBT_CREATEWND, hook },
761 { WM_NCCREATE, sent },
762 { WM_NCCALCSIZE, sent|wparam, 0 },
763 { WM_CREATE, sent },
764 { EVENT_OBJECT_CREATE, winevent_hook|wparam|lparam, 0, 0 },
766 { WM_MOVE, sent },
774 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 },
775 { 0 }
776};
777/* ShowWindow(SW_SHOWMAXIMIZED) for a resized not visible popup window */
778static const struct message WmShowMaxPopupResizedSeq[] = {
783 { EVENT_OBJECT_SHOW, winevent_hook|wparam|lparam, 0, 0 },
784 { HCBT_ACTIVATE, hook },
785 { EVENT_SYSTEM_FOREGROUND, winevent_hook|wparam|lparam, 0, 0 },
791 { WM_ACTIVATEAPP, sent|wparam, 1 },
792 { WM_NCACTIVATE, sent },
793 { WM_ACTIVATE, sent|wparam, 1 },
794 { HCBT_SETFOCUS, hook },
797 { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
803 /* WinNT4.0 sends WM_MOVE */
806 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 },
807 { 0 }
808};
809/* ShowWindow(SW_SHOWMAXIMIZED) for a not visible popup window */
810static const struct message WmShowMaxPopupSeq[] = {
815 { EVENT_OBJECT_SHOW, winevent_hook|wparam|lparam, 0, 0 },
816 { HCBT_ACTIVATE, hook },
817 { EVENT_SYSTEM_FOREGROUND, winevent_hook|wparam|lparam, 0, 0 },
823 { WM_ACTIVATEAPP, sent|wparam, 1 },
824 { WM_NCACTIVATE, sent },
825 { WM_ACTIVATE, sent|wparam, 1 },
826 { HCBT_SETFOCUS, hook },
829 { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
838 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 },
840 { 0 }
841};
842/* CreateWindow(WS_VISIBLE) for popup window */
843static const struct message WmCreatePopupSeq[] = {
844 { HCBT_CREATEWND, hook },
845 { WM_NCCREATE, sent },
846 { WM_NCCALCSIZE, sent|wparam, 0 },
847 { WM_CREATE, sent },
848 { EVENT_OBJECT_CREATE, winevent_hook|wparam|lparam, 0, 0 },
850 { WM_MOVE, sent },
851 { WM_SHOWWINDOW, sent|wparam, 1 },
853 { EVENT_OBJECT_SHOW, winevent_hook|wparam|lparam, 0, 0 },
854 { HCBT_ACTIVATE, hook },
855 { EVENT_SYSTEM_FOREGROUND, winevent_hook|wparam|lparam, 0, 0 },
861 { WM_ACTIVATEAPP, sent|wparam, 1 },
862 { WM_NCACTIVATE, sent },
863 { WM_ACTIVATE, sent|wparam, 1 },
864 { HCBT_SETFOCUS, hook },
867 { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
874 { 0 }
875};
876/* ShowWindow(SW_SHOWMAXIMIZED) for a visible popup window */
877static const struct message WmShowVisMaxPopupSeq[] = {
890 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 },
891 { 0 }
892};
893/* CreateWindow (for a child popup window, not initially visible) */
894static const struct message WmCreateChildPopupSeq[] = {
895 { HCBT_CREATEWND, hook },
896 { WM_NCCREATE, sent },
897 { WM_NCCALCSIZE, sent|wparam, 0 },
898 { WM_CREATE, sent },
899 { EVENT_OBJECT_CREATE, winevent_hook|wparam|lparam, 0, 0 },
901 { WM_MOVE, sent },
902 { 0 }
903};
904/* CreateWindow (for a popup window, not initially visible,
905 * which sets WS_VISIBLE in WM_CREATE handler)
906 */
907static const struct message WmCreateInvisiblePopupSeq[] = {
908 { HCBT_CREATEWND, hook },
909 { WM_NCCREATE, sent },
910 { WM_NCCALCSIZE, sent|wparam, 0 },
911 { WM_CREATE, sent },
912 { WM_STYLECHANGING, sent },
913 { WM_STYLECHANGED, sent },
914 { EVENT_OBJECT_CREATE, winevent_hook|wparam|lparam, 0, 0 },
916 { WM_MOVE, sent },
917 { 0 }
918};
919/* SetWindowPos(SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE|SWP_NOZORDER)
920 * for a popup window with WS_VISIBLE style set
921 */
922static const struct message WmShowVisiblePopupSeq_2[] = {
924 { 0 }
925};
926/* SetWindowPos(SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE)
927 * for a popup window with WS_VISIBLE style set
928 */
929static const struct message WmShowVisiblePopupSeq_3[] = {
931 { HCBT_ACTIVATE, hook },
932 { EVENT_SYSTEM_FOREGROUND, winevent_hook|wparam|lparam, 0, 0 },
935 { WM_NCACTIVATE, sent },
936 { WM_ACTIVATE, sent|wparam, 1 },
937 { HCBT_SETFOCUS, hook },
942 { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
946 { 0 }
947};
948/* CreateWindow (for a popup window with WS_VISIBLE style set and extreme location)
949 */
950static const struct message WmShowPopupExtremeLocationSeq[] = {
951 { HCBT_CREATEWND, hook },
952 { WM_NCCREATE, sent },
953 { WM_NCCALCSIZE, sent|wparam, 0 },
954 { WM_CREATE, sent },
955 { EVENT_OBJECT_CREATE, winevent_hook|wparam|lparam, 0, 0 },
957 { WM_MOVE, sent },
958 { WM_SHOWWINDOW, sent|wparam, 1 },
960 { HCBT_ACTIVATE, hook },
963 { WM_ACTIVATEAPP, sent },
964 { WM_NCACTIVATE, sent },
965 { WM_ACTIVATE, sent },
969 { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
970 { HCBT_SETFOCUS, hook },
972 { WM_NCPAINT, sent|wparam, 1 },
973 { WM_ERASEBKGND, sent },
975 /* occasionally received on test machines */
978 { 0 }
979};
980/* CreateWindow (for a popup window with WS_VISIBLE style set)
981 */
982static const struct message WmShowPopupFirstDrawSeq_1[] = {
983 { HCBT_CREATEWND, hook },
984 { WM_NCCREATE, sent },
985 { WM_NCCALCSIZE, sent|wparam, 0 },
986 { WM_CREATE, sent },
987 { EVENT_OBJECT_CREATE, winevent_hook|wparam|lparam, 0, 0 },
989 { WM_MOVE, sent },
990 { WM_SHOWWINDOW, sent|wparam, 1 },
992 { HCBT_ACTIVATE, hook },
995 { WM_ACTIVATEAPP, sent },
996 { WM_NCACTIVATE, sent },
997 { WM_ACTIVATE, sent },
1001 { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
1002 { HCBT_SETFOCUS, hook },
1004 { WM_NCPAINT, sent|wparam, 1 },
1005 { WM_ERASEBKGND, sent },
1007 { WM_PAINT, sent },
1008 /* occasionally received on test machines */
1011 { 0 }
1012};
1013/* CreateWindow (for a popup window that is shown with ShowWindow(SW_SHOWMAXIMIZED))
1014 */
1015static const struct message WmShowPopupFirstDrawSeq_2[] = {
1016 { HCBT_CREATEWND, hook },
1017 { WM_NCCREATE, sent },
1018 { WM_NCCALCSIZE, sent|wparam, 0 },
1019 { WM_CREATE, sent },
1020 { EVENT_OBJECT_CREATE, winevent_hook|wparam|lparam, 0, 0 },
1022 { WM_MOVE, sent },
1027 { HCBT_ACTIVATE, hook },
1033 { WM_ACTIVATEAPP, sent },
1034 { WM_NCACTIVATE, sent },
1035 { WM_ACTIVATE, sent },
1039 { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
1040 { HCBT_SETFOCUS, hook },
1042 { WM_NCPAINT, sent|wparam, 1 },
1043 { WM_ERASEBKGND, sent },
1045 { WM_MOVE, sent|defwinproc },
1046 { WM_SIZE, sent|defwinproc, 0 },
1047 { WM_PAINT, sent},
1048 /* occasionally received on test machines */
1051 { 0 }
1052};
1053static const struct message WmFirstDrawSetWindowPosSeq1[] = {
1054 { HCBT_CREATEWND, hook },
1055 { WM_NCCREATE, sent },
1056 { WM_NCCALCSIZE, sent|wparam, 0 },
1057 { WM_CREATE, sent },
1058 { EVENT_OBJECT_CREATE, winevent_hook|wparam|lparam, 0, 0 },
1060 { WM_MOVE, sent },
1062 { HCBT_ACTIVATE, hook },
1065 { WM_ACTIVATEAPP, sent },
1066 { WM_NCACTIVATE, sent },
1067 { WM_ACTIVATE, sent },
1071 { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
1072 { HCBT_SETFOCUS, hook },
1074 { WM_NCPAINT, sent|wparam, 1 },
1075 { WM_ERASEBKGND, sent },
1077 { WM_MOVE, sent|defwinproc },
1078 { 0 }
1079};
1080static const struct message WmFirstDrawSetWindowPosSeq2[] = {
1081 { HCBT_CREATEWND, hook },
1082 { WM_NCCREATE, sent },
1083 { WM_NCCALCSIZE, sent|wparam, 0 },
1084 { WM_CREATE, sent },
1085 { EVENT_OBJECT_CREATE, winevent_hook|wparam|lparam, 0, 0 },
1087 { WM_MOVE, sent },
1089 { HCBT_ACTIVATE, hook },
1092 { WM_ACTIVATEAPP, sent },
1093 { WM_NCACTIVATE, sent },
1094 { WM_ACTIVATE, sent },
1098 { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
1099 { HCBT_SETFOCUS, hook },
1102 { WM_MOVE, sent|defwinproc },
1103 { 0 }
1104};
1105static const struct message WmFirstDrawSetWindowPosSeq3[] = {
1106 { HCBT_CREATEWND, hook },
1107 { WM_NCCREATE, sent },
1108 { WM_NCCALCSIZE, sent|wparam, 0 },
1109 { WM_CREATE, sent },
1110 { EVENT_OBJECT_CREATE, winevent_hook|wparam|lparam, 0, 0 },
1112 { WM_MOVE, sent },
1114 /* Probably shouldn't happen, but not part of this test */
1121 { 0 }
1122};
1123static const struct message WmFirstDrawSetWindowPosSeq4[] = {
1124 { HCBT_CREATEWND, hook },
1125 { WM_NCCREATE, sent },
1126 { WM_NCCALCSIZE, sent|wparam, 0 },
1127 { WM_CREATE, sent },
1128 { EVENT_OBJECT_CREATE, winevent_hook|wparam|lparam, 0, 0 },
1130 { WM_MOVE, sent },
1132 { HCBT_ACTIVATE, hook },
1135 { WM_ACTIVATEAPP, sent },
1136 { WM_NCACTIVATE, sent },
1137 { WM_ACTIVATE, sent },
1141 { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
1142 { HCBT_SETFOCUS, hook },
1144 { WM_NCPAINT, sent|wparam, 1 },
1145 { WM_ERASEBKGND, sent },
1147 { 0 }
1148};
1149static const struct message WmFirstDrawSetWindowPosSeq5[] = {
1150 { HCBT_CREATEWND, hook },
1151 { WM_NCCREATE, sent },
1152 { WM_NCCALCSIZE, sent|wparam, 0 },
1153 { WM_CREATE, sent },
1154 { EVENT_OBJECT_CREATE, winevent_hook|wparam|lparam, 0, 0 },
1156 { WM_MOVE, sent },
1158 { HCBT_ACTIVATE, hook },
1161 { WM_ACTIVATEAPP, sent },
1162 { WM_NCACTIVATE, sent },
1163 { WM_ACTIVATE, sent },
1167 { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
1168 { HCBT_SETFOCUS, hook },
1171 { 0 }
1172};
1173static const struct message WmFirstDrawChildSeq1[] = {
1174 { 0 }
1175};
1176static const struct message WmFirstDrawChildSeq2[] = {
1177 { WM_NCPAINT, sent|wparam, 1 },
1178 { WM_ERASEBKGND, sent },
1179 /* occasionally received on test machines */
1182 { 0 }
1183};
1184/* CreateWindow (for child window, not initially visible) */
1185static const struct message WmCreateChildSeq[] = {
1186 { HCBT_CREATEWND, hook },
1187 { WM_NCCREATE, sent },
1188 /* child is inserted into parent's child list after WM_NCCREATE returns */
1189 { WM_NCCALCSIZE, sent|wparam, 0 },
1190 { WM_CREATE, sent },
1191 { EVENT_OBJECT_CREATE, winevent_hook|wparam|lparam, 0, 0 },
1193 { WM_MOVE, sent },
1195 { 0 }
1196};
1197/* CreateWindow (for maximized child window, not initially visible) */
1198static const struct message WmCreateMaximizedChildSeq[] = {
1199 { HCBT_CREATEWND, hook },
1200 { WM_NCCREATE, sent },
1201 { WM_NCCALCSIZE, sent|wparam, 0 },
1202 { WM_CREATE, sent },
1203 { EVENT_OBJECT_CREATE, winevent_hook|wparam|lparam, 0, 0 },
1205 { WM_MOVE, sent },
1209 { WM_NCCALCSIZE, sent|wparam, 1 },
1212 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 },
1214 { 0 }
1215};
1216/* CreateWindow (for a child window, initially visible) */
1217static const struct message WmCreateVisibleChildSeq[] = {
1218 { HCBT_CREATEWND, hook },
1219 { WM_NCCREATE, sent },
1220 /* child is inserted into parent's child list after WM_NCCREATE returns */
1221 { WM_NCCALCSIZE, sent|wparam, 0 },
1222 { EVENT_OBJECT_REORDER, winevent_hook|wparam|lparam, 0, 0 },
1223 { WM_CREATE, sent },
1224 { EVENT_OBJECT_CREATE, winevent_hook|wparam|lparam, 0, 0 },
1226 { WM_MOVE, sent },
1228 { WM_SHOWWINDOW, sent|wparam, 1 },
1230 { EVENT_OBJECT_SHOW, winevent_hook|wparam|lparam, 0, 0 },
1233 { WM_NCCALCSIZE, sent|wparam|optional, 1 }, /* WinXP */
1234 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 },
1235 { 0 }
1236};
1237/* ShowWindow(SW_SHOW) for a not visible child window */
1238static const struct message WmShowChildSeq[] = {
1239 { WM_SHOWWINDOW, sent|wparam, 1 },
1241 { EVENT_OBJECT_SHOW, winevent_hook|wparam|lparam, 0, 0 },
1244 { 0 }
1245};
1246/* ShowWindow(SW_HIDE) for a visible child window */
1247static const struct message WmHideChildSeq[] = {
1248 { WM_SHOWWINDOW, sent|wparam, 0 },
1250 { EVENT_OBJECT_HIDE, winevent_hook|wparam|lparam, 0, 0 },
1253 { 0 }
1254};
1255/* ShowWindow(SW_HIDE) for a visible child window checking all parent events*/
1256static const struct message WmHideChildSeq2[] = {
1257 { WM_SHOWWINDOW, sent|wparam, 0 },
1259 { EVENT_OBJECT_HIDE, winevent_hook|wparam|lparam, 0, 0 },
1262 { 0 }
1263};
1264/* SetWindowPos(SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE)
1265 * for a not visible child window
1266 */
1267static const struct message WmShowChildSeq_2[] = {
1269 { EVENT_OBJECT_SHOW, winevent_hook|wparam|lparam, 0, 0 },
1272 { 0 }
1273};
1274/* SetWindowPos(SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE)
1275 * for a not visible child window
1276 */
1277static const struct message WmShowChildSeq_3[] = {
1279 { EVENT_OBJECT_SHOW, winevent_hook|wparam|lparam, 0, 0 },
1281 { 0 }
1282};
1283/* SetWindowPos(SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE)
1284 * for a visible child window with a caption
1285 */
1286static const struct message WmShowChildSeq_4[] = {
1289 { 0 }
1290};
1291/* ShowWindow(SW_MINIMIZE) for child with invisible parent */
1295 { WM_NCCALCSIZE, sent|wparam, 1 },
1296 { EVENT_OBJECT_SHOW, winevent_hook|wparam|lparam, 0, 0 },
1299 { WM_MOVE, sent|defwinproc },
1301 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 },
1302 { EVENT_SYSTEM_MINIMIZESTART, winevent_hook|wparam|lparam, 0, 0 },
1303 /* FIXME: Wine creates an icon/title window while Windows doesn't */
1306 { 0 }
1307};
1308/* repeated ShowWindow(SW_MINIMIZE) for child with invisible parent */
1311 { 0 }
1312};
1313/* ShowWindow(SW_MAXIMIZE) for child with invisible parent */
1318 { WM_NCCALCSIZE, sent|wparam, 1 },
1319 { EVENT_OBJECT_SHOW, winevent_hook|wparam|lparam, 0, 0 },
1323 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 },
1324 { 0 }
1325};
1326/* repeated ShowWindow(SW_MAXIMIZE) for child with invisible parent */
1329 { 0 }
1330};
1331/* ShowWindow(SW_SHOWMINIMIZED) for child with invisible parent */
1335 { WM_NCCALCSIZE, sent|wparam, 1 },
1336 { EVENT_OBJECT_SHOW, winevent_hook|wparam|lparam, 0, 0 },
1339 { WM_MOVE, sent|defwinproc },
1341 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 },
1342 { EVENT_SYSTEM_MINIMIZESTART, winevent_hook|wparam|lparam, 0, 0 },
1343 /* FIXME: Wine creates an icon/title window while Windows doesn't */
1346 { 0 }
1347};
1348/* repeated ShowWindow(SW_SHOWMINIMIZED) for child with invisible parent */
1351 { 0 }
1352};
1353/* ShowWindow(SW_SHOWMINNOACTIVE) for child with invisible parent */
1357 { WM_NCCALCSIZE, sent|wparam, 1 },
1358 { EVENT_OBJECT_SHOW, winevent_hook|wparam|lparam, 0, 0 },
1360 { WM_MOVE, sent|defwinproc },
1362 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 },
1363 { EVENT_SYSTEM_MINIMIZESTART, winevent_hook|wparam|lparam, 0, 0 },
1364 /* FIXME: Wine creates an icon/title window while Windows doesn't */
1367 { 0 }
1368};
1369/* repeated ShowWindow(SW_SHOWMINNOACTIVE) for child with invisible parent */
1372 { 0 }
1373};
1374/* ShowWindow(SW_SHOW) for child with invisible parent */
1376 { WM_SHOWWINDOW, sent|wparam, 1 },
1377 { 0 }
1378};
1379/* ShowWindow(SW_HIDE) for child with invisible parent */
1381 { WM_SHOWWINDOW, sent|wparam, 0 },
1382 { 0 }
1383};
1384/* SetWindowPos(SWP_SHOWWINDOW) for child with invisible parent */
1387 { EVENT_OBJECT_SHOW, winevent_hook|wparam|lparam, 0, 0 },
1389 { 0 }
1390};
1391/* SetWindowPos(SWP_HIDEWINDOW) for child with invisible parent */
1394 { EVENT_OBJECT_HIDE, winevent_hook|wparam|lparam, 0, 0 },
1396 { 0 }
1397};
1398/* DestroyWindow for a visible child window */
1399static const struct message WmDestroyChildSeq[] = {
1400 { HCBT_DESTROYWND, hook },
1401 { 0x0090, sent|optional },
1403 { WM_SHOWWINDOW, sent|wparam, 0 },
1405 { EVENT_OBJECT_HIDE, winevent_hook|wparam|lparam, 0, 0 },
1408 { HCBT_SETFOCUS, hook }, /* set focus to a parent */
1409 { WM_KILLFOCUS, sent },
1412 { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
1413 { WM_SETFOCUS, sent|parent },
1414 { EVENT_OBJECT_DESTROY, winevent_hook|wparam|lparam, 0, 0 },
1415 { WM_DESTROY, sent },
1416 { WM_DESTROY, sent|optional }, /* some other (IME?) window */
1417 { WM_NCDESTROY, sent|optional }, /* some other (IME?) window */
1418 { WM_NCDESTROY, sent },
1419 { 0 }
1420};
1421/* visible child window destroyed by thread exit */
1422static const struct message WmExitThreadSeq[] = {
1423 { WM_NCDESTROY, sent }, /* actually in grandchild */
1424 { WM_PAINT, sent|parent },
1426 { 0 }
1427};
1428/* DestroyWindow for a visible child window with invisible parent */
1429static const struct message WmDestroyInvisibleChildSeq[] = {
1430 { HCBT_DESTROYWND, hook },
1431 { 0x0090, sent|optional },
1433 { WM_SHOWWINDOW, sent|wparam, 0 },
1434 { EVENT_OBJECT_DESTROY, winevent_hook|wparam|lparam, 0, 0 },
1435 { WM_DESTROY, sent },
1436 { WM_NCDESTROY, sent },
1437 { 0 }
1438};
1439/* Resizing child window with MoveWindow (32) */
1442 { WM_NCCALCSIZE, sent|wparam, 1 },
1446 { WM_MOVE, sent|defwinproc },
1448 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 },
1449 { 0 }
1450};
1451/* Creation of a custom dialog (32) */
1452static const struct message WmCreateCustomDialogSeq[] = {
1453 { HCBT_CREATEWND, hook },
1455 { WM_NCCREATE, sent },
1456 { WM_NCCALCSIZE, sent|wparam, 0 },
1457 { EVENT_OBJECT_REORDER, winevent_hook|wparam|lparam, 0, 0 },
1458 { WM_CREATE, sent },
1459 { EVENT_OBJECT_CREATE, winevent_hook|wparam|lparam, 0, 0 },
1460 { WM_NOTIFYFORMAT, sent|optional },
1461 { WM_QUERYUISTATE, sent|optional },
1466 { WM_SHOWWINDOW, sent|wparam, 1 },
1468 { EVENT_OBJECT_SHOW, winevent_hook|wparam|lparam, 0, 0 },
1469 { HCBT_ACTIVATE, hook },
1470 { EVENT_SYSTEM_FOREGROUND, winevent_hook|wparam|lparam, 0, 0 },
1471
1472
1474
1476
1477 { WM_NCACTIVATE, sent },
1481 { EVENT_OBJECT_DEFACTIONCHANGE, winevent_hook|wparam|lparam|optional, OBJID_CLIENT, 0 },
1482 { WM_ACTIVATE, sent|wparam, 1 },
1488 { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
1489 { WM_SETFOCUS, sent },
1491 { WM_NCPAINT, sent|wparam, 1 },
1494 { WM_ERASEBKGND, sent },
1505 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 },
1507 { WM_MOVE, sent },
1508 { 0 }
1509};
1510/* Calling EndDialog for a custom dialog (32) */
1511static const struct message WmEndCustomDialogSeq[] = {
1513 { EVENT_OBJECT_HIDE, winevent_hook|wparam|lparam, 0, 0 },
1516 { HCBT_ACTIVATE, hook },
1517 { WM_NCACTIVATE, sent|wparam, 0 },
1520 { WM_ACTIVATE, sent|wparam, 0 },
1521 { EVENT_SYSTEM_FOREGROUND, winevent_hook|wparam|lparam, 0, 0 },
1526 { HCBT_SETFOCUS, hook },
1527 { WM_KILLFOCUS, sent },
1531 { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
1533 { 0 }
1534};
1535/* ShowWindow(SW_SHOW) for a custom dialog (initially invisible) */
1536static const struct message WmShowCustomDialogSeq[] = {
1537 { WM_SHOWWINDOW, sent|wparam, 1 },
1539 { EVENT_OBJECT_SHOW, winevent_hook|wparam|lparam, 0, 0 },
1540 { HCBT_ACTIVATE, hook },
1541 { EVENT_SYSTEM_FOREGROUND, winevent_hook|wparam|lparam, 0, 0 },
1542
1544
1547 { WM_NCACTIVATE, sent },
1548 { WM_ACTIVATE, sent|wparam, 1 },
1550
1555 { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
1556 { WM_SETFOCUS, sent },
1558 { WM_NCPAINT, sent|wparam, 1 },
1559 { WM_ERASEBKGND, sent },
1562 { 0 }
1563};
1564/* Creation and destruction of a modal dialog (32) */
1565static const struct message WmModalDialogSeq[] = {
1567 { HCBT_SETFOCUS, hook },
1568 { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
1571 { EVENT_OBJECT_STATECHANGE, winevent_hook|wparam|lparam, 0, 0 },
1572 { WM_ENABLE, sent|parent|wparam, 0 },
1573 { HCBT_CREATEWND, hook },
1574 { EVENT_OBJECT_REORDER, winevent_hook|wparam|lparam, 0, 0 },
1575 { EVENT_OBJECT_CREATE, winevent_hook|wparam|lparam, 0, 0 },
1576 { WM_SETFONT, sent },
1577 { WM_INITDIALOG, sent },
1578 { WM_CHANGEUISTATE, sent|optional },
1579 { WM_UPDATEUISTATE, sent|optional },
1580 { WM_SHOWWINDOW, sent },
1581 { HCBT_ACTIVATE, hook },
1582 { EVENT_SYSTEM_FOREGROUND, winevent_hook|wparam|lparam, 0, 0 },
1585 { WM_NCACTIVATE, sent },
1587 { WM_ACTIVATE, sent|wparam, 1 },
1589 { EVENT_OBJECT_SHOW, winevent_hook|wparam|lparam, 0, 0 },
1601 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 },
1602 { WM_PAINT, sent|optional },
1625 { WM_TIMER, sent },
1626 { EVENT_OBJECT_STATECHANGE, winevent_hook|wparam|lparam, 0, 0 },
1627 { WM_ENABLE, sent|parent|wparam, 1 },
1629 { EVENT_OBJECT_HIDE, winevent_hook|wparam|lparam, 0, 0 },
1632 { HCBT_ACTIVATE, hook },
1633 { WM_NCACTIVATE, sent|wparam, 0 },
1635 { WM_ACTIVATE, sent|wparam, 0 },
1636 { EVENT_SYSTEM_FOREGROUND, winevent_hook|wparam|lparam, 0, 0 },
1639 { HCBT_SETFOCUS, hook },
1641 { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
1643 { EVENT_SYSTEM_DIALOGEND, winevent_hook|wparam|lparam, 0, 0 },
1644 { HCBT_DESTROYWND, hook },
1645 { 0x0090, sent|optional },
1646 { EVENT_OBJECT_DESTROY, winevent_hook|wparam|lparam, 0, 0 },
1647 { WM_DESTROY, sent },
1648 { WM_NCDESTROY, sent },
1649 { 0 }
1650};
1651static const struct message WmModalDialogSeq_2[] = {
1652 { WM_CANCELMODE, sent },
1653 { HCBT_SETFOCUS, hook },
1654 { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
1655 { WM_KILLFOCUS, sent },
1657 { EVENT_OBJECT_STATECHANGE, winevent_hook|wparam|lparam, 0, 0 },
1658 { WM_ENABLE, sent|wparam, 0 },
1659 { HCBT_CREATEWND, hook },
1660 { EVENT_OBJECT_REORDER, winevent_hook|wparam|lparam, 0, 0 },
1661 { EVENT_OBJECT_CREATE, winevent_hook|wparam|lparam, 0, 0 },
1662 { WM_SETFONT, sent },
1663 { WM_INITDIALOG, sent },
1664 { WM_CHANGEUISTATE, sent|optional },
1665 { WM_UPDATEUISTATE, sent|optional },
1666 { WM_ENABLE, sent|wparam, 1 },
1668 { EVENT_OBJECT_HIDE, winevent_hook|wparam|lparam, 0, 0 },
1669 { WM_CHANGEUISTATE, sent|optional },
1670 { WM_UPDATEUISTATE, sent|optional },
1671 { HCBT_DESTROYWND, hook },
1672 { 0x0090, sent|optional },
1673 { EVENT_OBJECT_DESTROY, winevent_hook|wparam|lparam, 0, 0 },
1674 { WM_DESTROY, sent },
1675 { WM_NCDESTROY, sent },
1676 { 0 }
1677};
1678/* SetMenu for NonVisible windows with size change*/
1681 { WM_NCCALCSIZE, sent|wparam, 1 },
1682 { EVENT_OBJECT_REORDER, winevent_hook|wparam|lparam, 0, 0 },
1684 { WM_MOVE, sent|defwinproc },
1686 { WM_NCCALCSIZE,sent|wparam|optional, 1 }, /* XP */
1687 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 },
1688 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam|optional, 0, 0 }, /* XP sends a duplicate */
1691 { 0 }
1692};
1693/* SetMenu for NonVisible windows with no size change */
1696 { WM_NCCALCSIZE, sent|wparam, 1 },
1698 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 },
1699 { 0 }
1700};
1701/* SetMenu for Visible windows with size change */
1704 { WM_NCCALCSIZE, sent|wparam, 1 },
1705 { 0x0093, sent|defwinproc|optional },
1706 { EVENT_OBJECT_REORDER, winevent_hook|wparam|lparam, 0, 0 },
1707 { WM_NCPAINT, sent|optional }, /* wparam != 1 */
1708 { 0x0093, sent|defwinproc|optional },
1709 { 0x0093, sent|defwinproc|optional },
1710 { 0x0091, sent|defwinproc|optional },
1711 { 0x0092, sent|defwinproc|optional },
1716 { WM_MOVE, sent|defwinproc },
1718 { 0x0093, sent|optional },
1720 { 0x0093, sent|defwinproc|optional },
1721 { WM_NCPAINT, sent|optional }, /* wparam != 1 */
1722 { 0x0093, sent|defwinproc|optional },
1723 { 0x0093, sent|defwinproc|optional },
1724 { 0x0091, sent|defwinproc|optional },
1725 { 0x0092, sent|defwinproc|optional },
1727 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 },
1728 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam|optional, 0, 0 }, /* XP sends a duplicate */
1729 { 0 }
1730};
1731/* SetMenu for Visible windows with no size change */
1734 { WM_NCCALCSIZE, sent|wparam, 1 },
1735 { WM_NCPAINT, sent|optional }, /* wparam != 1 */
1740 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 },
1741 { 0 }
1742};
1743/* DrawMenuBar for a visible window */
1744static const struct message WmDrawMenuBarSeq[] =
1745{
1747 { WM_NCCALCSIZE, sent|wparam, 1 },
1748 { 0x0093, sent|defwinproc|optional },
1749 { WM_NCPAINT, sent|optional }, /* wparam != 1 */
1750 { 0x0093, sent|defwinproc|optional },
1751 { 0x0093, sent|defwinproc|optional },
1752 { 0x0091, sent|defwinproc|optional },
1753 { 0x0092, sent|defwinproc|optional },
1757 { 0x0093, sent|optional },
1758 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 },
1759 { 0 }
1760};
1761
1762static const struct message WmSetRedrawFalseSeq[] =
1763{
1764 { WM_SETREDRAW, sent|wparam, 0 },
1765 { 0 }
1766};
1767
1768static const struct message WmSetRedrawTrueSeq[] =
1769{
1770 { WM_SETREDRAW, sent|wparam, 1 },
1771 { 0 }
1772};
1773
1774static const struct message WmEnableWindowSeq_1[] =
1775{
1776 { WM_CANCELMODE, sent|wparam|lparam, 0, 0 },
1777 { EVENT_OBJECT_STATECHANGE, winevent_hook|wparam|lparam, 0, 0 },
1780 { WM_ENABLE, sent|wparam|lparam, FALSE, 0 },
1781 { 0 }
1782};
1783
1784static const struct message WmEnableWindowSeq_2[] =
1785{
1786 { WM_CANCELMODE, sent|wparam|lparam, 0, 0 },
1787 { EVENT_OBJECT_STATECHANGE, winevent_hook|wparam|lparam, 0, 0 },
1788 { 0 }
1789};
1790
1791static const struct message WmEnableWindowSeq_3[] =
1792{
1793 { EVENT_OBJECT_STATECHANGE, winevent_hook|wparam|lparam, 0, 0 },
1794 { WM_ENABLE, sent|wparam|lparam, TRUE, 0 },
1795 { 0 }
1796};
1797
1798static const struct message WmEnableWindowSeq_4[] =
1799{
1800 { EVENT_OBJECT_STATECHANGE, winevent_hook|wparam|lparam, 0, 0 },
1801 { 0 }
1802};
1803
1804static const struct message WmGetScrollRangeSeq[] =
1805{
1806 { SBM_GETRANGE, sent },
1807 { 0 }
1808};
1809static const struct message WmGetScrollInfoSeq[] =
1810{
1811 { SBM_GETSCROLLINFO, sent },
1812 { 0 }
1813};
1814static const struct message WmSetScrollRangeSeq[] =
1815{
1816 /* MSDN claims that Windows sends SBM_SETRANGE message, but win2k SP4
1817 sends SBM_SETSCROLLINFO.
1818 */
1819 { SBM_SETSCROLLINFO, sent },
1820 { 0 }
1821};
1822/* SetScrollRange for a window without a non-client area */
1824{
1825 { EVENT_OBJECT_VALUECHANGE, winevent_hook|wparam|lparam, OBJID_HSCROLL, 0 },
1826 { 0 }
1827};
1829{
1830 { EVENT_OBJECT_VALUECHANGE, winevent_hook|wparam|lparam, OBJID_VSCROLL, 0 },
1831 { 0 }
1832};
1833static const struct message WmSetScrollRangeHVSeq[] =
1834{
1836 { WM_NCCALCSIZE, sent|wparam, 1 },
1840 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 },
1841 { EVENT_OBJECT_VALUECHANGE, winevent_hook|lparam|optional, 0/*OBJID_HSCROLL or OBJID_VSCROLL*/, 0 },
1842 { 0 }
1843};
1844/* SetScrollRange for a window with a non-client area */
1845static const struct message WmSetScrollRangeHV_NC_Seq[] =
1846{
1848 { WM_NCCALCSIZE, sent|wparam, 1 },
1849 { EVENT_OBJECT_REORDER, winevent_hook|wparam|lparam, 0, 0 },
1851 { WM_STYLECHANGING, sent|defwinproc|optional },
1852 { WM_STYLECHANGED, sent|defwinproc|optional },
1853 { WM_STYLECHANGING, sent|defwinproc|optional },
1854 { WM_STYLECHANGED, sent|defwinproc|optional },
1855 { WM_STYLECHANGING, sent|defwinproc|optional },
1856 { WM_STYLECHANGED, sent|defwinproc|optional },
1857 { WM_STYLECHANGING, sent|defwinproc|optional },
1858 { WM_STYLECHANGED, sent|defwinproc|optional },
1862 { WM_CTLCOLORDLG, sent|defwinproc|optional }, /* sent to a parent of the dialog */
1865 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 },
1866 { EVENT_OBJECT_VALUECHANGE, winevent_hook|lparam|optional, 0/*OBJID_HSCROLL or OBJID_VSCROLL*/, 0 },
1871 { 0 }
1872};
1873/* test if we receive the right sequence of messages */
1874/* after calling ShowWindow( SW_SHOWNA) */
1875static const struct message WmSHOWNAChildInvisParInvis[] = {
1876 { WM_SHOWWINDOW, sent|wparam, 1 },
1877 { 0 }
1878};
1879static const struct message WmSHOWNAChildVisParInvis[] = {
1880 { WM_SHOWWINDOW, sent|wparam, 1 },
1881 { 0 }
1882};
1883static const struct message WmSHOWNAChildVisParVis[] = {
1884 { WM_SHOWWINDOW, sent|wparam, 1 },
1886 { 0 }
1887};
1888static const struct message WmSHOWNAChildInvisParVis[] = {
1889 { WM_SHOWWINDOW, sent|wparam, 1 },
1891 { EVENT_OBJECT_SHOW, winevent_hook|wparam|lparam, 0, 0 },
1894 { 0 }
1895};
1896static const struct message WmSHOWNATopVisible[] = {
1897 { WM_SHOWWINDOW, sent|wparam, 1 },
1903 { 0 }
1904};
1905static const struct message WmSHOWNATopInvisible[] = {
1906 { WM_NOTIFYFORMAT, sent|optional },
1907 { WM_QUERYUISTATE, sent|optional },
1912 { WM_SHOWWINDOW, sent|wparam, 1 },
1914 { EVENT_OBJECT_SHOW, winevent_hook|wparam|lparam, 0, 0 },
1922 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 },
1924 { WM_MOVE, sent },
1925 { 0 }
1926};
1927
1928static const struct message WmTrackPopupMenu[] = {
1929 { HCBT_CREATEWND, hook },
1931 { WM_INITMENU, sent|lparam, 0, 0 },
1932 { WM_INITMENUPOPUP, sent|lparam, 0, 0 },
1933 { 0x0093, sent|optional },
1934 { 0x0094, sent|optional },
1935 { 0x0094, sent|optional },
1936 { WM_ENTERIDLE, sent|wparam, 2 },
1938 { HCBT_DESTROYWND, hook },
1939 { WM_UNINITMENUPOPUP, sent|lparam, 0, 0 },
1940 { WM_MENUSELECT, sent|wparam|lparam, 0xffff0000, 0 },
1941 { WM_EXITMENULOOP, sent|wparam|lparam, 1, 0 },
1942 { 0 }
1943};
1944
1945static const struct message WmTrackPopupMenuEsc[] = {
1946 { 0 }
1947};
1948
1949static const struct message WmTrackPopupMenuCapture[] = {
1950 { HCBT_CREATEWND, hook },
1953 { WM_INITMENU, sent|lparam, 0, 0 },
1954 { WM_INITMENUPOPUP, sent|lparam, 0, 0 },
1955 { 0x0093, sent|optional },
1956 { 0x0094, sent|optional },
1957 { 0x0094, sent|optional },
1958 { WM_ENTERIDLE, sent|wparam, 2 },
1960 { HCBT_DESTROYWND, hook },
1961 { WM_UNINITMENUPOPUP, sent|lparam, 0, 0 },
1962 { WM_MENUSELECT, sent|wparam|lparam, 0xffff0000, 0 },
1963 { WM_EXITMENULOOP, sent|wparam|lparam, 1, 0 },
1964 { 0 }
1965};
1966
1967static const struct message WmTrackPopupMenuEmpty[] = {
1968 { HCBT_CREATEWND, hook },
1970 { WM_INITMENU, sent|lparam, 0, 0 },
1971 { WM_INITMENUPOPUP, sent|lparam, 0, 0 },
1972 { 0x0093, sent|optional },
1973 { 0x0094, sent|optional },
1974 { 0x0094, sent|optional },
1976 { WM_EXITMENULOOP, sent|wparam|lparam, 1, 0 },
1977 { HCBT_DESTROYWND, hook },
1978 { WM_UNINITMENUPOPUP, sent|lparam, 0, 0 },
1979 { 0 }
1980};
1981
1982static const struct message WmTrackPopupMenuAbort[] = {
1983 { HCBT_CREATEWND, hook },
1985 { WM_INITMENU, sent|lparam, 0, 0 },
1986 { WM_INITMENUPOPUP, sent|lparam, 0, 0 },
1987 { 0x0093, sent|optional },
1988 { 0x0094, sent|optional },
1989 { 0x0094, sent|optional },
1991 { HCBT_DESTROYWND, hook },
1992 { WM_UNINITMENUPOPUP, sent|lparam, 0, 0 },
1993 { WM_MENUSELECT, sent|wparam|lparam, 0xffff0000, 0 },
1994 { WM_EXITMENULOOP, sent|wparam|lparam, 1, 0 },
1995 { 0 }
1996};
1997
2003
2004/* user32 functions */
2005static HWND (WINAPI *pGetAncestor)(HWND,UINT);
2006static BOOL (WINAPI *pGetMenuInfo)(HMENU,LPCMENUINFO);
2007static void (WINAPI *pNotifyWinEvent)(DWORD, HWND, LONG, LONG);
2008static BOOL (WINAPI *pSetMenuInfo)(HMENU,LPCMENUINFO);
2010static BOOL (WINAPI *pTrackMouseEvent)(TRACKMOUSEEVENT*);
2011static BOOL (WINAPI *pUnhookWinEvent)(HWINEVENTHOOK);
2012static BOOL (WINAPI *pGetMonitorInfoA)(HMONITOR,LPMONITORINFO);
2013static HMONITOR (WINAPI *pMonitorFromPoint)(POINT,DWORD);
2014static BOOL (WINAPI *pUpdateLayeredWindow)(HWND,HDC,POINT*,SIZE*,HDC,POINT*,COLORREF,BLENDFUNCTION*,DWORD);
2015static UINT_PTR (WINAPI *pSetSystemTimer)(HWND, UINT_PTR, UINT, TIMERPROC);
2016static UINT_PTR (WINAPI *pKillSystemTimer)(HWND, UINT_PTR);
2017static UINT_PTR (WINAPI *pSetCoalescableTimer)(HWND, UINT_PTR, UINT, TIMERPROC, ULONG);
2018/* kernel32 functions */
2019static BOOL (WINAPI *pGetCPInfoExA)(UINT, DWORD, LPCPINFOEXA);
2020
2021static void init_procs(void)
2022{
2023 HMODULE user32 = GetModuleHandleA("user32.dll");
2024 HMODULE kernel32 = GetModuleHandleA("kernel32.dll");
2025
2026#define GET_PROC(dll, func) \
2027 p ## func = (void*)GetProcAddress(dll, #func); \
2028 if(!p ## func) { \
2029 trace("GetProcAddress(%s) failed\n", #func); \
2030 }
2031
2032 GET_PROC(user32, GetAncestor)
2033 GET_PROC(user32, GetMenuInfo)
2034 GET_PROC(user32, NotifyWinEvent)
2035 GET_PROC(user32, SetMenuInfo)
2036 GET_PROC(user32, SetWinEventHook)
2037 GET_PROC(user32, TrackMouseEvent)
2038 GET_PROC(user32, UnhookWinEvent)
2039 GET_PROC(user32, GetMonitorInfoA)
2040 GET_PROC(user32, MonitorFromPoint)
2042 GET_PROC(user32, SetSystemTimer)
2043 GET_PROC(user32, KillSystemTimer)
2044 GET_PROC(user32, SetCoalescableTimer)
2045
2046 GET_PROC(kernel32, GetCPInfoExA)
2047
2048#undef GET_PROC
2049}
2050
2051static const char *get_winpos_flags(UINT flags)
2052{
2053 static char buffer[300];
2054
2055 buffer[0] = 0;
2056#define DUMP(flag) do { if (flags & flag) { strcat( buffer, "|" #flag ); flags &= ~flag; } } while(0)
2066 DUMP( SWP_NOZORDER );
2067 DUMP( SWP_NOREDRAW );
2068 DUMP( SWP_NOSIZE );
2069 DUMP( SWP_NOMOVE );
2072 if (flags) sprintf(buffer + strlen(buffer),"|0x%04x", flags);
2073 return buffer + 1;
2074#undef DUMP
2075}
2076
2078{
2079 /* these are always ignored */
2080 return (message >= 0xc000 ||
2081 message == WM_GETICON ||
2082 message == WM_GETOBJECT ||
2084 message == WM_DISPLAYCHANGE ||
2087}
2088
2089static unsigned hash_Ly_W(const WCHAR *str)
2090{
2091 unsigned hash = 0;
2092
2093 for (; *str; str++)
2094 hash = hash * 1664525u + (unsigned char)(*str) + 1013904223u;
2095
2096 return hash;
2097}
2098
2099static unsigned hash_Ly(const char *str)
2100{
2101 unsigned hash = 0;
2102
2103 for (; *str; str++)
2104 hash = hash * 1664525u + (unsigned char)(*str) + 1013904223u;
2105
2106 return hash;
2107}
2108
2109#define add_message(msg) add_message_(__LINE__,msg);
2110static void add_message_(int line, const struct recvd_message *msg)
2111{
2112 struct recvd_message *seq;
2113
2115 if (!sequence)
2116 {
2117 sequence_size = 10;
2119 }
2121 {
2122 sequence_size *= 2;
2124 }
2126
2127 seq = &sequence[sequence_cnt++];
2128 seq->hwnd = msg->hwnd;
2129 seq->message = msg->message;
2130 seq->flags = msg->flags;
2131 seq->wParam = msg->wParam;
2132 seq->lParam = msg->lParam;
2133 seq->line = line;
2134 seq->descr = msg->descr;
2135 seq->output[0] = 0;
2137
2138 if (msg->descr)
2139 {
2140 if (msg->flags & hook)
2141 {
2142 static const char * const CBT_code_name[10] =
2143 {
2144 "HCBT_MOVESIZE",
2145 "HCBT_MINMAX",
2146 "HCBT_QS",
2147 "HCBT_CREATEWND",
2148 "HCBT_DESTROYWND",
2149 "HCBT_ACTIVATE",
2150 "HCBT_CLICKSKIPPED",
2151 "HCBT_KEYSKIPPED",
2152 "HCBT_SYSCOMMAND",
2153 "HCBT_SETFOCUS"
2154 };
2155 const char *code_name = (msg->message <= HCBT_SETFOCUS) ? CBT_code_name[msg->message] : "Unknown";
2156
2157 sprintf( seq->output, "%s: hook %d (%s) wp %08lx lp %08lx",
2158 msg->descr, msg->message, code_name, msg->wParam, msg->lParam );
2159 }
2160 else if (msg->flags & winevent_hook)
2161 {
2162 sprintf( seq->output, "%s: winevent %p %08x %08lx %08lx",
2163 msg->descr, msg->hwnd, msg->message, msg->wParam, msg->lParam );
2164 }
2165 else
2166 {
2167 switch (msg->message)
2168 {
2171 {
2172 WINDOWPOS *winpos = (WINDOWPOS *)msg->lParam;
2173
2174 sprintf( seq->output, "%s: %p WM_WINDOWPOS%s wp %08lx lp %08lx after %p x %d y %d cx %d cy %d flags %s",
2175 msg->descr, msg->hwnd,
2176 (msg->message == WM_WINDOWPOSCHANGING) ? "CHANGING" : "CHANGED",
2177 msg->wParam, msg->lParam, winpos->hwndInsertAfter,
2178 winpos->x, winpos->y, winpos->cx, winpos->cy,
2179 get_winpos_flags(winpos->flags) );
2180
2181 /* Log only documented flags, win2k uses 0x1000 and 0x2000
2182 * in the high word for internal purposes
2183 */
2184 seq->wParam = winpos->flags & 0xffff;
2185 /* We are not interested in the flags that don't match under XP and Win9x */
2186 seq->wParam &= ~SWP_NOZORDER;
2187 break;
2188 }
2189
2190 case WM_DRAWITEM:
2191 {
2193 DRAWITEMSTRUCT *dis = (DRAWITEMSTRUCT *)msg->lParam;
2194
2195 sprintf( seq->output, "%s: %p WM_DRAWITEM: type %x, ctl_id %x, item_id %x, action %x, state %x",
2196 msg->descr, msg->hwnd, dis->CtlType, dis->CtlID,
2197 dis->itemID, dis->itemAction, dis->itemState);
2198
2199 di.u.lp = 0;
2200 di.u.item.type = dis->CtlType;
2201 di.u.item.ctl_id = dis->CtlID;
2202 if (dis->CtlType == ODT_LISTBOX ||
2203 dis->CtlType == ODT_COMBOBOX ||
2204 dis->CtlType == ODT_MENU)
2205 di.u.item.item_id = dis->itemID;
2206 di.u.item.action = dis->itemAction;
2207 di.u.item.state = dis->itemState;
2208
2209 seq->lParam = di.u.lp;
2210 break;
2211 }
2212
2213 case WM_MEASUREITEM:
2214 {
2216 MEASUREITEMSTRUCT *mis = (MEASUREITEMSTRUCT *)msg->lParam;
2217 BOOL is_unicode_data = TRUE;
2218
2219 sprintf( seq->output, "%s: %p WM_MEASUREITEM: CtlType %#x, CtlID %#x, itemID %#x, itemData %#lx",
2220 msg->descr, msg->hwnd, mis->CtlType, mis->CtlID,
2221 mis->itemID, mis->itemData);
2222
2223 if (mis->CtlType == ODT_LISTBOX)
2224 {
2225 HWND ctrl = GetDlgItem(msg->hwnd, mis->CtlID);
2226 is_unicode_data = GetWindowLongA(ctrl, GWL_STYLE) & LBS_HASSTRINGS;
2227 }
2228
2229 mi.u.wp = 0;
2230 mi.u.item.CtlType = mis->CtlType;
2231 mi.u.item.CtlID = mis->CtlID;
2232 mi.u.item.itemID = mis->itemID;
2233 mi.u.item.wParam = msg->wParam;
2234 seq->wParam = mi.u.wp;
2235 if (is_unicode_data)
2236 seq->lParam = mis->itemData ? hash_Ly_W((const WCHAR *)mis->itemData) : 0;
2237 else
2238 seq->lParam = mis->itemData ? hash_Ly((const char *)mis->itemData) : 0;
2239 break;
2240 }
2241
2242 case WM_COMPAREITEM:
2243 {
2244 COMPAREITEMSTRUCT *cis = (COMPAREITEMSTRUCT *)msg->lParam;
2245 HWND ctrl = GetDlgItem(msg->hwnd, cis->CtlID);
2246 BOOL is_unicode_data = TRUE;
2247
2248 ok(msg->wParam == cis->CtlID, "expected %#x, got %#lx\n", cis->CtlID, msg->wParam);
2249 ok(cis->hwndItem == ctrl, "expected %p, got %p\n", ctrl, cis->hwndItem);
2250 ok((int)cis->itemID1 >= 0, "expected >= 0, got %d\n", cis->itemID1);
2251 ok((int)cis->itemID2 == -1, "expected -1, got %d\n", cis->itemID2);
2252
2253 sprintf( seq->output, "%s: %p WM_COMPAREITEM: CtlType %#x, CtlID %#x, itemID1 %#x, itemData1 %#lx, itemID2 %#x, itemData2 %#lx",
2254 msg->descr, msg->hwnd, cis->CtlType, cis->CtlID,
2255 cis->itemID1, cis->itemData1, cis->itemID2, cis->itemData2);
2256
2257 if (cis->CtlType == ODT_LISTBOX)
2258 is_unicode_data = GetWindowLongA(ctrl, GWL_STYLE) & LBS_HASSTRINGS;
2259
2260 if (is_unicode_data)
2261 {
2262 seq->wParam = cis->itemData1 ? hash_Ly_W((const WCHAR *)cis->itemData1) : 0;
2263 seq->lParam = cis->itemData2 ? hash_Ly_W((const WCHAR *)cis->itemData2) : 0;
2264 }
2265 else
2266 {
2267 seq->wParam = cis->itemData1 ? hash_Ly((const char *)cis->itemData1) : 0;
2268 seq->lParam = cis->itemData2 ? hash_Ly((const char *)cis->itemData2) : 0;
2269 }
2270 break;
2271 }
2272
2273 default:
2274 if (msg->message >= 0xc000) return; /* ignore registered messages */
2275 sprintf( seq->output, "%s: %p %04x wp %08lx lp %08lx",
2276 msg->descr, msg->hwnd, msg->message, msg->wParam, msg->lParam );
2277 }
2278 if (msg->flags & (sent|posted|parent|defwinproc|beginpaint))
2279 sprintf( seq->output + strlen(seq->output), " (flags %x)", msg->flags );
2280 }
2281 }
2282}
2283
2284/* try to make sure pending X events have been processed before continuing */
2285static void flush_events(void)
2286{
2287 MSG msg;
2288 int diff = 200;
2289 int min_timeout = 100;
2290 DWORD time = GetTickCount() + diff;
2291
2292 while (diff > 0)
2293 {
2294 if (MsgWaitForMultipleObjects( 0, NULL, FALSE, min_timeout, QS_ALLINPUT ) == WAIT_TIMEOUT) break;
2295 while (PeekMessageA( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessageA( &msg );
2296 diff = time - GetTickCount();
2297 }
2298}
2299
2300static void flush_sequence(void)
2301{
2304 sequence = 0;
2307}
2308
2309static void dump_sequence(const struct message *expected, const char *context, const char *file, int line)
2310{
2311 const struct recvd_message *actual = sequence;
2312 unsigned int count = 0;
2313
2314 trace_(file, line)("Failed sequence %s:\n", context );
2315 while (expected->message && actual->message)
2316 {
2317 if (actual->output[0])
2318 {
2319 if (expected->flags & hook)
2320 {
2321 trace_(file, line)( " %u: expected: hook %04x - actual: %s\n",
2322 count, expected->message, actual->output );
2323 }
2324 else if (expected->flags & winevent_hook)
2325 {
2326 trace_(file, line)( " %u: expected: winevent %04x - actual: %s\n",
2327 count, expected->message, actual->output );
2328 }
2329 else if (expected->flags & kbd_hook)
2330 {
2331 trace_(file, line)( " %u: expected: kbd %04x - actual: %s\n",
2332 count, expected->message, actual->output );
2333 }
2334 else
2335 {
2336 trace_(file, line)( " %u: expected: msg %04x - actual: %s\n",
2337 count, expected->message, actual->output );
2338 }
2339 }
2340
2341 if (expected->message == actual->message)
2342 {
2343 if ((expected->flags & defwinproc) != (actual->flags & defwinproc) &&
2344 (expected->flags & optional))
2345 {
2346 /* don't match messages if their defwinproc status differs */
2347 expected++;
2348 }
2349 else
2350 {
2351 expected++;
2352 actual++;
2353 }
2354 }
2355 /* silently drop winevent messages if there is no support for them */
2356 else if ((expected->flags & optional) || ((expected->flags & winevent_hook) && !hEvent_hook))
2357 expected++;
2358 else
2359 {
2360 expected++;
2361 actual++;
2362 }
2363 count++;
2364 }
2365
2366 /* optional trailing messages */
2367 while (expected->message && ((expected->flags & optional) ||
2368 ((expected->flags & winevent_hook) && !hEvent_hook)))
2369 {
2370 trace_(file, line)( " %u: expected: msg %04x - actual: nothing\n", count, expected->message );
2371 expected++;
2372 count++;
2373 }
2374
2375 if (expected->message)
2376 {
2377 trace_(file, line)( " %u: expected: msg %04x - actual: nothing\n", count, expected->message );
2378 return;
2379 }
2380
2381 while (actual->message && actual->output[0])
2382 {
2383 trace_(file, line)( " %u: expected: nothing - actual: %s\n", count, actual->output );
2384 actual++;
2385 count++;
2386 }
2387}
2388
2389#define ok_sequence( exp, contx, todo) \
2390 ok_sequence_( (exp), (contx), (todo), __FILE__, __LINE__)
2391
2392
2393static void ok_sequence_(const struct message *expected_list, const char *context, BOOL todo,
2394 const char *file, int line)
2395{
2396 static const struct recvd_message end_of_sequence;
2397 const struct message *expected = expected_list;
2398 const struct recvd_message *actual;
2399 int failcount = 0, dump = 0;
2400 unsigned int count = 0;
2401
2402 add_message(&end_of_sequence);
2403
2404 actual = sequence;
2405
2406 while (expected->message && actual->message)
2407 {
2408 if (expected->message == actual->message &&
2409 !((expected->flags ^ actual->flags) & (hook|winevent_hook|kbd_hook)))
2410 {
2411 if (expected->flags & wparam)
2412 {
2413 if (((expected->wParam ^ actual->wParam) & ~expected->wp_mask) && todo)
2414 {
2415 todo_wine {
2416 failcount ++;
2417 if (strcmp(winetest_platform, "wine")) dump++;
2418 ok_( file, line) (FALSE,
2419 "%s: %u: in msg 0x%04x expecting wParam 0x%lx got 0x%lx\n",
2420 context, count, expected->message, expected->wParam, actual->wParam);
2421 }
2422 }
2423 else
2424 {
2425 ok_( file, line)( ((expected->wParam ^ actual->wParam) & ~expected->wp_mask) == 0,
2426 "%s: %u: in msg 0x%04x expecting wParam 0x%lx got 0x%lx\n",
2427 context, count, expected->message, expected->wParam, actual->wParam);
2428 if ((expected->wParam ^ actual->wParam) & ~expected->wp_mask) dump++;
2429 }
2430
2431 }
2432 if (expected->flags & lparam)
2433 {
2434 if (((expected->lParam ^ actual->lParam) & ~expected->lp_mask) && todo)
2435 {
2436 todo_wine {
2437 failcount ++;
2438 if (strcmp(winetest_platform, "wine")) dump++;
2439 ok_( file, line) (FALSE,
2440 "%s: %u: in msg 0x%04x expecting lParam 0x%lx got 0x%lx\n",
2441 context, count, expected->message, expected->lParam, actual->lParam);
2442 }
2443 }
2444 else
2445 {
2446 ok_( file, line)(((expected->lParam ^ actual->lParam) & ~expected->lp_mask) == 0,
2447 "%s: %u: in msg 0x%04x expecting lParam 0x%lx got 0x%lx\n",
2448 context, count, expected->message, expected->lParam, actual->lParam);
2449 if ((expected->lParam ^ actual->lParam) & ~expected->lp_mask) dump++;
2450 }
2451 }
2452 if ((expected->flags & optional) &&
2453 ((expected->flags ^ actual->flags) & (defwinproc|parent)))
2454 {
2455 /* don't match optional messages if their defwinproc or parent status differs */
2456 expected++;
2457 count++;
2458 continue;
2459 }
2460 if ((expected->flags & defwinproc) != (actual->flags & defwinproc) && todo)
2461 {
2462 todo_wine {
2463 failcount ++;
2464 if (strcmp(winetest_platform, "wine")) dump++;
2465 ok_( file, line) (FALSE,
2466 "%s: %u: the msg 0x%04x should %shave been sent by DefWindowProc\n",
2467 context, count, expected->message, (expected->flags & defwinproc) ? "" : "NOT ");
2468 }
2469 }
2470 else
2471 {
2472 ok_( file, line) ((expected->flags & defwinproc) == (actual->flags & defwinproc),
2473 "%s: %u: the msg 0x%04x should %shave been sent by DefWindowProc\n",
2474 context, count, expected->message, (expected->flags & defwinproc) ? "" : "NOT ");
2475 if ((expected->flags & defwinproc) != (actual->flags & defwinproc)) dump++;
2476 }
2477
2478 ok_( file, line) ((expected->flags & beginpaint) == (actual->flags & beginpaint),
2479 "%s: %u: the msg 0x%04x should %shave been sent by BeginPaint\n",
2480 context, count, expected->message, (expected->flags & beginpaint) ? "" : "NOT ");
2481 if ((expected->flags & beginpaint) != (actual->flags & beginpaint)) dump++;
2482
2483 ok_( file, line) ((expected->flags & (sent|posted)) == (actual->flags & (sent|posted)),
2484 "%s: %u: the msg 0x%04x should have been %s\n",
2485 context, count, expected->message, (expected->flags & posted) ? "posted" : "sent");
2486 if ((expected->flags & (sent|posted)) != (actual->flags & (sent|posted))) dump++;
2487
2488 ok_( file, line) ((expected->flags & parent) == (actual->flags & parent),
2489 "%s: %u: the msg 0x%04x was expected in %s\n",
2490 context, count, expected->message, (expected->flags & parent) ? "parent" : "child");
2491 if ((expected->flags & parent) != (actual->flags & parent)) dump++;
2492
2493 ok_( file, line) ((expected->flags & hook) == (actual->flags & hook),
2494 "%s: %u: the msg 0x%04x should have been sent by a hook\n",
2495 context, count, expected->message);
2496 if ((expected->flags & hook) != (actual->flags & hook)) dump++;
2497
2498 ok_( file, line) ((expected->flags & winevent_hook) == (actual->flags & winevent_hook),
2499 "%s: %u: the msg 0x%04x should have been sent by a winevent hook\n",
2500 context, count, expected->message);
2501 if ((expected->flags & winevent_hook) != (actual->flags & winevent_hook)) dump++;
2502
2503 ok_( file, line) ((expected->flags & kbd_hook) == (actual->flags & kbd_hook),
2504 "%s: %u: the msg 0x%04x should have been sent by a keyboard hook\n",
2505 context, count, expected->message);
2506 if ((expected->flags & kbd_hook) != (actual->flags & kbd_hook)) dump++;
2507
2508 expected++;
2509 actual++;
2510 }
2511 /* silently drop hook messages if there is no support for them */
2512 else if ((expected->flags & optional) ||
2513 ((expected->flags & hook) && !hCBT_hook) ||
2514 ((expected->flags & winevent_hook) && !hEvent_hook) ||
2515 ((expected->flags & kbd_hook) && !hKBD_hook))
2516 expected++;
2517 else if (todo)
2518 {
2519 failcount++;
2520 todo_wine {
2521 if (strcmp(winetest_platform, "wine")) dump++;
2522 ok_( file, line) (FALSE, "%s: %u: the msg 0x%04x was expected, but got msg 0x%04x instead\n",
2523 context, count, expected->message, actual->message);
2524 }
2525 goto done;
2526 }
2527 else
2528 {
2529 ok_( file, line) (FALSE, "%s: %u: the msg 0x%04x was expected, but got msg 0x%04x instead\n",
2530 context, count, expected->message, actual->message);
2531 dump++;
2532 expected++;
2533 actual++;
2534 }
2535 count++;
2536 }
2537
2538 /* skip all optional trailing messages */
2539 while (expected->message && ((expected->flags & optional) ||
2540 ((expected->flags & hook) && !hCBT_hook) ||
2541 ((expected->flags & winevent_hook) && !hEvent_hook)))
2542 expected++;
2543
2544 if (todo)
2545 {
2546 todo_wine {
2547 if (expected->message || actual->message) {
2548 failcount++;
2549 if (strcmp(winetest_platform, "wine")) dump++;
2550 ok_( file, line) (FALSE, "%s: %u: the msg sequence is not complete: expected %04x - actual %04x\n",
2551 context, count, expected->message, actual->message);
2552 }
2553 }
2554 }
2555 else
2556 {
2557 if (expected->message || actual->message)
2558 {
2559 dump++;
2560 ok_( file, line) (FALSE, "%s: %u: the msg sequence is not complete: expected %04x - actual %04x\n",
2561 context, count, expected->message, actual->message);
2562 }
2563 }
2564 if( todo && !failcount) /* succeeded yet marked todo */
2565 todo_wine {
2566 if (!strcmp(winetest_platform, "wine")) dump++;
2567 ok_( file, line)( TRUE, "%s: marked \"todo_wine\" but succeeds\n", context);
2568 }
2569
2570done:
2571 if (dump) dump_sequence(expected_list, context, file, line);
2573}
2574
2575#define expect(EXPECTED,GOT) ok((GOT)==(EXPECTED), "Expected %d, got %d\n", (EXPECTED), (GOT))
2576
2577/******************************** MDI test **********************************/
2578
2579/* CreateWindow for MDI frame window, initially visible */
2580static const struct message WmCreateMDIframeSeq[] = {
2581 { HCBT_CREATEWND, hook },
2583 { WM_NCCREATE, sent },
2584 { WM_NCCALCSIZE, sent|wparam, 0 },
2585 { EVENT_OBJECT_REORDER, winevent_hook|wparam|lparam, 0, 0 },
2586 { WM_CREATE, sent },
2587 { EVENT_OBJECT_CREATE, winevent_hook|wparam|lparam, 0, 0 },
2588 { WM_NOTIFYFORMAT, sent|optional },
2589 { WM_QUERYUISTATE, sent|optional },
2594 { WM_SHOWWINDOW, sent|wparam, 1 },
2596 { EVENT_OBJECT_SHOW, winevent_hook|wparam|lparam, 0, 0 },
2597 { HCBT_ACTIVATE, hook },
2598 { EVENT_SYSTEM_FOREGROUND, winevent_hook|wparam|lparam, 0, 0 },
2601 { WM_ACTIVATEAPP, sent|wparam|optional, 1 }, /* Win9x doesn't send it */
2602 { WM_NCACTIVATE, sent },
2604 { WM_ACTIVATE, sent|wparam, 1 },
2606 { HCBT_SETFOCUS, hook },
2609 { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
2611 /* Win9x adds SWP_NOZORDER below */
2613 { WM_NCCALCSIZE, sent|wparam|optional, 1 }, /* XP */
2614 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 },
2616 { WM_MOVE, sent },
2617 { 0 }
2618};
2619/* DestroyWindow for MDI frame window, initially visible */
2620static const struct message WmDestroyMDIframeSeq[] = {
2621 { HCBT_DESTROYWND, hook },
2622 { 0x0090, sent|optional },
2624 { EVENT_OBJECT_HIDE, winevent_hook|wparam|lparam, 0, 0 },
2625 { WM_NCACTIVATE, sent|wparam|optional, 0 }, /* Win9x */
2627 { WM_NCACTIVATE, sent|wparam|optional, 0 }, /* XP */
2628 { WM_ACTIVATE, sent|wparam|optional, 0 }, /* Win9x */
2629 { WM_ACTIVATEAPP, sent|wparam|optional, 0 }, /* Win9x */
2630 { EVENT_OBJECT_HIDE, winevent_hook|wparam|lparam, OBJID_CARET, 0 },
2631 { EVENT_OBJECT_DESTROY, winevent_hook|wparam|lparam, 0, 0 },
2632 { WM_DESTROY, sent },
2633 { WM_NCDESTROY, sent },
2634 { 0 }
2635};
2636/* CreateWindow for MDI client window, initially visible */
2637static const struct message WmCreateMDIclientSeq[] = {
2638 { HCBT_CREATEWND, hook },
2639 { WM_NCCREATE, sent },
2640 { WM_NCCALCSIZE, sent|wparam, 0 },
2641 { EVENT_OBJECT_REORDER, winevent_hook|wparam|lparam|optional, 0, 0 },
2642 { WM_CREATE, sent },
2643 { EVENT_OBJECT_REORDER, winevent_hook|wparam|lparam|optional, 0, 0 },
2644 { EVENT_OBJECT_CREATE, winevent_hook|wparam|lparam, 0, 0 },
2646 { WM_MOVE, sent },
2647 { WM_PARENTNOTIFY, sent|wparam, WM_CREATE }, /* in MDI frame */
2648 { WM_SHOWWINDOW, sent|wparam, 1 },
2650 { EVENT_OBJECT_SHOW, winevent_hook|wparam|lparam, 0, 0 },
2652 { 0 }
2653};
2654/* ShowWindow(SW_SHOW) for MDI client window */
2655static const struct message WmShowMDIclientSeq[] = {
2656 { WM_SHOWWINDOW, sent|wparam, 1 },
2658 { EVENT_OBJECT_SHOW, winevent_hook|wparam|lparam, 0, 0 },
2660 { 0 }
2661};
2662/* ShowWindow(SW_HIDE) for MDI client window */
2663static const struct message WmHideMDIclientSeq[] = {
2664 { WM_SHOWWINDOW, sent|wparam, 0 },
2666 { EVENT_OBJECT_SHOW, winevent_hook|wparam|lparam|optional, 0, 0 }, /* win2000 */
2667 { EVENT_OBJECT_HIDE, winevent_hook|wparam|lparam|optional, 0, 0 }, /* XP */
2669 { 0 }
2670};
2671/* DestroyWindow for MDI client window, initially visible */
2672static const struct message WmDestroyMDIclientSeq[] = {
2673 { HCBT_DESTROYWND, hook },
2674 { 0x0090, sent|optional },
2675 { WM_PARENTNOTIFY, sent|wparam, WM_DESTROY }, /* in MDI frame */
2676 { WM_SHOWWINDOW, sent|wparam, 0 },
2678 { EVENT_OBJECT_HIDE, winevent_hook|wparam|lparam, 0, 0 },
2680 { EVENT_OBJECT_DESTROY, winevent_hook|wparam|lparam, 0, 0 },
2681 { WM_DESTROY, sent },
2682 { WM_NCDESTROY, sent },
2683 { 0 }
2684};
2685/* CreateWindow for MDI child window, initially visible */
2686static const struct message WmCreateMDIchildVisibleSeq[] = {
2687 { HCBT_CREATEWND, hook },
2688 { WM_NCCREATE, sent },
2689 { WM_NCCALCSIZE, sent|wparam, 0 },
2690 { WM_CREATE, sent },
2691 { EVENT_OBJECT_CREATE, winevent_hook|wparam|lparam, 0, 0 },
2693 { WM_MOVE, sent },
2694 /* Win2k sends wparam set to
2695 * MAKEWPARAM(WM_CREATE, MDI_FIRST_CHILD_ID + nTotalCreated),
2696 * while Win9x doesn't bother to set child window id according to
2697 * CLIENTCREATESTRUCT.idFirstChild
2698 */
2699 { WM_PARENTNOTIFY, sent /*|wparam, WM_CREATE*/ }, /* in MDI client */
2700 { WM_SHOWWINDOW, sent|wparam, 1 },
2702 { EVENT_OBJECT_SHOW, winevent_hook|wparam|lparam, 0, 0 },
2704 { WM_MDIREFRESHMENU, sent/*|wparam|lparam, 0, 0*/ },
2708
2709 /* Win9x: message sequence terminates here. */
2710
2712 { HCBT_SETFOCUS, hook }, /* in MDI client */
2713 { WM_IME_SETCONTEXT, sent|wparam|optional, 1 }, /* in MDI client */
2714 { WM_IME_NOTIFY, sent|wparam|optional, 2 }, /* in MDI client */
2715 { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
2716 { WM_SETFOCUS, sent }, /* in MDI client */
2717 { HCBT_SETFOCUS, hook },
2718 { WM_KILLFOCUS, sent }, /* in MDI client */
2719 { WM_IME_SETCONTEXT, sent|wparam|optional, 0 }, /* in MDI client */
2721 { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
2724 { 0 }
2725};
2726/* WM_CHILDACTIVATE sent to disabled window */
2729 { 0 }
2730};
2731/* WM_CHILDACTIVATE sent to enabled window */
2732static const struct message WmChildActivateWindowSeq[] = {
2739 { HCBT_SETFOCUS, hook },
2741 { WM_SETFOCUS, sent },
2742 { HCBT_SETFOCUS, hook },
2743 { WM_KILLFOCUS, sent },
2746 { 0 }
2747};
2748/* CreateWindow for MDI child window with invisible parent */
2750 { HCBT_CREATEWND, hook },
2752 { WM_NCCREATE, sent },
2753 { WM_NCCALCSIZE, sent|wparam, 0 },
2754 { EVENT_OBJECT_REORDER, winevent_hook|wparam|lparam|optional, 0, 0 },
2755 { WM_CREATE, sent },
2756 { EVENT_OBJECT_CREATE, winevent_hook|wparam|lparam, 0, 0 },
2758 { WM_MOVE, sent },
2759 { WM_PARENTNOTIFY, sent /*|wparam, WM_CREATE*/ }, /* in MDI client */
2760 { WM_SHOWWINDOW, sent|wparam, 1 },
2761 { WM_MDIREFRESHMENU, sent }, /* in MDI client */
2765
2766 /* Win9x: message sequence terminates here. */
2767
2769 { HCBT_SETFOCUS, hook }, /* in MDI client */
2770 { WM_IME_SETCONTEXT, sent|wparam|optional, 1 }, /* in MDI client */
2771 { WM_IME_NOTIFY, sent|wparam|optional, 2 }, /* in MDI client */
2772 { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
2773 { WM_SETFOCUS, sent }, /* in MDI client */
2774 { HCBT_SETFOCUS, hook },
2775 { WM_KILLFOCUS, sent }, /* in MDI client */
2776 { WM_IME_SETCONTEXT, sent|wparam|optional, 0 }, /* in MDI client */
2778 { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
2781 { 0 }
2782};
2783/* DestroyWindow for MDI child window, initially visible */
2784static const struct message WmDestroyMDIchildVisibleSeq[] = {
2785 { HCBT_DESTROYWND, hook },
2786 /* Win2k sends wparam set to
2787 * MAKEWPARAM(WM_DESTROY, MDI_FIRST_CHILD_ID + nTotalCreated),
2788 * while Win9x doesn't bother to set child window id according to
2789 * CLIENTCREATESTRUCT.idFirstChild
2790 */
2791 { 0x0090, sent|optional },
2792 { WM_PARENTNOTIFY, sent /*|wparam, WM_DESTROY*/ }, /* in MDI client */
2793 { WM_SHOWWINDOW, sent|wparam, 0 },
2795 { EVENT_OBJECT_HIDE, winevent_hook|wparam|lparam, 0, 0 },
2798
2799 /* { WM_DESTROY, sent }
2800 * Win9x: message sequence terminates here.
2801 */
2802
2803 { HCBT_SETFOCUS, hook }, /* set focus to MDI client */
2804 { WM_KILLFOCUS, sent },
2806 { WM_IME_SETCONTEXT, sent|wparam|optional, 1 }, /* in MDI client */
2807 { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
2808 { WM_SETFOCUS, sent }, /* in MDI client */
2809
2810 { HCBT_SETFOCUS, hook }, /* MDI client sets focus back to MDI child */
2811 { WM_KILLFOCUS, sent }, /* in MDI client */
2812 { WM_IME_SETCONTEXT, sent|wparam|optional, 0 }, /* in MDI client */
2814 { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
2815 { WM_SETFOCUS, sent }, /* in MDI client */
2816
2817 { EVENT_OBJECT_DESTROY, winevent_hook|wparam|lparam, 0, 0 },
2818
2819 { HCBT_SETFOCUS, hook }, /* set focus to MDI client */
2820 { WM_KILLFOCUS, sent },
2822 { WM_IME_SETCONTEXT, sent|wparam|optional, 1 }, /* in MDI client */
2823 { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
2824 { WM_SETFOCUS, sent }, /* in MDI client */
2825
2826 { HCBT_SETFOCUS, hook }, /* MDI client sets focus back to MDI child */
2827 { WM_KILLFOCUS, sent }, /* in MDI client */
2828 { WM_IME_SETCONTEXT, sent|wparam|optional, 0 }, /* in MDI client */
2830 { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
2831 { WM_SETFOCUS, sent }, /* in MDI client */
2832
2833 { WM_DESTROY, sent },
2834
2835 { HCBT_SETFOCUS, hook }, /* set focus to MDI client */
2836 { WM_KILLFOCUS, sent },
2838 { WM_IME_SETCONTEXT, sent|wparam|optional, 1 }, /* in MDI client */
2839 { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
2840 { WM_SETFOCUS, sent }, /* in MDI client */
2841
2842 { HCBT_SETFOCUS, hook }, /* MDI client sets focus back to MDI child */
2843 { WM_KILLFOCUS, sent }, /* in MDI client */
2844 { WM_IME_SETCONTEXT, sent|wparam|optional, 0 }, /* in MDI client */
2846 { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
2847 { WM_SETFOCUS, sent }, /* in MDI client */
2848
2849 { WM_NCDESTROY, sent },
2850 { 0 }
2851};
2852/* CreateWindow for MDI child window, initially invisible */
2853static const struct message WmCreateMDIchildInvisibleSeq[] = {
2854 { HCBT_CREATEWND, hook },
2855 { WM_NCCREATE, sent },
2856 { WM_NCCALCSIZE, sent|wparam, 0 },
2857 { WM_CREATE, sent },
2858 { EVENT_OBJECT_CREATE, winevent_hook|wparam|lparam, 0, 0 },
2860 { WM_MOVE, sent },
2861 /* Win2k sends wparam set to
2862 * MAKEWPARAM(WM_CREATE, MDI_FIRST_CHILD_ID + nTotalCreated),
2863 * while Win9x doesn't bother to set child window id according to
2864 * CLIENTCREATESTRUCT.idFirstChild
2865 */
2866 { WM_PARENTNOTIFY, sent /*|wparam, WM_CREATE*/ }, /* in MDI client */
2867 { 0 }
2868};
2869/* DestroyWindow for MDI child window, initially invisible */
2871 { HCBT_DESTROYWND, hook },
2872 /* Win2k sends wparam set to
2873 * MAKEWPARAM(WM_DESTROY, MDI_FIRST_CHILD_ID + nTotalCreated),
2874 * while Win9x doesn't bother to set child window id according to
2875 * CLIENTCREATESTRUCT.idFirstChild
2876 */
2877 { 0x0090, sent|optional },
2878 { WM_PARENTNOTIFY, sent /*|wparam, WM_DESTROY*/ }, /* in MDI client */
2879 { EVENT_OBJECT_DESTROY, winevent_hook|wparam|lparam, 0, 0 },
2880 { WM_DESTROY, sent },
2881 { WM_NCDESTROY, sent },
2882 /* FIXME: Wine destroys an icon/title window while Windows doesn't */
2883 { WM_PARENTNOTIFY, sent|wparam|optional, WM_DESTROY }, /* MDI client */
2884 { 0 }
2885};
2886/* CreateWindow for the 1st MDI child window, initially visible and maximized */
2888 { HCBT_CREATEWND, hook },
2889 { WM_NCCREATE, sent },
2890 { WM_NCCALCSIZE, sent|wparam, 0 },
2891 { WM_CREATE, sent },
2892 { EVENT_OBJECT_CREATE, winevent_hook|wparam|lparam, 0, 0 },
2894 { WM_MOVE, sent },
2898 { WM_NCCALCSIZE, sent|wparam, 1 },
2901 /* in MDI frame */
2903 { WM_NCCALCSIZE, sent|wparam, 1 },
2905 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, /* MDI frame */
2906 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, /* MDI child */
2907 /* Win2k sends wparam set to
2908 * MAKEWPARAM(WM_CREATE, MDI_FIRST_CHILD_ID + nTotalCreated),
2909 * while Win9x doesn't bother to set child window id according to
2910 * CLIENTCREATESTRUCT.idFirstChild
2911 */
2912 { WM_PARENTNOTIFY, sent /*|wparam, WM_CREATE*/ }, /* in MDI client */
2913 { WM_SHOWWINDOW, sent|wparam, 1 },
2915 { EVENT_OBJECT_SHOW, winevent_hook|wparam|lparam, 0, 0 },
2917 { WM_MDIREFRESHMENU, sent/*|wparam|lparam, 0, 0*/ },
2921
2922 /* Win9x: message sequence terminates here. */
2923
2925 { HCBT_SETFOCUS, hook|optional }, /* in MDI client */
2926 { WM_IME_SETCONTEXT, sent|wparam|optional, 1 }, /* in MDI client */
2927 { WM_IME_NOTIFY, sent|wparam|optional, 2 }, /* in MDI client */
2928 { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
2929 { WM_SETFOCUS, sent|optional }, /* in MDI client */
2931 { WM_KILLFOCUS, sent|optional }, /* in MDI client */
2932 { WM_IME_SETCONTEXT, sent|wparam|optional, 0 }, /* in MDI client */
2934 { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
2937 /* in MDI frame */
2939 { WM_NCCALCSIZE, sent|wparam, 1 },
2941 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, /* MDI frame */
2942 { 0 }
2943};
2944/* CreateWindow for the 2nd MDI child window, initially visible and maximized */
2946 /* restore the 1st MDI child */
2947 { WM_SETREDRAW, sent|wparam, 0 },
2950 { WM_NCCALCSIZE, sent|wparam, 1 },
2954 /* in MDI frame */
2956 { WM_NCCALCSIZE, sent|wparam, 1 },
2958 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, /* MDI frame */
2959 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, /* MDI child */
2960 { WM_SETREDRAW, sent|wparam, 1 }, /* in the 1st MDI child */
2961 /* create the 2nd MDI child */
2962 { HCBT_CREATEWND, hook },
2963 { WM_NCCREATE, sent },
2964 { WM_NCCALCSIZE, sent|wparam, 0 },
2965 { WM_CREATE, sent },
2966 { EVENT_OBJECT_CREATE, winevent_hook|wparam|lparam, 0, 0 },
2968 { WM_MOVE, sent },
2972 { WM_NCCALCSIZE, sent|wparam, 1 },
2973 { EVENT_OBJECT_REORDER, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
2976 /* in MDI frame */
2978 { WM_NCCALCSIZE, sent|wparam, 1 },
2980 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, /* MDI frame */
2981 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, /* MDI child */
2982 /* Win2k sends wparam set to
2983 * MAKEWPARAM(WM_CREATE, MDI_FIRST_CHILD_ID + nTotalCreated),
2984 * while Win9x doesn't bother to set child window id according to
2985 * CLIENTCREATESTRUCT.idFirstChild
2986 */
2987 { WM_PARENTNOTIFY, sent /*|wparam, WM_CREATE*/ }, /* in MDI client */
2988 { WM_SHOWWINDOW, sent|wparam, 1 },
2990 { EVENT_OBJECT_SHOW, winevent_hook|wparam|lparam, 0, 0 },
2992 { WM_MDIREFRESHMENU, sent/*|wparam|lparam, 0, 0*/ },
2995
2996 { WM_NCACTIVATE, sent|wparam|defwinproc, 0 }, /* in the 1st MDI child */
2997 { WM_MDIACTIVATE, sent|defwinproc }, /* in the 1st MDI child */
2998
3000
3001 /* Win9x: message sequence terminates here. */
3002
3004 { HCBT_SETFOCUS, hook },
3005 { WM_KILLFOCUS, sent|defwinproc|optional }, /* in the 1st MDI child */
3006 { WM_IME_SETCONTEXT, sent|wparam|defwinproc|optional, 0 }, /* in the 1st MDI child */
3007 { WM_IME_SETCONTEXT, sent|wparam|optional, 1 }, /* in MDI client */
3008 { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
3009 { WM_SETFOCUS, sent }, /* in MDI client */
3010 { HCBT_SETFOCUS, hook },
3011 { WM_KILLFOCUS, sent }, /* in MDI client */
3012 { WM_IME_SETCONTEXT, sent|wparam|optional, 0 }, /* in MDI client */
3014 { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
3016
3018 /* in MDI frame */
3020 { WM_NCCALCSIZE, sent|wparam, 1 },
3022 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, /* MDI frame */
3023 { 0 }
3024};
3025/* WM_MDICREATE MDI child window, initially visible and maximized */
3027 { WM_MDICREATE, sent },
3028 { HCBT_CREATEWND, hook },
3029 { WM_NCCREATE, sent },
3030 { WM_NCCALCSIZE, sent|wparam, 0 },
3031 { WM_CREATE, sent },
3032 { EVENT_OBJECT_CREATE, winevent_hook|wparam|lparam, 0, 0 },
3034 { WM_MOVE, sent },
3038 { WM_NCCALCSIZE, sent|wparam, 1 },
3041
3042 /* in MDI frame */
3044 { WM_NCCALCSIZE, sent|wparam, 1 },
3046 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, /* MDI frame */
3047 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, /* MDI child */
3048
3049 /* Win2k sends wparam set to
3050 * MAKEWPARAM(WM_CREATE, MDI_FIRST_CHILD_ID + nTotalCreated),
3051 * while Win9x doesn't bother to set child window id according to
3052 * CLIENTCREATESTRUCT.idFirstChild
3053 */
3054 { WM_PARENTNOTIFY, sent /*|wparam, WM_CREATE*/ }, /* in MDI client */
3055 { WM_SHOWWINDOW, sent|wparam, 1 },
3057
3058 { EVENT_OBJECT_SHOW, winevent_hook|wparam|lparam, 0, 0 },
3059
3061 { WM_MDIREFRESHMENU, sent/*|wparam|lparam, 0, 0*/ },
3063
3066
3067 /* Win9x: message sequence terminates here. */
3068
3070 { WM_SETFOCUS, sent|optional }, /* in MDI client */
3071 { HCBT_SETFOCUS, hook }, /* in MDI client */
3072 { WM_IME_SETCONTEXT, sent|wparam|optional, 1 }, /* in MDI client */
3074 { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam|optional, OBJID_CLIENT, 0 },
3075 { WM_SETFOCUS, sent|optional }, /* in MDI client */
3077 { WM_KILLFOCUS, sent }, /* in MDI client */
3078 { WM_IME_SETCONTEXT, sent|wparam|optional, 0 }, /* in MDI client */
3080 { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
3082
3084
3085 /* in MDI child */
3087 { WM_NCCALCSIZE, sent|wparam, 1 },
3089 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 },
3090
3091 /* in MDI frame */
3093 { WM_NCCALCSIZE, sent|wparam, 1 },
3094 { 0x0093, sent|defwinproc|optional },
3095 { 0x0093, sent|defwinproc|optional },
3096 { 0x0093, sent|defwinproc|optional },
3098 { WM_MOVE, sent|defwinproc },
3100
3101 /* in MDI client */
3103 { WM_NCCALCSIZE, sent|wparam, 1 },
3106
3107 /* in MDI child */
3109 { WM_NCCALCSIZE, sent|wparam, 1 },
3110 { 0x0093, sent|optional },
3113
3114 { 0x0093, sent|optional },
3115 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, /* MDI child */
3116 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, /* MDI client */
3117 { WM_NCCALCSIZE, sent|wparam|optional, 1 }, /* XP sends it to MDI frame */
3118 { 0x0093, sent|defwinproc|optional },
3119 { 0x0093, sent|defwinproc|optional },
3120 { 0x0093, sent|defwinproc|optional },
3121 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, /* MDI frame */
3122 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, /* XP sends a duplicate */
3123
3124 { 0 }
3125};
3126/* CreateWindow for the 1st MDI child window, initially invisible and maximized */
3128 { HCBT_CREATEWND, hook },
3130 { WM_NCCREATE, sent },
3131 { WM_NCCALCSIZE, sent|wparam, 0 },
3132 { EVENT_OBJECT_REORDER, winevent_hook|wparam|lparam, 0, 0 },
3133 { WM_CREATE, sent },
3134 { EVENT_OBJECT_CREATE, winevent_hook|wparam|lparam, 0, 0 },
3137 { WM_NCCALCSIZE, sent|wparam|optional, 1 }, /* MDI frame */
3139 { WM_MOVE, sent },
3144 { WM_NCCALCSIZE, sent|wparam, 1 },
3146 { WM_MOVE, sent|defwinproc },
3148 /* in MDI frame */
3150 { WM_NCCALCSIZE, sent|wparam, 1 },
3152 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, /* MDI frame */
3153 { WM_NCCALCSIZE, sent|wparam|optional, 1 }, /* MDI child */
3154 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, /* MDI child */
3155 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, /* MDI child */
3156 /* Win2k sends wparam set to
3157 * MAKEWPARAM(WM_CREATE, MDI_FIRST_CHILD_ID + nTotalCreated),
3158 * while Win9x doesn't bother to set child window id according to
3159 * CLIENTCREATESTRUCT.idFirstChild
3160 */
3161 { WM_PARENTNOTIFY, sent /*|wparam, WM_CREATE*/ }, /* in MDI client */
3162 { 0 }
3163};
3164/* WM_SYSCOMMAND/SC_CLOSE for the 2nd MDI child window, initially visible and maximized */
3167 { HCBT_SYSCOMMAND, hook },
3169 { WM_MDIDESTROY, sent }, /* in MDI client */
3170
3171 /* bring the 1st MDI child to top */
3172 { WM_WINDOWPOSCHANGING, sent|wparam|defwinproc, SWP_NOSIZE|SWP_NOMOVE }, /* in the 1st MDI child */
3174
3175 { EVENT_OBJECT_REORDER, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
3176
3177 { WM_CHILDACTIVATE, sent|defwinproc|wparam|lparam, 0, 0 }, /* in the 1st MDI child */
3178 { WM_NCACTIVATE, sent|wparam|defwinproc, 0 }, /* in the 1st MDI child */
3179 { WM_MDIACTIVATE, sent|defwinproc }, /* in the 1st MDI child */
3180
3181 /* maximize the 1st MDI child */
3189
3190 /* restore the 2nd MDI child */
3195
3196 { EVENT_OBJECT_SHOW, winevent_hook|wparam|lparam, 0, 0 },
3197
3200
3201 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, /* MDI frame */
3202
3204 /* in MDI frame */
3206 { WM_NCCALCSIZE, sent|wparam, 1 },
3208 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, /* MDI frame */
3209 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, /* MDI child */
3210
3211 /* bring the 1st MDI child to top */
3214 { HCBT_SETFOCUS, hook },
3217 { WM_IME_SETCONTEXT, sent|wparam|optional, 1 }, /* in MDI client */
3218 { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
3219 { WM_SETFOCUS, sent }, /* in MDI client */
3220 { HCBT_SETFOCUS, hook },
3221 { WM_KILLFOCUS, sent }, /* in MDI client */
3222 { WM_IME_SETCONTEXT, sent|wparam|optional, 0 }, /* in MDI client */
3224 { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
3228
3229 /* apparently ShowWindow(SW_SHOW) on an MDI client */
3230 { WM_SHOWWINDOW, sent|wparam, 1 },
3232 { EVENT_OBJECT_SHOW, winevent_hook|wparam|lparam, 0, 0 },
3235
3236 { HCBT_DESTROYWND, hook },
3237 /* Win2k sends wparam set to
3238 * MAKEWPARAM(WM_DESTROY, MDI_FIRST_CHILD_ID + nTotalCreated),
3239 * while Win9x doesn't bother to set child window id according to
3240 * CLIENTCREATESTRUCT.idFirstChild
3241 */
3242 { 0x0090, sent|defwinproc|optional },
3243 { WM_PARENTNOTIFY, sent /*|wparam, WM_DESTROY*/ }, /* in MDI client */
3246 { EVENT_OBJECT_HIDE, winevent_hook|wparam|lparam, 0, 0 },
3249
3250 { EVENT_OBJECT_DESTROY, winevent_hook|wparam|lparam, 0, 0 },
3253 { 0 }
3254};
3255/* WM_MDIDESTROY for the single MDI child window, initially visible and maximized */
3257 { WM_MDIDESTROY, sent }, /* in MDI client */
3258 { WM_SHOWWINDOW, sent|wparam, 0 },
3260 { EVENT_OBJECT_HIDE, winevent_hook|wparam|lparam, 0, 0 },
3263
3264 { HCBT_SETFOCUS, hook },
3265 { WM_KILLFOCUS, sent },
3267 { WM_IME_SETCONTEXT, sent|wparam|optional, 1 }, /* in MDI client */
3268 { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
3269 { WM_SETFOCUS, sent }, /* in MDI client */
3270 { HCBT_SETFOCUS, hook },
3271 { WM_KILLFOCUS, sent }, /* in MDI client */
3272 { WM_IME_SETCONTEXT, sent|wparam|optional, 0 }, /* in MDI client */
3274 { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
3275 { WM_SETFOCUS, sent },
3276
3277 /* in MDI child */
3279 { WM_NCCALCSIZE, sent|wparam, 1 },
3281 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, /* MDI child */
3282
3283 /* in MDI frame */
3285 { WM_NCCALCSIZE, sent|wparam, 1 },
3286 { 0x0093, sent|defwinproc|optional },
3287 { 0x0093, sent|defwinproc|optional },
3289 { WM_MOVE, sent|defwinproc },
3291
3292 /* in MDI client */
3294 { WM_NCCALCSIZE, sent|wparam, 1 },
3297
3298 /* in MDI child */
3300 { WM_NCCALCSIZE, sent|wparam, 1 },
3303
3304 /* in MDI child */
3308 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, /* MDI child */
3309
3310 /* in MDI frame */
3313 { 0x0093, sent|defwinproc|optional },
3314 { 0x0093, sent|defwinproc|optional },
3315 { 0x0093, sent|defwinproc|optional },
3317 { WM_MOVE, sent|defwinproc },
3319
3320 /* in MDI client */
3322 { WM_NCCALCSIZE, sent|wparam, 1 },
3325
3326 /* in MDI child */
3331 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, /* MDI child */
3332 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, /* MDI client */
3333
3334 { 0x0093, sent|defwinproc|optional },
3335 { WM_NCCALCSIZE, sent|wparam|defwinproc|optional, 1 }, /* XP sends it to MDI frame */
3336 { 0x0093, sent|defwinproc|optional },
3337 { 0x0093, sent|defwinproc|optional },
3338 { 0x0093, sent|defwinproc|optional },
3339 { 0x0093, sent|optional },
3340
3341 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, /* MDI frame */
3342 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, /* MDI child */
3343 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, /* MDI client */
3344 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, /* MDI frame */
3345 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, /* XP sends a duplicate */
3346
3347 /* in MDI frame */
3350 { 0x0093, sent|defwinproc|optional },
3351 { 0x0093, sent|defwinproc|optional },
3352 { 0x0093, sent|defwinproc|optional },
3354 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, /* MDI frame */
3355 { 0x0093, sent|optional },
3356
3357 { WM_NCACTIVATE, sent|wparam, 0 },
3358 { WM_MDIACTIVATE, sent },
3359
3362 { WM_NCCALCSIZE, sent|wparam, 1 },
3363
3364 { EVENT_OBJECT_SHOW, winevent_hook|wparam|lparam, 0, 0 },
3365
3369
3370 /* in MDI child */
3374 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, /* MDI child */
3375
3376 /* in MDI frame */
3378 { WM_NCCALCSIZE, sent|wparam, 1 },
3380 { WM_MOVE, sent|defwinproc },
3382
3383 /* in MDI client */
3385 { WM_NCCALCSIZE, sent|wparam, 1 },
3388 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, /* MDI child */
3389 { WM_NCCALCSIZE, sent|wparam|optional, 1 }, /* XP */
3390 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, /* MDI client */
3391 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, /* MDI frame */
3392 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, /* XP sends a duplicate */
3393
3394 { HCBT_SETFOCUS, hook },
3395 { WM_KILLFOCUS, sent },
3397 { WM_IME_SETCONTEXT, sent|wparam|optional, 1 }, /* in MDI client */
3398 { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
3399 { WM_SETFOCUS, sent }, /* in MDI client */
3400
3401 { WM_MDIREFRESHMENU, sent }, /* in MDI client */
3402
3403 { HCBT_DESTROYWND, hook },
3404 /* Win2k sends wparam set to
3405 * MAKEWPARAM(WM_DESTROY, MDI_FIRST_CHILD_ID + nTotalCreated),
3406 * while Win9x doesn't bother to set child window id according to
3407 * CLIENTCREATESTRUCT.idFirstChild
3408 */
3409 { 0x0090, sent|optional },
3410 { WM_PARENTNOTIFY, sent /*|wparam, WM_DESTROY*/ }, /* in MDI client */
3411
3412 { WM_SHOWWINDOW, sent|wparam, 0 },
3414 { EVENT_OBJECT_HIDE, winevent_hook|wparam|lparam, 0, 0 },
3417
3418 { EVENT_OBJECT_DESTROY, winevent_hook|wparam|lparam, 0, 0 },
3419 { WM_DESTROY, sent },
3420 { WM_NCDESTROY, sent },
3421 { 0 }
3422};
3423/* ShowWindow(SW_MAXIMIZE) for a not visible MDI child window */
3428 { WM_NCCALCSIZE, sent|wparam, 1 },
3429 { EVENT_OBJECT_SHOW, winevent_hook|wparam|lparam, 0, 0 },
3431
3435 { WM_IME_SETCONTEXT, sent|wparam|optional, 1 }, /* in MDI client */
3436 { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
3437 { WM_SETFOCUS, sent|optional }, /* in MDI client */
3439 { WM_KILLFOCUS, sent|optional }, /* in MDI client */
3440 { WM_IME_SETCONTEXT, sent|wparam|optional, 0 }, /* in MDI client */
3442 { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
3447 /* in MDI frame */
3449 { WM_NCCALCSIZE, sent|wparam, 1 },
3451 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, /* MDI frame */
3452 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, /* MDI child */
3453 { 0 }
3454};
3455/* ShowWindow(SW_MAXIMIZE) for a not visible maximized MDI child window */
3461 { WM_NCCALCSIZE, sent|wparam, 1 },
3462 { EVENT_OBJECT_SHOW, winevent_hook|wparam|lparam, 0, 0 },
3464
3468 { WM_IME_SETCONTEXT, sent|wparam|optional, 1 }, /* in MDI client */
3469 { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
3470 { WM_SETFOCUS, sent|optional }, /* in MDI client */
3472 { WM_KILLFOCUS, sent|optional }, /* in MDI client */
3473 { WM_IME_SETCONTEXT, sent|wparam|optional, 0 }, /* in MDI client */
3475 { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
3479 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, /* MDI child */
3481 { 0 }
3482};
3483/* WM_MDIMAXIMIZE for an MDI child window with invisible parent */
3485 { WM_MDIMAXIMIZE, sent }, /* in MDI client */
3490 { WM_NCCALCSIZE, sent|wparam, 1 },
3491 { EVENT_OBJECT_SHOW, winevent_hook|wparam|lparam|optional, 0, 0 }, /* XP doesn't send it */
3494 { WM_MOVE, sent|defwinproc },
3496
3501 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam|optional, 0, 0 }, /* MDI child XP */
3502 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam|optional, 0, 0 }, /* MDI client XP */
3503 /* in MDI frame */
3505 { WM_NCCALCSIZE, sent|wparam, 1 },
3506 { 0x0093, sent|defwinproc|optional },
3507 { 0x0094, sent|defwinproc|optional },
3508 { 0x0094, sent|defwinproc|optional },
3509 { 0x0094, sent|defwinproc|optional },
3510 { 0x0094, sent|defwinproc|optional },
3511 { 0x0093, sent|defwinproc|optional },
3512 { 0x0093, sent|defwinproc|optional },
3513 { 0x0091, sent|defwinproc|optional },
3514 { 0x0092, sent|defwinproc|optional },
3515 { 0x0092, sent|defwinproc|optional },
3516 { 0x0092, sent|defwinproc|optional },
3517 { 0x0092, sent|defwinproc|optional },
3519 { WM_MOVE, sent|defwinproc },
3521 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam|optional, 0, 0 }, /* MDI frame win2000 */
3522 /* in MDI client */
3524 { WM_NCCALCSIZE, sent|wparam, 1 },
3527 /* in MDI child */
3533 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam|optional, 0, 0 }, /* MDI child win2000 */
3535 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam|optional, 0, 0 }, /* MDI child XP */
3536 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam|optional, 0, 0 }, /* MDI child XP */
3537 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam|optional, 0, 0 }, /* MDI client XP */
3538 /* in MDI frame */
3539 { 0x0093, sent|optional },
3541 { 0x0093, sent|defwinproc|optional },
3542 { 0x0093, sent|defwinproc|optional },
3543 { 0x0093, sent|defwinproc|optional },
3544 { 0x0091, sent|defwinproc|optional },
3545 { 0x0092, sent|defwinproc|optional },
3546 { 0x0092, sent|defwinproc|optional },
3547 { 0x0092, sent|defwinproc|optional },
3548 { 0x0092, sent|defwinproc|optional },
3549 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam|optional, 0, 0 }, /* MDI frame XP */
3550 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam|optional, 0, 0 }, /* MDI frame XP */
3551 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam|optional, 0, 0 }, /* MDI child XP */
3552 { 0 }
3553};
3554/* ShowWindow(SW_MAXIMIZE) for a visible MDI child window */
3555static const struct message WmMaximizeMDIchildVisibleSeq[] = {
3559 { WM_NCCALCSIZE, sent|wparam, 1 },
3563 /* in MDI frame */
3565 { WM_NCCALCSIZE, sent|wparam, 1 },
3567 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, /* MDI frame */
3568 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, /* MDI child */
3569 { 0 }
3570};
3571/* ShowWindow(SW_RESTORE) for a visible maximized MDI child window */
3572static const struct message WmRestoreMDIchildVisibleSeq[] = {
3575 { WM_NCCALCSIZE, sent|wparam, 1 },
3579 /* in MDI frame */
3581 { WM_NCCALCSIZE, sent|wparam, 1 },
3583 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, /* MDI frame */
3584 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, /* MDI child */
3585 { 0 }
3586};
3587/* ShowWindow(SW_RESTORE) for a visible minimized MDI child window */
3590 { WM_QUERYOPEN, sent|wparam|lparam, 0, 0 },
3592 { WM_NCCALCSIZE, sent|wparam, 1 },
3595 { WM_MOVE, sent|defwinproc },
3597 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, /* MDI child */
3598 { EVENT_SYSTEM_MINIMIZEEND, winevent_hook|wparam|lparam, 0, 0 }, /* MDI child */
3599 { HCBT_SETFOCUS, hook },
3602 { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
3603 { WM_SETFOCUS, sent },
3604 { 0 }
3605};
3606/* ShowWindow(SW_MINIMIZE) for a visible restored MDI child window */
3607static const struct message WmMinimizeMDIchildVisibleSeq[] = {
3610 { WM_NCCALCSIZE, sent|wparam, 1 },
3612 { WM_MOVE, sent|defwinproc },
3615 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, /* MDI child */
3616 { EVENT_SYSTEM_MINIMIZESTART, winevent_hook|wparam|lparam, 0, 0 }, /* MDI child */
3617 /* FIXME: Wine creates an icon/title window while Windows doesn't */
3618 { WM_PARENTNOTIFY, sent|parent|wparam|optional, WM_CREATE }, /* MDI client */
3619 { 0 }
3620};
3621/* ShowWindow(SW_RESTORE) for a not visible MDI child window */
3625 { WM_NCCALCSIZE, sent|wparam, 1 },
3626 { EVENT_OBJECT_SHOW, winevent_hook|wparam|lparam, 0, 0 },
3630 /* in MDI frame */
3632 { WM_NCCALCSIZE, sent|wparam, 1 },
3634 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, /* MDI frame */
3635 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 }, /* MDI child */
3636 { 0 }
3637};
3638
3641
3643{
3644 struct recvd_message msg;
3645
3646 /* do not log painting messages */
3647 if (message != WM_PAINT &&
3648 message != WM_NCPAINT &&
3649 message != WM_SYNCPAINT &&
3651 message != WM_NCHITTEST &&
3652 message != WM_GETTEXT &&
3655 {
3656 msg.hwnd = hwnd;
3657 msg.message = message;
3658 msg.flags = sent|wparam|lparam;
3659 msg.wParam = wParam;
3660 msg.lParam = lParam;
3661 msg.descr = "mdi client";
3662 add_message(&msg);
3663 }
3664
3666}
3667
3669{
3670 static LONG defwndproc_counter = 0;
3671 LRESULT ret;
3672 struct recvd_message msg;
3673
3674 /* do not log painting messages */
3675 if (message != WM_PAINT &&
3676 message != WM_NCPAINT &&
3677 message != WM_SYNCPAINT &&
3679 message != WM_NCHITTEST &&
3680 message != WM_GETTEXT &&
3682 {
3683 switch (message)
3684 {
3685 case WM_MDIACTIVATE:
3686 {
3687 HWND active, client = GetParent(hwnd);
3688
3689 active = (HWND)SendMessageA(client, WM_MDIGETACTIVE, 0, 0);
3690
3691 if (hwnd == (HWND)lParam) /* if we are being activated */
3692 ok (active == (HWND)lParam, "new active %p != active %p\n", (HWND)lParam, active);
3693 else
3694 ok (active == (HWND)wParam, "old active %p != active %p\n", (HWND)wParam, active);
3695 break;
3696 }
3697 }
3698
3699 msg.hwnd = hwnd;
3700 msg.message = message;
3701 msg.flags = sent|wparam|lparam;
3702 if (defwndproc_counter) msg.flags |= defwinproc;
3703 msg.wParam = wParam;
3704 msg.lParam = lParam;
3705 msg.descr = "mdi child";
3706 add_message(&msg);
3707 }
3708
3709 defwndproc_counter++;
3711 defwndproc_counter--;
3712
3713 return ret;
3714}
3715
3717{
3718 static LONG defwndproc_counter = 0;
3719 LRESULT ret;
3720 struct recvd_message msg;
3721
3722 /* do not log painting messages */
3723 if (message != WM_PAINT &&
3724 message != WM_NCPAINT &&
3725 message != WM_SYNCPAINT &&
3727 message != WM_NCHITTEST &&
3728 message != WM_GETTEXT &&
3730 {
3731 msg.hwnd = hwnd;
3732 msg.message = message;
3733 msg.flags = sent|wparam|lparam;
3734 if (defwndproc_counter) msg.flags |= defwinproc;
3735 msg.wParam = wParam;
3736 msg.lParam = lParam;
3737 msg.descr = "mdi frame";
3738 add_message(&msg);
3739 }
3740
3741 defwndproc_counter++;
3743 defwndproc_counter--;
3744
3745 return ret;
3746}
3747
3749{
3750 WNDCLASSA cls;
3751
3752 cls.style = 0;
3754 cls.cbClsExtra = 0;
3755 cls.cbWndExtra = 0;
3756 cls.hInstance = GetModuleHandleA(0);
3757 cls.hIcon = 0;
3760 cls.lpszMenuName = NULL;
3761 cls.lpszClassName = "MDI_frame_class";
3762 if (!RegisterClassA(&cls)) return FALSE;
3763
3765 cls.lpszClassName = "MDI_child_class";
3766 if (!RegisterClassA(&cls)) return FALSE;
3767
3768 if (!GetClassInfoA(0, "MDIClient", &cls)) assert(0);
3770 cls.hInstance = GetModuleHandleA(0);
3772 cls.lpszClassName = "MDI_client_class";
3773 if (!RegisterClassA(&cls)) assert(0);
3774
3775 return TRUE;
3776}
3777
3778static void test_mdi_messages(void)
3779{
3780 MDICREATESTRUCTA mdi_cs;
3781 CLIENTCREATESTRUCT client_cs;
3782 HWND mdi_frame, mdi_child, mdi_child2, active_child;
3783 BOOL zoomed;
3784 RECT rc;
3785 HMENU hMenu = CreateMenu();
3786 LONG val;
3787
3789
3791
3792 trace("creating MDI frame window\n");
3793 mdi_frame = CreateWindowExA(0, "MDI_frame_class", "MDI frame window",
3796 100, 100, CW_USEDEFAULT, CW_USEDEFAULT,
3797 GetDesktopWindow(), hMenu,
3799 assert(mdi_frame);
3800 ok_sequence(WmCreateMDIframeSeq, "Create MDI frame window", FALSE);
3801
3802 ok(GetActiveWindow() == mdi_frame, "wrong active window %p\n", GetActiveWindow());
3803 ok(GetFocus() == mdi_frame, "wrong focus window %p\n", GetFocus());
3804
3805 trace("creating MDI client window\n");
3806 GetClientRect(mdi_frame, &rc);
3807 client_cs.hWindowMenu = 0;
3808 client_cs.idFirstChild = MDI_FIRST_CHILD_ID;
3809 mdi_client = CreateWindowExA(0, "MDI_client_class",
3810 NULL,
3812 rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top,
3813 mdi_frame, 0, GetModuleHandleA(0), &client_cs);
3815 SetWindowLongA(mdi_client, 0, 0xdeadbeef);
3816
3817 ok_sequence(WmCreateMDIclientSeq, "Create visible MDI client window", FALSE);
3818 ok(GetActiveWindow() == mdi_frame, "wrong active window %p\n", GetActiveWindow());
3819 ok(GetFocus() == mdi_frame, "input focus should be on MDI frame not on %p\n", GetFocus());
3820
3821 active_child = (HWND)SendMessageA(mdi_client, WM_MDIGETACTIVE, 0, (LPARAM)&zoomed);
3822 ok(!active_child, "wrong active MDI child %p\n", active_child);
3823 ok(!zoomed, "wrong zoomed state %d\n", zoomed);
3824
3825 SetFocus(0);
3827
3828 trace("creating invisible MDI child window\n");
3829 mdi_child = CreateWindowExA(WS_EX_MDICHILD, "MDI_child_class", "MDI child",
3830 WS_CHILD,
3833 assert(mdi_child);
3834
3836 ShowWindow(mdi_child, SW_SHOWNORMAL);
3837 ok_sequence(WmShowChildSeq, "ShowWindow(SW_SHOWNORMAL) MDI child window", FALSE);
3838
3839 ok(GetWindowLongA(mdi_child, GWL_STYLE) & WS_VISIBLE, "MDI child should be visible\n");
3840 ok(IsWindowVisible(mdi_child), "MDI child should be visible\n");
3841
3842 ok(GetActiveWindow() == mdi_frame, "wrong active window %p\n", GetActiveWindow());
3843 ok(GetFocus() == 0, "wrong focus window %p\n", GetFocus());
3844
3845 active_child = (HWND)SendMessageA(mdi_client, WM_MDIGETACTIVE, 0, (LPARAM)&zoomed);
3846 ok(!active_child, "wrong active MDI child %p\n", active_child);
3847 ok(!zoomed, "wrong zoomed state %d\n", zoomed);
3848
3849 ShowWindow(mdi_child, SW_HIDE);
3850 ok_sequence(WmHideChildSeq, "ShowWindow(SW_HIDE) MDI child window", FALSE);
3852
3853 ShowWindow(mdi_child, SW_SHOW);
3854 ok_sequence(WmShowChildSeq, "ShowWindow(SW_SHOW) MDI child window", FALSE);
3855
3856 ok(GetWindowLongA(mdi_child, GWL_STYLE) & WS_VISIBLE, "MDI child should be visible\n");
3857 ok(IsWindowVisible(mdi_child), "MDI child should be visible\n");
3858
3859 ok(GetActiveWindow() == mdi_frame, "wrong active window %p\n", GetActiveWindow());
3860 ok(GetFocus() == 0, "wrong focus window %p\n", GetFocus());
3861
3862 active_child = (HWND)SendMessageA(mdi_client, WM_MDIGETACTIVE, 0, (LPARAM)&zoomed);
3863 ok(!active_child, "wrong active MDI child %p\n", active_child);
3864 ok(!zoomed, "wrong zoomed state %d\n", zoomed);
3865
3866 DestroyWindow(mdi_child);
3868
3869 trace("creating visible MDI child window\n");
3870 mdi_child = CreateWindowExA(WS_EX_MDICHILD, "MDI_child_class", "MDI child",
3874 assert(mdi_child);
3875 ok_sequence(WmCreateMDIchildVisibleSeq, "Create visible MDI child window", FALSE);
3876
3877 ok(GetWindowLongA(mdi_child, GWL_STYLE) & WS_VISIBLE, "MDI child should be visible\n");
3878 ok(IsWindowVisible(mdi_child), "MDI child should be visible\n");
3879
3880 ok(GetActiveWindow() == mdi_frame, "wrong active window %p\n", GetActiveWindow());
3881 ok(GetFocus() == mdi_child, "wrong focus window %p\n", GetFocus());
3882
3883 active_child = (HWND)SendMessageA(mdi_client, WM_MDIGETACTIVE, 0, (LPARAM)&zoomed);
3884 ok(active_child == mdi_child, "wrong active MDI child %p\n", active_child);
3885 ok(!zoomed, "wrong zoomed state %d\n", zoomed);
3887
3888 DestroyWindow(mdi_child);
3889 ok_sequence(WmDestroyMDIchildVisibleSeq, "Destroy visible MDI child window", TRUE);
3890
3891 ok(GetActiveWindow() == mdi_frame, "wrong active window %p\n", GetActiveWindow());
3892 ok(GetFocus() == 0, "wrong focus window %p\n", GetFocus());
3893
3894 /* Win2k: MDI client still returns a just destroyed child as active
3895 * Win9x: MDI client returns 0
3896 */
3897 active_child = (HWND)SendMessageA(mdi_client, WM_MDIGETACTIVE, 0, (LPARAM)&zoomed);
3898 ok(active_child == mdi_child || /* win2k */
3899 !active_child, /* win9x */
3900 "wrong active MDI child %p\n", active_child);
3901 ok(!zoomed, "wrong zoomed state %d\n", zoomed);
3902
3904
3905 trace("creating invisible MDI child window\n");
3906 mdi_child2 = CreateWindowExA(WS_EX_MDICHILD, "MDI_child_class", "MDI child",
3907 WS_CHILD,
3910 assert(mdi_child2);
3911 ok_sequence(WmCreateMDIchildInvisibleSeq, "Create invisible MDI child window", FALSE);
3912
3913 ok(!(GetWindowLongA(mdi_child2, GWL_STYLE) & WS_VISIBLE), "MDI child should not be visible\n");
3914 ok(!IsWindowVisible(mdi_child2), "MDI child should not be visible\n");
3915
3916 ok(GetActiveWindow() == mdi_frame, "wrong active window %p\n", GetActiveWindow());
3917 ok(GetFocus() == 0, "wrong focus window %p\n", GetFocus());
3918
3919 /* Win2k: MDI client still returns a just destroyed child as active
3920 * Win9x: MDI client returns mdi_child2
3921 */
3922 active_child = (HWND)SendMessageA(mdi_client, WM_MDIGETACTIVE, 0, (LPARAM)&zoomed);
3923 ok(active_child == mdi_child || /* win2k */
3924 active_child == mdi_child2, /* win9x */
3925 "wrong active MDI child %p\n", active_child);
3926 ok(!zoomed, "wrong zoomed state %d\n", zoomed);
3928
3929 ShowWindow(mdi_child2, SW_MAXIMIZE);
3930 ok_sequence(WmMaximizeMDIchildInvisibleSeq, "ShowWindow(SW_MAXIMIZE):invisible MDI child", FALSE);
3931
3932 ok(GetWindowLongA(mdi_child2, GWL_STYLE) & WS_VISIBLE, "MDI child should be visible\n");
3933 ok(IsWindowVisible(mdi_child2), "MDI child should be visible\n");
3934
3935 active_child = (HWND)SendMessageA(mdi_client, WM_MDIGETACTIVE, 0, (LPARAM)&zoomed);
3936 ok(active_child == mdi_child2, "wrong active MDI child %p\n", active_child);
3937 ok(zoomed, "wrong zoomed state %d\n", zoomed);
3939
3940 ok(GetActiveWindow() == mdi_frame, "wrong active window %p\n", GetActiveWindow());
3941 ok(GetFocus() == mdi_child2 || /* win2k */
3942 GetFocus() == 0, /* win9x */
3943 "wrong focus window %p\n", GetFocus());
3944
3945 SetFocus(0);
3947
3948 ShowWindow(mdi_child2, SW_HIDE);
3949 ok_sequence(WmHideChildSeq, "ShowWindow(SW_HIDE):MDI child", FALSE);
3950
3951 ShowWindow(mdi_child2, SW_RESTORE);
3952 ok_sequence(WmRestoreMDIchildInvisibleSeq, "ShowWindow(SW_RESTORE):invisible MDI child", FALSE);
3954
3955 ok(GetWindowLongA(mdi_child2, GWL_STYLE) & WS_VISIBLE, "MDI child should be visible\n");
3956 ok(IsWindowVisible(mdi_child2), "MDI child should be visible\n");
3957
3958 active_child = (HWND)SendMessageA(mdi_client, WM_MDIGETACTIVE, 0, (LPARAM)&zoomed);
3959 ok(active_child == mdi_child2, "wrong active MDI child %p\n", active_child);
3960 ok(!zoomed, "wrong zoomed state %d\n", zoomed);
3962
3963 SetFocus(0);
3965
3966 ShowWindow(mdi_child2, SW_HIDE);
3967 ok_sequence(WmHideChildSeq, "ShowWindow(SW_HIDE):MDI child", FALSE);
3968
3969 ShowWindow(mdi_child2, SW_SHOW);
3970 ok_sequence(WmShowChildSeq, "ShowWindow(SW_SHOW):MDI child", FALSE);
3971
3972 ok(GetActiveWindow() == mdi_frame, "wrong active window %p\n", GetActiveWindow());
3973 ok(GetFocus() == 0, "wrong focus window %p\n", GetFocus());
3974
3975 ShowWindow(mdi_child2, SW_MAXIMIZE);
3976 ok_sequence(WmMaximizeMDIchildVisibleSeq, "ShowWindow(SW_MAXIMIZE):MDI child", FALSE);
3977
3978 ok(GetActiveWindow() == mdi_frame, "wrong active window %p\n", GetActiveWindow());
3979 ok(GetFocus() == 0, "wrong focus window %p\n", GetFocus());
3980
3981 ShowWindow(mdi_child2, SW_RESTORE);
3982 ok_sequence(WmRestoreMDIchildVisibleSeq, "ShowWindow(SW_RESTORE):maximized MDI child", FALSE);
3983
3984 ok(GetActiveWindow() == mdi_frame, "wrong active window %p\n", GetActiveWindow());
3985 ok(GetFocus() == 0, "wrong focus window %p\n", GetFocus());
3986
3987 ShowWindow(mdi_child2, SW_MINIMIZE);
3988 ok_sequence(WmMinimizeMDIchildVisibleSeq, "ShowWindow(SW_MINIMIZE):MDI child", FALSE);
3989
3990 ok(GetActiveWindow() == mdi_frame, "wrong active window %p\n", GetActiveWindow());
3991 ok(GetFocus() == 0, "wrong focus window %p\n", GetFocus());
3992
3993 active_child = (HWND)SendMessageA(mdi_client, WM_MDIGETACTIVE, 0, (LPARAM)&zoomed);
3994 ok(active_child == mdi_child2, "wrong active MDI child %p\n", active_child);
3995 ok(!zoomed, "wrong zoomed state %d\n", zoomed);
3997
3998 ShowWindow(mdi_child2, SW_RESTORE);
3999 ok_sequence(WmRestoreMDIchildVisibleSeq_2, "ShowWindow(SW_RESTORE):minimized MDI child", FALSE);
4000
4001 ok(GetActiveWindow() == mdi_frame, "wrong active window %p\n", GetActiveWindow());
4002 ok(GetFocus() == mdi_child2, "wrong focus window %p\n", GetFocus());
4003
4004 active_child = (HWND)SendMessageA(mdi_client, WM_MDIGETACTIVE, 0, (LPARAM)&zoomed);
4005 ok(active_child == mdi_child2, "wrong active MDI child %p\n", active_child);
4006 ok(!zoomed, "wrong zoomed state %d\n", zoomed);
4008
4009 SetFocus(0);
4011
4012 ShowWindow(mdi_child2, SW_HIDE);
4013 ok_sequence(WmHideChildSeq, "ShowWindow(SW_HIDE):MDI child", FALSE);
4014
4015 ok(GetActiveWindow() == mdi_frame, "wrong active window %p\n", GetActiveWindow());
4016 ok(GetFocus() == 0, "wrong focus window %p\n", GetFocus());
4017
4018 DestroyWindow(mdi_child2);
4019 ok_sequence(WmDestroyMDIchildInvisibleSeq, "Destroy invisible MDI child window", FALSE);
4020
4021 ok(GetActiveWindow() == mdi_frame, "wrong active window %p\n", GetActiveWindow());
4022 ok(GetFocus() == 0, "wrong focus window %p\n", GetFocus());
4023
4024 trace("Testing WM_CHILDACTIVATE\n");
4025
4026 mdi_child = CreateWindowExA(WS_EX_MDICHILD, "MDI_child_class", "MDI child",
4030
4031 mdi_child2 = CreateWindowExA(WS_EX_MDICHILD, "MDI_child_class", "MDI child",
4035
4036 active_child = (HWND)SendMessageA(mdi_client, WM_MDIGETACTIVE, 0, (LPARAM)&zoomed);
4037 ok(active_child == mdi_child2, "wrong active MDI child %p\n", active_child);
4038 ok(!zoomed, "wrong zoomed state %d\n", zoomed);
4039
4041 SendMessageW(mdi_child, WM_CHILDACTIVATE, 0, 0);
4042 ok_sequence(WmChildActivateDisabledWindowSeq, "WM_CHILDACTIVATE sent to disabled window", FALSE);
4043
4044 active_child = (HWND)SendMessageA(mdi_client, WM_MDIGETACTIVE, 0, (LPARAM)&zoomed);
4045 ok(active_child == mdi_child2, "wrong active MDI child %p\n", active_child);
4046 ok(!zoomed, "wrong zoomed state %d\n", zoomed);
4048
4049 EnableWindow(mdi_child, TRUE);
4050
4051 active_child = (HWND)SendMessageA(mdi_client, WM_MDIGETACTIVE, 0, (LPARAM)&zoomed);
4052 ok(active_child == mdi_child2, "wrong active MDI child %p\n", active_child);
4053 ok(!zoomed, "wrong zoomed state %d\n", zoomed);
4054
4056 SendMessageW(mdi_child, WM_CHILDACTIVATE, 0, 0);
4057 ok_sequence(WmChildActivateWindowSeq, "WM_CHILDACTIVATE sent to enabled window", FALSE);
4058
4059 active_child = (HWND)SendMessageA(mdi_client, WM_MDIGETACTIVE, 0, (LPARAM)&zoomed);
4060 ok(active_child == mdi_child, "wrong active MDI child %p\n", active_child);
4061 ok(!zoomed, "wrong zoomed state %d\n", zoomed);
4063
4064 DestroyWindow(mdi_child);
4065 DestroyWindow(mdi_child2);
4067
4068 /* test for maximized MDI children */
4069 trace("creating maximized visible MDI child window 1\n");
4070 mdi_child = CreateWindowExA(WS_EX_MDICHILD, "MDI_child_class", "MDI child",
4074 assert(mdi_child);
4075 ok_sequence(WmCreateMDIchildVisibleMaxSeq1, "Create maximized visible 1st MDI child window", TRUE);
4076 ok(IsZoomed(mdi_child), "1st MDI child should be maximized\n");
4077
4078 ok(GetActiveWindow() == mdi_frame, "wrong active window %p\n", GetActiveWindow());
4079 ok(GetFocus() == mdi_child || /* win2k */
4080 GetFocus() == 0, /* win9x */
4081 "wrong focus window %p\n", GetFocus());
4082
4083 active_child = (HWND)SendMessageA(mdi_client, WM_MDIGETACTIVE, 0, (LPARAM)&zoomed);
4084 ok(active_child == mdi_child, "wrong active MDI child %p\n", active_child);
4085 ok(zoomed, "wrong zoomed state %d\n", zoomed);
4087
4088 trace("creating maximized visible MDI child window 2\n");
4089 mdi_child2 = CreateWindowExA(WS_EX_MDICHILD, "MDI_child_class", "MDI child",
4093 assert(mdi_child2);
4094 ok_sequence(WmCreateMDIchildVisibleMaxSeq2, "Create maximized visible 2nd MDI child 2 window", TRUE);
4095 ok(IsZoomed(mdi_child2), "2nd MDI child should be maximized\n");
4096 ok(!IsZoomed(mdi_child), "1st MDI child should NOT be maximized\n");
4097
4098 ok(GetActiveWindow() == mdi_frame, "wrong active window %p\n", GetActiveWindow());
4099 ok(GetFocus() == mdi_child2, "wrong focus window %p\n", GetFocus());
4100
4101 active_child = (HWND)SendMessageA(mdi_client, WM_MDIGETACTIVE, 0, (LPARAM)&zoomed);
4102 ok(active_child == mdi_child2, "wrong active MDI child %p\n", active_child);
4103 ok(zoomed, "wrong zoomed state %d\n", zoomed);
4105
4106 trace("destroying maximized visible MDI child window 2\n");
4107 DestroyWindow(mdi_child2);
4108 ok_sequence(WmDestroyMDIchildVisibleSeq, "Destroy visible MDI child window", TRUE);
4109
4110 ok(!IsZoomed(mdi_child), "1st MDI child should NOT be maximized\n");
4111
4112 ok(GetActiveWindow() == mdi_frame, "wrong active window %p\n", GetActiveWindow());
4113 ok(GetFocus() == 0, "wrong focus window %p\n", GetFocus());
4114
4115 /* Win2k: MDI client still returns a just destroyed child as active
4116 * Win9x: MDI client returns 0
4117 */
4118 active_child = (HWND)SendMessageA(mdi_client, WM_MDIGETACTIVE, 0, (LPARAM)&zoomed);
4119 ok(active_child == mdi_child2 || /* win2k */
4120 !active_child, /* win9x */
4121 "wrong active MDI child %p\n", active_child);
4123
4124 ShowWindow(mdi_child, SW_MAXIMIZE);
4125 ok(IsZoomed(mdi_child), "1st MDI child should be maximized\n");
4127
4128 ok(GetActiveWindow() == mdi_frame, "wrong active window %p\n", GetActiveWindow());
4129 ok(GetFocus() == mdi_child, "wrong focus window %p\n", GetFocus());
4130
4131 trace("re-creating maximized visible MDI child window 2\n");
4132 mdi_child2 = CreateWindowExA(WS_EX_MDICHILD, "MDI_child_class", "MDI child",
4136 assert(mdi_child2);
4137 ok_sequence(WmCreateMDIchildVisibleMaxSeq2, "Create maximized visible 2nd MDI child 2 window", TRUE);
4138 ok(IsZoomed(mdi_child2), "2nd MDI child should be maximized\n");
4139 ok(!IsZoomed(mdi_child), "1st MDI child should NOT be maximized\n");
4140
4141 ok(GetActiveWindow() == mdi_frame, "wrong active window %p\n", GetActiveWindow());
4142 ok(GetFocus() == mdi_child2, "wrong focus window %p\n", GetFocus());
4143
4144 active_child = (HWND)SendMessageA(mdi_client, WM_MDIGETACTIVE, 0, (LPARAM)&zoomed);
4145 ok(active_child == mdi_child2, "wrong active MDI child %p\n", active_child);
4146 ok(zoomed, "wrong zoomed state %d\n", zoomed);
4148
4149 SendMessageA(mdi_child2, WM_SYSCOMMAND, SC_CLOSE, 0);
4150 ok_sequence(WmDestroyMDIchildVisibleMaxSeq2, "WM_SYSCOMMAND/SC_CLOSE on a visible maximized MDI child window", TRUE);
4151 ok(!IsWindow(mdi_child2), "MDI child 2 should be destroyed\n");
4152
4153 ok(IsZoomed(mdi_child), "1st MDI child should be maximized\n");
4154 ok(GetActiveWindow() == mdi_frame, "wrong active window %p\n", GetActiveWindow());
4155 ok(GetFocus() == mdi_child, "wrong focus window %p\n", GetFocus());
4156
4157 active_child = (HWND)SendMessageA(mdi_client, WM_MDIGETACTIVE, 0, (LPARAM)&zoomed);
4158 ok(active_child == mdi_child, "wrong active MDI child %p\n", active_child);
4159 ok(zoomed, "wrong zoomed state %d\n", zoomed);
4161
4162 DestroyWindow(mdi_child);
4163 ok_sequence(WmDestroyMDIchildVisibleSeq, "Destroy visible MDI child window", TRUE);
4164
4165 ok(GetActiveWindow() == mdi_frame, "wrong active window %p\n", GetActiveWindow());
4166 ok(GetFocus() == 0, "wrong focus window %p\n", GetFocus());
4167
4168 /* Win2k: MDI client still returns a just destroyed child as active
4169 * Win9x: MDI client returns 0
4170 */
4171 active_child = (HWND)SendMessageA(mdi_client, WM_MDIGETACTIVE, 0, (LPARAM)&zoomed);
4172 ok(active_child == mdi_child || /* win2k */
4173 !active_child, /* win9x */
4174 "wrong active MDI child %p\n", active_child);
4176
4177 trace("creating maximized invisible MDI child window\n");
4178 mdi_child2 = CreateWindowExA(WS_EX_MDICHILD, "MDI_child_class", "MDI child",
4182 assert(mdi_child2);
4183 ok_sequence(WmCreateMDIchildInvisibleMaxSeq4, "Create maximized invisible MDI child window", FALSE);
4184 ok(IsZoomed(mdi_child2), "MDI child should be maximized\n");
4185 ok(!(GetWindowLongA(mdi_child2, GWL_STYLE) & WS_VISIBLE), "MDI child should be not visible\n");
4186 ok(!IsWindowVisible(mdi_child2), "MDI child should be not visible\n");
4187
4188 /* Win2k: MDI client still returns a just destroyed child as active
4189 * Win9x: MDI client returns 0
4190 */
4191 active_child = (HWND)SendMessageA(mdi_client, WM_MDIGETACTIVE, 0, (LPARAM)&zoomed);
4192 ok(active_child == mdi_child || /* win2k */
4193 !active_child || active_child == mdi_child2, /* win9x */
4194 "wrong active MDI child %p\n", active_child);
4196
4197 trace("call ShowWindow(mdi_child, SW_MAXIMIZE)\n");
4198 ShowWindow(mdi_child2, SW_MAXIMIZE);
4199 ok_sequence(WmMaximizeMDIchildInvisibleSeq2, "ShowWindow(SW_MAXIMIZE):invisible maximized MDI child", FALSE);
4200 ok(IsZoomed(mdi_child2), "MDI child should be maximized\n");
4201 ok(GetWindowLongA(mdi_child2, GWL_STYLE) & WS_VISIBLE, "MDI child should be visible\n");
4202 ok(IsWindowVisible(mdi_child2), "MDI child should be visible\n");
4203
4204 active_child = (HWND)SendMessageA(mdi_client, WM_MDIGETACTIVE, 0, (LPARAM)&zoomed);
4205 ok(active_child == mdi_child2, "wrong active MDI child %p\n", active_child);
4206 ok(zoomed, "wrong zoomed state %d\n", zoomed);
4208
4209 SendMessageA(mdi_client, WM_MDIDESTROY, (WPARAM)mdi_child2, 0);
4211
4212 /* end of test for maximized MDI children */
4213 SetFocus(0);
4215 trace("creating maximized visible MDI child window 1(Switch test)\n");
4216 mdi_child = CreateWindowExA(WS_EX_MDICHILD, "MDI_child_class", "MDI child",
4220 assert(mdi_child);
4221 ok_sequence(WmCreateMDIchildVisibleMaxSeq1, "Create maximized visible 1st MDI child window(Switch test)", TRUE);
4222 ok(IsZoomed(mdi_child), "1st MDI child should be maximized(Switch test)\n");
4223
4224 ok(GetActiveWindow() == mdi_frame, "wrong active window %p(Switch test)\n", GetActiveWindow());
4225 ok(GetFocus() == mdi_child || /* win2k */
4226 GetFocus() == 0, /* win9x */
4227 "wrong focus window %p(Switch test)\n", GetFocus());
4228
4229 active_child = (HWND)SendMessageA(mdi_client, WM_MDIGETACTIVE, 0, (LPARAM)&zoomed);
4230 ok(active_child == mdi_child, "wrong active MDI child %p(Switch test)\n", active_child);
4231 ok(zoomed, "wrong zoomed state %d(Switch test)\n", zoomed);
4233
4234 trace("creating maximized visible MDI child window 2(Switch test)\n");
4235 mdi_child2 = CreateWindowExA(WS_EX_MDICHILD, "MDI_child_class", "MDI child",
4239 assert(mdi_child2);
4240 ok_sequence(WmCreateMDIchildVisibleMaxSeq2, "Create maximized visible 2nd MDI child window (Switch test)", TRUE);
4241
4242 ok(IsZoomed(mdi_child2), "2nd MDI child should be maximized(Switch test)\n");
4243 ok(!IsZoomed(mdi_child), "1st MDI child should NOT be maximized(Switch test)\n");
4244
4245 ok(GetActiveWindow() == mdi_frame, "wrong active window %p(Switch test)\n", GetActiveWindow());
4246 ok(GetFocus() == mdi_child2, "wrong focus window %p(Switch test)\n", GetFocus());
4247
4248 active_child = (HWND)SendMessageA(mdi_client, WM_MDIGETACTIVE, 0, (LPARAM)&zoomed);
4249 ok(active_child == mdi_child2, "wrong active MDI child %p(Switch test)\n", active_child);
4250 ok(zoomed, "wrong zoomed state %d(Switch test)\n", zoomed);
4252
4253 trace("Switch child window.\n");
4255 ok_sequence(WmSwitchChild, "Child did not switch correctly", TRUE);
4256 trace("end of test for switch maximized MDI children\n");
4258
4259 /* Prepare for switching test of not maximized MDI children */
4260 ShowWindow( mdi_child, SW_NORMAL );
4261 ok(!IsZoomed(mdi_child), "wrong zoomed state for %p(Switch test)\n", mdi_child);
4262 ok(!IsZoomed(mdi_child2), "wrong zoomed state for %p(Switch test)\n", mdi_child2);
4263 active_child = (HWND)SendMessageA(mdi_client, WM_MDIGETACTIVE, 0, 0);
4264 ok(active_child == mdi_child, "wrong active MDI child %p(Switch test)\n", active_child);
4266
4267 SendMessageA(mdi_client, WM_MDIACTIVATE, (WPARAM)mdi_child2, 0);
4268 ok_sequence(WmSwitchNotMaximizedChild, "Not maximized child did not switch correctly", FALSE);
4269 trace("end of test for switch not maximized MDI children\n");
4271
4274
4275 SendMessageA(mdi_client, WM_MDIDESTROY, (WPARAM)mdi_child2, 0);
4277
4278 SetFocus(0);
4280 /* end of tests for switch maximized/not maximized MDI children */
4281
4282 mdi_cs.szClass = "MDI_child_Class";
4283 mdi_cs.szTitle = "MDI child";
4284 mdi_cs.hOwner = GetModuleHandleA(0);
4285 mdi_cs.x = 0;
4286 mdi_cs.y = 0;
4287 mdi_cs.cx = CW_USEDEFAULT;
4288 mdi_cs.cy = CW_USEDEFAULT;
4290 mdi_cs.lParam = 0;
4291 mdi_child = (HWND)SendMessageA(mdi_client, WM_MDICREATE, 0, (LPARAM)&mdi_cs);
4292 ok(mdi_child != 0, "MDI child creation failed\n");
4293 ok_sequence(WmCreateMDIchildVisibleMaxSeq3, "WM_MDICREATE for maximized visible MDI child window", TRUE);
4294
4295 ok(GetMenuItemID(hMenu, GetMenuItemCount(hMenu) - 1) == SC_CLOSE, "SC_CLOSE menu item not found\n");
4296
4297 active_child = (HWND)SendMessageA(mdi_client, WM_MDIGETACTIVE, 0, (LPARAM)&zoomed);
4298 ok(active_child == mdi_child, "wrong active MDI child %p\n", active_child);
4299
4300 ok(IsZoomed(mdi_child), "MDI child should be maximized\n");
4301 ok(GetActiveWindow() == mdi_frame, "wrong active window %p\n", GetActiveWindow());
4302 ok(GetFocus() == mdi_child, "wrong focus window %p\n", GetFocus());
4303
4304 active_child = (HWND)SendMessageA(mdi_client, WM_MDIGETACTIVE, 0, (LPARAM)&zoomed);
4305 ok(active_child == mdi_child, "wrong active MDI child %p\n", active_child);
4306 ok(zoomed, "wrong zoomed state %d\n", zoomed);
4308
4310 ok_sequence(WmDestroyMDIchildVisibleMaxSeq1, "Destroy visible maximized MDI child window", TRUE);
4311
4312 ok(!IsWindow(mdi_child), "MDI child should be destroyed\n");
4313 active_child = (HWND)SendMessageA(mdi_client, WM_MDIGETACTIVE, 0, (LPARAM)&zoomed);
4314 ok(!active_child, "wrong active MDI child %p\n", active_child);
4315
4316 SetFocus(0);
4318
4320 ok(val == 0xdeadbeef || broken(val == 0) /* >= Win Vista */, "Expected 0xdeadbeef, got 0x%x\n", val);
4322 ok_sequence(WmDestroyMDIclientSeq, "Destroy MDI client window", FALSE);
4323
4324 /* test maximization of MDI child with invisible parent */
4325 client_cs.hWindowMenu = 0;
4326 mdi_client = CreateWindowA("MDI_client_class",
4327 NULL,
4329 0, 0, 660, 430,
4330 mdi_frame, 0, GetModuleHandleA(0), &client_cs);
4331 ok_sequence(WmCreateMDIclientSeq, "Create MDI client window", FALSE);
4332
4334 ok_sequence(WmHideMDIclientSeq, "Hide MDI client window", FALSE);
4335
4336 mdi_child = CreateWindowExA(WS_EX_MDICHILD, "MDI_child_class", "MDI child",
4338 0, 0, 650, 440,
4340 ok_sequence(WmCreateMDIchildInvisibleParentSeq, "Create MDI child window with invisible parent", FALSE);
4341
4342 SendMessageA(mdi_client, WM_MDIMAXIMIZE, (WPARAM) mdi_child, 0);
4343 ok_sequence(WmMaximizeMDIchildInvisibleParentSeq, "Maximize MDI child window with invisible parent", TRUE);
4344 zoomed = IsZoomed(mdi_child);
4345 ok(zoomed, "wrong zoomed state %d\n", zoomed);
4346
4348 ok_sequence(WmShowMDIclientSeq, "Show MDI client window", FALSE);
4349
4350 DestroyWindow(mdi_child);
4351 ok_sequence(WmDestroyMDIchildVisibleSeq, "Destroy visible maximized MDI child window", TRUE);
4352
4353 /* end of test for maximization of MDI child with invisible parent */
4354
4356 ok_sequence(WmDestroyMDIclientSeq, "Destroy MDI client window", FALSE);
4357
4358 DestroyWindow(mdi_frame);
4359 ok_sequence(WmDestroyMDIframeSeq, "Destroy MDI frame window", FALSE);
4360}
4361/************************* End of MDI test **********************************/
4362
4364{
4366
4367 flush_events();
4369
4371 ok_sequence(WmSetRedrawFalseSeq, "SetRedraw:FALSE", FALSE);
4372
4373 ok(!(GetWindowLongA(hwnd, GWL_STYLE) & WS_VISIBLE), "WS_VISIBLE should NOT be set\n");
4374 ok(!IsWindowVisible(hwnd), "IsWindowVisible() should return FALSE\n");
4375
4378 ok_sequence(WmSetRedrawTrueSeq, "SetRedraw:TRUE", FALSE);
4379
4380 ok(GetWindowLongA(hwnd, GWL_STYLE) & WS_VISIBLE, "WS_VISIBLE should be set\n");
4381 ok(IsWindowVisible(hwnd), "IsWindowVisible() should return TRUE\n");
4382
4383 /* restore original WS_VISIBLE state */
4385
4386 flush_events();
4388}
4389
4391{
4392 struct recvd_message msg;
4393
4394 if (ignore_message( message )) return 0;
4395
4396 switch (message)
4397 {
4398 /* ignore */
4399 case WM_MOUSEMOVE:
4400 case WM_NCMOUSEMOVE:
4401 case WM_NCMOUSELEAVE:
4402 case WM_SETCURSOR:
4403 return 0;
4404 case WM_NCHITTEST:
4405 return HTCLIENT;
4406 }
4407
4408 msg.hwnd = hwnd;
4409 msg.message = message;
4410 msg.flags = sent|wparam|lparam;
4411 msg.wParam = wParam;
4412 msg.lParam = lParam;
4413 msg.descr = "dialog";
4414 add_message(&msg);
4415
4416 if (message == WM_INITDIALOG) SetTimer( hwnd, 1, 100, NULL );
4417 if (message == WM_TIMER) EndDialog( hwnd, 0 );
4418 return 0;
4419}
4420
4422{
4423 struct recvd_message msg;
4424
4425 if (ignore_message( message )) return 0;
4426
4427 switch (message)
4428 {
4429 /* ignore */
4430 case WM_MOUSEMOVE:
4431 case WM_NCMOUSEMOVE:
4432 case WM_NCMOUSELEAVE:
4433 case WM_SETCURSOR:
4434 return 0;
4435 case WM_NCHITTEST:
4436 return HTCLIENT;
4437 }
4438
4439 msg.hwnd = hwnd;
4440 msg.message = message;
4441 msg.flags = sent|wparam|lparam;
4442 msg.wParam = wParam;
4443 msg.lParam = lParam;
4444 msg.descr = "dialog";
4445 add_message(&msg);
4446
4447 if (message == WM_INITDIALOG) EndDialog( hwnd, 0 );
4448 return 0;
4449}
4450
4451static void test_hv_scroll_1(HWND hwnd, INT ctl, DWORD clear, DWORD set, INT min, INT max)
4452{
4453 DWORD style, exstyle;
4454 INT xmin, xmax;
4455 BOOL ret;
4456
4457 exstyle = GetWindowLongA(hwnd, GWL_EXSTYLE);
4459 /* do not be confused by WS_DLGFRAME set */
4460 if ((style & WS_CAPTION) == WS_CAPTION) style &= ~WS_CAPTION;
4461
4462 if (clear) ok(style & clear, "style %08x should be set\n", clear);
4463 if (set) ok(!(style & set), "style %08x should not be set\n", set);
4464
4465 ret = SetScrollRange(hwnd, ctl, min, max, FALSE);
4466 ok( ret, "SetScrollRange(%d) error %d\n", ctl, GetLastError());
4467 if ((style & (WS_DLGFRAME | WS_BORDER | WS_THICKFRAME)) || (exstyle & WS_EX_DLGMODALFRAME))
4468 ok_sequence(WmSetScrollRangeHV_NC_Seq, "SetScrollRange(SB_HORZ/SB_VERT) NC", FALSE);
4469 else
4470 ok_sequence(WmSetScrollRangeHVSeq, "SetScrollRange(SB_HORZ/SB_VERT)", FALSE);
4471
4473 if (set) ok(style & set, "style %08x should be set\n", set);
4474 if (clear) ok(!(style & clear), "style %08x should not be set\n", clear);
4475
4476 /* a subsequent call should do nothing */
4477 ret = SetScrollRange(hwnd, ctl, min, max, FALSE);
4478 ok( ret, "SetScrollRange(%d) error %d\n", ctl, GetLastError());
4479 ok_sequence(WmEmptySeq, "SetScrollRange(SB_HORZ/SB_VERT) empty sequence", FALSE);
4480
4481 xmin = 0xdeadbeef;
4482 xmax = 0xdeadbeef;
4483 ret = GetScrollRange(hwnd, ctl, &xmin, &xmax);
4484 ok( ret, "GetScrollRange(%d) error %d\n", ctl, GetLastError());
4485 ok_sequence(WmEmptySeq, "GetScrollRange(SB_HORZ/SB_VERT) empty sequence", FALSE);
4486 ok(xmin == min, "unexpected min scroll value %d\n", xmin);
4487 ok(xmax == max, "unexpected max scroll value %d\n", xmax);
4488}
4489
4490static void test_hv_scroll_2(HWND hwnd, INT ctl, DWORD clear, DWORD set, INT min, INT max)
4491{
4492 DWORD style, exstyle;
4493 SCROLLINFO si;
4494 BOOL ret;
4495
4496 exstyle = GetWindowLongA(hwnd, GWL_EXSTYLE);
4498 /* do not be confused by WS_DLGFRAME set */
4499 if ((style & WS_CAPTION) == WS_CAPTION) style &= ~WS_CAPTION;
4500
4501 if (clear) ok(style & clear, "style %08x should be set\n", clear);
4502 if (set) ok(!(style & set), "style %08x should not be set\n", set);
4503
4504 si.cbSize = sizeof(si);
4505 si.fMask = SIF_RANGE;
4506 si.nMin = min;
4507 si.nMax = max;
4508 SetScrollInfo(hwnd, ctl, &si, TRUE);
4509 if ((style & (WS_DLGFRAME | WS_BORDER | WS_THICKFRAME)) || (exstyle & WS_EX_DLGMODALFRAME))
4510 ok_sequence(WmSetScrollRangeHV_NC_Seq, "SetScrollInfo(SB_HORZ/SB_VERT) NC", FALSE);
4511 else
4512 ok_sequence(WmSetScrollRangeHVSeq, "SetScrollInfo(SB_HORZ/SB_VERT)", FALSE);
4513
4515 if (set) ok(style & set, "style %08x should be set\n", set);
4516 if (clear) ok(!(style & clear), "style %08x should not be set\n", clear);
4517
4518 /* a subsequent call should do nothing */
4519 SetScrollInfo(hwnd, ctl, &si, TRUE);
4520 if (style & WS_HSCROLL)
4521 ok_sequence(WmSetScrollRangeHSeq_empty, "SetScrollInfo(SB_HORZ/SB_VERT) empty sequence", FALSE);
4522 else if (style & WS_VSCROLL)
4523 ok_sequence(WmSetScrollRangeVSeq_empty, "SetScrollInfo(SB_HORZ/SB_VERT) empty sequence", FALSE);
4524 else
4525 ok_sequence(WmEmptySeq, "SetScrollInfo(SB_HORZ/SB_VERT) empty sequence", FALSE);
4526
4527 si.fMask = SIF_PAGE;
4528 si.nPage = 5;
4529 SetScrollInfo(hwnd, ctl, &si, FALSE);
4530 ok_sequence(WmEmptySeq, "SetScrollInfo(SB_HORZ/SB_VERT) empty sequence", FALSE);
4531
4532 si.fMask = SIF_POS;
4533 si.nPos = max - 1;
4534 SetScrollInfo(hwnd, ctl, &si, FALSE);
4535 ok_sequence(WmEmptySeq, "SetScrollInfo(SB_HORZ/SB_VERT) empty sequence", FALSE);
4536
4537 si.fMask = SIF_RANGE;
4538 si.nMin = 0xdeadbeef;
4539 si.nMax = 0xdeadbeef;
4540 ret = GetScrollInfo(hwnd, ctl, &si);
4541 ok( ret, "GetScrollInfo error %d\n", GetLastError());
4542 ok_sequence(WmEmptySeq, "GetScrollRange(SB_HORZ/SB_VERT) empty sequence", FALSE);
4543 ok(si.nMin == min, "unexpected min scroll value %d\n", si.nMin);
4544 ok(si.nMax == max, "unexpected max scroll value %d\n", si.nMax);
4545}
4546
4547/* Win9x sends WM_USER+xxx while and NT versions send SBM_xxx messages */
4549{
4550 SCROLLINFO si;
4551 INT min, max;
4552 BOOL ret;
4553
4554 flush_events();
4556
4557 min = 0xdeadbeef;
4558 max = 0xdeadbeef;
4560 ok( ret, "GetScrollRange error %d\n", GetLastError());
4561 if (sequence->message != WmGetScrollRangeSeq[0].message)
4562 trace("GetScrollRange(SB_CTL) generated unknown message %04x\n", sequence->message);
4563 /* values of min and max are undefined */
4565
4566 ret = SetScrollRange(hwnd, SB_CTL, 10, 150, FALSE);
4567 ok( ret, "SetScrollRange error %d\n", GetLastError());
4568 if (sequence->message != WmSetScrollRangeSeq[0].message)
4569 trace("SetScrollRange(SB_CTL) generated unknown message %04x\n", sequence->message);
4571
4572 min = 0xdeadbeef;
4573 max = 0xdeadbeef;
4575 ok( ret, "GetScrollRange error %d\n", GetLastError());
4576 if (sequence->message != WmGetScrollRangeSeq[0].message)
4577 trace("GetScrollRange(SB_CTL) generated unknown message %04x\n", sequence->message);
4578 /* values of min and max are undefined */
4580
4581 si.cbSize = sizeof(si);
4582 si.fMask = SIF_RANGE;
4583 si.nMin = 20;
4584 si.nMax = 160;
4586 if (sequence->message != WmSetScrollRangeSeq[0].message)
4587 trace("SetScrollInfo(SB_CTL) generated unknown message %04x\n", sequence->message);
4589
4590 si.fMask = SIF_PAGE;
4591 si.nPage = 10;
4593 if (sequence->message != WmSetScrollRangeSeq[0].message)
4594 trace("SetScrollInfo(SB_CTL) generated unknown message %04x\n", sequence->message);
4596
4597 si.fMask = SIF_POS;
4598 si.nPos = 20;
4600 if (sequence->message != WmSetScrollRangeSeq[0].message)
4601 trace("SetScrollInfo(SB_CTL) generated unknown message %04x\n", sequence->message);
4603
4604 si.fMask = SIF_RANGE;
4605 si.nMin = 0xdeadbeef;
4606 si.nMax = 0xdeadbeef;
4607 ret = GetScrollInfo(hwnd, SB_CTL, &si);
4608 ok( ret, "GetScrollInfo error %d\n", GetLastError());
4609 if (sequence->message != WmGetScrollInfoSeq[0].message)
4610 trace("GetScrollInfo(SB_CTL) generated unknown message %04x\n", sequence->message);
4611 /* values of min and max are undefined */
4613
4614 /* set WS_HSCROLL */
4615 test_hv_scroll_1(hwnd, SB_HORZ, 0, WS_HSCROLL, 10, 150);
4616 /* clear WS_HSCROLL */
4618
4619 /* set WS_HSCROLL */
4620 test_hv_scroll_2(hwnd, SB_HORZ, 0, WS_HSCROLL, 10, 150);
4621 /* clear WS_HSCROLL */
4623
4624 /* set WS_VSCROLL */
4625 test_hv_scroll_1(hwnd, SB_VERT, 0, WS_VSCROLL, 10, 150);
4626 /* clear WS_VSCROLL */
4628
4629 /* set WS_VSCROLL */
4630 test_hv_scroll_2(hwnd, SB_VERT, 0, WS_VSCROLL, 10, 150);
4631 /* clear WS_VSCROLL */
4633}
4634
4635static void test_showwindow(void)
4636{
4637 HWND hwnd, hchild;
4638 RECT rc;
4639
4640 hwnd = CreateWindowExA(0, "TestWindowClass", "Test overlapped", WS_OVERLAPPEDWINDOW,
4641 100, 100, 200, 200, 0, 0, 0, NULL);
4642 ok (hwnd != 0, "Failed to create overlapped window\n");
4643 hchild = CreateWindowExA(0, "TestWindowClass", "Test child", WS_CHILD,
4644 0, 0, 10, 10, hwnd, 0, 0, NULL);
4645 ok (hchild != 0, "Failed to create child\n");
4647
4648 /* ShowWindow( SW_SHOWNA) for invisible top level window */
4649 trace("calling ShowWindow( SW_SHOWNA) for invisible top level window\n");
4650 ok( ShowWindow(hwnd, SW_SHOWNA) == FALSE, "ShowWindow: window was visible\n" );
4651 ok_sequence(WmSHOWNATopInvisible, "ShowWindow(SW_SHOWNA) on invisible top level window", FALSE);
4652
4653 /* ShowWindow( SW_SHOWNA) for now visible top level window */
4654 trace("calling ShowWindow( SW_SHOWNA) for now visible top level window\n");
4655 ok( ShowWindow(hwnd, SW_SHOWNA) != FALSE, "ShowWindow: window was invisible\n" );
4656 ok_sequence(WmSHOWNATopVisible, "ShowWindow(SW_SHOWNA) on visible top level window", FALSE);
4657 /* back to invisible */
4658 ShowWindow(hchild, SW_HIDE);
4661 /* ShowWindow(SW_SHOWNA) with child and parent invisible */
4662 trace("calling ShowWindow( SW_SHOWNA) for invisible child with invisible parent\n");
4663 ok( ShowWindow(hchild, SW_SHOWNA) == FALSE, "ShowWindow: window was visible\n" );
4664 ok_sequence(WmSHOWNAChildInvisParInvis, "ShowWindow(SW_SHOWNA) invisible child and parent", FALSE);
4665 /* ShowWindow(SW_SHOWNA) with child visible and parent invisible */
4666 ok( ShowWindow(hchild, SW_SHOW) != FALSE, "ShowWindow: window was invisible\n" );
4668 trace("calling ShowWindow( SW_SHOWNA) for the visible child and invisible parent\n");
4669 ok( ShowWindow(hchild, SW_SHOWNA) != FALSE, "ShowWindow: window was invisible\n" );
4670 ok_sequence(WmSHOWNAChildVisParInvis, "ShowWindow(SW_SHOWNA) visible child and invisible parent", FALSE);
4671 /* ShowWindow(SW_SHOWNA) with child visible and parent visible */
4674 trace("calling ShowWindow( SW_SHOWNA) for the visible child and parent\n");
4675 ok( ShowWindow(hchild, SW_SHOWNA) != FALSE, "ShowWindow: window was invisible\n" );
4676 ok_sequence(WmSHOWNAChildVisParVis, "ShowWindow(SW_SHOWNA) for the visible child and parent", FALSE);
4677
4678 /* ShowWindow(SW_SHOWNA) with child invisible and parent visible */
4679 ShowWindow( hchild, SW_HIDE);
4681 trace("calling ShowWindow( SW_SHOWNA) for the invisible child and visible parent\n");
4682 ok( ShowWindow(hchild, SW_SHOWNA) == FALSE, "ShowWindow: window was visible\n" );
4683 ok_sequence(WmSHOWNAChildInvisParVis, "ShowWindow(SW_SHOWNA) for the invisible child and visible parent", FALSE);
4684
4685 SetCapture(hchild);
4686 ok(GetCapture() == hchild, "wrong capture window %p\n", GetCapture());
4687 DestroyWindow(hchild);
4688 ok(!GetCapture(), "wrong capture window %p\n", GetCapture());
4689
4692
4693 /* Popup windows */
4694 /* Test 1:
4695 * 1. Create invisible maximized popup window.
4696 * 2. Move and resize it.
4697 * 3. Show it maximized.
4698 */
4699 trace("calling CreateWindowExA( WS_MAXIMIZE ) for invisible maximized popup window\n");
4700 hwnd = CreateWindowExA(0, "TestWindowClass", "Test popup", WS_POPUP | WS_MAXIMIZE,
4701 100, 100, 200, 200, 0, 0, 0, NULL);
4702 ok (hwnd != 0, "Failed to create popup window\n");
4703 ok(IsZoomed(hwnd), "window should be maximized\n");
4704 ok_sequence(WmCreateInvisibleMaxPopupSeq, "CreateWindow(WS_MAXIMIZED):popup", FALSE);
4705
4706 GetWindowRect(hwnd, &rc);
4709 "Invalid maximized size before ShowWindow %s\n", wine_dbgstr_rect( &rc ));
4710 /* Reset window's size & position */
4711 SetWindowPos(hwnd, 0, 10, 10, 200, 200, SWP_NOZORDER | SWP_NOACTIVATE);
4712 ok(IsZoomed(hwnd), "window should be maximized\n");
4714
4715 trace("calling ShowWindow( SW_SHOWMAXIMIZE ) for invisible maximized popup window\n");
4717 ok(IsZoomed(hwnd), "window should be maximized\n");
4718 ok_sequence(WmShowMaxPopupResizedSeq, "ShowWindow(SW_SHOWMAXIMIZED):invisible maximized and resized popup", FALSE);
4719
4720 GetWindowRect(hwnd, &rc);
4723 "Invalid maximized size after ShowWindow %s\n", wine_dbgstr_rect( &rc ));
4726
4727 /* Test 2:
4728 * 1. Create invisible maximized popup window.
4729 * 2. Show it maximized.
4730 */
4731 trace("calling CreateWindowExA( WS_MAXIMIZE ) for invisible maximized popup window\n");
4732 hwnd = CreateWindowExA(0, "TestWindowClass", "Test popup", WS_POPUP | WS_MAXIMIZE,
4733 100, 100, 200, 200, 0, 0, 0, NULL);
4734 ok (hwnd != 0, "Failed to create popup window\n");
4735 ok(IsZoomed(hwnd), "window should be maximized\n");
4736 ok_sequence(WmCreateInvisibleMaxPopupSeq, "CreateWindow(WS_MAXIMIZED):popup", FALSE);
4737
4738 trace("calling ShowWindow( SW_SHOWMAXIMIZE ) for invisible maximized popup window\n");
4740 ok(IsZoomed(hwnd), "window should be maximized\n");
4741 ok_sequence(WmShowMaxPopupSeq, "ShowWindow(SW_SHOWMAXIMIZED):invisible maximized popup", FALSE);
4744
4745 /* Test 3:
4746 * 1. Create visible maximized popup window.
4747 */
4748 trace("calling CreateWindowExA( WS_MAXIMIZE ) for maximized popup window\n");
4749 hwnd = CreateWindowExA(0, "TestWindowClass", "Test popup", WS_POPUP | WS_MAXIMIZE | WS_VISIBLE,
4750 100, 100, 200, 200, 0, 0, 0, NULL);
4751 ok (hwnd != 0, "Failed to create popup window\n");
4752 ok(IsZoomed(hwnd), "window should be maximized\n");
4753 ok_sequence(WmCreateMaxPopupSeq, "CreateWindow(WS_MAXIMIZED):popup", FALSE);
4756
4757 /* Test 4:
4758 * 1. Create visible popup window.
4759 * 2. Maximize it.
4760 */
4761 trace("calling CreateWindowExA( WS_VISIBLE ) for popup window\n");
4762 hwnd = CreateWindowExA(0, "TestWindowClass", "Test popup", WS_POPUP | WS_VISIBLE,
4763 100, 100, 200, 200, 0, 0, 0, NULL);
4764 ok (hwnd != 0, "Failed to create popup window\n");
4765 ok(!IsZoomed(hwnd), "window should NOT be maximized\n");
4766 ok_sequence(WmCreatePopupSeq, "CreateWindow(WS_VISIBLE):popup", FALSE);
4767
4768 trace("calling ShowWindow( SW_SHOWMAXIMIZE ) for visible popup window\n");
4770 ok(IsZoomed(hwnd), "window should be maximized\n");
4771 ok_sequence(WmShowVisMaxPopupSeq, "ShowWindow(SW_SHOWMAXIMIZED):popup", FALSE);
4774}
4775
4777{
4778 static const struct message seq[] =
4779 {
4780 { HCBT_ACTIVATE, hook },
4783 { HCBT_ACTIVATE, hook },
4787 { 0 }
4788 };
4789 HWND hwnd, recursive;
4790
4791 hwnd = CreateWindowExA(0, "SimpleWindowClass", NULL, WS_OVERLAPPED|WS_VISIBLE,
4792 100, 100, 200, 200, 0, 0, 0, NULL);
4793 ok(hwnd != 0, "Failed to create simple window\n");
4794
4795 recursive = CreateWindowExA(0, "RecursiveActivationClass", NULL, WS_OVERLAPPED|WS_VISIBLE,
4796 10, 10, 50, 50, hwnd, 0, 0, NULL);
4797 ok(recursive != 0, "Failed to create recursive activation window\n");
4799
4801 SetActiveWindow(recursive);
4802 ok_sequence(seq, "Recursive Activation", FALSE);
4803
4804 DestroyWindow(recursive);
4807}
4808
4809static void test_sys_menu(void)
4810{
4811 HWND hwnd;
4812 HMENU hmenu;
4813 UINT state;
4814
4815 hwnd = CreateWindowExA(0, "TestWindowClass", NULL, WS_OVERLAPPEDWINDOW,
4816 100, 100, 200, 200, 0, 0, 0, NULL);
4817 ok (hwnd != 0, "Failed to create overlapped window\n");
4818
4820
4821 /* test existing window without CS_NOCLOSE style */
4823 ok(hmenu != 0, "GetSystemMenu error %d\n", GetLastError());
4824
4826 ok(state != 0xffffffff, "wrong SC_CLOSE state %x\n", state);
4827 ok(!(state & (MF_DISABLED | MF_GRAYED)), "wrong SC_CLOSE state %x\n", state);
4828
4830 ok_sequence(WmEmptySeq, "WmEnableMenuItem", FALSE);
4831
4833 ok(state != 0xffffffff, "wrong SC_CLOSE state %x\n", state);
4834 ok((state & (MF_DISABLED | MF_GRAYED)) == MF_GRAYED, "wrong SC_CLOSE state %x\n", state);
4835
4837 ok_sequence(WmEmptySeq, "WmEnableMenuItem", FALSE);
4838
4840 ok(state != 0xffffffff, "wrong SC_CLOSE state %x\n", state);
4841 ok(!(state & (MF_DISABLED | MF_GRAYED)), "wrong SC_CLOSE state %x\n", state);
4842
4843 /* test whether removing WS_SYSMENU destroys a system menu */
4848 ok(hmenu != 0, "GetSystemMenu error %d\n", GetLastError());
4849
4851
4852 /* test new window with CS_NOCLOSE style */
4853 hwnd = CreateWindowExA(0, "NoCloseWindowClass", NULL, WS_OVERLAPPEDWINDOW,
4854 100, 100, 200, 200, 0, 0, 0, NULL);
4855 ok (hwnd != 0, "Failed to create overlapped window\n");
4856
4858 ok(hmenu != 0, "GetSystemMenu error %d\n", GetLastError());
4859
4861 ok(state == 0xffffffff, "wrong SC_CLOSE state %x\n", state);
4862
4864
4865 /* test new window without WS_SYSMENU style */
4866 hwnd = CreateWindowExA(0, "NoCloseWindowClass", NULL, WS_OVERLAPPEDWINDOW & ~WS_SYSMENU,
4867 100, 100, 200, 200, 0, 0, 0, NULL);
4868 ok(hwnd != 0, "Failed to create overlapped window\n");
4869
4871 ok(!hmenu, "GetSystemMenu error %d\n", GetLastError());
4872
4874}
4875
4876/* For shown WS_OVERLAPPEDWINDOW */
4877static const struct message WmSetIcon_1[] = {
4878 { WM_SETICON, sent },
4879 { 0x00AE, sent|defwinproc|optional }, /* XP */
4881 { WM_GETTEXT, sent|defwinproc|optional }, /* XP sends a duplicate */
4882 { 0 }
4883};
4884
4885/* For WS_POPUP and hidden WS_OVERLAPPEDWINDOW */
4886static const struct message WmSetIcon_2[] = {
4887 { WM_SETICON, sent },
4888 { 0 }
4889};
4890
4891/* Sending undocumented 0x3B message with wparam = 0x8000000b */
4892static const struct message WmInitEndSession[] = {
4893 { 0x003B, sent },
4894 { WM_QUERYENDSESSION, sent|defwinproc|wparam|lparam, 0, ENDSESSION_LOGOFF },
4895 { 0 }
4896};
4897
4898/* Sending undocumented 0x3B message with wparam = 0x0000000b */
4899static const struct message WmInitEndSession_2[] = {
4900 { 0x003B, sent },
4902 { 0 }
4903};
4904
4905/* Sending undocumented 0x3B message with wparam = 0x80000008 */
4906static const struct message WmInitEndSession_3[] = {
4907 { 0x003B, sent },
4908 { WM_ENDSESSION, sent|defwinproc|wparam|lparam, 0, ENDSESSION_LOGOFF },
4909 { 0 }
4910};
4911
4912/* Sending undocumented 0x3B message with wparam = 0x00000008 */
4913static const struct message WmInitEndSession_4[] = {
4914 { 0x003B, sent },
4916 { 0 }
4917};
4918
4919/* Sending undocumented 0x3B message with wparam = 0x80000001 */
4920static const struct message WmInitEndSession_5[] = {
4921 { 0x003B, sent },
4922 { WM_ENDSESSION, sent|defwinproc/*|wparam*/|lparam, 1, ENDSESSION_LOGOFF },
4923 { 0 }
4924};
4925
4926static const struct message WmOptionalPaint[] = {
4927 { WM_PAINT, sent|optional },
4931 { 0 }
4932};
4933
4934static const struct message WmZOrder[] = {
4935 { WM_WINDOWPOSCHANGING, sent|wparam, 0, 0 },
4937 { HCBT_ACTIVATE, hook },
4939 { WM_WINDOWPOSCHANGING, sent|wparam, 3, 0 },
4943 { WM_ACTIVATEAPP, sent|wparam, 1, 0 },
4944 { WM_NCACTIVATE, sent|lparam, 1, 0 },
4947 { WM_ACTIVATE, sent|wparam|lparam, 1, 0 },
4948 { HCBT_SETFOCUS, hook },
4955 { 0 }
4956};
4957
4959{
4960 /* nothing */
4961}
4962
4964{
4965 DWORD ret;
4966 MSG msg;
4967
4969 ok(ret == WAIT_TIMEOUT, "MsgWaitForMultipleObjects returned %x\n", ret);
4970
4971 PostMessageA(hwnd, WM_USER, 0, 0);
4972
4974 ok(ret == WAIT_OBJECT_0, "MsgWaitForMultipleObjects returned %x\n", ret);
4975
4976 ok(PeekMessageA( &msg, 0, 0, 0, PM_REMOVE ), "PeekMessage should succeed\n");
4977 ok(msg.message == WM_USER, "got %04x instead of WM_USER\n", msg.message);
4978
4980 ok(ret == WAIT_TIMEOUT, "MsgWaitForMultipleObjects returned %x\n", ret);
4981
4982 PostMessageA(hwnd, WM_USER, 0, 0);
4983
4985 ok(ret == WAIT_OBJECT_0, "MsgWaitForMultipleObjects returned %x\n", ret);
4986
4987 ok(PeekMessageA( &msg, 0, 0, 0, PM_NOREMOVE ), "PeekMessage should succeed\n");
4988 ok(msg.message == WM_USER, "got %04x instead of WM_USER\n", msg.message);
4989
4990 /* shows QS_POSTMESSAGE flag is cleared in the PeekMessage call */
4992 ok(ret == WAIT_TIMEOUT, "MsgWaitForMultipleObjects returned %x\n", ret);
4993
4994 PostMessageA(hwnd, WM_USER, 0, 0);
4995
4996 /* new incoming message causes it to become signaled again */
4998 ok(ret == WAIT_OBJECT_0, "MsgWaitForMultipleObjects returned %x\n", ret);
4999
5000 ok(PeekMessageA( &msg, 0, 0, 0, PM_REMOVE ), "PeekMessage should succeed\n");
5001 ok(msg.message == WM_USER, "got %04x instead of WM_USER\n", msg.message);
5002 ok(PeekMessageA( &msg, 0, 0, 0, PM_REMOVE ), "PeekMessage should succeed\n");
5003 ok(msg.message == WM_USER, "got %04x instead of WM_USER\n", msg.message);
5004
5005 /* MWMO_INPUTAVAILABLE should succeed even if the message was already seen */
5006 PostMessageA( hwnd, WM_USER, 0, 0 );
5007 ok(PeekMessageA( &msg, 0, 0, 0, PM_NOREMOVE ), "PeekMessage should succeed\n");
5008 ok(msg.message == WM_USER, "got %04x instead of WM_USER\n", msg.message);
5009
5011 ok(ret == WAIT_OBJECT_0, "MsgWaitForMultipleObjectsEx returned %x\n", ret);
5012
5013 ok(PeekMessageA( &msg, 0, 0, 0, PM_REMOVE ), "PeekMessage should succeed\n");
5014 ok(msg.message == WM_USER, "got %04x instead of WM_USER\n", msg.message);
5015
5016 /* without MWMO_ALERTABLE the result is never WAIT_IO_COMPLETION */
5018 ok(ret, "QueueUserAPC failed %u\n", GetLastError());
5019
5021 ok(ret == WAIT_TIMEOUT, "MsgWaitForMultipleObjectsEx returned %x\n", ret);
5022
5023 /* but even with MWMO_ALERTABLE window events are preferred */
5024 PostMessageA( hwnd, WM_USER, 0, 0 );
5025
5027 ok(ret == WAIT_OBJECT_0, "MsgWaitForMultipleObjectsEx returned %x\n", ret);
5028
5029 ok(PeekMessageA( &msg, 0, 0, 0, PM_REMOVE ), "PeekMessage should succeed\n");
5030 ok(msg.message == WM_USER, "got %04x instead of WM_USER\n", msg.message);
5031
5032 /* the APC call is still queued */
5034 ok(ret == WAIT_IO_COMPLETION, "MsgWaitForMultipleObjectsEx returned %x\n", ret);
5035}
5036
5038{
5039 DWORD ret;
5040 MSG msg;
5041 int i;
5042 static const WPARAM wparams[] = {0,
5049 DBT_CONFIGMGPRIVATE, /* 0x7fff */
5050 DBT_DEVICEARRIVAL, /* 0x8000 */
5057
5058 for (i = 0; i < ARRAY_SIZE(wparams); i++)
5059 {
5060 SetLastError(0xdeadbeef);
5061 ret = PostMessageA(hwnd, WM_DEVICECHANGE, wparams[i], 0);
5062 if (wparams[i] & 0x8000)
5063 {
5064 ok(ret == FALSE, "PostMessage should returned %d\n", ret);
5065 ok(GetLastError() == ERROR_MESSAGE_SYNC_ONLY, "PostMessage error %08x\n", GetLastError());
5066 }
5067 else
5068 {
5070 ok(ret == WAIT_OBJECT_0, "MsgWaitForMultipleObjects returned %x\n", ret);
5071 memset(&msg, 0, sizeof(msg));
5072 ok(PeekMessageA(&msg, 0, 0, 0, PM_REMOVE), "PeekMessage should succeed\n");
5073 ok(msg.message == WM_DEVICECHANGE, "got %04x instead of WM_DEVICECHANGE\n", msg.message);
5074 }
5075 }
5076}
5077
5079{
5080 HWND hwnd = arg;
5081
5082 /* function will not return if ShowWindow(SW_HIDE) calls SendMessage() */
5083 ok(ShowWindow(hwnd, SW_HIDE) == FALSE, "ShowWindow(SW_HIDE) expected FALSE\n");
5084
5085 return 0;
5086}
5087
5088/* Helper function to easier test SetWindowPos messages */
5089#define test_msg_setpos( expected_list, flags, todo ) \
5090 test_msg_setpos_( (expected_list), (flags), (todo), __FILE__, __LINE__)
5091static void test_msg_setpos_(const struct message *expected_list, UINT flags, BOOL todo, const char *file, int line)
5092{
5093 HWND hwnd;
5094
5095 flush_events();
5097 hwnd = CreateWindowExA(0, "TestWindowClass", "Test Popup", WS_POPUP,
5098 10, 10, 100, 100, NULL, 0, 0, NULL );
5099 ok (hwnd != 0, "Failed to create popup window\n");
5100 SetWindowPos(hwnd, NULL, 0, 0, 100, 100, flags);
5101 ok_sequence_(expected_list, "SetWindowPos:show_popup_first_show_window", todo, file, line);
5103}
5104
5105/* test if we receive the right sequence of messages */
5106static void test_messages(void)
5107{
5108 DWORD tid;
5109 HANDLE hthread;
5110 HWND hwnd, hparent, hchild;
5111 HWND hchild2, hbutton;
5112 HMENU hmenu;
5113 MSG msg;
5114 LRESULT res;
5115 POINT pos;
5116 BOOL ret;
5117
5119
5120 hwnd = CreateWindowExA(0, "TestWindowClass", "Test overlapped", WS_OVERLAPPEDWINDOW,
5121 100, 100, 200, 200, 0, 0, 0, NULL);
5122 ok (hwnd != 0, "Failed to create overlapped window\n");
5123 ok_sequence(WmCreateOverlappedSeq, "CreateWindow:overlapped", FALSE);
5124
5125 /* test ShowWindow(SW_HIDE) on a newly created invisible window */
5126 ok( ShowWindow(hwnd, SW_HIDE) == FALSE, "ShowWindow: window was visible\n" );
5127 ok_sequence(WmEmptySeq, "ShowWindow(SW_HIDE):overlapped, invisible", FALSE);
5128
5129 /* test WM_SETREDRAW on a not visible top level window */
5131
5133 flush_events();
5134 ok_sequence(WmSWP_ShowOverlappedSeq, "SetWindowPos:SWP_SHOWWINDOW:overlapped", FALSE);
5135 ok(IsWindowVisible(hwnd), "window should be visible at this point\n");
5136
5137 ok(GetActiveWindow() == hwnd, "window should be active\n");
5138 ok(GetFocus() == hwnd, "window should have input focus\n");
5140 flush_events();
5141 ok_sequence(WmHideOverlappedSeq, "ShowWindow(SW_HIDE):overlapped", FALSE);
5142
5143 /* test ShowWindow(SW_HIDE) on a hidden window - single threaded */
5144 ok(ShowWindow(hwnd, SW_HIDE) == FALSE, "ShowWindow(SW_HIDE) expected FALSE\n");
5145 flush_events();
5146 ok_sequence(WmEmptySeq, "ShowWindow(SW_HIDE):overlapped", FALSE);
5147
5148 /* test ShowWindow(SW_HIDE) on a hidden window - multi-threaded */
5149 hthread = CreateThread(NULL, 0, show_window_thread, hwnd, 0, &tid);
5150 ok(hthread != NULL, "CreateThread failed, error %d\n", GetLastError());
5151 ok(WaitForSingleObject(hthread, INFINITE) == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
5152 CloseHandle(hthread);
5153 flush_events();
5154 ok_sequence(WmEmptySeq, "ShowWindow(SW_HIDE):overlapped", FALSE);
5155
5157 flush_events();
5158 ok_sequence(WmShowOverlappedSeq, "ShowWindow(SW_SHOW):overlapped", TRUE);
5159
5161 flush_events();
5162 ok_sequence(WmHideOverlappedSeq, "ShowWindow(SW_HIDE):overlapped", FALSE);
5163
5165 flush_events();
5166 ok_sequence(WmShowMaxOverlappedSeq, "ShowWindow(SW_SHOWMAXIMIZED):overlapped", TRUE);
5168
5170 {
5172 flush_events();
5173 ok_sequence(WmShowRestoreMaxOverlappedSeq, "ShowWindow(SW_RESTORE):overlapped", TRUE);
5175 }
5176
5178 flush_events();
5179 ok_sequence(WmShowMinOverlappedSeq, "ShowWindow(SW_SHOWMINIMIZED):overlapped", FALSE);
5181
5183 {
5185 flush_events();
5186 ok_sequence(WmShowRestoreMinOverlappedSeq, "ShowWindow(SW_RESTORE):overlapped", TRUE);
5188 }
5189
5191 flush_events();
5192 ok_sequence(WmOptionalPaint, "ShowWindow(SW_SHOW):overlapped already visible", FALSE);
5193
5195 ok_sequence(WmSWP_HideOverlappedSeq, "SetWindowPos:SWP_HIDEWINDOW:overlapped", FALSE);
5196 ok(!IsWindowVisible(hwnd), "window should not be visible at this point\n");
5197 ok(GetActiveWindow() == hwnd, "window should still be active\n");
5198
5199 /* test WM_SETREDRAW on a visible top level window */
5201 flush_events();
5203
5204 trace("testing scroll APIs on a visible top level window %p\n", hwnd);
5206
5207 /* test resizing and moving */
5208 SetWindowPos( hwnd, 0, 0, 0, 300, 300, SWP_NOMOVE|SWP_NOACTIVATE );
5209 ok_sequence(WmSWP_ResizeSeq, "SetWindowPos:Resize", FALSE );
5210 flush_events();
5212 SetWindowPos( hwnd, 0, 200, 200, 0, 0, SWP_NOSIZE|SWP_NOACTIVATE );
5213 ok_sequence(WmSWP_MoveSeq, "SetWindowPos:Move", FALSE );
5214 flush_events();
5216 SetWindowPos( hwnd, 0, 200, 200, 250, 250, SWP_NOZORDER|SWP_NOACTIVATE );
5217 ok_sequence(WmSWP_ResizeNoZOrder, "SetWindowPos:WmSWP_ResizeNoZOrder", FALSE );
5218 flush_events();
5220
5221 /* popups don't get WM_GETMINMAXINFO */
5225 SetWindowPos( hwnd, 0, 0, 0, 200, 200, SWP_NOMOVE|SWP_NOACTIVATE );
5226 ok_sequence(WmSWP_ResizePopupSeq, "SetWindowPos:ResizePopup", FALSE );
5227
5229 ok_sequence(WmDestroyOverlappedSeq, "DestroyWindow:overlapped", FALSE);
5230
5231 /* Test if windows are correctly drawn when first shown */
5232
5233 /* Visible, redraw */
5234 flush_events();
5236 hwnd = CreateWindowExA(0, "TestWindowClass", "Test Popup", WS_POPUP | WS_VISIBLE,
5237 10, 10, 100, 100, NULL, 0, 0, NULL );
5238 ok (hwnd != 0, "Failed to create popup window\n");
5240 ok_sequence(WmShowPopupFirstDrawSeq_1, "RedrawWindow:show_popup_first_draw_visible", FALSE);
5242
5243 /* Invisible, show, message */
5244 flush_events();
5246 hwnd = CreateWindowExA(0, "TestWindowClass", "Test Popup", WS_POPUP,
5247 10, 10, 100, 100, NULL, 0, 0, NULL );
5248 ok (hwnd != 0, "Failed to create popup window\n");
5250 SendMessageW(hwnd, WM_PAINT, 0, 0);
5251 ok_sequence(WmShowPopupFirstDrawSeq_1, "RedrawWindow:show_popup_first_draw_show", FALSE);
5253
5254 /* Invisible, show maximized, redraw */
5255 flush_events();
5257 hwnd = CreateWindowExA(0, "TestWindowClass", "Test Popup", WS_POPUP,
5258 10, 10, 100, 100, NULL, 0, 0, NULL );
5259 ok (hwnd != 0, "Failed to create popup window\n");
5262 ok_sequence(WmShowPopupFirstDrawSeq_2, "RedrawWindow:show_popup_first_draw_show_maximized", FALSE);
5264
5265 /* Test SetWindowPos */
5270
5276
5283
5290
5297
5298 /* Test SetWindowPos with child windows */
5299 flush_events();
5300 hparent = CreateWindowExA(0, "TestParentClass", "Test parent", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
5301 100, 100, 200, 200, 0, 0, 0, NULL);
5302 ok (hparent != 0, "Failed to create parent window\n");
5303
5304 hchild = CreateWindowExA(0, "TestWindowClass", "Test child", WS_CHILD | WS_VISIBLE,
5305 0, 0, 10, 10, hparent, 0, 0, NULL);
5306 ok (hchild != 0, "Failed to create child window\n");
5308 SetWindowPos(hparent, NULL, 0, 0, 100, 100, SWP_SHOWWINDOW);
5309 ok_sequence(WmFirstDrawChildSeq1, /* Expect no messages for the child */
5310 "SetWindowPos:show_popup_first_show_window_child1", FALSE);
5311 DestroyWindow(hchild);
5312 DestroyWindow(hparent);
5313
5314 flush_events();
5315 hparent = CreateWindowExA(0, "TestParentClass", "Test parent", WS_OVERLAPPEDWINDOW | WS_VISIBLE | WS_CLIPCHILDREN,
5316 100, 100, 200, 200, 0, 0, 0, NULL);
5317 ok (hparent != 0, "Failed to create parent window\n");
5318
5319 hchild = CreateWindowExA(0, "TestWindowClass", "Test child", WS_CHILD | WS_VISIBLE,
5320 0, 0, 10, 10, hparent, 0, 0, NULL);
5321 ok (hchild != 0, "Failed to create child window\n");
5323 SetWindowPos(hparent, NULL, 0, 0, 100, 100, SWP_SHOWWINDOW);
5324 ok_sequence(WmFirstDrawChildSeq2, /* Expect child to be redrawn */
5325 "SetWindowPos:show_popup_first_show_window_child2", FALSE);
5326 DestroyWindow(hchild);
5327 DestroyWindow(hparent);
5328
5329 /* Test message sequence for extreme position and size */
5330
5332 hwnd = CreateWindowExA(0, "TestWindowClass", "Test Popup", WS_POPUP | WS_VISIBLE,
5333 -10, -10, 10000, 10000, NULL, 0, 0, NULL );
5334 ok (hwnd != 0, "Failed to create popup window\n");
5335 ok_sequence(WmShowPopupExtremeLocationSeq, "RedrawWindow:show_popup_extreme_location", FALSE);
5337
5338
5339 /* Test child windows */
5340
5341 hparent = CreateWindowExA(0, "TestParentClass", "Test parent", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
5342 100, 100, 200, 200, 0, 0, 0, NULL);
5343 ok (hparent != 0, "Failed to create parent window\n");
5345
5346 hchild = CreateWindowExA(0, "TestWindowClass", "Test child", WS_CHILD | WS_MAXIMIZE,
5347 0, 0, 10, 10, hparent, 0, 0, NULL);
5348 ok (hchild != 0, "Failed to create child window\n");
5349 ok_sequence(WmCreateMaximizedChildSeq, "CreateWindow:maximized child", FALSE);
5350 DestroyWindow(hchild);
5352
5353 /* visible child window with a caption */
5354 hchild = CreateWindowExA(0, "TestWindowClass", "Test child",
5356 0, 0, 10, 10, hparent, 0, 0, NULL);
5357 ok (hchild != 0, "Failed to create child window\n");
5358 ok_sequence(WmCreateVisibleChildSeq, "CreateWindow:visible child", FALSE);
5359
5360 trace("testing scroll APIs on a visible child window %p\n", hchild);
5361 test_scroll_messages(hchild);
5362
5364 ok_sequence(WmShowChildSeq_4, "SetWindowPos(SWP_SHOWWINDOW):child with a caption", FALSE);
5365
5366 DestroyWindow(hchild);
5368
5369 hchild = CreateWindowExA(0, "TestWindowClass", "Test child", WS_CHILD,
5370 0, 0, 10, 10, hparent, 0, 0, NULL);
5371 ok (hchild != 0, "Failed to create child window\n");
5372 ok_sequence(WmCreateChildSeq, "CreateWindow:child", FALSE);
5373
5374 hchild2 = CreateWindowExA(0, "SimpleWindowClass", "Test child2", WS_CHILD,
5375 100, 100, 50, 50, hparent, 0, 0, NULL);
5376 ok (hchild2 != 0, "Failed to create child2 window\n");
5378
5379 hbutton = CreateWindowExA(0, "TestWindowClass", "Test button", WS_CHILD,
5380 0, 100, 50, 50, hchild, 0, 0, NULL);
5381 ok (hbutton != 0, "Failed to create button window\n");
5382
5383 /* test WM_SETREDRAW on a not visible child window */
5384 test_WM_SETREDRAW(hchild);
5385
5386 ShowWindow(hchild, SW_SHOW);
5387 ok_sequence(WmShowChildSeq, "ShowWindow(SW_SHOW):child", FALSE);
5388
5389 /* check parent messages too */
5391 ShowWindow(hchild, SW_HIDE);
5392 ok_sequence(WmHideChildSeq2, "ShowWindow(SW_HIDE):child", FALSE);
5394
5395 ShowWindow(hchild, SW_SHOW);
5396 ok_sequence(WmShowChildSeq, "ShowWindow(SW_SHOW):child", FALSE);
5397
5398 ShowWindow(hchild, SW_HIDE);
5399 ok_sequence(WmHideChildSeq, "ShowWindow(SW_HIDE):child", FALSE);
5400
5401 ShowWindow(hchild, SW_SHOW);
5402 ok_sequence(WmShowChildSeq, "ShowWindow(SW_SHOW):child", FALSE);
5403
5404 /* test WM_SETREDRAW on a visible child window */
5405 test_WM_SETREDRAW(hchild);
5406
5408 MoveWindow(hchild, 10, 10, 20, 20, TRUE);
5411
5412 ShowWindow(hchild, SW_HIDE);
5415 ok_sequence(WmShowChildSeq_2, "SetWindowPos:show_child_2", FALSE);
5416
5417 ShowWindow(hchild, SW_HIDE);
5420 ok_sequence(WmShowChildSeq_3, "SetWindowPos:show_child_3", FALSE);
5421
5422 /* DestroyWindow sequence below expects that a child has focus */
5423 SetFocus(hchild);
5425
5426 DestroyWindow(hchild);
5427 ok_sequence(WmDestroyChildSeq, "DestroyWindow:child", FALSE);
5428 DestroyWindow(hchild2);
5429 DestroyWindow(hbutton);
5430
5432 hchild = CreateWindowExA(0, "TestWindowClass", "Test Child Popup", WS_CHILD | WS_POPUP,
5433 0, 0, 100, 100, hparent, 0, 0, NULL);
5434 ok (hchild != 0, "Failed to create child popup window\n");
5435 ok_sequence(WmCreateChildPopupSeq, "CreateWindow:child_popup", FALSE);
5436 DestroyWindow(hchild);
5437
5438 /* test what happens to a window which sets WS_VISIBLE in WM_CREATE */
5440 hchild = CreateWindowExA(0, "TestPopupClass", "Test Popup", WS_POPUP,
5441 0, 0, 100, 100, hparent, 0, 0, NULL);
5442 ok (hchild != 0, "Failed to create popup window\n");
5443 ok_sequence(WmCreateInvisiblePopupSeq, "CreateWindow:invisible_popup", FALSE);
5444 ok(GetWindowLongA(hchild, GWL_STYLE) & WS_VISIBLE, "WS_VISIBLE should be set\n");
5445 ok(IsWindowVisible(hchild), "IsWindowVisible() should return TRUE\n");
5447 ShowWindow(hchild, SW_SHOW);
5448 ok_sequence(WmEmptySeq, "ShowWindow:show_visible_popup", FALSE);
5451 ok_sequence(WmShowVisiblePopupSeq_2, "SetWindowPos:show_visible_popup_2", FALSE);
5454 ok_sequence(WmShowVisiblePopupSeq_3, "SetWindowPos:show_visible_popup_3", FALSE);
5455 DestroyWindow(hchild);
5456
5457 /* this time add WS_VISIBLE for CreateWindowEx, but this fact actually
5458 * changes nothing in message sequences.
5459 */
5461 hchild = CreateWindowExA(0, "TestPopupClass", "Test Popup", WS_POPUP | WS_VISIBLE,
5462 0, 0, 100, 100, hparent, 0, 0, NULL);
5463 ok (hchild != 0, "Failed to create popup window\n");
5464 ok_sequence(WmCreateInvisiblePopupSeq, "CreateWindow:invisible_popup", FALSE);
5465 ok(GetWindowLongA(hchild, GWL_STYLE) & WS_VISIBLE, "WS_VISIBLE should be set\n");
5466 ok(IsWindowVisible(hchild), "IsWindowVisible() should return TRUE\n");
5468 ShowWindow(hchild, SW_SHOW);
5469 ok_sequence(WmEmptySeq, "ShowWindow:show_visible_popup", FALSE);
5472 ok_sequence(WmShowVisiblePopupSeq_2, "SetWindowPos:show_visible_popup_2", FALSE);
5473 DestroyWindow(hchild);
5474
5477 0, 0, 100, 100, hparent, 0, 0, NULL);
5478 ok(hwnd != 0, "Failed to create custom dialog window\n");
5479 ok_sequence(WmCreateCustomDialogSeq, "CreateCustomDialog", TRUE);
5480
5481 if(0) {
5482 trace("testing scroll APIs on a visible dialog %p\n", hwnd);
5484 }
5485
5487
5488 test_def_id = TRUE;
5489 SendMessageA(hwnd, WM_NULL, 0, 0);
5490
5493 EndDialog( hwnd, 0 );
5494 ok_sequence(WmEndCustomDialogSeq, "EndCustomDialog", FALSE);
5495
5499
5500 ok(GetCursorPos(&pos), "GetCursorPos failed\n");
5501 ok(SetCursorPos(109, 109), "SetCursorPos failed\n");
5502
5503 hwnd = CreateWindowExA(0, "TestDialogClass", NULL, WS_POPUP|WS_CHILD,
5504 0, 0, 100, 100, 0, 0, GetModuleHandleA(0), NULL);
5505 ok(hwnd != 0, "Failed to create custom dialog window\n");
5507 trace("call ShowWindow(%p, SW_SHOW)\n", hwnd);
5509 ok_sequence(WmShowCustomDialogSeq, "ShowCustomDialog", TRUE);
5510
5511 flush_events();
5513 ret = DrawMenuBar(hwnd);
5514 ok(ret, "DrawMenuBar failed: %d\n", GetLastError());
5515 flush_events();
5516 ok_sequence(WmDrawMenuBarSeq, "DrawMenuBar", FALSE);
5517 ok(SetCursorPos(pos.x, pos.y), "SetCursorPos failed\n");
5518
5520
5521 hwnd = CreateWindowExA(0, "TestDialogClass", NULL, WS_CHILD|WS_VISIBLE,
5522 0, 0, 100, 100, hparent, 0, GetModuleHandleA(0), NULL);
5523 ok(hwnd != 0, "Failed to create custom dialog window\n");
5524 flush_events();
5526 ret = DrawMenuBar(hwnd);
5527 ok(ret, "DrawMenuBar failed: %d\n", GetLastError());
5528 flush_events();
5529 ok_sequence(WmEmptySeq, "DrawMenuBar for a child window", FALSE);
5530
5532
5534 DialogBoxA( 0, "TEST_DIALOG", hparent, TestModalDlgProcA );
5535 ok_sequence(WmModalDialogSeq, "ModalDialog", TRUE);
5536
5537 DestroyWindow(hparent);
5539
5540 /* Message sequence for SetMenu */
5541 ok(!DrawMenuBar(hwnd), "DrawMenuBar should return FALSE for a destroyed window\n");
5542 ok(GetLastError() == ERROR_INVALID_WINDOW_HANDLE, "last error is %d\n", GetLastError());
5543 ok_sequence(WmEmptySeq, "DrawMenuBar for a window without a menu", FALSE);
5544
5545 hmenu = CreateMenu();
5546 ok (hmenu != 0, "Failed to create menu\n");
5547 ok (InsertMenuA(hmenu, -1, MF_BYPOSITION, 0x1000, "foo"), "InsertMenu failed\n");
5548 hwnd = CreateWindowExA(0, "TestWindowClass", "Test overlapped", WS_OVERLAPPEDWINDOW,
5549 100, 100, 200, 200, 0, hmenu, 0, NULL);
5550 ok_sequence(WmCreateOverlappedSeq, "CreateWindow:overlapped", FALSE);
5551 ok (SetMenu(hwnd, 0), "SetMenu\n");
5552 ok_sequence(WmSetMenuNonVisibleSizeChangeSeq, "SetMenu:NonVisibleSizeChange", FALSE);
5553 ok (SetMenu(hwnd, 0), "SetMenu\n");
5554 ok_sequence(WmSetMenuNonVisibleNoSizeChangeSeq, "SetMenu:NonVisibleNoSizeChange", FALSE);
5556 UpdateWindow( hwnd );
5557 flush_events();
5559 ok (SetMenu(hwnd, 0), "SetMenu\n");
5560 ok_sequence(WmSetMenuVisibleNoSizeChangeSeq, "SetMenu:VisibleNoSizeChange", FALSE);
5561 ok (SetMenu(hwnd, hmenu), "SetMenu\n");
5562 ok_sequence(WmSetMenuVisibleSizeChangeSeq, "SetMenu:VisibleSizeChange", FALSE);
5563
5564 UpdateWindow( hwnd );
5565 flush_events();
5567 ok(DrawMenuBar(hwnd), "DrawMenuBar\n");
5568 flush_events();
5569 ok_sequence(WmDrawMenuBarSeq, "DrawMenuBar", FALSE);
5570
5573
5574 /* Message sequence for EnableWindow */
5575 hparent = CreateWindowExA(0, "TestWindowClass", "Test parent", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
5576 100, 100, 200, 200, 0, 0, 0, NULL);
5577 ok (hparent != 0, "Failed to create parent window\n");
5578 hchild = CreateWindowExA(0, "TestWindowClass", "Test child", WS_CHILD | WS_VISIBLE,
5579 0, 0, 10, 10, hparent, 0, 0, NULL);
5580 ok (hchild != 0, "Failed to create child window\n");
5581
5582 SetFocus(hchild);
5583 flush_events();
5585
5586 EnableWindow(hparent, FALSE);
5587 ok_sequence(WmEnableWindowSeq_1, "EnableWindow(FALSE)", FALSE);
5588
5589 EnableWindow(hparent, FALSE);
5590 ok_sequence(WmEnableWindowSeq_2, "EnableWindow(FALSE)", FALSE);
5591
5592 EnableWindow(hparent, TRUE);
5593 ok_sequence(WmEnableWindowSeq_3, "EnableWindow(TRUE)", FALSE);
5594
5595 EnableWindow(hparent, TRUE);
5596 ok_sequence(WmEnableWindowSeq_4, "EnableWindow(TRUE)", FALSE);
5597
5598 flush_events();
5600
5602 test_WM_DEVICECHANGE(hparent);
5603
5604 /* the following test causes an exception in user.exe under win9x */
5605 if (!PostMessageW( hparent, WM_USER, 0, 0 ))
5606 {
5607 DestroyWindow(hparent);
5609 return;
5610 }
5611 PostMessageW( hparent, WM_USER+1, 0, 0 );
5612 /* PeekMessage(NULL) fails, but still removes the message */
5613 SetLastError(0xdeadbeef);
5614 ok( !PeekMessageW( NULL, 0, 0, 0, PM_REMOVE ), "PeekMessage(NULL) should fail\n" );
5615 ok( GetLastError() == ERROR_NOACCESS || /* Win2k */
5616 GetLastError() == 0xdeadbeef, /* NT4 */
5617 "last error is %d\n", GetLastError() );
5618 ok( PeekMessageW( &msg, 0, 0, 0, PM_REMOVE ), "PeekMessage should succeed\n" );
5619 ok( msg.message == WM_USER+1, "got %x instead of WM_USER+1\n", msg.message );
5620
5621 DestroyWindow(hchild);
5622 DestroyWindow(hparent);
5624
5625 /* Message sequences for WM_SETICON */
5626 trace("testing WM_SETICON\n");
5627 hwnd = CreateWindowExA(0, "TestWindowClass", NULL, WS_OVERLAPPEDWINDOW,
5628 CW_USEDEFAULT, CW_USEDEFAULT, 300, 300, 0,
5629 NULL, NULL, 0);
5632 flush_events();
5635 ok_sequence(WmSetIcon_1, "WM_SETICON for shown window with caption", FALSE);
5636
5638 flush_events();
5641 ok_sequence(WmSetIcon_2, "WM_SETICON for hidden window with caption", FALSE);
5644
5645 hwnd = CreateWindowExA(0, "TestPopupClass", NULL, WS_POPUP,
5646 CW_USEDEFAULT, CW_USEDEFAULT, 300, 300, 0,
5647 NULL, NULL, 0);
5650 flush_events();
5653 ok_sequence(WmSetIcon_2, "WM_SETICON for shown window without caption", FALSE);
5654
5656 flush_events();
5659 ok_sequence(WmSetIcon_2, "WM_SETICON for hidden window without caption", FALSE);
5660
5662 res = SendMessageA(hwnd, 0x3B, 0x8000000b, 0);
5663 if (!res)
5664 {
5665 todo_wine win_skip( "Message 0x3b not supported\n" );
5666 goto done;
5667 }
5668 ok_sequence(WmInitEndSession, "Handling of undocumented 0x3B message by DefWindowProc wparam=0x8000000b", TRUE);
5669 ok(res == 1, "SendMessage(hwnd, 0x3B, 0x8000000b, 0) should have returned 1 instead of %ld\n", res);
5670 res = SendMessageA(hwnd, 0x3B, 0x0000000b, 0);
5671 ok_sequence(WmInitEndSession_2, "Handling of undocumented 0x3B message by DefWindowProc wparam=0x0000000b", TRUE);
5672 ok(res == 1, "SendMessage(hwnd, 0x3B, 0x0000000b, 0) should have returned 1 instead of %ld\n", res);
5673 res = SendMessageA(hwnd, 0x3B, 0x0000000f, 0);
5674 ok_sequence(WmInitEndSession_2, "Handling of undocumented 0x3B message by DefWindowProc wparam=0x0000000f", TRUE);
5675 ok(res == 1, "SendMessage(hwnd, 0x3B, 0x0000000f, 0) should have returned 1 instead of %ld\n", res);
5676
5678 res = SendMessageA(hwnd, 0x3B, 0x80000008, 0);
5679 ok_sequence(WmInitEndSession_3, "Handling of undocumented 0x3B message by DefWindowProc wparam=0x80000008", TRUE);
5680 ok(res == 2, "SendMessage(hwnd, 0x3B, 0x80000008, 0) should have returned 2 instead of %ld\n", res);
5681 res = SendMessageA(hwnd, 0x3B, 0x00000008, 0);
5682 ok_sequence(WmInitEndSession_4, "Handling of undocumented 0x3B message by DefWindowProc wparam=0x00000008", TRUE);
5683 ok(res == 2, "SendMessage(hwnd, 0x3B, 0x00000008, 0) should have returned 2 instead of %ld\n", res);
5684
5685 res = SendMessageA(hwnd, 0x3B, 0x80000004, 0);
5686 ok_sequence(WmInitEndSession_3, "Handling of undocumented 0x3B message by DefWindowProc wparam=0x80000004", TRUE);
5687 ok(res == 2, "SendMessage(hwnd, 0x3B, 0x80000004, 0) should have returned 2 instead of %ld\n", res);
5688
5689 res = SendMessageA(hwnd, 0x3B, 0x80000001, 0);
5690 ok_sequence(WmInitEndSession_5, "Handling of undocumented 0x3B message by DefWindowProc wparam=0x80000001", TRUE);
5691 ok(res == 2, "SendMessage(hwnd, 0x3B, 0x80000001, 0) should have returned 2 instead of %ld\n", res);
5692
5693done:
5696}
5697
5698static void test_setwindowpos(void)
5699{
5700 HWND hwnd;
5701 RECT rc;
5702 LRESULT res;
5703 const INT winX = 100;
5704 const INT winY = 100;
5705 const INT sysX = GetSystemMetrics(SM_CXMINTRACK);
5706
5707 hwnd = CreateWindowExA(0, "TestWindowClass", NULL, 0,
5708 0, 0, winX, winY, 0,
5709 NULL, NULL, 0);
5710
5711 GetWindowRect(hwnd, &rc);
5712 expect(sysX, rc.right);
5713 expect(winY, rc.bottom);
5714
5715 flush_events();
5717 res = SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, winX, winY, 0);
5718 ok_sequence(WmZOrder, "Z-Order", TRUE);
5719 ok(res == TRUE, "SetWindowPos expected TRUE, got %ld\n", res);
5720
5721 GetWindowRect(hwnd, &rc);
5722 expect(sysX, rc.right);
5723 expect(winY, rc.bottom);
5725}
5726
5727static void invisible_parent_tests(void)
5728{
5729 HWND hparent, hchild;
5730
5731 hparent = CreateWindowExA(0, "TestParentClass", "Test parent", WS_OVERLAPPEDWINDOW,
5732 100, 100, 200, 200, 0, 0, 0, NULL);
5733 ok (hparent != 0, "Failed to create parent window\n");
5735
5736 /* test showing child with hidden parent */
5737
5738 hchild = CreateWindowExA(0, "TestWindowClass", "Test child", WS_CHILD,
5739 0, 0, 10, 10, hparent, 0, 0, NULL);
5740 ok (hchild != 0, "Failed to create child window\n");
5741 ok_sequence(WmCreateChildSeq, "CreateWindow:child", FALSE);
5742
5743 ShowWindow( hchild, SW_MINIMIZE );
5744 ok_sequence(WmShowChildInvisibleParentSeq_1, "ShowWindow(SW_MINIMIZE) child with invisible parent", FALSE);
5745 ok(GetWindowLongA(hchild, GWL_STYLE) & WS_VISIBLE, "WS_VISIBLE should be set\n");
5746 ok(!IsWindowVisible(hchild), "IsWindowVisible() should return FALSE\n");
5747
5748 /* repeat */
5749 flush_events();
5751 ShowWindow( hchild, SW_MINIMIZE );
5752 ok_sequence(WmShowChildInvisibleParentSeq_1r, "ShowWindow(SW_MINIMIZE) child with invisible parent", FALSE);
5753
5754 DestroyWindow(hchild);
5755 hchild = CreateWindowExA(0, "TestWindowClass", "Test child", WS_CHILD,
5756 0, 0, 10, 10, hparent, 0, 0, NULL);
5758
5759 ShowWindow( hchild, SW_MAXIMIZE );
5760 ok_sequence(WmShowChildInvisibleParentSeq_2, "ShowWindow(SW_MAXIMIZE) child with invisible parent", FALSE);
5761 ok(GetWindowLongA(hchild, GWL_STYLE) & WS_VISIBLE, "WS_VISIBLE should be set\n");
5762 ok(!IsWindowVisible(hchild), "IsWindowVisible() should return FALSE\n");
5763
5764 /* repeat */
5765 flush_events();
5767 ShowWindow( hchild, SW_MAXIMIZE );
5768 ok_sequence(WmShowChildInvisibleParentSeq_2r, "ShowWindow(SW_MAXIMIZE) child with invisible parent", FALSE);
5769
5770 DestroyWindow(hchild);
5771 hchild = CreateWindowExA(0, "TestWindowClass", "Test child", WS_CHILD,
5772 0, 0, 10, 10, hparent, 0, 0, NULL);
5774
5775 ShowWindow( hchild, SW_RESTORE );
5776 ok_sequence(WmShowChildInvisibleParentSeq_5, "ShowWindow(SW_RESTORE) child with invisible parent", FALSE);
5777 ok(GetWindowLongA(hchild, GWL_STYLE) & WS_VISIBLE, "WS_VISIBLE should be set\n");
5778 ok(!IsWindowVisible(hchild), "IsWindowVisible() should return FALSE\n");
5779
5780 DestroyWindow(hchild);
5781 hchild = CreateWindowExA(0, "TestWindowClass", "Test child", WS_CHILD,
5782 0, 0, 10, 10, hparent, 0, 0, NULL);
5784
5785 ShowWindow( hchild, SW_SHOWMINIMIZED );
5786 ok_sequence(WmShowChildInvisibleParentSeq_3, "ShowWindow(SW_SHOWMINIMIZED) child with invisible parent", FALSE);
5787 ok(GetWindowLongA(hchild, GWL_STYLE) & WS_VISIBLE, "WS_VISIBLE should be set\n");
5788 ok(!IsWindowVisible(hchild), "IsWindowVisible() should return FALSE\n");
5789
5790 /* repeat */
5791 flush_events();
5793 ShowWindow( hchild, SW_SHOWMINIMIZED );
5794 ok_sequence(WmShowChildInvisibleParentSeq_3r, "ShowWindow(SW_SHOWMINIMIZED) child with invisible parent", FALSE);
5795
5796 DestroyWindow(hchild);
5797 hchild = CreateWindowExA(0, "TestWindowClass", "Test child", WS_CHILD,
5798 0, 0, 10, 10, hparent, 0, 0, NULL);
5800
5801 /* same as ShowWindow( hchild, SW_MAXIMIZE ); */
5802 ShowWindow( hchild, SW_SHOWMAXIMIZED );
5803 ok_sequence(WmShowChildInvisibleParentSeq_2, "ShowWindow(SW_SHOWMAXIMIZED) child with invisible parent", FALSE);
5804 ok(GetWindowLongA(hchild, GWL_STYLE) & WS_VISIBLE, "WS_VISIBLE should be set\n");
5805 ok(!IsWindowVisible(hchild), "IsWindowVisible() should return FALSE\n");
5806
5807 DestroyWindow(hchild);
5808 hchild = CreateWindowExA(0, "TestWindowClass", "Test child", WS_CHILD,
5809 0, 0, 10, 10, hparent, 0, 0, NULL);
5811
5812 ShowWindow( hchild, SW_SHOWMINNOACTIVE );
5813 ok_sequence(WmShowChildInvisibleParentSeq_4, "ShowWindow(SW_SHOWMINNOACTIVE) child with invisible parent", FALSE);
5814 ok(GetWindowLongA(hchild, GWL_STYLE) & WS_VISIBLE, "WS_VISIBLE should be set\n");
5815 ok(!IsWindowVisible(hchild), "IsWindowVisible() should return FALSE\n");
5816
5817 /* repeat */
5818 flush_events();
5820 ShowWindow( hchild, SW_SHOWMINNOACTIVE );
5821 ok_sequence(WmShowChildInvisibleParentSeq_4r, "ShowWindow(SW_SHOWMINNOACTIVE) child with invisible parent", FALSE);
5822
5823 DestroyWindow(hchild);
5824 hchild = CreateWindowExA(0, "TestWindowClass", "Test child", WS_CHILD,
5825 0, 0, 10, 10, hparent, 0, 0, NULL);
5827
5828 /* FIXME: looks like XP SP2 doesn't know about SW_FORCEMINIMIZE at all */
5829 ShowWindow( hchild, SW_FORCEMINIMIZE );
5830 ok_sequence(WmEmptySeq, "ShowWindow(SW_FORCEMINIMIZE) child with invisible parent", TRUE);
5831todo_wine {
5832 ok(!(GetWindowLongA(hchild, GWL_STYLE) & WS_VISIBLE), "WS_VISIBLE should be not set\n");
5833}
5834 ok(!IsWindowVisible(hchild), "IsWindowVisible() should return FALSE\n");
5835
5836 DestroyWindow(hchild);
5837 hchild = CreateWindowExA(0, "TestWindowClass", "Test child", WS_CHILD,
5838 0, 0, 10, 10, hparent, 0, 0, NULL);
5840
5841 ShowWindow( hchild, SW_SHOWNA );
5842 ok_sequence(WmShowChildInvisibleParentSeq_5, "ShowWindow(SW_SHOWNA) child with invisible parent", FALSE);
5843 ok(GetWindowLongA(hchild, GWL_STYLE) & WS_VISIBLE, "WS_VISIBLE should be set\n");
5844 ok(!IsWindowVisible(hchild), "IsWindowVisible() should return FALSE\n");
5845
5846 /* repeat */
5847 flush_events();
5849 ShowWindow( hchild, SW_SHOWNA );
5850 ok_sequence(WmShowChildInvisibleParentSeq_5, "ShowWindow(SW_SHOWNA) child with invisible parent", FALSE);
5851
5852 DestroyWindow(hchild);
5853 hchild = CreateWindowExA(0, "TestWindowClass", "Test child", WS_CHILD,
5854 0, 0, 10, 10, hparent, 0, 0, NULL);
5856
5857 ShowWindow( hchild, SW_SHOW );
5858 ok_sequence(WmShowChildInvisibleParentSeq_5, "ShowWindow(SW_SHOW) child with invisible parent", FALSE);
5859 ok(GetWindowLongA(hchild, GWL_STYLE) & WS_VISIBLE, "WS_VISIBLE should be set\n");
5860 ok(!IsWindowVisible(hchild), "IsWindowVisible() should return FALSE\n");
5861
5862 /* repeat */
5863 flush_events();
5865 ShowWindow( hchild, SW_SHOW );
5866 ok_sequence(WmEmptySeq, "ShowWindow(SW_SHOW) child with invisible parent", FALSE);
5867
5868 ShowWindow( hchild, SW_HIDE );
5869 ok_sequence(WmHideChildInvisibleParentSeq, "ShowWindow:hide child with invisible parent", FALSE);
5870 ok(!(GetWindowLongA(hchild, GWL_STYLE) & WS_VISIBLE), "WS_VISIBLE should be not set\n");
5871 ok(!IsWindowVisible(hchild), "IsWindowVisible() should return FALSE\n");
5872
5874 ok_sequence(WmShowChildInvisibleParentSeq_6, "SetWindowPos:show child with invisible parent", FALSE);
5875 ok(GetWindowLongA(hchild, GWL_STYLE) & WS_VISIBLE, "WS_VISIBLE should be set\n");
5876 ok(!IsWindowVisible(hchild), "IsWindowVisible() should return FALSE\n");
5877
5879 ok_sequence(WmHideChildInvisibleParentSeq_2, "SetWindowPos:hide child with invisible parent", FALSE);
5880 ok(!(GetWindowLongA(hchild, GWL_STYLE) & WS_VISIBLE), "WS_VISIBLE should not be set\n");
5881 ok(!IsWindowVisible(hchild), "IsWindowVisible() should return FALSE\n");
5882
5885 DestroyWindow(hchild);
5886 ok_sequence(WmDestroyInvisibleChildSeq, "DestroyInvisibleChildSeq", FALSE);
5887
5888 DestroyWindow(hparent);
5890}
5891
5892/****************** button message test *************************/
5893#define ID_BUTTON 0x000e
5894
5895static const struct message WmSetFocusButtonSeq[] =
5896{
5897 { HCBT_SETFOCUS, hook },
5900 { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
5901 { WM_SETFOCUS, sent|wparam, 0 },
5904 { WM_APP, sent|wparam|lparam, 0, 0 },
5905 { 0 }
5906};
5907static const struct message WmKillFocusButtonSeq[] =
5908{
5909 { HCBT_SETFOCUS, hook },
5910 { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
5911 { WM_KILLFOCUS, sent|wparam, 0 },
5916 { WM_APP, sent|wparam|lparam, 0, 0 },
5917 { WM_PAINT, sent },
5919 { 0 }
5920};
5921static const struct message WmSetFocusStaticSeq[] =
5922{
5923 { HCBT_SETFOCUS, hook },
5926 { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
5927 { WM_SETFOCUS, sent|wparam, 0 },
5931 { WM_APP, sent|wparam|lparam, 0, 0 },
5932 { 0 }
5933};
5934static const struct message WmKillFocusStaticSeq[] =
5935{
5936 { HCBT_SETFOCUS, hook },
5937 { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
5938 { WM_KILLFOCUS, sent|wparam, 0 },
5943 { WM_APP, sent|wparam|lparam, 0, 0 },
5944 { WM_PAINT, sent },
5946 { 0 }
5947};
5948static const struct message WmSetFocusOwnerdrawSeq[] =
5949{
5950 { HCBT_SETFOCUS, hook },
5953 { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
5954 { WM_SETFOCUS, sent|wparam, 0 },
5956 { WM_DRAWITEM, sent|wparam|lparam|parent, ID_BUTTON, 0x001040e4 },
5958 { WM_APP, sent|wparam|lparam, 0, 0 },
5959 { 0 }
5960};
5961static const struct message WmKillFocusOwnerdrawSeq[] =
5962{
5963 { HCBT_SETFOCUS, hook },
5964 { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
5965 { WM_KILLFOCUS, sent|wparam, 0 },
5967 { WM_DRAWITEM, sent|wparam|lparam|parent, ID_BUTTON, 0x000040e4 },
5971 { WM_APP, sent|wparam|lparam, 0, 0 },
5972 { WM_PAINT, sent },
5974 { WM_DRAWITEM, sent|wparam|lparam|parent, ID_BUTTON, 0x000010e4 },
5975 { 0 }
5976};
5977static const struct message WmLButtonDownSeq[] =
5978{
5979 { WM_LBUTTONDOWN, sent|wparam|lparam, 0, 0 },
5980 { EVENT_SYSTEM_CAPTURESTART, winevent_hook|wparam|lparam, 0, 0 },
5981 { HCBT_SETFOCUS, hook },
5984 { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
5989 { EVENT_OBJECT_STATECHANGE, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
5990 { 0 }
5991};
5992static const struct message WmLButtonDownStaticSeq[] =
5993{
5994 { WM_LBUTTONDOWN, sent|wparam|lparam, 0, 0 },
5995 { EVENT_SYSTEM_CAPTURESTART, winevent_hook|wparam|lparam, 0, 0 },
5996 { HCBT_SETFOCUS, hook },
5999 { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
6004 { EVENT_OBJECT_STATECHANGE, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
6005 { 0 }
6006};
6007static const struct message WmLButtonUpSeq[] =
6008{
6009 { WM_LBUTTONUP, sent|wparam|lparam, 0, 0 },
6012 { EVENT_OBJECT_STATECHANGE, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
6013 { EVENT_SYSTEM_CAPTUREEND, winevent_hook|wparam|lparam, 0, 0 },
6015 { 0 }
6016};
6017static const struct message WmLButtonUpStaticSeq[] =
6018{
6019 { WM_LBUTTONUP, sent|wparam|lparam, 0, 0 },
6022 { EVENT_OBJECT_STATECHANGE, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
6023 { EVENT_SYSTEM_CAPTUREEND, winevent_hook|wparam|lparam, 0, 0 },
6025 { 0 }
6026};
6027static const struct message WmLButtonUpAutoSeq[] =
6028{
6029 { WM_LBUTTONUP, sent|wparam|lparam, 0, 0 },
6032 { EVENT_OBJECT_STATECHANGE, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
6033 { EVENT_SYSTEM_CAPTUREEND, winevent_hook|wparam|lparam, 0, 0 },
6037 { 0 }
6038};
6039static const struct message WmLButtonUpBrokenSeq[] =
6040{
6041 { WM_LBUTTONUP, sent|wparam|lparam, 0, 0 },
6042 { 0 }
6043};
6044static const struct message WmSetFontButtonSeq[] =
6045{
6046 { WM_SETFONT, sent },
6047 { WM_PAINT, sent },
6050 { WM_CTLCOLORBTN, sent|defwinproc|optional }, /* FIXME: Wine sends it twice for BS_OWNERDRAW */
6051 { 0 }
6052};
6053static const struct message WmSetFontStaticSeq[] =
6054{
6055 { WM_SETFONT, sent },
6056 { WM_PAINT, sent },
6059 { 0 }
6060};
6061static const struct message WmSetTextButtonSeq[] =
6062{
6063 { WM_SETTEXT, sent },
6068 { 0 }
6069};
6070static const struct message WmSetTextStaticSeq[] =
6071{
6072 { WM_SETTEXT, sent },
6075 { 0 }
6076};
6077static const struct message WmSetTextGroupSeq[] =
6078{
6079 { WM_SETTEXT, sent },
6081 { WM_CTLCOLORSTATIC, sent|parent|optional }, /* FIXME: Missing in Wine */
6082 { WM_CTLCOLORSTATIC, sent|parent|optional }, /* FIXME: Missing in Wine */
6083 { 0 }
6084};
6085static const struct message WmSetTextInvisibleSeq[] =
6086{
6087 { WM_SETTEXT, sent },
6088 { 0 }
6089};
6090static const struct message WmSetStyleButtonSeq[] =
6091{
6092 { BM_SETSTYLE, sent },
6093 { WM_APP, sent|wparam|lparam, 0, 0 },
6094 { WM_PAINT, sent },
6095 { WM_NCPAINT, sent|defwinproc|optional }, /* FIXME: Wine sends it */
6096 { WM_ERASEBKGND, sent|defwinproc|optional }, /* Win9x doesn't send it */
6098 { 0 }
6099};
6100static const struct message WmSetStyleStaticSeq[] =
6101{
6102 { BM_SETSTYLE, sent },
6103 { WM_APP, sent|wparam|lparam, 0, 0 },
6104 { WM_PAINT, sent },
6105 { WM_NCPAINT, sent|defwinproc|optional }, /* FIXME: Wine sends it */
6106 { WM_ERASEBKGND, sent|defwinproc|optional }, /* Win9x doesn't send it */
6108 { 0 }
6109};
6110static const struct message WmSetStyleUserSeq[] =
6111{
6112 { BM_SETSTYLE, sent },
6113 { WM_APP, sent|wparam|lparam, 0, 0 },
6114 { WM_PAINT, sent },
6115 { WM_NCPAINT, sent|defwinproc|optional }, /* FIXME: Wine sends it */
6116 { WM_ERASEBKGND, sent|defwinproc|optional }, /* Win9x doesn't send it */
6119 { 0 }
6120};
6121static const struct message WmSetStyleOwnerdrawSeq[] =
6122{
6123 { BM_SETSTYLE, sent },
6124 { WM_APP, sent|wparam|lparam, 0, 0 },
6125 { WM_PAINT, sent },
6126 { WM_NCPAINT, sent|optional }, /* FIXME: Wine sends it */
6127 { WM_ERASEBKGND, sent|defwinproc|optional }, /* Win9x doesn't send it */
6129 { WM_CTLCOLORBTN, sent|parent|optional }, /* Win9x doesn't send it */
6130 { WM_DRAWITEM, sent|wparam|lparam|parent, ID_BUTTON, 0x000010e4 },
6131 { 0 }
6132};
6133static const struct message WmSetStateButtonSeq[] =
6134{
6135 { BM_SETSTATE, sent },
6137 { WM_APP, sent|wparam|lparam, 0, 0 },
6138 { 0 }
6139};
6140static const struct message WmSetStateStaticSeq[] =
6141{
6142 { BM_SETSTATE, sent },
6144 { WM_APP, sent|wparam|lparam, 0, 0 },
6145 { 0 }
6146};
6147static const struct message WmSetStateUserSeq[] =
6148{
6149 { BM_SETSTATE, sent },
6152 { WM_APP, sent|wparam|lparam, 0, 0 },
6153 { 0 }
6154};
6155static const struct message WmSetStateOwnerdrawSeq[] =
6156{
6157 { BM_SETSTATE, sent },
6159 { WM_DRAWITEM, sent|wparam|lparam|parent, ID_BUTTON, 0x000120e4 },
6160 { WM_APP, sent|wparam|lparam, 0, 0 },
6161 { 0 }
6162};
6163static const struct message WmClearStateButtonSeq[] =
6164{
6165 { BM_SETSTATE, sent },
6168 { WM_APP, sent|wparam|lparam, 0, 0 },
6169 { 0 }
6170};
6171static const struct message WmDisableButtonSeq[] =
6172{
6173 { WM_LBUTTONDOWN, sent },
6177 { WM_LBUTTONUP, sent },
6185 { WM_COMMAND, sent },
6186 { 0 }
6187};
6188static const struct message WmClearStateOwnerdrawSeq[] =
6189{
6190 { BM_SETSTATE, sent },
6192 { WM_DRAWITEM, sent|wparam|lparam|parent, ID_BUTTON, 0x000020e4 },
6193 { WM_APP, sent|wparam|lparam, 0, 0 },
6194 { 0 }
6195};
6196static const struct message WmSetCheckIgnoredSeq[] =
6197{
6198 { BM_SETCHECK, sent },
6199 { WM_APP, sent|wparam|lparam, 0, 0 },
6200 { 0 }
6201};
6202static const struct message WmSetCheckStaticSeq[] =
6203{
6204 { BM_SETCHECK, sent },
6206 { WM_APP, sent|wparam|lparam, 0, 0 },
6207 { 0 }
6208};
6209
6211
6213{
6214 static LONG defwndproc_counter = 0;
6215 LRESULT ret;
6216 struct recvd_message msg;
6217
6218 if (ignore_message( message )) return 0;
6219
6220 switch (message)
6221 {
6222 case WM_SYNCPAINT:
6223 break;
6224 case BM_SETSTATE:
6225 if (GetCapture())
6226 ok(GetCapture() == hwnd, "GetCapture() = %p\n", GetCapture());
6227
6229 goto log_it;
6230
6231 case WM_GETDLGCODE:
6232 if (lParam)
6233 {
6234 MSG *msg = (MSG *)lParam;
6235 lParam = MAKELPARAM(msg->message, msg->wParam);
6236 }
6238 goto log_it;
6239
6240 case BM_SETCHECK:
6241 case BM_GETCHECK:
6243 /* fall through */
6244log_it:
6245 default:
6246 msg.hwnd = hwnd;
6247 msg.message = message;
6248 msg.flags = sent|wparam|lparam;
6249 if (defwndproc_counter) msg.flags |= defwinproc;
6250 msg.wParam = wParam;
6251 msg.lParam = lParam;
6252 msg.descr = "button";
6253 add_message(&msg);
6254 }
6255
6256 defwndproc_counter++;
6258 defwndproc_counter--;
6259
6260 return ret;
6261}
6262
6263static void subclass_button(void)
6264{
6265 WNDCLASSA cls;
6266
6267 if (!GetClassInfoA(0, "button", &cls)) assert(0);
6268
6270
6273 cls.lpszClassName = "my_button_class";
6275 if (!RegisterClassA(&cls)) assert(0);
6276}
6277
6278static void test_button_messages(void)
6279{
6280 static const struct
6281 {
6282 DWORD style;
6283 DWORD dlg_code;
6284 const struct message *setfocus;
6285 const struct message *killfocus;
6286 const struct message *setstyle;
6287 const struct message *setstate;
6288 const struct message *clearstate;
6289 const struct message *setcheck;
6290 const struct message *lbuttondown;
6291 const struct message *lbuttonup;
6292 const struct message *setfont;
6293 const struct message *settext;
6294 } button[] = {
6343 NULL /* avoid infinite loop */, WmLButtonUpBrokenSeq, WmSetFontStaticSeq,
6350 };
6351 LOGFONTA logfont = { 0 };
6352 HFONT zfont, hfont2;
6353 unsigned int i;
6354 HWND hwnd, parent;
6355 DWORD dlg_code;
6356
6357 /* selection with VK_SPACE should capture button window */
6358 hwnd = CreateWindowExA(0, "button", "test", BS_CHECKBOX | WS_VISIBLE | WS_POPUP,
6359 0, 0, 50, 14, 0, 0, 0, NULL);
6360 ok(hwnd != 0, "Failed to create button window\n");
6362 SetFocus(hwnd);
6364 ok(GetCapture() == hwnd, "Should be captured on VK_SPACE WM_KEYDOWN\n");
6367
6369
6370 parent = CreateWindowExA(0, "TestParentClass", "Test parent", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
6371 100, 100, 200, 200, 0, 0, 0, NULL);
6372 ok(parent != 0, "Failed to create parent window\n");
6373
6374 memset(&logfont, 0, sizeof(logfont));
6375 logfont.lfHeight = -12;
6376 logfont.lfWeight = FW_NORMAL;
6377 strcpy(logfont.lfFaceName, "Tahoma");
6378
6379 hfont2 = CreateFontIndirectA(&logfont);
6380 ok(hfont2 != NULL, "Failed to create Tahoma font\n");
6381
6382 for (i = 0; i < ARRAY_SIZE(button); i++)
6383 {
6384 MSG msg;
6385 DWORD style, state;
6386 HFONT prevfont;
6387 char desc[64];
6388 HDC hdc;
6389
6390 trace("button style %08x\n", button[i].style);
6391
6392 hwnd = CreateWindowExA(0, "my_button_class", "test", button[i].style | WS_CHILD | BS_NOTIFY,
6393 0, 0, 50, 14, parent, (HMENU)ID_BUTTON, 0, NULL);
6394 ok(hwnd != 0, "Failed to create button window\n");
6395
6397 style &= ~(WS_CHILD | BS_NOTIFY);
6398 /* XP turns a BS_USERBUTTON into BS_PUSHBUTTON */
6399 if (button[i].style == BS_USERBUTTON)
6400 ok(style == BS_PUSHBUTTON, "expected style BS_PUSHBUTTON got %x\n", style);
6401 else
6402 ok(style == button[i].style, "expected style %x got %x\n", button[i].style, style);
6403
6404 dlg_code = SendMessageA(hwnd, WM_GETDLGCODE, 0, 0);
6405 ok(dlg_code == button[i].dlg_code, "%u: wrong dlg_code %08x\n", i, dlg_code);
6406
6409 SetFocus(0);
6410 flush_events();
6411 SetFocus(0);
6413
6415
6416 ok(GetFocus() == 0, "expected focus 0, got %p\n", GetFocus());
6417 SetFocus(hwnd);
6418 SendMessageA(hwnd, WM_APP, 0, 0); /* place a separator mark here */
6419 while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
6420 ok_sequence(button[i].setfocus, "SetFocus(hwnd) on a button", FALSE);
6421
6422 SetFocus(0);
6423 SendMessageA(hwnd, WM_APP, 0, 0); /* place a separator mark here */
6424 while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
6425 ok_sequence(button[i].killfocus, "SetFocus(0) on a button", FALSE);
6426
6427 ok(GetFocus() == 0, "expected focus 0, got %p\n", GetFocus());
6428
6430 SendMessageA(hwnd, WM_APP, 0, 0); /* place a separator mark here */
6431 while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
6432 ok_sequence(button[i].setstyle, "BM_SETSTYLE on a button", FALSE);
6433
6436 /* XP doesn't turn a BS_USERBUTTON into BS_PUSHBUTTON here! */
6437 ok(style == button[i].style, "expected style %04x got %04x\n", button[i].style, style);
6438
6440 ok(state == 0, "expected state 0, got %04x\n", state);
6441
6443
6445 SendMessageA(hwnd, WM_APP, 0, 0); /* place a separator mark here */
6446 while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
6447 ok_sequence(button[i].setstate, "BM_SETSTATE/TRUE on a button", FALSE);
6448
6450 ok(state == 0x0004, "expected state 0x0004, got %04x\n", state);
6451
6454 ok(style == button[i].style, "expected style %04x got %04x\n", button[i].style, style);
6455
6457
6459 SendMessageA(hwnd, WM_APP, 0, 0); /* place a separator mark here */
6460 while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
6461 ok_sequence(button[i].clearstate, "BM_SETSTATE/FALSE on a button", FALSE);
6462
6464 ok(state == 0, "expected state 0, got %04x\n", state);
6465
6468 ok(style == button[i].style, "expected style %04x got %04x\n", button[i].style, style);
6469
6471 ok(state == BST_UNCHECKED, "expected BST_UNCHECKED, got %04x\n", state);
6472
6474
6476 SendMessageA(hwnd, WM_APP, 0, 0); /* place a separator mark here */
6477 while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
6478 ok_sequence(WmSetCheckIgnoredSeq, "BM_SETCHECK on a button", FALSE);
6479
6481 ok(state == BST_UNCHECKED, "expected BST_UNCHECKED, got %04x\n", state);
6482
6485 ok(style == button[i].style, "expected style %04x got %04x\n", button[i].style, style);
6486
6488
6490 SendMessageA(hwnd, WM_APP, 0, 0); /* place a separator mark here */
6491 while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
6492 ok_sequence(button[i].setcheck, "BM_SETCHECK on a button", FALSE);
6493
6494 SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)"Text 1");
6495 sprintf(desc, "button[%i]: WM_SETTEXT on a visible button", i);
6496 ok_sequence(button[i].settext, desc, FALSE);
6497
6499 flush_events();
6501
6502 SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)"Text 2");
6503 sprintf(desc, "button[%i]: WM_SETTEXT on an invisible button", i);
6505
6508 flush_events();
6510
6511 SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)"Text 3");
6512 sprintf(desc, "button[%i]: WM_SETTEXT on an invisible button", i);
6514
6516 flush_events();
6517
6519 if (button[i].style == BS_PUSHBUTTON ||
6521 button[i].style == BS_GROUPBOX ||
6524 ok(state == BST_UNCHECKED, "expected check 0, got %04x\n", state);
6525 else
6526 ok(state == BST_CHECKED, "expected check 1, got %04x\n", state);
6527
6530 if (button[i].style == BS_RADIOBUTTON ||
6532 ok(style == (button[i].style | WS_TABSTOP), "expected style %04x | WS_TABSTOP got %04x\n", button[i].style, style);
6533 else
6534 ok(style == button[i].style, "expected style %04x got %04x\n", button[i].style, style);
6535
6537
6539
6540 hwnd = CreateWindowExA(0, "my_button_class", "test", button[i].style | WS_POPUP | WS_VISIBLE,
6541 0, 0, 50, 14, 0, 0, 0, NULL);
6542 ok(hwnd != 0, "Failed to create button window\n");
6543
6545 flush_events();
6546
6548 SetFocus(0);
6550
6551 if (button[i].lbuttondown)
6552 {
6554 sprintf(desc, "button[%i]: WM_LBUTTONDOWN on a button", i);
6555 ok_sequence(button[i].lbuttondown, desc, FALSE);
6556 }
6557
6559 sprintf(desc, "button[%i]: WM_LBUTTONUP on a button", i);
6560 ok_sequence(button[i].lbuttonup, desc, FALSE);
6561
6566 sprintf(desc, "button[%i]: WM_SETFONT on a button", i);
6567 ok_sequence(button[i].setfont, desc, FALSE);
6568
6569 /* Test that original font is not selected back after painting */
6571
6572 prevfont = SelectObject(hdc, hfont2);
6573 ok(prevfont == GetStockObject(SYSTEM_FONT), "Unexpected default font\n");
6575 ok(hfont2 != GetCurrentObject(hdc, OBJ_FONT), "button[%u]: unexpected font selected after WM_PRINTCLIENT\n", i);
6576 SelectObject(hdc, prevfont);
6577
6578 prevfont = SelectObject(hdc, hfont2);
6579 ok(prevfont == GetStockObject(SYSTEM_FONT), "Unexpected default font\n");
6581 ok(hfont2 != GetCurrentObject(hdc, OBJ_FONT), "button[%u]: unexpected font selected after WM_PAINT\n", i);
6582 SelectObject(hdc, prevfont);
6583
6584 DeleteDC(hdc);
6585
6587 }
6588
6589 DeleteObject(hfont2);
6591
6592 /* Test if WM_LBUTTONDOWN and WM_LBUTTONUP to a disabled button leads to a WM_COMMAND for the parent */
6593
6594 parent = CreateWindowExA(0, "TestWindowClass", "Test overlapped", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
6595 100, 100, 200, 200, 0, 0, 0, NULL);
6596 ok (hwnd != 0, "Failed to create overlapped window\n");
6597
6598 hwnd = CreateWindowExA(0, "my_button_class", "test", BS_DEFPUSHBUTTON | WS_VISIBLE | WS_CHILD,
6599 0, 0, 50, 14, parent, 0, 0, NULL);
6600
6605 ok_sequence(WmDisableButtonSeq, "Mouseclick on a disabled button", FALSE);
6606
6609}
6610
6612{
6613 HWND hwnd;
6614 HDC hdc;
6615 HBITMAP hbmp1x1;
6616 HBITMAP hbmp2x2;
6617 HBITMAP hmask2x2;
6618 ICONINFO icon_info2x2;
6619 HICON hicon2x2;
6620 HBITMAP hbmp;
6621 HICON hicon;
6622 ICONINFO icon_info;
6623 BITMAP bm;
6624 DWORD default_style = BS_PUSHBUTTON | WS_TABSTOP | WS_POPUP | WS_VISIBLE;
6625 LRESULT ret;
6626
6627 hdc = GetDC(0);
6628 hbmp1x1 = CreateCompatibleBitmap(hdc, 1, 1);
6629 hbmp2x2 = CreateCompatibleBitmap(hdc, 2, 2);
6630 ZeroMemory(&bm, sizeof(bm));
6631 ok(GetObjectW(hbmp1x1, sizeof(bm), &bm), "Expect GetObjectW() success\n");
6632 ok(bm.bmWidth == 1 && bm.bmHeight == 1, "Expect bitmap size: %d,%d, got: %d,%d\n", 1, 1,
6633 bm.bmWidth, bm.bmHeight);
6634 ZeroMemory(&bm, sizeof(bm));
6635 ok(GetObjectW(hbmp2x2, sizeof(bm), &bm), "Expect GetObjectW() success\n");
6636 ok(bm.bmWidth == 2 && bm.bmHeight == 2, "Expect bitmap size: %d,%d, got: %d,%d\n", 2, 2,
6637 bm.bmWidth, bm.bmHeight);
6638
6639 hmask2x2 = CreateCompatibleBitmap(hdc, 2, 2);
6640 ZeroMemory(&icon_info2x2, sizeof(icon_info2x2));
6641 icon_info2x2.fIcon = TRUE;
6642 icon_info2x2.hbmMask = hmask2x2;
6643 icon_info2x2.hbmColor = hbmp2x2;
6644 hicon2x2 = CreateIconIndirect(&icon_info2x2);
6645
6646 ZeroMemory(&icon_info, sizeof(icon_info));
6647 ok(GetIconInfo(hicon2x2, &icon_info), "Expect GetIconInfo() success\n");
6648 ZeroMemory(&bm, sizeof(bm));
6649 ok(GetObjectW(icon_info.hbmColor, sizeof(bm), &bm), "Expect GetObjectW() success\n");
6650 ok(bm.bmWidth == 2 && bm.bmHeight == 2, "Expect bitmap size: %d,%d, got: %d,%d\n", 2, 2,
6651 bm.bmWidth, bm.bmHeight);
6652 DeleteObject(icon_info.hbmColor);
6653 DeleteObject(icon_info.hbmMask);
6654
6655 /* Set bitmap with BS_BITMAP */
6656 hwnd = CreateWindowA("Button", "test", default_style | BS_BITMAP, 0, 0, 100, 100, 0, 0, 0, 0);
6657 ok(hwnd != NULL, "Expect hwnd not NULL\n");
6660 ok(hbmp != 0, "Expect hbmp not 0\n");
6661 ZeroMemory(&bm, sizeof(bm));
6662 ok(GetObjectW(hbmp, sizeof(bm), &bm), "Expect GetObjectW() success\n");
6663 ok(bm.bmWidth == 1 && bm.bmHeight == 1, "Expect bitmap size: %d,%d, got: %d,%d\n", 1, 1,
6664 bm.bmWidth, bm.bmHeight);
6666
6667 /* Set bitmap without BS_BITMAP */
6668 hwnd = CreateWindowA("Button", "test", default_style, 0, 0, 100, 100, 0, 0, 0, 0);
6669 ok(hwnd != NULL, "Expect hwnd not NULL\n");
6671 ok(ret == 0, "Expect ret to be 0\n");
6673 ok(hbmp == NULL, "Expect hbmp to be NULL\n");
6675
6676 /* Set icon with BS_ICON */
6677 hwnd = CreateWindowA("Button", "test", default_style | BS_ICON, 0, 0, 100, 100, 0, 0, 0, 0);
6678 ok(hwnd != NULL, "Expect hwnd not NULL\n");
6681 ok(hicon != NULL, "Expect hicon not NULL\n");
6682 ZeroMemory(&icon_info, sizeof(icon_info));
6683 ok(GetIconInfo(hicon, &icon_info), "Expect GetIconInfo() success\n");
6684 ZeroMemory(&bm, sizeof(bm));
6685 ok(GetObjectW(icon_info.hbmColor, sizeof(bm), &bm), "Expect GetObjectW() success\n");
6686 ok(bm.bmWidth == 2 && bm.bmHeight == 2, "Expect bitmap size: %d,%d, got: %d,%d\n", 2, 2,
6687 bm.bmWidth, bm.bmHeight);
6688 DeleteObject(icon_info.hbmColor);
6689 DeleteObject(icon_info.hbmMask);
6691
6692 /* Set icon without BS_ICON */
6693 hwnd = CreateWindowA("Button", "test", default_style, 0, 0, 100, 100, 0, 0, 0, 0);
6694 ok(hwnd != NULL, "Expect hwnd not NULL\n");
6696 ok(ret == 0, "Expect ret to be 0\n");
6698 ok(hicon == NULL, "Expect hicon to be NULL\n");
6700
6701 /* Set icon with BS_BITMAP */
6702 hwnd = CreateWindowA("Button", "test", default_style | BS_BITMAP, 0, 0, 100, 100, 0, 0, 0, 0);
6703 ok(hwnd != NULL, "Expect hwnd to be not NULL\n");
6705 ok(ret == 0, "Expect ret to be 0\n");
6707 ok(hicon == NULL, "Expect hicon to be NULL\n");
6709
6710 /* Set bitmap with BS_ICON */
6711 hwnd = CreateWindowA("Button", "test", default_style | BS_ICON, 0, 0, 100, 100, 0, 0, 0, 0);
6712 ok(hwnd != NULL, "Expect hwnd to be not NULL\n");
6714 ok(ret == 0, "Expect ret to be 0\n");
6716 ok(hbmp == NULL, "Expect hbmp to be NULL\n");
6718
6719 DestroyIcon(hicon2x2);
6720 DeleteObject(hmask2x2);
6721 DeleteObject(hbmp2x2);
6722 DeleteObject(hbmp1x1);
6723 ReleaseDC(0, hdc);
6724}
6725
6726#define ID_RADIO1 501
6727#define ID_RADIO2 502
6728#define ID_RADIO3 503
6729#define ID_TEXT 504
6730
6732{
6733 { BM_CLICK, sent|wparam|lparam, 0, 0 },
6735 { EVENT_SYSTEM_CAPTURESTART, winevent_hook|wparam|lparam, 0, 0 },
6738 { EVENT_OBJECT_STATECHANGE, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
6742 { EVENT_OBJECT_STATECHANGE, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
6748 { EVENT_OBJECT_STATECHANGE, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
6752 { EVENT_OBJECT_STATECHANGE, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
6754 { EVENT_SYSTEM_CAPTUREEND, winevent_hook|wparam|lparam, 0, 0 },
6757 { WM_NCHITTEST, sent|optional, 0, 0 }, /* FIXME: Wine doesn't send it */
6758 { WM_SETCURSOR, sent|optional, 0, 0 }, /* FIXME: Wine doesn't send it */
6759 { WM_MOUSEMOVE, sent|optional, 0, 0 }, /* FIXME: Wine doesn't send it */
6760 { 0 }
6761};
6762
6764{
6766 { WM_KEYUP, sent|wparam|lparam, VK_UP, 0 },
6767 { 0 }
6768};
6769
6771{
6774 { 0 }
6775};
6776
6778{
6779 { WM_GETDLGCODE, sent|parent, 0, 0 },
6780
6781 /* optional trailer seen on some windows setups */
6782 { WM_CHANGEUISTATE, sent|optional },
6783 { WM_UPDATEUISTATE, sent|optional },
6784 { WM_UPDATEUISTATE, sent|optional },
6785 { WM_UPDATEUISTATE, sent|optional },
6786 { WM_UPDATEUISTATE, sent|optional },
6787 { WM_UPDATEUISTATE, sent|optional },
6788 { WM_UPDATEUISTATE, sent|optional },
6789 { WM_UPDATEUISTATE, sent|optional },
6790 { WM_UPDATEUISTATE, sent|optional },
6791 { WM_UPDATEUISTATE, sent|optional },
6792 { WM_UPDATEUISTATE, sent|optional },
6793 { WM_UPDATEUISTATE, sent|optional },
6794 { WM_UPDATEUISTATE, sent|optional },
6795 { WM_UPDATEUISTATE, sent|optional },
6796 { WM_UPDATEUISTATE, sent|optional },
6797 { WM_UPDATEUISTATE, sent|optional },
6798 { WM_UPDATEUISTATE, sent|optional },
6799 { WM_UPDATEUISTATE, sent|optional },
6800 { WM_UPDATEUISTATE, sent|optional },
6804 { WM_UPDATEUISTATE, sent|optional },
6807 { WM_UPDATEUISTATE, sent|optional },
6810 { WM_UPDATEUISTATE, sent|optional },
6813 { 0 }
6814};
6815
6817{
6818 { WM_GETDLGCODE, sent|parent, 0, 0 },
6821 { HCBT_SETFOCUS, hook },
6822 { WM_KILLFOCUS, sent, 0, 0 },
6825 { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
6826 { WM_SETFOCUS, sent, 0, 0 },
6831 { WM_GETDLGCODE, sent|parent, 0, 0 },
6832 { DM_GETDEFID, sent|parent, 0, 0 },
6834 { BM_CLICK, sent|wparam|lparam, 1, 0 },
6836 { EVENT_SYSTEM_CAPTURESTART, winevent_hook|wparam|lparam, 0, 0 },
6839 { EVENT_OBJECT_STATECHANGE, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
6843 { EVENT_OBJECT_STATECHANGE, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
6847 { EVENT_OBJECT_STATECHANGE, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
6851 { EVENT_OBJECT_STATECHANGE, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
6856 { EVENT_OBJECT_STATECHANGE, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
6857 { EVENT_SYSTEM_CAPTUREEND, winevent_hook|wparam|lparam, 0, 0 },
6860 { WM_NCHITTEST, sent|optional, 0, 0 }, /* FIXME: Wine doesn't send it */
6861 { WM_SETCURSOR, sent|optional, 0, 0 }, /* FIXME: Wine doesn't send it */
6862 { WM_MOUSEMOVE, sent|optional, 0, 0 }, /* FIXME: Wine doesn't send it */
6863 { WM_PAINT, sent },
6865 { 0 }
6866};
6867
6869{
6873 { WM_GETDLGCODE, sent|parent, 0, 0 },
6878 { WM_USER, sent|parent, 0, 0 },
6880 { 0 }
6881};
6882
6884{
6885 { WM_GETDLGCODE, sent|parent, 0, 0 },
6886 { 0 }
6887};
6888
6890{
6891 ParentMsgCheckProcA(hwnd, msg, wp, lp);
6892 return 1;
6893}
6894
6896{
6897 HWND parent, radio1, radio2, radio3;
6898 RECT rc;
6899 MSG msg;
6900 DWORD ret;
6901
6903
6904 parent = CreateDialogParamA(0, "AUTORADIO_TEST_DIALOG_1", 0, radio_test_dlg_proc, 0);
6905 ok(parent != 0, "failed to create parent window\n");
6906
6907 radio1 = GetDlgItem(parent, ID_RADIO1);
6908 radio2 = GetDlgItem(parent, ID_RADIO2);
6909 radio3 = GetDlgItem(parent, ID_RADIO3);
6910
6911 /* this avoids focus messages in the generated sequence */
6912 SetFocus(radio2);
6913
6914 flush_events();
6916
6917 ret = SendMessageA(radio1, BM_GETCHECK, 0, 0);
6918 ok(ret == BST_UNCHECKED, "got %08x\n", ret);
6919 ret = SendMessageA(radio2, BM_GETCHECK, 0, 0);
6920 ok(ret == BST_UNCHECKED, "got %08x\n", ret);
6921 ret = SendMessageA(radio3, BM_GETCHECK, 0, 0);
6922 ok(ret == BST_UNCHECKED, "got %08x\n", ret);
6923
6925
6926 ret = SendMessageA(radio1, BM_GETCHECK, 0, 0);
6927 ok(ret == BST_CHECKED, "got %08x\n", ret);
6928 ret = SendMessageA(radio2, BM_GETCHECK, 0, 0);
6929 ok(ret == BST_UNCHECKED, "got %08x\n", ret);
6930 ret = SendMessageA(radio3, BM_GETCHECK, 0, 0);
6931 ok(ret == BST_UNCHECKED, "got %08x\n", ret);
6932
6934
6935 ret = SendMessageA(radio1, BM_GETCHECK, 0, 0);
6936 ok(ret == BST_CHECKED, "got %08x\n", ret);
6937 ret = SendMessageA(radio2, BM_GETCHECK, 0, 0);
6938 ok(ret == BST_CHECKED, "got %08x\n", ret);
6939 ret = SendMessageA(radio3, BM_GETCHECK, 0, 0);
6940 ok(ret == BST_UNCHECKED, "got %08x\n", ret);
6941
6943
6944 ret = SendMessageA(radio1, BM_GETCHECK, 0, 0);
6945 ok(ret == BST_CHECKED, "got %08x\n", ret);
6946 ret = SendMessageA(radio2, BM_GETCHECK, 0, 0);
6947 ok(ret == BST_CHECKED, "got %08x\n", ret);
6948 ret = SendMessageA(radio3, BM_GETCHECK, 0, 0);
6949 ok(ret == BST_CHECKED, "got %08x\n", ret);
6950
6951 GetWindowRect(radio2, &rc);
6952 SetCursorPos(rc.left+1, rc.top+1);
6953
6954 flush_events();
6956
6958
6959 SendMessageA(radio2, BM_CLICK, 0, 0);
6960 while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
6961 ok_sequence(auto_radio_button_BM_CLICK, "BM_CLICK on auto-radio button", FALSE);
6962
6964
6965 ret = SendMessageA(radio1, BM_GETCHECK, 0, 0);
6966 ok(ret == BST_UNCHECKED, "got %08x\n", ret);
6967 ret = SendMessageA(radio2, BM_GETCHECK, 0, 0);
6968 ok(ret == BST_CHECKED, "got %08x\n", ret);
6969 ret = SendMessageA(radio3, BM_GETCHECK, 0, 0);
6970 ok(ret == BST_UNCHECKED, "got %08x\n", ret);
6971
6973}
6974
6975#define test_radio(r1, s1, r2, s2, r3, s3) test_radio_dbg(r1, s1, r2, s2, r3, s3, __LINE__)
6976static void test_radio_dbg(HWND radio1, int state1, HWND radio2, int state2, HWND radio3, int state3, int line)
6977{
6978 DWORD ret;
6979
6980 ret = SendMessageA(radio1, BM_GETCHECK, 0, 0);
6981 ok_(__FILE__,line)(ret == state1 ? BST_CHECKED : BST_UNCHECKED, "got %08x\n", ret);
6982 ret = SendMessageA(radio2, BM_GETCHECK, 0, 0);
6983 ok_(__FILE__,line)(ret == state2 ? BST_CHECKED : BST_UNCHECKED, "got %08x\n", ret);
6984 ret = SendMessageA(radio3, BM_GETCHECK, 0, 0);
6985 ok_(__FILE__,line)(ret == state3 ? BST_CHECKED : BST_UNCHECKED, "got %08x\n", ret);
6986}
6987
6988static void set_radio(HWND radio1, int state1, HWND radio2, int state2, HWND radio3, int state3)
6989{
6990 SendMessageA(radio1, BM_SETCHECK, state1 ? BST_CHECKED : BST_UNCHECKED, 0);
6991 SendMessageA(radio2, BM_SETCHECK, state2 ? BST_CHECKED : BST_UNCHECKED, 0);
6992 SendMessageA(radio3, BM_SETCHECK, state3 ? BST_CHECKED : BST_UNCHECKED, 0);
6993}
6994
6996{
6997 HWND parent, radio1, radio2, radio3, hwnd;
6998 RECT rc;
6999 MSG msg;
7000 DWORD ret;
7001
7003
7004 parent = CreateDialogParamA(0, "AUTORADIO_TEST_DIALOG_2", 0, radio_test_dlg_proc, 0);
7005 ok(parent != 0, "failed to create parent window\n");
7006
7007 radio1 = GetDlgItem(parent, ID_RADIO1);
7008 radio2 = GetDlgItem(parent, ID_RADIO2);
7009 radio3 = GetDlgItem(parent, ID_RADIO3);
7010
7011 flush_events();
7013
7014 test_radio(radio1, 0, radio2, 0, radio3, 0);
7015 set_radio(radio1, 1, radio2, 1, radio3, 1);
7016 test_radio(radio1, 1, radio2, 1, radio3, 1);
7017
7018 SetFocus(radio3);
7019
7020 flush_events();
7022
7024
7025 SendMessageA(radio3, WM_KEYDOWN, VK_UP, 0);
7026 SendMessageA(radio3, WM_KEYUP, VK_UP, 0);
7027 while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
7028 ok_sequence(auto_radio_button_VK_UP_child, "press/release VK_UP on auto-radio button", FALSE);
7029
7030 test_radio(radio1, 1, radio2, 1, radio3, 1);
7031
7032 flush_events();
7034
7037 while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
7038 ok_sequence(auto_radio_button_VK_UP_parent, "press/release VK_UP on dialog", FALSE);
7039
7040 test_radio(radio1, 1, radio2, 1, radio3, 1);
7041
7042 SetFocus(radio3);
7043 GetWindowRect(radio3, &rc);
7044
7045 flush_events();
7047
7048 msg.hwnd = parent;
7049 msg.message = WM_KEYDOWN;
7050 msg.wParam = VK_UP;
7051 msg.lParam = 0;
7052 msg.pt.x = rc.left + 1;
7053 msg.pt.y = rc.top + 1;
7055 ok(ret, "IsDialogMessage should return TRUE\n");
7056 while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
7057if (0) /* actual message sequence is different on every run in some Windows setups */
7058 ok_sequence(auto_radio_button_VK_UP_dialog, "IsDialogMessage(VK_UP) #1", FALSE);
7059 /* what really matters is that nothing has changed */
7060 test_radio(radio1, 1, radio2, 1, radio3, 1);
7061
7062 set_radio(radio1, 0, radio2, 1, radio3, 1);
7063 test_radio(radio1, 0, radio2, 1, radio3, 1);
7064
7065 flush_events();
7067
7069 ok(ret, "IsDialogMessage should return TRUE\n");
7070 while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
7071if (0) /* actual message sequence is different on every run in some Windows setups */
7072 ok_sequence(auto_radio_button_VK_UP_dialog, "IsDialogMessage(VK_UP) #2", FALSE);
7073 /* what really matters is that nothing has changed */
7074 test_radio(radio1, 0, radio2, 1, radio3, 1);
7075
7076 /* switch from radio3 ro radio1 */
7077 SetFocus(radio3);
7078 GetWindowRect(radio3, &rc);
7079
7080 flush_events();
7082
7083 msg.hwnd = parent;
7084 msg.message = WM_KEYDOWN;
7085 msg.wParam = VK_DOWN;
7086 msg.lParam = 0;
7087 msg.pt.x = rc.left + 1;
7088 msg.pt.y = rc.top + 1;
7090 ok(ret, "IsDialogMessage should return TRUE\n");
7091 while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
7092 ok_sequence(auto_radio_button_VK_DOWN_dialog, "IsDialogMessage(VK_DOWN)", TRUE);
7093
7094 test_radio(radio1, 1, radio2, 0, radio3, 0);
7095
7096 hwnd = GetFocus();
7097 ok(hwnd == radio1, "focus should be on radio1, not on %p\n", hwnd);
7098 GetWindowRect(radio1, &rc);
7099
7100 msg.hwnd = parent;
7101 msg.message = WM_KEYDOWN;
7102 msg.wParam = VK_DOWN;
7103 msg.lParam = 0;
7104 msg.pt.x = rc.left + 1;
7105 msg.pt.y = rc.top + 1;
7107 ok(ret, "IsDialogMessage should return TRUE\n");
7108 while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
7110
7111 test_radio(radio1, 1, radio2, 0, radio3, 0);
7112
7113 hwnd = GetFocus();
7114 ok(hwnd == radio1, "focus should be on radio1, not on %p\n", hwnd);
7115
7116 flush_events();
7118
7119 msg.hwnd = parent;
7120 msg.message = WM_KEYDOWN;
7121 msg.wParam = VK_UP;
7122 msg.lParam = 0;
7123 msg.pt.x = rc.left + 1;
7124 msg.pt.y = rc.top + 1;
7126 ok(ret, "IsDialogMessage should return TRUE\n");
7127 while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
7129
7130 test_radio(radio1, 1, radio2, 0, radio3, 0);
7131
7132 hwnd = GetFocus();
7133 ok(hwnd == radio1, "focus should be on radio1, not on %p\n", hwnd);
7134
7135 flush_events();
7137
7138 msg.hwnd = parent;
7139 msg.message = WM_KEYDOWN;
7140 msg.wParam = VK_UP;
7141 msg.lParam = 0;
7142 msg.pt.x = rc.left + 1;
7143 msg.pt.y = rc.top + 1;
7145 ok(ret, "IsDialogMessage should return TRUE\n");
7146 while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
7147if (0) /* actual message sequence is different on every run in some Windows setups */
7148 ok_sequence(auto_radio_button_VK_UP_dialog, "IsDialogMessage(VK_UP) #3", FALSE);
7149 /* what really matters is that nothing has changed */
7150 test_radio(radio1, 1, radio2, 0, radio3, 0);
7151
7153
7155}
7156
7157/****************** static message test *************************/
7158static const struct message WmSetFontStaticSeq2[] =
7159{
7160 { WM_SETFONT, sent },
7164 { 0 }
7165};
7166
7168
7170{
7171 static LONG defwndproc_counter = 0;
7172 LRESULT ret;
7173 struct recvd_message msg;
7174
7175 if (ignore_message( message )) return 0;
7176
7177 msg.hwnd = hwnd;
7178 msg.message = message;
7179 msg.flags = sent|wparam|lparam;
7180 if (defwndproc_counter) msg.flags |= defwinproc;
7181 msg.wParam = wParam;
7182 msg.lParam = lParam;
7183 msg.descr = "static";
7184 add_message(&msg);
7185
7186 defwndproc_counter++;
7188 defwndproc_counter--;
7189
7190 return ret;
7191}
7192
7193static void subclass_static(void)
7194{
7195 WNDCLASSA cls;
7196
7197 if (!GetClassInfoA(0, "static", &cls)) assert(0);
7198
7200
7203 cls.lpszClassName = "my_static_class";
7205 if (!RegisterClassA(&cls)) assert(0);
7206}
7207
7208static void test_static_messages(void)
7209{
7210 /* FIXME: make as comprehensive as the button message test */
7211 static const struct
7212 {
7213 DWORD style;
7214 DWORD dlg_code;
7215 const struct message *setfont;
7216 } static_ctrl[] = {
7219 };
7220 unsigned int i;
7221 HWND hwnd;
7222 DWORD dlg_code;
7223
7225
7226 for (i = 0; i < ARRAY_SIZE(static_ctrl); i++)
7227 {
7228 hwnd = CreateWindowExA(0, "my_static_class", "test", static_ctrl[i].style | WS_POPUP,
7229 0, 0, 50, 14, 0, 0, 0, NULL);
7230 ok(hwnd != 0, "Failed to create static window\n");
7231
7232 dlg_code = SendMessageA(hwnd, WM_GETDLGCODE, 0, 0);
7233 ok(dlg_code == static_ctrl[i].dlg_code, "%u: wrong dlg_code %08x\n", i, dlg_code);
7234
7237 SetFocus(0);
7239
7240 trace("static style %08x\n", static_ctrl[i].style);
7242 ok_sequence(static_ctrl[i].setfont, "WM_SETFONT on a static", FALSE);
7243
7245 }
7246}
7247
7248/****************** ComboBox message test *************************/
7249#define ID_COMBOBOX 0x000f
7250
7251static const struct message SetCurSelComboSeq[] =
7252{
7253 { CB_SETCURSEL, sent|wparam|lparam, 0, 0 },
7254 { LB_SETCURSEL, sent|wparam|lparam, 0, 0 },
7255 { LB_SETTOPINDEX, sent|wparam|lparam, 0, 0 },
7256 { LB_GETCURSEL, sent|wparam|lparam, 0, 0 },
7257 { LB_GETTEXTLEN, sent|wparam|lparam, 0, 0 },
7258 { LB_GETTEXTLEN, sent|wparam|lparam|optional, 0, 0 }, /* TODO: it's sent on all Windows versions */
7259 { LB_GETTEXT, sent|wparam, 0 },
7261 { LB_GETITEMDATA, sent|wparam|lparam, 0, 0 },
7262 { WM_DRAWITEM, sent|wparam|lparam|parent, ID_COMBOBOX, 0x100010f3 },
7263 { 0 }
7264};
7265
7266static const struct message SetCurSelComboSeq2[] =
7267{
7268 { CB_SETCURSEL, sent|wparam|lparam, 0, 0 },
7269 { LB_SETCURSEL, sent|wparam|lparam, 0, 0 },
7270 { LB_SETTOPINDEX, sent|wparam|lparam, 0, 0 },
7271 { LB_GETCURSEL, sent|wparam|lparam, 0, 0 },
7272 { LB_GETTEXTLEN, sent|wparam|lparam, 0, 0 },
7273 { LB_GETTEXTLEN, sent|wparam|lparam|optional, 0, 0 }, /* TODO: it's sent on all Windows versions */
7274 { LB_GETTEXT, sent|wparam, 0 },
7275 { 0 }
7276};
7277
7278static const struct message SetCurSelComboSeq_edit[] =
7279{
7280 { CB_SETCURSEL, sent|wparam|lparam, 0, 0 },
7281 { WM_SETTEXT, sent|wparam, 0 },
7283 { 0 }
7284};
7285
7286static const struct message WmKeyDownComboSeq[] =
7287{
7294 { 0 }
7295};
7296
7297static const struct message WmSetPosComboSeq[] =
7298{
7303 { WM_MOVE, sent|defwinproc },
7309 { 0 }
7310};
7311
7312static const struct message WMSetFocusComboBoxSeq[] =
7313{
7314 { WM_SETFOCUS, sent },
7316 { WM_SETFOCUS, sent },
7319 { WM_CTLCOLOREDIT, sent|defwinproc|optional },/* Not sent on W2000, XP or Server 2003 */
7320 { WM_CTLCOLOREDIT, sent|parent|optional },/* Not sent on W2000, XP or Server 2003 */
7322 { 0 }
7323};
7324
7325static const struct message SetFocusButtonSeq[] =
7326{
7327 { WM_KILLFOCUS, sent },
7328 { CB_GETCOMBOBOXINFO, sent|optional },/* Windows 2000 */
7329 { 0x0167, sent|optional },/* Undocumented message. Sent on all versions except Windows 2000 */
7333 { WM_CTLCOLOREDIT, sent|defwinproc|optional },/* Not sent on W2000, XP or Server 2003 */
7334 { WM_CTLCOLOREDIT, sent|parent|optional },/* Not sent on W2000, XP or Server 2003 */
7337 { 0 }
7338};
7339
7340static const struct message SetFocusComboBoxSeq[] =
7341{
7343 { WM_SETFOCUS, sent },
7345 { WM_SETFOCUS, sent },
7348 { WM_CTLCOLOREDIT, sent|defwinproc|optional },/* Not sent on W2000, XP or Server 2003 */
7349 { WM_CTLCOLOREDIT, sent|parent|optional },/* Not sent on W2000, XP or Server 2003 */
7351 { 0 }
7352};
7353
7354static const struct message SetFocusButtonSeq2[] =
7355{
7356 { WM_KILLFOCUS, sent },
7357 { CB_GETCOMBOBOXINFO, sent|optional },/* Windows 2000 */
7358 { 0x0167, sent|optional },/* Undocumented message. Sent on all versions except Windows 2000 */
7366 { 0 }
7367};
7368
7370
7373{
7374 static LONG defwndproc_counter = 0;
7375 LRESULT ret;
7376 struct recvd_message msg;
7377
7378 /* do not log painting messages */
7379 if (message != WM_PAINT &&
7380 message != WM_NCPAINT &&
7381 message != WM_SYNCPAINT &&
7383 message != WM_NCHITTEST &&
7384 message != WM_GETTEXT &&
7386 {
7387 msg.hwnd = hwnd;
7388 msg.message = message;
7389 msg.flags = sent|wparam|lparam;
7390 if (defwndproc_counter) msg.flags |= defwinproc;
7391 msg.wParam = wParam;
7392 msg.lParam = lParam;
7393 msg.descr = "combo edit";
7394 add_message(&msg);
7395 }
7396
7397 defwndproc_counter++;
7399 defwndproc_counter--;
7400
7401 return ret;
7402}
7403
7406{
7407 static LONG defwndproc_counter = 0;
7408 LRESULT ret;
7409 struct recvd_message msg;
7410
7411 /* do not log painting messages */
7412 if (message != WM_PAINT &&
7413 message != WM_NCPAINT &&
7414 message != WM_SYNCPAINT &&
7416 message != WM_NCHITTEST &&
7418 {
7419 msg.hwnd = hwnd;
7420 msg.message = message;
7421 msg.flags = sent|wparam|lparam;
7422 if (defwndproc_counter) msg.flags |= defwinproc;
7423 msg.wParam = wParam;
7424 msg.lParam = lParam;
7425 msg.descr = "combo lbox";
7426 add_message(&msg);
7427 }
7428
7429 defwndproc_counter++;
7431 defwndproc_counter--;
7432
7433 return ret;
7434}
7435
7437{
7438 static LONG defwndproc_counter = 0;
7439 LRESULT ret;
7440 struct recvd_message msg;
7441
7442 /* do not log painting messages */
7443 if (message != WM_PAINT &&
7444 message != WM_NCPAINT &&
7445 message != WM_SYNCPAINT &&
7447 message != WM_NCHITTEST &&
7448 message != WM_GETTEXT &&
7450 {
7451 msg.hwnd = hwnd;
7452 msg.message = message;
7453 msg.flags = sent|wparam|lparam;
7454 if (defwndproc_counter) msg.flags |= defwinproc;
7455 msg.wParam = wParam;
7456 msg.lParam = lParam;
7457 msg.descr = "combo";
7458 add_message(&msg);
7459 }
7460
7461 defwndproc_counter++;
7463 defwndproc_counter--;
7464
7465 return ret;
7466}
7467
7468static void subclass_combobox(void)
7469{
7470 WNDCLASSA cls;
7471
7472 if (!GetClassInfoA(0, "ComboBox", &cls)) assert(0);
7473
7475
7478 cls.lpszClassName = "my_combobox_class";
7480 if (!RegisterClassA(&cls)) assert(0);
7481}
7482
7483static void test_combobox_messages(void)
7484{
7485 HWND parent, combo, button, edit, lbox;
7486 LRESULT ret;
7487 COMBOBOXINFO cbInfo;
7488 BOOL res;
7489
7491
7492 parent = CreateWindowExA(0, "TestParentClass", "Test parent", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
7493 100, 100, 200, 200, 0, 0, 0, NULL);
7494 ok(parent != 0, "Failed to create parent window\n");
7496
7497 combo = CreateWindowExA(0, "my_combobox_class", "test", WS_CHILD | WS_VISIBLE | CBS_DROPDOWNLIST | CBS_HASSTRINGS,
7498 0, 0, 100, 150, parent, (HMENU)ID_COMBOBOX, 0, NULL);
7499 ok(combo != 0, "Failed to create combobox window\n");
7500
7501 UpdateWindow(combo);
7502
7503 ret = SendMessageA(combo, WM_GETDLGCODE, 0, 0);
7504 ok(ret == (DLGC_WANTCHARS | DLGC_WANTARROWS), "wrong dlg_code %08lx\n", ret);
7505
7506 ret = SendMessageA(combo, CB_ADDSTRING, 0, (LPARAM)"item 0");
7507 ok(ret == 0, "expected 0, got %ld\n", ret);
7508 ret = SendMessageA(combo, CB_ADDSTRING, 0, (LPARAM)"item 1");
7509 ok(ret == 1, "expected 1, got %ld\n", ret);
7510 ret = SendMessageA(combo, CB_ADDSTRING, 0, (LPARAM)"item 2");
7511 ok(ret == 2, "expected 2, got %ld\n", ret);
7512
7513 SendMessageA(combo, CB_SETCURSEL, 0, 0);
7514 SetFocus(combo);
7516
7518 SendMessageA(combo, WM_KEYDOWN, VK_DOWN, 0);
7519 SendMessageA(combo, WM_KEYUP, VK_DOWN, 0);
7521 ok_sequence(WmKeyDownComboSeq, "WM_KEYDOWN/VK_DOWN on a ComboBox", FALSE);
7522
7524 SetWindowPos(combo, 0, 10, 10, 120, 130, SWP_NOZORDER);
7525 ok_sequence(WmSetPosComboSeq, "repositioning messages on a ComboBox", FALSE);
7526
7527 DestroyWindow(combo);
7529
7530 /* Start again. Test combobox text selection when getting and losing focus */
7531 parent = CreateWindowExA(0, "TestParentClass", "Parent", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
7532 10, 10, 300, 300, NULL, NULL, NULL, NULL);
7533 ok(parent != 0, "Failed to create parent window\n");
7534
7535 combo = CreateWindowExA(0, "my_combobox_class", "test", WS_CHILD | WS_VISIBLE | CBS_DROPDOWN,
7536 5, 5, 100, 100, parent, (HMENU)ID_COMBOBOX, NULL, NULL);
7537 ok(combo != 0, "Failed to create combobox window\n");
7538
7539 cbInfo.cbSize = sizeof(COMBOBOXINFO);
7540 SetLastError(0xdeadbeef);
7541 res = GetComboBoxInfo(combo, &cbInfo);
7542 ok(res, "Failed to get COMBOBOXINFO structure; LastError: %u\n", GetLastError());
7543 edit = cbInfo.hwndItem;
7544
7547
7549 5, 50, 100, 20, parent, NULL,
7551 ok(button != 0, "Failed to create button window\n");
7552
7555 SendMessageA(combo, WM_SETFOCUS, 0, (LPARAM)edit);
7557 ok_sequence(WMSetFocusComboBoxSeq, "WM_SETFOCUS on a ComboBox", TRUE);
7558
7563 ok_sequence(SetFocusButtonSeq, "SetFocus on a Button", TRUE);
7564
7565 SendMessageA(combo, WM_SETTEXT, 0, (LPARAM)"Wine Test");
7566
7569 SetFocus(combo);
7571 ok_sequence(SetFocusComboBoxSeq, "SetFocus on a ComboBox", TRUE);
7572
7577 ok_sequence(SetFocusButtonSeq2, "SetFocus on a Button (2)", TRUE);
7578
7579 SetFocus(combo);
7580 SendMessageA(combo, WM_SETREDRAW, FALSE, 0);
7583 SendMessageA(combo, CB_SETCURSEL, 0, 0);
7585 ok_sequence(SetCurSelComboSeq_edit, "CB_SETCURSEL on a ComboBox with edit control", FALSE);
7586
7588 DestroyWindow(combo);
7589
7590 combo = CreateWindowExA(0, "my_combobox_class", "test",
7592 5, 5, 100, 100, parent, (HMENU)ID_COMBOBOX, NULL, NULL);
7593 ok(combo != 0, "Failed to create combobox window\n");
7594
7595 ret = SendMessageA(combo, CB_ADDSTRING, 0, (LPARAM)"item 0");
7596 ok(ret == 0, "expected 0, got %ld\n", ret);
7597
7598 cbInfo.cbSize = sizeof(COMBOBOXINFO);
7599 SetLastError(0xdeadbeef);
7600 res = GetComboBoxInfo(combo, &cbInfo);
7601 ok(res, "Failed to get COMBOBOXINFO structure; LastError: %u\n", GetLastError());
7602 lbox = cbInfo.hwndList;
7606
7608 SendMessageA(combo, CB_SETCURSEL, 0, 0);
7610 ok_sequence(SetCurSelComboSeq, "CB_SETCURSEL on a ComboBox", FALSE);
7611
7612 ShowWindow(combo, SW_HIDE);
7615 SendMessageA(combo, CB_SETCURSEL, 0, 0);
7617 ok_sequence(SetCurSelComboSeq2, "CB_SETCURSEL on a ComboBox", FALSE);
7618
7619 DestroyWindow(combo);
7621}
7622
7623/****************** WM_IME_KEYDOWN message test *******************/
7624
7625static const struct message WmImeKeydownMsgSeq_0[] =
7626{
7628 { WM_CHAR, wparam, 'A' },
7629 { 0 }
7630};
7631
7632static const struct message WmImeKeydownMsgSeq_1[] =
7633{
7636 { 0 }
7637};
7638
7640{
7641 struct recvd_message msg;
7642
7643 msg.hwnd = hwnd;
7644 msg.message = message;
7645 msg.flags = wparam|lparam;
7646 msg.wParam = wParam;
7647 msg.lParam = lParam;
7648 msg.descr = "wmime_keydown";
7649 add_message(&msg);
7650
7652}
7653
7655{
7656 WNDCLASSA cls;
7657
7658 ZeroMemory(&cls, sizeof(WNDCLASSA));
7660 cls.hInstance = GetModuleHandleA(0);
7661 cls.lpszClassName = "wmime_keydown_class";
7662 if (!RegisterClassA(&cls)) assert(0);
7663}
7664
7666{
7667 HWND hwnd;
7668 MSG msg;
7669
7670 trace("Message sequences by WM_IME_KEYDOWN\n");
7671
7673 hwnd = CreateWindowExA(0, "wmime_keydown_class", NULL, WS_OVERLAPPEDWINDOW,
7674 CW_USEDEFAULT, CW_USEDEFAULT, 300, 300, 0,
7675 NULL, NULL, 0);
7676 flush_events();
7678
7680 SendMessageA(hwnd, WM_CHAR, 'A', 1);
7681 ok_sequence(WmImeKeydownMsgSeq_0, "WM_IME_KEYDOWN 0", FALSE);
7682
7683 while ( PeekMessageA(&msg, 0, 0, 0, PM_REMOVE) )
7684 {
7687 }
7688 ok_sequence(WmImeKeydownMsgSeq_1, "WM_IME_KEYDOWN 1", FALSE);
7689
7691}
7692
7693/************* painting message test ********************/
7694
7696{
7697 DWORD i, size;
7698 RGNDATA *data = NULL;
7699 RECT *rect;
7700
7701 if (!hrgn)
7702 {
7703 printf( "null region\n" );
7704 return;
7705 }
7706 if (!(size = GetRegionData( hrgn, 0, NULL ))) return;
7707 if (!(data = HeapAlloc( GetProcessHeap(), 0, size ))) return;
7709 printf("%d rects:", data->rdh.nCount );
7710 for (i = 0, rect = (RECT *)data->Buffer; i < data->rdh.nCount; i++, rect++)
7711 printf( " %s", wine_dbgstr_rect( rect ));
7712 printf("\n");
7713 HeapFree( GetProcessHeap(), 0, data );
7714}
7715
7716#define check_update_rgn( hwnd, hrgn ) check_update_rgn_( __LINE__, hwnd, hrgn )
7717static void check_update_rgn_( int line, HWND hwnd, HRGN hrgn )
7718{
7719 INT ret;
7720 RECT r1, r2;
7721 HRGN tmp = CreateRectRgn( 0, 0, 0, 0 );
7722 HRGN update = CreateRectRgn( 0, 0, 0, 0 );
7723
7724 ret = GetUpdateRgn( hwnd, update, FALSE );
7725 ok( ret != ERROR, "GetUpdateRgn failed\n" );
7726 if (ret == NULLREGION)
7727 {
7728 ok_(__FILE__,line)( !hrgn, "Update region shouldn't be empty\n" );
7729 }
7730 else
7731 {
7732 if (CombineRgn( tmp, hrgn, update, RGN_XOR ) != NULLREGION)
7733 {
7734 ok_(__FILE__,line)( 0, "Regions are different\n" );
7735 if (winetest_debug > 0)
7736 {
7737 printf( "Update region: " );
7738 dump_region( update );
7739 printf( "Wanted region: " );
7740 dump_region( hrgn );
7741 }
7742 }
7743 }
7744 GetRgnBox( update, &r1 );
7745 GetUpdateRect( hwnd, &r2, FALSE );
7746 ok_(__FILE__,line)( EqualRect( &r1, &r2 ), "Rectangles are different: %s / %s\n",
7748
7749 DeleteObject( tmp );
7750 DeleteObject( update );
7751}
7752
7753static const struct message WmInvalidateRgn[] = {
7754 { WM_NCPAINT, sent },
7756 { 0 }
7757};
7758
7759static const struct message WmGetUpdateRect[] = {
7760 { WM_NCPAINT, sent },
7762 { WM_PAINT, sent },
7763 { 0 }
7764};
7765
7766static const struct message WmInvalidateFull[] = {
7767 { WM_NCPAINT, sent|wparam, 1 },
7769 { 0 }
7770};
7771
7772static const struct message WmInvalidateErase[] = {
7773 { WM_NCPAINT, sent|wparam, 1 },
7775 { WM_ERASEBKGND, sent },
7776 { 0 }
7777};
7778
7779static const struct message WmInvalidatePaint[] = {
7780 { WM_PAINT, sent },
7783 { 0 }
7784};
7785
7786static const struct message WmInvalidateErasePaint[] = {
7787 { WM_PAINT, sent },
7791 { 0 }
7792};
7793
7794static const struct message WmInvalidateErasePaint2[] = {
7795 { WM_PAINT, sent },
7799 { 0 }
7800};
7801
7802static const struct message WmErase[] = {
7803 { WM_ERASEBKGND, sent },
7804 { 0 }
7805};
7806
7807static const struct message WmPaint[] = {
7808 { WM_PAINT, sent },
7809 { 0 }
7810};
7811
7812static const struct message WmParentOnlyPaint[] = {
7813 { WM_PAINT, sent|parent },
7814 { 0 }
7815};
7816
7817static const struct message WmInvalidateParent[] = {
7818 { WM_NCPAINT, sent|parent },
7821 { 0 }
7822};
7823
7824static const struct message WmInvalidateParentChild[] = {
7825 { WM_NCPAINT, sent|parent },
7828 { WM_NCPAINT, sent },
7830 { WM_ERASEBKGND, sent },
7831 { 0 }
7832};
7833
7834static const struct message WmInvalidateParentChild2[] = {
7836 { WM_NCPAINT, sent },
7838 { WM_ERASEBKGND, sent },
7839 { 0 }
7840};
7841
7842static const struct message WmParentPaint[] = {
7843 { WM_PAINT, sent|parent },
7844 { WM_PAINT, sent },
7845 { 0 }
7846};
7847
7848static const struct message WmParentPaintNc[] = {
7849 { WM_PAINT, sent|parent },
7850 { WM_PAINT, sent },
7854 { 0 }
7855};
7856
7857static const struct message WmChildPaintNc[] = {
7858 { WM_PAINT, sent },
7862 { 0 }
7863};
7864
7865static const struct message WmParentErasePaint[] = {
7866 { WM_PAINT, sent|parent },
7870 { WM_PAINT, sent },
7874 { 0 }
7875};
7876
7877static const struct message WmParentOnlyNcPaint[] = {
7878 { WM_PAINT, sent|parent },
7881 { 0 }
7882};
7883
7884static const struct message WmSetParentStyle[] = {
7885 { WM_STYLECHANGING, sent|parent },
7886 { WM_STYLECHANGED, sent|parent },
7887 { 0 }
7888};
7889
7890static void test_paint_messages(void)
7891{
7892 BOOL ret;
7893 RECT rect, rect2;
7894 POINT pt;
7895 MSG msg;
7896 HWND hparent, hchild;
7897 HRGN hrgn = CreateRectRgn( 0, 0, 0, 0 );
7898 HRGN hrgn2 = CreateRectRgn( 0, 0, 0, 0 );
7899 HWND hwnd = CreateWindowExA(0, "TestWindowClass", "Test overlapped", WS_OVERLAPPEDWINDOW,
7900 100, 100, 200, 200, 0, 0, 0, NULL);
7901 ok (hwnd != 0, "Failed to create overlapped window\n");
7902
7904 UpdateWindow( hwnd );
7905 flush_events();
7907
7908 check_update_rgn( hwnd, 0 );
7909 SetRectRgn( hrgn, 10, 10, 20, 20 );
7911 ok(ret, "RedrawWindow returned %d instead of TRUE\n", ret);
7913 SetRectRgn( hrgn2, 20, 20, 30, 30 );
7915 ok(ret, "RedrawWindow returned %d instead of TRUE\n", ret);
7918 /* validate everything */
7920 ok(ret, "RedrawWindow returned %d instead of TRUE\n", ret);
7921 check_update_rgn( hwnd, 0 );
7922
7923 /* test empty region */
7924 SetRectRgn( hrgn, 10, 10, 10, 15 );
7926 ok(ret, "RedrawWindow returned %d instead of TRUE\n", ret);
7927 check_update_rgn( hwnd, 0 );
7928 /* test empty rect */
7929 SetRect( &rect, 10, 10, 10, 15 );
7931 ok(ret, "RedrawWindow returned %d instead of TRUE\n", ret);
7932 check_update_rgn( hwnd, 0 );
7933
7934 /* flush pending messages */
7935 flush_events();
7937
7938 GetClientRect( hwnd, &rect );
7939 SetRectRgn( hrgn, 0, 0, rect.right - rect.left, rect.bottom - rect.top );
7940 /* MSDN: if hwnd parameter is NULL, InvalidateRect invalidates and redraws
7941 * all windows and sends WM_ERASEBKGND and WM_NCPAINT.
7942 */
7943 SetRectEmpty( &rect );
7944 ok(InvalidateRect(0, &rect, FALSE), "InvalidateRect(0, &rc, FALSE) failed\n");
7946 ok_sequence( WmInvalidateErase, "InvalidateErase", FALSE );
7947 flush_events();
7948 ok_sequence( WmPaint, "Paint", FALSE );
7950 check_update_rgn( hwnd, 0 );
7951
7952 SetRectEmpty( &rect );
7954 "RedrawWindow failed\n");
7955 check_update_rgn( hwnd, 0 );
7956
7957 SetRectEmpty( &rect );
7959 "RedrawWindow failed\n");
7960 check_update_rgn( hwnd, 0 );
7961
7962 GetWindowRect( hwnd, &rect );
7964 "RedrawWindow failed\n");
7965 check_update_rgn( hwnd, 0 );
7966
7967 flush_events();
7969 "RedrawWindow failed\n");
7971 ok_sequence( WmInvalidateErase, "InvalidateErase", FALSE );
7972 flush_events();
7973 ok_sequence( WmPaint, "Paint", FALSE );
7975 check_update_rgn( hwnd, 0 );
7976
7979 "RedrawWindow failed\n");
7981 ok( ret == NULLREGION || broken(ret == SIMPLEREGION), /* <= win7 */
7982 "region should be null (%d)\n", ret );
7983 if (ret == SIMPLEREGION) ok_sequence( WmInvalidateErase, "InvalidateErase", FALSE );
7985 flush_events();
7986
7989 "RedrawWindow failed\n");
7991 ok( ret == NULLREGION || broken(ret == SIMPLEREGION), /* <= win7 */
7992 "region should be null (%d)\n", ret );
7993 if (ret == SIMPLEREGION) ok_sequence( WmInvalidateErase, "InvalidateErase", FALSE );
7995 flush_events();
7996
7997 SetRectRgn( hrgn2, rect.left, rect.top, rect.right, rect.bottom );
7999 "RedrawWindow failed\n");
8001 ok_sequence( WmInvalidateErase, "InvalidateErase", FALSE );
8002 flush_events();
8003 ok_sequence( WmPaint, "Paint", FALSE );
8005 check_update_rgn( hwnd, 0 );
8006
8008 "RedrawWindow failed\n");
8009 check_update_rgn( hwnd, 0 );
8010
8012 "RedrawWindow failed\n");
8014 ok_sequence( WmInvalidateErase, "InvalidateErase", FALSE );
8015 flush_events();
8016 ok_sequence( WmPaint, "Paint", FALSE );
8018 check_update_rgn( hwnd, 0 );
8019
8020 /* MSDN: if hwnd parameter is NULL, ValidateRect invalidates and redraws
8021 * all windows and sends WM_ERASEBKGND and WM_NCPAINT.
8022 */
8023 SetRectEmpty( &rect );
8024 if (ValidateRect(0, &rect) && /* not supported on Win9x */
8025 GetUpdateRect(hwnd, NULL, FALSE)) /* or >= Win 8 */
8026 {
8028 ok_sequence( WmInvalidateErase, "InvalidateErase", FALSE );
8029 flush_events();
8030 ok_sequence( WmPaint, "Paint", FALSE );
8032 check_update_rgn( hwnd, 0 );
8033 }
8034
8035 SetLastError(0xdeadbeef);
8036 ok(!InvalidateRgn(0, NULL, FALSE), "InvalidateRgn(0, NULL, FALSE) should fail\n");
8038 "wrong error code %d\n", GetLastError());
8039 check_update_rgn( hwnd, 0 );
8040 flush_events();
8041 ok_sequence( WmEmptySeq, "WmEmptySeq", FALSE );
8042
8043 SetLastError(0xdeadbeef);
8044 ok(!ValidateRgn(0, NULL), "ValidateRgn(0, NULL) should fail\n");
8046 broken( GetLastError() == 0xdeadbeef ) /* win9x */,
8047 "wrong error code %d\n", GetLastError());
8048 check_update_rgn( hwnd, 0 );
8049 flush_events();
8050 ok_sequence( WmEmptySeq, "WmEmptySeq", FALSE );
8051
8052 SetLastError(0xdeadbeef);
8053 ok(!UpdateWindow(NULL), "UpdateWindow(NULL) should fail\n");
8055 broken( GetLastError() == 0xdeadbeef ) /* win9x */,
8056 "wrong error code %d\n", GetLastError());
8057 check_update_rgn( hwnd, 0 );
8058 flush_events();
8059 ok_sequence( WmEmptySeq, "WmEmptySeq", FALSE );
8060
8061 /* now with frame */
8062 SetRectRgn( hrgn, -5, -5, 20, 20 );
8063
8064 /* flush pending messages */
8065 flush_events();
8068 ok_sequence( WmEmptySeq, "EmptySeq", FALSE );
8069
8070 SetRectRgn( hrgn, 0, 0, 20, 20 ); /* GetUpdateRgn clips to client area */
8072
8075 ok_sequence( WmInvalidateRgn, "InvalidateRgn", FALSE );
8076
8079 ok_sequence( WmInvalidateFull, "InvalidateFull", FALSE );
8080
8081 GetClientRect( hwnd, &rect );
8082 SetRectRgn( hrgn, rect.left, rect.top, rect.right, rect.bottom );
8084
8087 ok_sequence( WmInvalidateErase, "InvalidateErase", FALSE );
8088
8091 ok_sequence( WmInvalidatePaint, "InvalidatePaint", FALSE );
8092 check_update_rgn( hwnd, 0 );
8093
8096 ok_sequence( WmInvalidateErasePaint, "InvalidateErasePaint", FALSE );
8097 check_update_rgn( hwnd, 0 );
8098
8100 SetRectRgn( hrgn, 0, 0, 100, 100 );
8102 SetRectRgn( hrgn, 0, 0, 50, 100 );
8104 SetRectRgn( hrgn, 50, 0, 100, 100 );
8107 ok_sequence( WmEmptySeq, "EmptySeq", FALSE ); /* must not generate messages, everything is valid */
8108 check_update_rgn( hwnd, 0 );
8109
8111 SetRectRgn( hrgn, 0, 0, 100, 100 );
8113 SetRectRgn( hrgn, 0, 0, 100, 50 );
8115 ok_sequence( WmErase, "Erase", FALSE );
8116 SetRectRgn( hrgn, 0, 50, 100, 100 );
8118
8120 SetRectRgn( hrgn, 0, 0, 100, 100 );
8122 SetRectRgn( hrgn, 0, 0, 50, 50 );
8124 ok_sequence( WmPaint, "Paint", FALSE );
8125
8127 SetRectRgn( hrgn, -4, -4, -2, -2 );
8129 SetRectRgn( hrgn, -200, -200, -198, -198 );
8131 ok_sequence( WmEmptySeq, "EmptySeq", FALSE );
8132
8134 SetRectRgn( hrgn, -4, -4, -2, -2 );
8136 SetRectRgn( hrgn, -4, -4, -3, -3 );
8138 SetRectRgn( hrgn, 0, 0, 1, 1 );
8140 ok_sequence( WmPaint, "Paint", FALSE );
8141
8143 SetRectRgn( hrgn, -4, -4, -1, -1 );
8146 /* make sure no WM_PAINT was generated */
8147 flush_events();
8148 ok_sequence( WmInvalidateRgn, "InvalidateRgn", FALSE );
8149
8151 SetRectRgn( hrgn, -4, -4, -1, -1 );
8153 while (PeekMessageA( &msg, 0, 0, 0, PM_REMOVE ))
8154 {
8155 if (msg.hwnd == hwnd && msg.message == WM_PAINT)
8156 {
8157 /* GetUpdateRgn must return empty region since only nonclient area is invalidated */
8159 ok( ret == NULLREGION, "Invalid GetUpdateRgn result %d\n", ret );
8161 ok( ret, "Invalid GetUpdateRect result %d\n", ret );
8162 /* this will send WM_NCPAINT and validate the non client area */
8163 ret = GetUpdateRect( hwnd, &rect, TRUE );
8164 ok( !ret, "Invalid GetUpdateRect result %d\n", ret );
8165 }
8167 }
8168 ok_sequence( WmGetUpdateRect, "GetUpdateRect", FALSE );
8169
8171
8172 /* now test with a child window */
8173
8174 hparent = CreateWindowExA(0, "TestParentClass", "Test parent", WS_OVERLAPPEDWINDOW,
8175 100, 100, 200, 200, 0, 0, 0, NULL);
8176 ok (hparent != 0, "Failed to create parent window\n");
8177
8178 hchild = CreateWindowExA(0, "TestWindowClass", "Test child", WS_CHILD | WS_VISIBLE | WS_BORDER,
8179 10, 10, 100, 100, hparent, 0, 0, NULL);
8180 ok (hchild != 0, "Failed to create child window\n");
8181
8182 ShowWindow( hparent, SW_SHOW );
8183 UpdateWindow( hparent );
8184 UpdateWindow( hchild );
8185 flush_events();
8188
8189 SetRect( &rect, 0, 0, 50, 50 );
8190 RedrawWindow( hparent, &rect, 0, RDW_INVALIDATE | RDW_ERASE | RDW_FRAME );
8192 ok_sequence( WmInvalidateParentChild, "InvalidateParentChild", FALSE );
8193
8194 RedrawWindow( hparent, &rect, 0, RDW_INVALIDATE | RDW_ERASE | RDW_FRAME );
8195 pt.x = pt.y = 0;
8196 MapWindowPoints( hchild, hparent, &pt, 1 );
8197 SetRectRgn( hrgn, 0, 0, 50 - pt.x, 50 - pt.y );
8198 check_update_rgn( hchild, hrgn );
8199 SetRectRgn( hrgn, 0, 0, 50, 50 );
8200 check_update_rgn( hparent, hrgn );
8201 RedrawWindow( hparent, NULL, 0, RDW_ERASENOW );
8202 ok_sequence( WmInvalidateParent, "InvalidateParent", FALSE );
8203 RedrawWindow( hchild, NULL, 0, RDW_ERASENOW );
8204 ok_sequence( WmEmptySeq, "EraseNow child", FALSE );
8205
8206 flush_events();
8207 ok_sequence( WmParentPaintNc, "WmParentPaintNc", FALSE );
8208
8210 RedrawWindow( hparent, NULL, 0, RDW_ERASENOW );
8211 ok_sequence( WmInvalidateParent, "InvalidateParent2", FALSE );
8212 RedrawWindow( hchild, NULL, 0, RDW_ERASENOW );
8213 ok_sequence( WmEmptySeq, "EraseNow child", FALSE );
8214
8215 RedrawWindow( hparent, &rect, 0, RDW_INVALIDATE | RDW_ERASE );
8217 ok_sequence( WmInvalidateParentChild2, "InvalidateParentChild2", FALSE );
8218
8222 RedrawWindow( hparent, NULL, 0, RDW_ERASENOW );
8223 ok_sequence( WmInvalidateParentChild, "InvalidateParentChild3", FALSE );
8224
8225 /* flush all paint messages */
8226 flush_events();
8228
8229 /* RDW_UPDATENOW on child with WS_CLIPCHILDREN doesn't change corresponding parent area */
8231 SetRectRgn( hrgn, 0, 0, 50, 50 );
8232 check_update_rgn( hparent, hrgn );
8233 RedrawWindow( hchild, NULL, 0, RDW_UPDATENOW );
8234 ok_sequence( WmInvalidateErasePaint2, "WmInvalidateErasePaint2", FALSE );
8235 SetRectRgn( hrgn, 0, 0, 50, 50 );
8236 check_update_rgn( hparent, hrgn );
8237
8238 /* flush all paint messages */
8239 flush_events();
8242
8243 /* RDW_UPDATENOW on child without WS_CLIPCHILDREN will validate corresponding parent area */
8244 RedrawWindow( hparent, &rect, 0, RDW_INVALIDATE | RDW_ERASE | RDW_FRAME );
8245 SetRectRgn( hrgn, 0, 0, 50, 50 );
8246 check_update_rgn( hparent, hrgn );
8247 RedrawWindow( hchild, NULL, 0, RDW_UPDATENOW );
8248 ok_sequence( WmInvalidateErasePaint2, "WmInvalidateErasePaint2", FALSE );
8249 SetRectRgn( hrgn2, 10, 10, 50, 50 );
8251 check_update_rgn( hparent, hrgn );
8252 /* flush all paint messages */
8253 flush_events();
8255
8256 /* same as above but parent gets completely validated */
8257 SetRect( &rect, 20, 20, 30, 30 );
8258 RedrawWindow( hparent, &rect, 0, RDW_INVALIDATE | RDW_ERASE | RDW_FRAME );
8259 SetRectRgn( hrgn, 20, 20, 30, 30 );
8260 check_update_rgn( hparent, hrgn );
8261 RedrawWindow( hchild, NULL, 0, RDW_UPDATENOW );
8262 ok_sequence( WmInvalidateErasePaint2, "WmInvalidateErasePaint2", FALSE );
8263 check_update_rgn( hparent, 0 ); /* no update region */
8264 flush_events();
8265 ok_sequence( WmEmptySeq, "WmEmpty", FALSE ); /* and no paint messages */
8266
8267 /* make sure RDW_VALIDATE on child doesn't have the same effect */
8269 RedrawWindow( hparent, &rect, 0, RDW_INVALIDATE | RDW_ERASE | RDW_FRAME );
8270 SetRectRgn( hrgn, 20, 20, 30, 30 );
8271 check_update_rgn( hparent, hrgn );
8272 RedrawWindow( hchild, NULL, 0, RDW_VALIDATE | RDW_NOERASE );
8273 SetRectRgn( hrgn, 20, 20, 30, 30 );
8274 check_update_rgn( hparent, hrgn );
8275
8276 /* same as above but normal WM_PAINT doesn't validate parent */
8278 SetRect( &rect, 20, 20, 30, 30 );
8279 RedrawWindow( hparent, &rect, 0, RDW_INVALIDATE | RDW_ERASE | RDW_FRAME );
8280 SetRectRgn( hrgn, 20, 20, 30, 30 );
8281 check_update_rgn( hparent, hrgn );
8282 /* no WM_PAINT in child while parent still pending */
8283 while (PeekMessageA( &msg, hchild, 0, 0, PM_REMOVE )) DispatchMessageA( &msg );
8284 ok_sequence( WmEmptySeq, "No WM_PAINT", FALSE );
8285 while (PeekMessageA( &msg, hparent, 0, 0, PM_REMOVE )) DispatchMessageA( &msg );
8286 ok_sequence( WmParentErasePaint, "WmParentErasePaint", FALSE );
8287
8289 RedrawWindow( hparent, &rect, 0, RDW_INVALIDATE | RDW_ERASE | RDW_FRAME );
8290 /* no WM_PAINT in child while parent still pending */
8291 while (PeekMessageA( &msg, hchild, 0, 0, PM_REMOVE )) DispatchMessageA( &msg );
8292 ok_sequence( WmEmptySeq, "No WM_PAINT", FALSE );
8294 /* now that parent is valid child should get WM_PAINT */
8295 while (PeekMessageA( &msg, hchild, 0, 0, PM_REMOVE )) DispatchMessageA( &msg );
8296 ok_sequence( WmInvalidateErasePaint2, "WmInvalidateErasePaint2", FALSE );
8297 while (PeekMessageA( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessageA( &msg );
8298 ok_sequence( WmEmptySeq, "No other message", FALSE );
8299
8300 /* same thing with WS_CLIPCHILDREN in parent */
8303 ok_sequence( WmSetParentStyle, "WmSetParentStyle", FALSE );
8304 /* changing style invalidates non client area, but we need to invalidate something else to see it */
8305 RedrawWindow( hparent, &rect, 0, RDW_UPDATENOW );
8306 ok_sequence( WmEmptySeq, "No message", FALSE );
8307 RedrawWindow( hparent, &rect, 0, RDW_INVALIDATE | RDW_UPDATENOW );
8308 ok_sequence( WmParentOnlyNcPaint, "WmParentOnlyNcPaint", FALSE );
8309
8312 SetRectRgn( hrgn, 20, 20, 30, 30 );
8313 check_update_rgn( hparent, hrgn );
8314 /* no WM_PAINT in child while parent still pending */
8315 while (PeekMessageA( &msg, hchild, 0, 0, PM_REMOVE )) DispatchMessageA( &msg );
8316 ok_sequence( WmEmptySeq, "No WM_PAINT", FALSE );
8317 /* WM_PAINT in parent first */
8318 while (PeekMessageA( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessageA( &msg );
8319 ok_sequence( WmParentPaintNc, "WmParentPaintNc2", FALSE );
8320
8321 /* no RDW_ERASE in parent still causes RDW_ERASE and RDW_FRAME in child */
8323 SetRect( &rect, 0, 0, 30, 30 );
8325 SetRectRgn( hrgn, 0, 0, 30, 30 );
8326 check_update_rgn( hparent, hrgn );
8327 flush_events();
8328 ok_sequence( WmParentPaintNc, "WmParentPaintNc3", FALSE );
8329
8330 /* validate doesn't cause RDW_NOERASE or RDW_NOFRAME in child */
8332 SetRect( &rect, -10, 0, 30, 30 );
8334 SetRect( &rect, 0, 0, 20, 20 );
8335 RedrawWindow( hparent, &rect, 0, RDW_VALIDATE | RDW_ALLCHILDREN );
8336 RedrawWindow( hparent, NULL, 0, RDW_UPDATENOW );
8337 ok_sequence( WmChildPaintNc, "WmChildPaintNc", FALSE );
8338
8339 /* validate doesn't cause RDW_NOERASE or RDW_NOFRAME in child */
8341 SetRect( &rect, -10, 0, 30, 30 );
8343 SetRect( &rect, 0, 0, 100, 100 );
8344 RedrawWindow( hparent, &rect, 0, RDW_VALIDATE | RDW_ALLCHILDREN );
8345 RedrawWindow( hparent, NULL, 0, RDW_UPDATENOW );
8346 ok_sequence( WmEmptySeq, "WmChildPaintNc2", FALSE );
8347 RedrawWindow( hparent, NULL, 0, RDW_ERASENOW );
8348 ok_sequence( WmEmptySeq, "WmChildPaintNc3", FALSE );
8349
8350 /* WS_CLIPCHILDREN doesn't exclude children from update region */
8353 GetClientRect( hparent, &rect );
8354 SetRectRgn( hrgn, rect.left, rect.top, rect.right, rect.bottom );
8355 check_update_rgn( hparent, hrgn );
8356 flush_events();
8357
8359 GetClientRect( hparent, &rect );
8360 SetRectRgn( hrgn, rect.left, rect.top, rect.right, rect.bottom );
8361 check_update_rgn( hparent, hrgn );
8362 flush_events();
8363
8364 /* test RDW_INTERNALPAINT behavior */
8365
8368 flush_events();
8369 ok_sequence( WmParentOnlyPaint, "WmParentOnlyPaint", FALSE );
8370
8372 flush_events();
8373 ok_sequence( WmParentPaint, "WmParentPaint", FALSE );
8374
8375 RedrawWindow( hparent, NULL, 0, RDW_INTERNALPAINT );
8376 flush_events();
8377 ok_sequence( WmParentOnlyPaint, "WmParentOnlyPaint", FALSE );
8378
8380 UpdateWindow( hparent );
8381 flush_events();
8383 trace("testing SWP_FRAMECHANGED on parent with WS_CLIPCHILDREN\n");
8385 SetWindowPos( hparent, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE |
8387 flush_events();
8388 ok_sequence(WmSWP_FrameChanged_clip, "SetWindowPos:FrameChanged_clip", FALSE );
8389
8390 UpdateWindow( hparent );
8391 flush_events();
8393 trace("testing SWP_FRAMECHANGED|SWP_DEFERERASE on parent with WS_CLIPCHILDREN\n");
8395 SetWindowPos( hparent, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_DEFERERASE |
8397 flush_events();
8398 ok_sequence(WmSWP_FrameChangedDeferErase, "SetWindowPos:FrameChangedDeferErase", FALSE );
8399
8401 ok_sequence( WmSetParentStyle, "WmSetParentStyle", FALSE );
8402 RedrawWindow( hparent, NULL, 0, RDW_INTERNALPAINT );
8403 flush_events();
8404 ok_sequence( WmParentPaint, "WmParentPaint", FALSE );
8405
8407 UpdateWindow( hparent );
8408 flush_events();
8410 trace("testing SWP_FRAMECHANGED on parent without WS_CLIPCHILDREN\n");
8412 SetWindowPos( hparent, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE |
8414 flush_events();
8415 ok_sequence(WmSWP_FrameChanged_noclip, "SetWindowPos:FrameChanged_noclip", FALSE );
8416
8417 UpdateWindow( hparent );
8418 flush_events();
8420 trace("testing SWP_FRAMECHANGED|SWP_DEFERERASE on parent without WS_CLIPCHILDREN\n");
8422 SetWindowPos( hparent, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_DEFERERASE |
8424 flush_events();
8425 ok_sequence(WmSWP_FrameChangedDeferErase, "SetWindowPos:FrameChangedDeferErase", FALSE );
8426
8427 ok(GetWindowLongA( hparent, GWL_STYLE ) & WS_VISIBLE, "parent should be visible\n");
8428 ok(GetWindowLongA( hchild, GWL_STYLE ) & WS_VISIBLE, "child should be visible\n");
8429
8430 UpdateWindow( hparent );
8431 flush_events();
8433 trace("testing SetWindowPos(-10000, -10000) on child\n");
8434 SetWindowPos( hchild, 0, -10000, -10000, 0, 0, SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOZORDER );
8435 check_update_rgn( hchild, 0 );
8436 flush_events();
8437
8438#if 0 /* this one doesn't pass under Wine yet */
8439 UpdateWindow( hparent );
8440 flush_events();
8442 trace("testing ShowWindow(SW_MINIMIZE) on child\n");
8443 ShowWindow( hchild, SW_MINIMIZE );
8444 check_update_rgn( hchild, 0 );
8445 flush_events();
8446#endif
8447
8448 UpdateWindow( hparent );
8449 flush_events();
8451 trace("testing SetWindowPos(-10000, -10000) on parent\n");
8452 SetWindowPos( hparent, 0, -10000, -10000, 0, 0, SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOZORDER );
8453 check_update_rgn( hparent, 0 );
8454 flush_events();
8455
8457 DestroyWindow( hparent );
8458 ok(!IsWindow(hchild), "child must be destroyed with its parent\n");
8459
8460 /* tests for moving windows off-screen (needs simple WS_POPUP windows) */
8461
8462 hparent = CreateWindowExA(0, "TestParentClass", "Test parent", WS_POPUP | WS_VISIBLE,
8463 100, 100, 200, 200, 0, 0, 0, NULL);
8464 ok (hparent != 0, "Failed to create parent window\n");
8465
8466 hchild = CreateWindowExA(0, "TestWindowClass", "Test child", WS_CHILD | WS_VISIBLE,
8467 10, 10, 100, 100, hparent, 0, 0, NULL);
8468 ok (hchild != 0, "Failed to create child window\n");
8469
8470 ShowWindow( hparent, SW_SHOW );
8471 UpdateWindow( hparent );
8472 UpdateWindow( hchild );
8473 flush_events();
8475
8476 /* moving child outside of parent boundaries changes update region */
8477 SetRect( &rect, 0, 0, 40, 40 );
8478 RedrawWindow( hchild, &rect, 0, RDW_INVALIDATE | RDW_ERASE );
8479 SetRectRgn( hrgn, 0, 0, 40, 40 );
8480 check_update_rgn( hchild, hrgn );
8481 MoveWindow( hchild, -10, 10, 100, 100, FALSE );
8482 SetRectRgn( hrgn, 10, 0, 40, 40 );
8483 check_update_rgn( hchild, hrgn );
8484 MoveWindow( hchild, -10, -10, 100, 100, FALSE );
8485 SetRectRgn( hrgn, 10, 10, 40, 40 );
8486 check_update_rgn( hchild, hrgn );
8487
8488 /* moving parent off-screen does too */
8489 SetRect( &rect, 0, 0, 100, 100 );
8491 SetRectRgn( hrgn, 0, 0, 100, 100 );
8492 check_update_rgn( hparent, hrgn );
8493 SetRectRgn( hrgn, 10, 10, 40, 40 );
8494 check_update_rgn( hchild, hrgn );
8495 MoveWindow( hparent, -20, -20, 200, 200, FALSE );
8496 GetUpdateRect( hparent, &rect2, FALSE );
8497 if (!EqualRect( &rect2, &rect )) /* Win 8 and later don't crop update to screen */
8498 {
8499 rect.left += 20;
8500 rect.top += 20;
8501 }
8502 SetRectRgn( hrgn, rect.left, rect.top, rect.right, rect.bottom );
8503 check_update_rgn( hparent, hrgn );
8504 SetRectRgn( hrgn, rect.left + 10, rect.top + 10, 40, 40 );
8505 check_update_rgn( hchild, hrgn );
8506
8507 /* invalidated region is cropped by the parent rects */
8508 SetRect( &rect, 0, 0, 50, 50 );
8509 RedrawWindow( hchild, &rect, 0, RDW_INVALIDATE | RDW_ERASE );
8510 SetRectRgn( hrgn, rect2.left + 10, rect2.top + 10, 50, 50 );
8511 check_update_rgn( hchild, hrgn );
8512
8513 DestroyWindow( hparent );
8514 ok(!IsWindow(hchild), "child must be destroyed with its parent\n");
8516
8517 DeleteObject( hrgn );
8519}
8520
8521struct wnd_event
8522{
8523 HWND hwnd;
8527};
8528
8530{
8531 MSG msg;
8532 struct wnd_event *wnd_event = param;
8533
8534 wnd_event->hwnd = CreateWindowExA(0, "TestWindowClass", "window caption text", WS_OVERLAPPEDWINDOW,
8535 100, 100, 200, 200, 0, 0, 0, NULL);
8536 ok(wnd_event->hwnd != 0, "Failed to create overlapped window\n");
8537
8539
8540 while (GetMessageA(&msg, 0, 0, 0))
8541 {
8544 }
8545
8546 ok(IsWindow(wnd_event->hwnd), "window should still exist\n");
8547
8548 return 0;
8549}
8550
8552{
8553 struct wnd_event *wnd_event = param;
8554 HWND hchild;
8555 MSG msg;
8556
8557 hchild = CreateWindowExA(0, "TestWindowClass", "Test child",
8558 WS_CHILD | WS_VISIBLE, 0, 0, 10, 10, wnd_event->hwnd, 0, 0, NULL);
8559 ok (hchild != 0, "Failed to create child window\n");
8560 flush_events();
8563
8564 for (;;)
8565 {
8567 if (!IsWindow( hchild )) break; /* will be destroyed when parent thread exits */
8568 while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
8569 }
8570 return 0;
8571}
8572
8574{
8575 struct wnd_event *wnd_event = param;
8576 struct wnd_event child_event;
8577 DWORD ret, tid;
8578 MSG msg;
8579
8580 child_event.hwnd = CreateWindowExA(0, "TestWindowClass", "Test child",
8581 WS_CHILD | WS_VISIBLE, 0, 0, 10, 10, wnd_event->hwnd, 0, 0, NULL);
8582 ok (child_event.hwnd != 0, "Failed to create child window\n");
8583 SetFocus( child_event.hwnd );
8584 flush_events();
8586 child_event.start_event = wnd_event->start_event;
8588 for (;;)
8589 {
8591 if (ret != 1) break;
8592 while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
8593 }
8595 ok( !ret, "WaitForSingleObject failed %x\n", ret );
8596 return 0;
8597}
8598
8599static const char manifest_dep[] =
8600"<assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\" manifestVersion=\"1.0\">"
8601"<assemblyIdentity version=\"1.2.3.4\" name=\"testdep1\" type=\"win32\" processorArchitecture=\"" ARCH "\"/>"
8602" <file name=\"testdep.dll\" />"
8603"</assembly>";
8604
8605static const char manifest_main[] =
8606"<assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\" manifestVersion=\"1.0\">"
8607"<assemblyIdentity version=\"1.2.3.4\" name=\"Wine.Test\" type=\"win32\" />"
8608"<dependency>"
8609" <dependentAssembly>"
8610" <assemblyIdentity type=\"win32\" name=\"testdep1\" version=\"1.2.3.4\" processorArchitecture=\"" ARCH "\" />"
8611" </dependentAssembly>"
8612"</dependency>"
8613"</assembly>";
8614
8615static void create_manifest_file(const char *filename, const char *manifest)
8616{
8618 HANDLE file;
8619 DWORD size;
8620
8623 ok(file != INVALID_HANDLE_VALUE, "CreateFile failed: %u\n", GetLastError());
8626}
8627
8628static HANDLE test_create(const char *file)
8629{
8631 ACTCTXW actctx;
8632 HANDLE handle;
8633
8635 memset(&actctx, 0, sizeof(ACTCTXW));
8636 actctx.cbSize = sizeof(ACTCTXW);
8637 actctx.lpSource = path;
8638
8639 handle = pCreateActCtxW(&actctx);
8640 ok(handle != INVALID_HANDLE_VALUE, "failed to create context, error %u\n", GetLastError());
8641
8642 ok(actctx.cbSize == sizeof(actctx), "cbSize=%d\n", actctx.cbSize);
8643 ok(actctx.dwFlags == 0, "dwFlags=%d\n", actctx.dwFlags);
8644 ok(actctx.lpSource == path, "lpSource=%p\n", actctx.lpSource);
8645 ok(actctx.wProcessorArchitecture == 0, "wProcessorArchitecture=%d\n", actctx.wProcessorArchitecture);
8646 ok(actctx.wLangId == 0, "wLangId=%d\n", actctx.wLangId);
8647 ok(actctx.lpAssemblyDirectory == NULL, "lpAssemblyDirectory=%p\n", actctx.lpAssemblyDirectory);
8648 ok(actctx.lpResourceName == NULL, "lpResourceName=%p\n", actctx.lpResourceName);
8649 ok(actctx.lpApplicationName == NULL, "lpApplicationName=%p\n", actctx.lpApplicationName);
8650 ok(actctx.hModule == NULL, "hModule=%p\n", actctx.hModule);
8651
8652 return handle;
8653}
8654
8656{
8659 DWORD tid;
8660 WNDPROC proc;
8661 MSG msg;
8662 char buf[256];
8663 int len, expected_len;
8664 struct wnd_event wnd_event;
8665 BOOL ret;
8666
8669 {
8670 win_skip("skipping interthread message test under win9x\n");
8671 return;
8672 }
8673
8675 ok(hThread != NULL, "CreateThread failed, error %d\n", GetLastError());
8676
8677 ok(WaitForSingleObject(wnd_event.start_event, INFINITE) == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
8678
8680
8681 SetLastError(0xdeadbeef);
8682 ok(!DestroyWindow(wnd_event.hwnd), "DestroyWindow succeeded\n");
8683 ok(GetLastError() == ERROR_ACCESS_DENIED || GetLastError() == 0xdeadbeef,
8684 "wrong error code %d\n", GetLastError());
8685
8687 ok(proc != NULL, "GetWindowLongPtrA(GWLP_WNDPROC) error %d\n", GetLastError());
8688
8689 expected_len = lstrlenA("window caption text");
8690 memset(buf, 0, sizeof(buf));
8691 SetLastError(0xdeadbeef);
8693 ok(len == expected_len, "CallWindowProcA(WM_GETTEXT) error %d, len %d, expected len %d\n", GetLastError(), len, expected_len);
8694 ok(!lstrcmpA(buf, "window caption text"), "window text mismatch\n");
8695
8696 msg.hwnd = wnd_event.hwnd;
8697 msg.message = WM_GETTEXT;
8698 msg.wParam = sizeof(buf);
8699 msg.lParam = (LPARAM)buf;
8700 memset(buf, 0, sizeof(buf));
8701 SetLastError(0xdeadbeef);
8703 ok((!len && GetLastError() == ERROR_MESSAGE_SYNC_ONLY) || broken(len), /* nt4 */
8704 "DispatchMessageA(WM_GETTEXT) succeeded on another thread window: ret %d, error %d\n", len, GetLastError());
8705
8706 /* the following test causes an exception in user.exe under win9x */
8707 msg.hwnd = wnd_event.hwnd;
8708 msg.message = WM_TIMER;
8709 msg.wParam = 0;
8711 SetLastError(0xdeadbeef);
8713 ok(!len && GetLastError() == 0xdeadbeef,
8714 "DispatchMessageA(WM_TIMER) failed on another thread window: ret %d, error %d\n", len, GetLastError());
8715
8717 ok( ret, "PostMessageA(WM_QUIT) error %d\n", GetLastError());
8718
8719 ok(WaitForSingleObject(hThread, INFINITE) == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
8721
8722 ok(!IsWindow(wnd_event.hwnd), "window should be destroyed on thread exit\n");
8723
8724 wnd_event.hwnd = CreateWindowExA(0, "TestParentClass", "Test parent", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
8725 100, 100, 200, 200, 0, 0, 0, NULL);
8726 ok (wnd_event.hwnd != 0, "Failed to create parent window\n");
8727 flush_events();
8733 for (;;)
8734 {
8736 if (ret != 1) break;
8737 while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
8738 }
8739 ok( !ret, "MsgWaitForMultipleObjects failed %x\n", ret );
8740 /* now wait for the thread without processing messages; this shouldn't deadlock */
8742 ret = WaitForSingleObject( hThread, 5000 );
8743 ok( !ret, "WaitForSingleObject failed %x\n", ret );
8745
8747 ok( !ret, "WaitForSingleObject failed %x\n", ret );
8749
8752 flush_events();
8753 ok_sequence(WmExitThreadSeq, "destroy child on thread exit", FALSE);
8756
8757 /* activation context tests */
8758 if (!pActivateActCtx)
8759 {
8760 win_skip("Activation contexts are not supported, skipping\n");
8761 return;
8762 }
8763
8764 create_manifest_file("testdep1.manifest", manifest_dep);
8765 create_manifest_file("main.manifest", manifest_main);
8766
8767 context = test_create("main.manifest");
8768 DeleteFileA("testdep1.manifest");
8769 DeleteFileA("main.manifest");
8770
8771 handle = (void*)0xdeadbeef;
8772 ret = pGetCurrentActCtx(&handle);
8773 ok(ret, "GetCurrentActCtx failed: %u\n", GetLastError());
8774 ok(handle == 0, "active context %p\n", handle);
8775
8778 ok(hThread != NULL, "CreateThread failed, error %d\n", GetLastError());
8779 ok(WaitForSingleObject(wnd_event.start_event, INFINITE) == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
8781
8782 /* context is activated after thread creation, so it doesn't inherit it by default */
8783 ret = pActivateActCtx(context, &cookie);
8784 ok(ret, "activation failed: %u\n", GetLastError());
8785
8786 handle = 0;
8787 ret = pGetCurrentActCtx(&handle);
8788 ok(ret, "GetCurrentActCtx failed: %u\n", GetLastError());
8789 ok(handle != 0, "active context %p\n", handle);
8790 pReleaseActCtx(handle);
8791
8792 /* destination window will test for active context */
8793 ret = SendMessageA(wnd_event.hwnd, WM_USER+10, 0, 0);
8794 ok(ret, "thread window returned %d\n", ret);
8795
8796 event = CreateEventW(NULL, 0, 0, NULL);
8798 ok(ret, "thread window returned %d\n", ret);
8799 ok(WaitForSingleObject(event, INFINITE) == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
8801
8803 ok(ret, "PostMessageA(WM_QUIT) error %d\n", GetLastError());
8804
8805 ok(WaitForSingleObject(hThread, INFINITE) == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
8807
8808 ret = pDeactivateActCtx(0, cookie);
8809 ok(ret, "DeactivateActCtx failed: %u\n", GetLastError());
8810 pReleaseActCtx(context);
8811}
8812
8813
8814static const struct message WmVkN[] = {
8815 { HCBT_KEYSKIPPED, hook|wparam|lparam|optional, 'N', 1 }, /* XP */
8816 { WM_KEYDOWN, wparam|lparam, 'N', 1 },
8817 { WM_KEYDOWN, sent|wparam|lparam, 'N', 1 },
8818 { WM_CHAR, wparam|lparam, 'n', 1 },
8819 { WM_COMMAND, sent|wparam|lparam, MAKEWPARAM(1002,1), 0 },
8820 { HCBT_KEYSKIPPED, hook|wparam|lparam|optional, 'N', 0xc0000001 }, /* XP */
8821 { WM_KEYUP, wparam|lparam, 'N', 0xc0000001 },
8822 { WM_KEYUP, sent|wparam|lparam, 'N', 0xc0000001 },
8823 { 0 }
8824};
8825static const struct message WmShiftVkN[] = {
8829 { HCBT_KEYSKIPPED, hook|wparam|lparam|optional, 'N', 1 }, /* XP */
8830 { WM_KEYDOWN, wparam|lparam, 'N', 1 },
8831 { WM_KEYDOWN, sent|wparam|lparam, 'N', 1 },
8832 { WM_CHAR, wparam|lparam, 'N', 1 },
8833 { WM_COMMAND, sent|wparam|lparam, MAKEWPARAM(1001,1), 0 },
8834 { HCBT_KEYSKIPPED, hook|wparam|lparam|optional, 'N', 0xc0000001 }, /* XP */
8835 { WM_KEYUP, wparam|lparam, 'N', 0xc0000001 },
8836 { WM_KEYUP, sent|wparam|lparam, 'N', 0xc0000001 },
8837 { HCBT_KEYSKIPPED, hook|wparam|lparam|optional, VK_SHIFT, 0xc0000001 }, /* XP */
8838 { WM_KEYUP, wparam|lparam, VK_SHIFT, 0xc0000001 },
8839 { WM_KEYUP, sent|wparam|lparam, VK_SHIFT, 0xc0000001 },
8840 { 0 }
8841};
8842static const struct message WmCtrlVkN[] = {
8846 { HCBT_KEYSKIPPED, hook|wparam|lparam|optional, 'N', 1 }, /* XP */
8847 { WM_KEYDOWN, wparam|lparam, 'N', 1 },
8848 { WM_KEYDOWN, sent|wparam|lparam, 'N', 1 },
8849 { WM_CHAR, wparam|lparam, 0x000e, 1 },
8850 { WM_COMMAND, sent|wparam|lparam, MAKEWPARAM(1000,1), 0 },
8851 { HCBT_KEYSKIPPED, hook|wparam|lparam|optional, 'N', 0xc0000001 }, /* XP */
8852 { WM_KEYUP, wparam|lparam, 'N', 0xc0000001 },
8853 { WM_KEYUP, sent|wparam|lparam, 'N', 0xc0000001 },
8854 { HCBT_KEYSKIPPED, hook|wparam|lparam|optional, VK_CONTROL, 0xc0000001 }, /* XP */
8855 { WM_KEYUP, wparam|lparam, VK_CONTROL, 0xc0000001 },
8856 { WM_KEYUP, sent|wparam|lparam, VK_CONTROL, 0xc0000001 },
8857 { 0 }
8858};
8859static const struct message WmCtrlVkN_2[] = {
8863 { HCBT_KEYSKIPPED, hook|wparam|lparam|optional, 'N', 1 }, /* XP */
8864 { WM_KEYDOWN, wparam|lparam, 'N', 1 },
8865 { WM_COMMAND, sent|wparam|lparam, MAKEWPARAM(1000,1), 0 },
8866 { HCBT_KEYSKIPPED, hook|wparam|lparam|optional, 'N', 0xc0000001 }, /* XP */
8867 { WM_KEYUP, wparam|lparam, 'N', 0xc0000001 },
8868 { WM_KEYUP, sent|wparam|lparam, 'N', 0xc0000001 },
8869 { HCBT_KEYSKIPPED, hook|wparam|lparam|optional, VK_CONTROL, 0xc0000001 }, /* XP */
8870 { WM_KEYUP, wparam|lparam, VK_CONTROL, 0xc0000001 },
8871 { WM_KEYUP, sent|wparam|lparam, VK_CONTROL, 0xc0000001 },
8872 { 0 }
8873};
8874static const struct message WmAltVkN[] = {
8875 { HCBT_KEYSKIPPED, hook|wparam|lparam|optional, VK_MENU, 0x20000001 }, /* XP */
8876 { WM_SYSKEYDOWN, wparam|lparam, VK_MENU, 0x20000001 },
8877 { WM_SYSKEYDOWN, sent|wparam|lparam, VK_MENU, 0x20000001 },
8878 { HCBT_KEYSKIPPED, hook|wparam|lparam|optional, 'N', 0x20000001 }, /* XP */
8879 { WM_SYSKEYDOWN, wparam|lparam, 'N', 0x20000001 },
8880 { WM_SYSKEYDOWN, sent|wparam|lparam, 'N', 0x20000001 },
8881 { WM_SYSCHAR, wparam|lparam, 'n', 0x20000001 },
8882 { WM_SYSCHAR, sent|wparam|lparam, 'n', 0x20000001 },
8884 { HCBT_SYSCOMMAND, hook },
8886 { EVENT_SYSTEM_CAPTURESTART, winevent_hook|wparam|lparam, 0, 0 },
8887 { 0x00AE, sent|defwinproc|optional }, /* XP */
8888 { WM_GETTEXT, sent|defwinproc|optional }, /* XP */
8890 { EVENT_SYSTEM_MENUSTART, winevent_hook|wparam|lparam, OBJID_SYSMENU, 0 },
8892 { EVENT_SYSTEM_CAPTUREEND, winevent_hook|wparam|lparam, 0, 0 },
8895 { EVENT_SYSTEM_MENUEND, winevent_hook|wparam|lparam, OBJID_SYSMENU, 0 },
8897 { WM_MENUSELECT, sent|defwinproc|wparam|optional, MAKEWPARAM(0,0xffff) }, /* Win95 bug */
8898 { WM_EXITMENULOOP, sent|defwinproc|optional }, /* Win95 bug */
8899 { HCBT_KEYSKIPPED, hook|wparam|lparam|optional, 'N', 0xe0000001 }, /* XP */
8900 { WM_SYSKEYUP, wparam|lparam, 'N', 0xe0000001 },
8901 { WM_SYSKEYUP, sent|wparam|lparam, 'N', 0xe0000001 },
8902 { HCBT_KEYSKIPPED, hook|wparam|lparam|optional, VK_MENU, 0xc0000001 }, /* XP */
8903 { WM_KEYUP, wparam|lparam, VK_MENU, 0xc0000001 },
8904 { WM_KEYUP, sent|wparam|lparam, VK_MENU, 0xc0000001 },
8905 { 0 }
8906};
8907static const struct message WmAltVkN_2[] = {
8908 { HCBT_KEYSKIPPED, hook|wparam|lparam|optional, VK_MENU, 0x20000001 }, /* XP */
8909 { WM_SYSKEYDOWN, wparam|lparam, VK_MENU, 0x20000001 },
8910 { WM_SYSKEYDOWN, sent|wparam|lparam, VK_MENU, 0x20000001 },
8911 { HCBT_KEYSKIPPED, hook|wparam|lparam|optional, 'N', 0x20000001 }, /* XP */
8912 { WM_SYSKEYDOWN, wparam|lparam, 'N', 0x20000001 },
8913 { WM_COMMAND, sent|wparam|lparam, MAKEWPARAM(1003,1), 0 },
8914 { HCBT_KEYSKIPPED, hook|wparam|lparam|optional, 'N', 0xe0000001 }, /* XP */
8915 { WM_SYSKEYUP, wparam|lparam, 'N', 0xe0000001 },
8916 { WM_SYSKEYUP, sent|wparam|lparam, 'N', 0xe0000001 },
8917 { HCBT_KEYSKIPPED, hook|wparam|lparam|optional, VK_MENU, 0xc0000001 }, /* XP */
8918 { WM_KEYUP, wparam|lparam, VK_MENU, 0xc0000001 },
8919 { WM_KEYUP, sent|wparam|lparam, VK_MENU, 0xc0000001 },
8920 { 0 }
8921};
8922static const struct message WmCtrlAltVkN[] = {
8926 { HCBT_KEYSKIPPED, hook|wparam|lparam|optional, VK_MENU, 0x20000001 }, /* XP */
8927 { WM_KEYDOWN, wparam|lparam, VK_MENU, 0x20000001 },
8928 { WM_KEYDOWN, sent|wparam|lparam, VK_MENU, 0x20000001 },
8929 { HCBT_KEYSKIPPED, hook|wparam|lparam|optional, 'N', 0x20000001 }, /* XP */
8930 { WM_KEYDOWN, wparam|lparam, 'N', 0x20000001 },
8931 { WM_KEYDOWN, sent|wparam|lparam, 'N', 0x20000001 },
8932 { WM_CHAR, optional },
8933 { WM_CHAR, sent|optional },
8934 { HCBT_KEYSKIPPED, hook|wparam|lparam|optional, 'N', 0xe0000001 }, /* XP */
8935 { WM_KEYUP, wparam|lparam, 'N', 0xe0000001 },
8936 { WM_KEYUP, sent|wparam|lparam, 'N', 0xe0000001 },
8937 { HCBT_KEYSKIPPED, hook|wparam|lparam|optional, VK_MENU, 0xc0000001 }, /* XP */
8938 { WM_KEYUP, wparam|lparam, VK_MENU, 0xc0000001 },
8939 { WM_KEYUP, sent|wparam|lparam, VK_MENU, 0xc0000001 },
8940 { HCBT_KEYSKIPPED, hook|wparam|lparam|optional, VK_CONTROL, 0xc0000001 }, /* XP */
8941 { WM_KEYUP, wparam|lparam, VK_CONTROL, 0xc0000001 },
8942 { WM_KEYUP, sent|wparam|lparam, VK_CONTROL, 0xc0000001 },
8943 { 0 }
8944};
8945static const struct message WmCtrlShiftVkN[] = {
8952 { HCBT_KEYSKIPPED, hook|wparam|lparam|optional, 'N', 1 }, /* XP */
8953 { WM_KEYDOWN, wparam|lparam, 'N', 1 },
8954 { WM_COMMAND, sent|wparam|lparam, MAKEWPARAM(1004,1), 0 },
8955 { HCBT_KEYSKIPPED, hook|wparam|lparam|optional, 'N', 0xc0000001 }, /* XP */
8956 { WM_KEYUP, wparam|lparam, 'N', 0xc0000001 },
8957 { WM_KEYUP, sent|wparam|lparam, 'N', 0xc0000001 },
8958 { HCBT_KEYSKIPPED, hook|wparam|lparam|optional, VK_SHIFT, 0xc0000001 }, /* XP */
8959 { WM_KEYUP, wparam|lparam, VK_SHIFT, 0xc0000001 },
8960 { WM_KEYUP, sent|wparam|lparam, VK_SHIFT, 0xc0000001 },
8961 { HCBT_KEYSKIPPED, hook|wparam|lparam|optional, VK_CONTROL, 0xc0000001 }, /* XP */
8962 { WM_KEYUP, wparam|lparam, VK_CONTROL, 0xc0000001 },
8963 { WM_KEYUP, sent|wparam|lparam, VK_CONTROL, 0xc0000001 },
8964 { 0 }
8965};
8966static const struct message WmCtrlAltShiftVkN[] = {
8970 { HCBT_KEYSKIPPED, hook|wparam|lparam|optional, VK_MENU, 0x20000001 }, /* XP */
8971 { WM_KEYDOWN, wparam|lparam, VK_MENU, 0x20000001 },
8972 { WM_KEYDOWN, sent|wparam|lparam, VK_MENU, 0x20000001 },
8973 { HCBT_KEYSKIPPED, hook|wparam|lparam|optional, VK_SHIFT, 0x20000001 }, /* XP */
8974 { WM_KEYDOWN, wparam|lparam, VK_SHIFT, 0x20000001 },
8975 { WM_KEYDOWN, sent|wparam|lparam, VK_SHIFT, 0x20000001 },
8976 { HCBT_KEYSKIPPED, hook|wparam|lparam|optional, 'N', 0x20000001 }, /* XP */
8977 { WM_KEYDOWN, wparam|lparam, 'N', 0x20000001 },
8978 { WM_COMMAND, sent|wparam|lparam, MAKEWPARAM(1005,1), 0 },
8979 { HCBT_KEYSKIPPED, hook|wparam|lparam|optional, 'N', 0xe0000001 }, /* XP */
8980 { WM_KEYUP, wparam|lparam, 'N', 0xe0000001 },
8981 { WM_KEYUP, sent|wparam|lparam, 'N', 0xe0000001 },
8982 { HCBT_KEYSKIPPED, hook|wparam|lparam|optional, VK_SHIFT, 0xe0000001 }, /* XP */
8983 { WM_KEYUP, wparam|lparam, VK_SHIFT, 0xe0000001 },
8984 { WM_KEYUP, sent|wparam|lparam, VK_SHIFT, 0xe0000001 },
8985 { HCBT_KEYSKIPPED, hook|wparam|lparam|optional, VK_MENU, 0xc0000001 }, /* XP */
8986 { WM_KEYUP, wparam|lparam, VK_MENU, 0xc0000001 },
8987 { WM_KEYUP, sent|wparam|lparam, VK_MENU, 0xc0000001 },
8988 { HCBT_KEYSKIPPED, hook|wparam|lparam|optional, VK_CONTROL, 0xc0000001 }, /* XP */
8989 { WM_KEYUP, wparam|lparam, VK_CONTROL, 0xc0000001 },
8990 { WM_KEYUP, sent|wparam|lparam, VK_CONTROL, 0xc0000001 },
8991 { 0 }
8992};
8993static const struct message WmAltPressRelease[] = {
8994 { HCBT_KEYSKIPPED, hook|wparam|lparam|optional, VK_MENU, 0x20000001 }, /* XP */
8995 { WM_SYSKEYDOWN, wparam|lparam, VK_MENU, 0x20000001 },
8996 { WM_SYSKEYDOWN, sent|wparam|lparam, VK_MENU, 0x20000001 },
8997 { HCBT_KEYSKIPPED, hook|wparam|lparam|optional, VK_MENU, 0xc0000001 }, /* XP */
8998 { WM_SYSKEYUP, wparam|lparam, VK_MENU, 0xc0000001 },
8999 { WM_SYSKEYUP, sent|wparam|lparam, VK_MENU, 0xc0000001 },
9001 { HCBT_SYSCOMMAND, hook },
9003 { EVENT_SYSTEM_CAPTURESTART, winevent_hook|wparam|lparam, 0, 0 },
9005 { EVENT_SYSTEM_MENUSTART, winevent_hook|wparam|lparam, OBJID_SYSMENU, 0 },
9007 { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_SYSMENU, 1 },
9008
9009 { HCBT_KEYSKIPPED, hook|wparam|lparam|optional, VK_MENU, 0x30000001 }, /* XP */
9010
9011 { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_SYSMENU, 0 },
9012 { EVENT_SYSTEM_CAPTUREEND, winevent_hook|wparam|lparam, 0, 0, },
9015 { EVENT_SYSTEM_MENUEND, winevent_hook|wparam|lparam, OBJID_SYSMENU, 0 },
9017 { HCBT_KEYSKIPPED, hook|wparam|lparam|optional, VK_MENU, 0xc0000001 }, /* XP */
9018 { WM_SYSKEYUP, wparam|lparam, VK_MENU, 0xc0000001 },
9019 { WM_SYSKEYUP, sent|wparam|lparam, VK_MENU, 0xc0000001 },
9020 { 0 }
9021};
9022static const struct message WmShiftMouseButton[] = {
9026 { WM_MOUSEMOVE, wparam|optional, 0, 0 },
9027 { WM_MOUSEMOVE, sent|wparam|optional, 0, 0 },
9030 { WM_LBUTTONUP, wparam, MK_SHIFT, 0 },
9032 { HCBT_KEYSKIPPED, hook|wparam|lparam|optional, VK_SHIFT, 0xc0000001 }, /* XP */
9033 { WM_KEYUP, wparam|lparam, VK_SHIFT, 0xc0000001 },
9034 { WM_KEYUP, sent|wparam|lparam, VK_SHIFT, 0xc0000001 },
9035 { 0 }
9036};
9037static const struct message WmF1Seq[] = {
9038 { HCBT_KEYSKIPPED, hook|wparam|lparam|optional, VK_F1, 1 }, /* XP */
9039 { WM_KEYDOWN, wparam|lparam, VK_F1, 1 },
9040 { WM_KEYDOWN, sent|wparam|lparam, VK_F1, 0x00000001 },
9041 { WM_KEYF1, wparam|lparam, 0, 0 },
9042 { WM_KEYF1, sent|wparam|lparam, 0, 0 },
9043 { WM_HELP, sent|defwinproc },
9044 { HCBT_KEYSKIPPED, hook|wparam|lparam|optional, VK_F1, 0xc0000001 }, /* XP */
9045 { WM_KEYUP, wparam|lparam, VK_F1, 0xc0000001 },
9046 { WM_KEYUP, sent|wparam|lparam, VK_F1, 0xc0000001 },
9047 { 0 }
9048};
9049static const struct message WmVkAppsSeq[] = {
9052 { WM_KEYDOWN, sent|wparam|lparam, VK_APPS, 0x00000001 },
9053 { HCBT_KEYSKIPPED, hook|wparam|lparam|optional, VK_APPS, 0xc0000001 }, /* XP */
9054 { WM_KEYUP, wparam|lparam, VK_APPS, 0xc0000001 },
9055 { WM_KEYUP, sent|wparam|lparam, VK_APPS, 0xc0000001 },
9056 { WM_CONTEXTMENU, lparam, /*hwnd*/0, -1 },
9057 { WM_CONTEXTMENU, sent|lparam, /*hwnd*/0, -1 },
9058 { 0 }
9059};
9060static const struct message WmVkF10Seq[] = {
9061 { HCBT_KEYSKIPPED, hook|wparam|lparam|optional, VK_F10, 1 }, /* XP */
9063 { WM_SYSKEYDOWN, sent|wparam|lparam, VK_F10, 0x00000001 },
9064 { HCBT_KEYSKIPPED, hook|wparam|lparam|optional, VK_F10, 0xc0000001 }, /* XP */
9065 { WM_SYSKEYUP, wparam|lparam, VK_F10, 0xc0000001 },
9066 { WM_SYSKEYUP, sent|wparam|lparam, VK_F10, 0xc0000001 },
9068 { HCBT_SYSCOMMAND, hook },
9070 { EVENT_SYSTEM_CAPTURESTART, winevent_hook|wparam|lparam, 0, 0 },
9072 { EVENT_SYSTEM_MENUSTART, winevent_hook|wparam|lparam, OBJID_SYSMENU, 0 },
9074 { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_SYSMENU, 1 },
9075
9076 { HCBT_KEYSKIPPED, hook|wparam|lparam|optional, VK_F10, 0x10000001 }, /* XP */
9077
9078 { HCBT_KEYSKIPPED, hook|wparam|lparam|optional, VK_F10, 1 }, /* XP */
9079 { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_SYSMENU, 0 },
9080 { EVENT_SYSTEM_CAPTUREEND, winevent_hook|wparam|lparam, 0, 0, },
9083 { EVENT_SYSTEM_MENUEND, winevent_hook|wparam|lparam, OBJID_SYSMENU, 0 },
9085 { HCBT_KEYSKIPPED, hook|wparam|lparam|optional, VK_F10, 0xc0000001 }, /* XP */
9086 { WM_SYSKEYUP, wparam|lparam, VK_F10, 0xc0000001 },
9087 { WM_SYSKEYUP, sent|wparam|lparam, VK_F10, 0xc0000001 },
9088 { 0 }
9089};
9090static const struct message WmShiftF10Seq[] = {
9093 { WM_KEYDOWN, sent|wparam|lparam, VK_SHIFT, 0x00000001 },
9094 { HCBT_KEYSKIPPED, hook|wparam|lparam|optional, VK_F10, 1 }, /* XP */
9096 { WM_SYSKEYDOWN, sent|wparam|lparam, VK_F10, 0x00000001 },
9097 { WM_CONTEXTMENU, sent|defwinproc|lparam, /*hwnd*/0, -1 },
9098 { HCBT_KEYSKIPPED, hook|wparam|lparam|optional, VK_F10, 0xc0000001 }, /* XP */
9099 { WM_SYSKEYUP, wparam|lparam, VK_F10, 0xc0000001 },
9100 { WM_SYSKEYUP, sent|wparam|lparam, VK_F10, 0xc0000001 },
9102 { HCBT_SYSCOMMAND, hook },
9106 { HCBT_KEYSKIPPED, hook|wparam|lparam|optional, VK_SHIFT, 0xd0000001 }, /* XP */
9107 { HCBT_KEYSKIPPED, hook|wparam|lparam|optional, VK_ESCAPE, 0x10000001 }, /* XP */
9109 { WM_MENUSELECT, sent|defwinproc|wparam|lparam, 0xffff0000, 0 },
9111 { HCBT_KEYSKIPPED, hook|wparam|lparam|optional, VK_ESCAPE, 0xc0000001 }, /* XP */
9112 { WM_KEYUP, wparam|lparam, VK_ESCAPE, 0xc0000001 },
9113 { WM_KEYUP, sent|wparam|lparam, VK_ESCAPE, 0xc0000001 },
9114 { 0 }
9115};
9116
9117static void pump_msg_loop(HWND hwnd, HACCEL hAccel)
9118{
9119 MSG msg;
9120
9121 while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE))
9122 {
9123 struct recvd_message log_msg;
9124
9125 /* ignore some unwanted messages */
9126 if (msg.message == WM_MOUSEMOVE ||
9127 msg.message == WM_TIMER ||
9128 ignore_message( msg.message ))
9129 continue;
9130
9131 log_msg.hwnd = msg.hwnd;
9132 log_msg.message = msg.message;
9133 log_msg.flags = wparam|lparam;
9134 log_msg.wParam = msg.wParam;
9135 log_msg.lParam = msg.lParam;
9136 log_msg.descr = "accel";
9137 add_message(&log_msg);
9138
9140 {
9143 }
9144 }
9145}
9146
9147static void test_accelerators(void)
9148{
9149 RECT rc;
9150 POINT pt;
9151 SHORT state;
9152 HACCEL hAccel;
9153 HWND hwnd = CreateWindowExA(0, "TestWindowClass", NULL, WS_OVERLAPPEDWINDOW | WS_VISIBLE,
9154 100, 100, 200, 200, 0, 0, 0, NULL);
9155 BOOL ret;
9156
9157 assert(hwnd != 0);
9159 flush_events();
9161
9162 SetFocus(hwnd);
9163 ok(GetFocus() == hwnd, "wrong focus window %p\n", GetFocus());
9164
9166 ok(!(state & 0x8000), "wrong Shift state %04x\n", state);
9168 ok(state == 0, "wrong CapsLock state %04x\n", state);
9169
9171 assert(hAccel != 0);
9172
9173 flush_events();
9174 pump_msg_loop(hwnd, 0);
9176
9177 trace("testing VK_N press/release\n");
9179 keybd_event('N', 0, 0, 0);
9180 keybd_event('N', 0, KEYEVENTF_KEYUP, 0);
9182 if (!sequence_cnt) /* we didn't get any message */
9183 {
9184 skip( "queuing key events not supported\n" );
9185 goto done;
9186 }
9187 ok_sequence(WmVkN, "VK_N press/release", FALSE);
9188
9189 trace("testing Shift+VK_N press/release\n");
9191 keybd_event(VK_SHIFT, 0, 0, 0);
9192 keybd_event('N', 0, 0, 0);
9193 keybd_event('N', 0, KEYEVENTF_KEYUP, 0);
9196 ok_sequence(WmShiftVkN, "Shift+VK_N press/release", FALSE);
9197
9198 trace("testing Ctrl+VK_N press/release\n");
9200 keybd_event(VK_CONTROL, 0, 0, 0);
9201 keybd_event('N', 0, 0, 0);
9202 keybd_event('N', 0, KEYEVENTF_KEYUP, 0);
9205 ok_sequence(WmCtrlVkN, "Ctrl+VK_N press/release", FALSE);
9206
9207 trace("testing Alt+VK_N press/release\n");
9209 keybd_event(VK_MENU, 0, 0, 0);
9210 keybd_event('N', 0, 0, 0);
9211 keybd_event('N', 0, KEYEVENTF_KEYUP, 0);
9214 ok_sequence(WmAltVkN, "Alt+VK_N press/release", FALSE);
9215
9216 trace("testing Ctrl+Alt+VK_N press/release 1\n");
9218 keybd_event(VK_CONTROL, 0, 0, 0);
9219 keybd_event(VK_MENU, 0, 0, 0);
9220 keybd_event('N', 0, 0, 0);
9221 keybd_event('N', 0, KEYEVENTF_KEYUP, 0);
9225 ok_sequence(WmCtrlAltVkN, "Ctrl+Alt+VK_N press/release 1", FALSE);
9226
9228 ok( ret, "DestroyAcceleratorTable error %d\n", GetLastError());
9229
9231 assert(hAccel != 0);
9232
9233 trace("testing VK_N press/release\n");
9235 keybd_event('N', 0, 0, 0);
9236 keybd_event('N', 0, KEYEVENTF_KEYUP, 0);
9238 ok_sequence(WmVkN, "VK_N press/release", FALSE);
9239
9240 trace("testing Shift+VK_N press/release\n");
9242 keybd_event(VK_SHIFT, 0, 0, 0);
9243 keybd_event('N', 0, 0, 0);
9244 keybd_event('N', 0, KEYEVENTF_KEYUP, 0);
9247 ok_sequence(WmShiftVkN, "Shift+VK_N press/release", FALSE);
9248
9249 trace("testing Ctrl+VK_N press/release 2\n");
9251 keybd_event(VK_CONTROL, 0, 0, 0);
9252 keybd_event('N', 0, 0, 0);
9253 keybd_event('N', 0, KEYEVENTF_KEYUP, 0);
9256 ok_sequence(WmCtrlVkN_2, "Ctrl+VK_N press/release 2", FALSE);
9257
9258 trace("testing Alt+VK_N press/release 2\n");
9260 keybd_event(VK_MENU, 0, 0, 0);
9261 keybd_event('N', 0, 0, 0);
9262 keybd_event('N', 0, KEYEVENTF_KEYUP, 0);
9265 ok_sequence(WmAltVkN_2, "Alt+VK_N press/release 2", FALSE);
9266
9267 trace("testing Ctrl+Alt+VK_N press/release 2\n");
9269 keybd_event(VK_CONTROL, 0, 0, 0);
9270 keybd_event(VK_MENU, 0, 0, 0);
9271 keybd_event('N', 0, 0, 0);
9272 keybd_event('N', 0, KEYEVENTF_KEYUP, 0);
9276 ok_sequence(WmCtrlAltVkN, "Ctrl+Alt+VK_N press/release 2", FALSE);
9277
9278 trace("testing Ctrl+Shift+VK_N press/release\n");
9280 keybd_event(VK_CONTROL, 0, 0, 0);
9281 keybd_event(VK_SHIFT, 0, 0, 0);
9282 keybd_event('N', 0, 0, 0);
9283 keybd_event('N', 0, KEYEVENTF_KEYUP, 0);
9287 ok_sequence(WmCtrlShiftVkN, "Ctrl+Shift+VK_N press/release", FALSE);
9288
9289 trace("testing Ctrl+Alt+Shift+VK_N press/release\n");
9291 keybd_event(VK_CONTROL, 0, 0, 0);
9292 keybd_event(VK_MENU, 0, 0, 0);
9293 keybd_event(VK_SHIFT, 0, 0, 0);
9294 keybd_event('N', 0, 0, 0);
9295 keybd_event('N', 0, KEYEVENTF_KEYUP, 0);
9300 ok_sequence(WmCtrlAltShiftVkN, "Ctrl+Alt+Shift+VK_N press/release", FALSE);
9301
9303 ok( ret, "DestroyAcceleratorTable error %d\n", GetLastError());
9304 hAccel = 0;
9305
9306 trace("testing Alt press/release\n");
9308 keybd_event(VK_MENU, 0, 0, 0);
9310 keybd_event(VK_MENU, 0, 0, 0);
9312 pump_msg_loop(hwnd, 0);
9313 /* this test doesn't pass in Wine for managed windows */
9314 ok_sequence(WmAltPressRelease, "Alt press/release", TRUE);
9315
9316 trace("testing VK_F1 press/release\n");
9317 keybd_event(VK_F1, 0, 0, 0);
9319 pump_msg_loop(hwnd, 0);
9320 ok_sequence(WmF1Seq, "F1 press/release", FALSE);
9321
9322 trace("testing VK_APPS press/release\n");
9323 keybd_event(VK_APPS, 0, 0, 0);
9325 pump_msg_loop(hwnd, 0);
9326 ok_sequence(WmVkAppsSeq, "VK_APPS press/release", FALSE);
9327
9328 trace("testing VK_F10 press/release\n");
9329 keybd_event(VK_F10, 0, 0, 0);
9331 keybd_event(VK_F10, 0, 0, 0);
9333 pump_msg_loop(hwnd, 0);
9334 ok_sequence(WmVkF10Seq, "VK_F10 press/release", TRUE);
9335
9336 trace("testing SHIFT+F10 press/release\n");
9337 keybd_event(VK_SHIFT, 0, 0, 0);
9338 keybd_event(VK_F10, 0, 0, 0);
9341 keybd_event(VK_ESCAPE, 0, 0, 0);
9343 pump_msg_loop(hwnd, 0);
9344 ok_sequence(WmShiftF10Seq, "SHIFT+F10 press/release", TRUE);
9345
9346 trace("testing Shift+MouseButton press/release\n");
9347 /* first, move mouse pointer inside of the window client area */
9348 GetClientRect(hwnd, &rc);
9349 MapWindowPoints(hwnd, 0, (LPPOINT)&rc, 2);
9350 rc.left += (rc.right - rc.left)/2;
9351 rc.top += (rc.bottom - rc.top)/2;
9352 SetCursorPos(rc.left, rc.top);
9354
9355 flush_events();
9357 GetCursorPos(&pt);
9358 if (pt.x == rc.left && pt.y == rc.top)
9359 {
9360 int i;
9361 keybd_event(VK_SHIFT, 0, 0, 0);
9362 mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);
9363 mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
9365 pump_msg_loop(hwnd, 0);
9366 for (i = 0; i < sequence_cnt; i++) if (sequence[i].message == WM_LBUTTONDOWN) break;
9367 if (i < sequence_cnt)
9368 ok_sequence(WmShiftMouseButton, "Shift+MouseButton press/release", FALSE);
9369 else
9370 skip( "Shift+MouseButton event didn't get to the window\n" );
9371 }
9372
9373done:
9376}
9377
9378/************* window procedures ********************/
9379
9382{
9383 static LONG defwndproc_counter = 0;
9384 static LONG beginpaint_counter = 0;
9385 LRESULT ret;
9386 struct recvd_message msg;
9387
9388 if (ignore_message( message )) return 0;
9389
9390 switch (message)
9391 {
9392 case WM_ENABLE:
9393 {
9395 ok((BOOL)wParam == !(style & WS_DISABLED),
9396 "wrong WS_DISABLED state: %ld != %d\n", wParam, !(style & WS_DISABLED));
9397 break;
9398 }
9399
9400 case WM_CAPTURECHANGED:
9402 {
9404 if (style & WS_CHILD)
9406 else if (style & WS_POPUP)
9408 else
9410 }
9411 break;
9412
9413 case WM_NCDESTROY:
9414 {
9415 HWND capture;
9416
9417 ok(!GetWindow(hwnd, GW_CHILD), "children should be unlinked at this point\n");
9418 capture = GetCapture();
9419 if (capture)
9420 {
9421 ok(capture == hwnd, "capture should NOT be released at this point (capture %p)\n", capture);
9422 trace("current capture %p, releasing...\n", capture);
9424 }
9425 }
9426 /* fall through */
9427 case WM_DESTROY:
9428 if (pGetAncestor)
9429 ok(pGetAncestor(hwnd, GA_PARENT) != 0, "parent should NOT be unlinked at this point\n");
9431 {
9433 if (style & WS_CHILD)
9435 else if (style & WS_POPUP)
9437 else
9439 }
9440 break;
9441
9442 /* test_accelerators() depends on this */
9443 case WM_NCHITTEST:
9444 return HTCLIENT;
9445
9446 case WM_USER+10:
9447 {
9448 ACTIVATION_CONTEXT_BASIC_INFORMATION basicinfo;
9449 HANDLE handle, event = (HANDLE)lParam;
9450 BOOL ret;
9451
9452 handle = (void*)0xdeadbeef;
9453 ret = pGetCurrentActCtx(&handle);
9454 ok(ret, "failed to get current context, %u\n", GetLastError());
9455 ok(handle == 0, "got active context %p\n", handle);
9456
9457 memset(&basicinfo, 0xff, sizeof(basicinfo));
9458 ret = pQueryActCtxW(QUERY_ACTCTX_FLAG_USE_ACTIVE_ACTCTX, handle, 0, ActivationContextBasicInformation,
9459 &basicinfo, sizeof(basicinfo), NULL);
9460 ok(ret, "got %d, error %d\n", ret, GetLastError());
9461 ok(basicinfo.hActCtx == NULL, "got %p\n", basicinfo.hActCtx);
9462 ok(basicinfo.dwFlags == 0, "got %x\n", basicinfo.dwFlags);
9463
9464 if (event) SetEvent(event);
9465 return 1;
9466 }
9467
9468 /* ignore */
9469 case WM_MOUSEMOVE:
9470 case WM_MOUSEACTIVATE:
9471 case WM_NCMOUSEMOVE:
9472 case WM_SETCURSOR:
9473 case WM_IME_SELECT:
9474 return 0;
9475 }
9476
9477 msg.hwnd = hwnd;
9478 msg.message = message;
9479 msg.flags = sent|wparam|lparam;
9480 if (defwndproc_counter) msg.flags |= defwinproc;
9481 if (beginpaint_counter) msg.flags |= beginpaint;
9482 msg.wParam = wParam;
9483 msg.lParam = lParam;
9484 msg.descr = "MsgCheckProc";
9485 add_message(&msg);
9486
9488 {
9490 RECT rc;
9491 MINMAXINFO *minmax = (MINMAXINFO *)lParam;
9492
9493 GetClientRect(parent, &rc);
9494 trace("parent %p client size = (%d x %d)\n", parent, rc.right, rc.bottom);
9495 trace("Reserved=%d,%d MaxSize=%d,%d MaxPos=%d,%d MinTrack=%d,%d MaxTrack=%d,%d\n",
9496 minmax->ptReserved.x, minmax->ptReserved.y,
9497 minmax->ptMaxSize.x, minmax->ptMaxSize.y,
9498 minmax->ptMaxPosition.x, minmax->ptMaxPosition.y,
9499 minmax->ptMinTrackSize.x, minmax->ptMinTrackSize.y,
9500 minmax->ptMaxTrackSize.x, minmax->ptMaxTrackSize.y);
9501
9502 ok(minmax->ptMaxSize.x == rc.right, "default width of maximized child %d != %d\n",
9503 minmax->ptMaxSize.x, rc.right);
9504 ok(minmax->ptMaxSize.y == rc.bottom, "default height of maximized child %d != %d\n",
9505 minmax->ptMaxSize.y, rc.bottom);
9506 }
9507
9508 if (message == WM_PAINT)
9509 {
9510 PAINTSTRUCT ps;
9511 beginpaint_counter++;
9512 BeginPaint( hwnd, &ps );
9513 beginpaint_counter--;
9514 EndPaint( hwnd, &ps );
9515 return 0;
9516 }
9517
9519 {
9520 /* don't create context menu */
9521 return 0;
9522 }
9523
9524 defwndproc_counter++;
9525 ret = unicode ? DefWindowProcW(hwnd, message, wParam, lParam)
9527 defwndproc_counter--;
9528
9529 return ret;
9530}
9531
9533{
9535}
9536
9538{
9540}
9541
9543{
9544 static LONG defwndproc_counter = 0;
9545 LRESULT ret;
9546 struct recvd_message msg;
9547
9548 if (ignore_message( message )) return 0;
9549
9550 switch (message)
9551 {
9552 case WM_QUERYENDSESSION:
9553 case WM_ENDSESSION:
9554 lParam &= ~0x01; /* Vista adds a 0x01 flag */
9555 break;
9556 }
9557
9558 msg.hwnd = hwnd;
9559 msg.message = message;
9560 msg.flags = sent|wparam|lparam;
9561 if (defwndproc_counter) msg.flags |= defwinproc;
9562 msg.wParam = wParam;
9563 msg.lParam = lParam;
9564 msg.descr = "popup";
9565 add_message(&msg);
9566
9567 if (message == WM_CREATE)
9568 {
9571 }
9572
9573 defwndproc_counter++;
9575 defwndproc_counter--;
9576
9577 return ret;
9578}
9579
9581{
9582 static LONG defwndproc_counter = 0;
9583 static LONG beginpaint_counter = 0;
9584 LRESULT ret;
9585 struct recvd_message msg;
9586
9587 if (ignore_message( message )) return 0;
9588
9595 {
9596 switch (message)
9597 {
9598 /* ignore */
9599 case WM_NCHITTEST:
9600 return HTCLIENT;
9601 case WM_SETCURSOR:
9602 case WM_MOUSEMOVE:
9603 case WM_NCMOUSEMOVE:
9604 return 0;
9605
9606 case WM_ERASEBKGND:
9607 {
9608 RECT rc;
9609 INT ret = GetClipBox((HDC)wParam, &rc);
9610
9611 trace("WM_ERASEBKGND: GetClipBox()=%d, %s\n", ret, wine_dbgstr_rect(&rc));
9612 break;
9613 }
9614 }
9615
9616 msg.hwnd = hwnd;
9617 msg.message = message;
9618 msg.flags = sent|parent|wparam|lparam;
9619 if (defwndproc_counter) msg.flags |= defwinproc;
9620 if (beginpaint_counter) msg.flags |= beginpaint;
9621 msg.wParam = wParam;
9622 msg.lParam = lParam;
9623 msg.descr = "parent";
9624 add_message(&msg);
9625 }
9626
9627 if (message == WM_PAINT)
9628 {
9629 PAINTSTRUCT ps;
9630 beginpaint_counter++;
9631 BeginPaint( hwnd, &ps );
9632 beginpaint_counter--;
9633 EndPaint( hwnd, &ps );
9634 return 0;
9635 }
9636
9637 defwndproc_counter++;
9639 defwndproc_counter--;
9640
9641 return message == WM_COMPAREITEM ? -1 : ret;
9642}
9643
9645{
9646 if (message == WM_CREATE)
9647 PostMessageA(hwnd, WM_CLOSE, 0, 0);
9648 else if (message == WM_CLOSE)
9649 {
9650 /* Only the first WM_QUIT will survive the window destruction */
9651 PostMessageA(hwnd, WM_USER, 0x1234, 0x5678);
9652 PostMessageA(hwnd, WM_QUIT, 0x1234, 0x5678);
9653 PostMessageA(hwnd, WM_QUIT, 0x4321, 0x8765);
9654 }
9655
9656 return DefWindowProcA(hwnd, message, wp, lp);
9657}
9658
9660{
9661 static LONG defwndproc_counter = 0;
9662 LRESULT ret;
9663 struct recvd_message msg;
9664
9665 if (ignore_message( message )) return 0;
9666
9667 if (test_def_id)
9668 {
9670 ret = DefDlgProcA(hwnd, DM_GETDEFID, 0, 0);
9671 if (after_end_dialog)
9672 ok( ret == 0, "DM_GETDEFID should return 0 after EndDialog, got %lx\n", ret );
9673 else
9674 ok(HIWORD(ret) == DC_HASDEFID, "DM_GETDEFID should return DC_HASDEFID, got %lx\n", ret);
9675 }
9676
9677 msg.hwnd = hwnd;
9678 msg.message = message;
9679 msg.flags = sent|wparam|lparam;
9680 if (defwndproc_counter) msg.flags |= defwinproc;
9681 msg.wParam = wParam;
9682 msg.lParam = lParam;
9683 msg.descr = "dialog";
9684 add_message(&msg);
9685
9686 defwndproc_counter++;
9688 defwndproc_counter--;
9689
9690 return ret;
9691}
9692
9694{
9695 static LONG defwndproc_counter = 0;
9696 LRESULT ret;
9697 struct recvd_message msg;
9698
9699 /* log only specific messages we are interested in */
9700 switch (message)
9701 {
9702#if 0 /* probably log these as well */
9703 case WM_ACTIVATE:
9704 case WM_SETFOCUS:
9705 case WM_KILLFOCUS:
9706#endif
9707 case WM_SHOWWINDOW:
9708 case WM_SIZE:
9709 case WM_MOVE:
9710 case WM_GETMINMAXINFO:
9713 break;
9714
9715 default: /* ignore */
9716 /*trace("showwindow: %p, %04x, %08x, %08lx\n", hwnd, message, wParam, lParam);*/
9718 }
9719
9720 msg.hwnd = hwnd;
9721 msg.message = message;
9722 msg.flags = sent|wparam|lparam;
9723 if (defwndproc_counter) msg.flags |= defwinproc;
9724 msg.wParam = wParam;
9725 msg.lParam = lParam;
9726 msg.descr = "show";
9727 add_message(&msg);
9728
9729 defwndproc_counter++;
9731 defwndproc_counter--;
9732
9733 return ret;
9734}
9735
9737{
9738 static LONG defwndproc_counter = 0;
9739 struct recvd_message msg;
9740 LRESULT ret;
9741
9742 switch (message)
9743 {
9744 /* log only specific messages we are interested in */
9745 case WM_NCACTIVATE:
9746 case WM_ACTIVATE:
9747 case WM_SETFOCUS:
9748 case WM_KILLFOCUS:
9749 break;
9750 default:
9752 }
9753
9754 msg.hwnd = hwnd;
9755 msg.message = message;
9756 msg.flags = sent|wparam|lparam;
9757 if (defwndproc_counter) msg.flags |= defwinproc;
9758 msg.wParam = wParam;
9759 msg.lParam = lParam;
9760 msg.descr = "recursive_activation";
9761 add_message(&msg);
9762
9763 /* recursively activate ourselves by first losing activation and changing it back */
9765 {
9768 return 0;
9769 }
9770
9771 defwndproc_counter++;
9773 defwndproc_counter--;
9774
9775 return ret;
9776}
9777
9779{
9780 switch (msg)
9781 {
9782 case WM_CREATE: return 0;
9783 case WM_PAINT:
9784 {
9785 MSG msg2;
9786 static int i = 0;
9787
9788 if (i < 256)
9789 {
9790 i++;
9791 if (PeekMessageA(&msg2, 0, 0, 0, 1))
9792 {
9793 TranslateMessage(&msg2);
9794 DispatchMessageA(&msg2);
9795 }
9796 i--;
9797 }
9798 else ok(broken(1), "infinite loop\n");
9799 if ( i == 0)
9802 }
9803 }
9805}
9806
9808{
9809 static LONG defwndproc_counter = 0;
9810 LRESULT ret;
9811 struct recvd_message msg;
9812 DWORD queue_status;
9813
9814 if (ignore_message( message )) return 0;
9815
9816 if ((message >= WM_KEYFIRST && message <= WM_KEYLAST) ||
9818 {
9819 msg.hwnd = hwnd;
9820 msg.message = message;
9821 msg.flags = sent|wparam|lparam;
9822 if (defwndproc_counter) msg.flags |= defwinproc;
9823 msg.wParam = wParam;
9824 msg.lParam = lParam;
9825 msg.descr = "HotkeyMsgCheckProcA";
9826 add_message(&msg);
9827 }
9828
9829 defwndproc_counter++;
9831 defwndproc_counter--;
9832
9833 if (message == WM_APP)
9834 {
9835 queue_status = GetQueueStatus(QS_HOTKEY);
9836 ok((queue_status & (QS_HOTKEY << 16)) == QS_HOTKEY << 16, "expected QS_HOTKEY << 16 set, got %x\n", queue_status);
9837 queue_status = GetQueueStatus(QS_POSTMESSAGE);
9838 ok((queue_status & (QS_POSTMESSAGE << 16)) == QS_POSTMESSAGE << 16, "expected QS_POSTMESSAGE << 16 set, got %x\n", queue_status);
9839 PostMessageA(hwnd, WM_APP+1, 0, 0);
9840 }
9841 else if (message == WM_APP+1)
9842 {
9843 queue_status = GetQueueStatus(QS_HOTKEY);
9844 ok((queue_status & (QS_HOTKEY << 16)) == 0, "expected QS_HOTKEY << 16 cleared, got %x\n", queue_status);
9845 }
9846
9847 return ret;
9848}
9849
9851{
9852 WNDCLASSA cls;
9853 WNDCLASSW clsW;
9854
9855 cls.style = 0;
9857 cls.cbClsExtra = 0;
9858 cls.cbWndExtra = 0;
9859 cls.hInstance = GetModuleHandleA(0);
9860 cls.hIcon = 0;
9863 cls.lpszMenuName = NULL;
9864 cls.lpszClassName = "TestWindowClass";
9865 if(!RegisterClassA(&cls)) return FALSE;
9866
9868 cls.lpszClassName = "HotkeyWindowClass";
9869 if(!RegisterClassA(&cls)) return FALSE;
9870
9872 cls.lpszClassName = "ShowWindowClass";
9873 if(!RegisterClassA(&cls)) return FALSE;
9874
9876 cls.lpszClassName = "RecursiveActivationClass";
9877 if(!RegisterClassA(&cls)) return FALSE;
9878
9880 cls.lpszClassName = "TestPopupClass";
9881 if(!RegisterClassA(&cls)) return FALSE;
9882
9884 cls.lpszClassName = "TestParentClass";
9885 if(!RegisterClassA(&cls)) return FALSE;
9886
9888 cls.lpszClassName = "StopQuitClass";
9889 if(!RegisterClassA(&cls)) return FALSE;
9890
9892 cls.lpszClassName = "SimpleWindowClass";
9893 if(!RegisterClassA(&cls)) return FALSE;
9894
9896 cls.lpszClassName = "PaintLoopWindowClass";
9897 if(!RegisterClassA(&cls)) return FALSE;
9898
9899 cls.style = CS_NOCLOSE;
9900 cls.lpszClassName = "NoCloseWindowClass";
9901 if(!RegisterClassA(&cls)) return FALSE;
9902
9903 ok(GetClassInfoA(0, "#32770", &cls), "GetClassInfo failed\n");
9904 cls.style = 0;
9905 cls.hInstance = GetModuleHandleA(0);
9906 cls.hbrBackground = 0;
9908 cls.lpszClassName = "TestDialogClass";
9909 if(!RegisterClassA(&cls)) return FALSE;
9910
9911 clsW.style = 0;
9913 clsW.cbClsExtra = 0;
9914 clsW.cbWndExtra = 0;
9915 clsW.hInstance = GetModuleHandleW(0);
9916 clsW.hIcon = 0;
9917 clsW.hCursor = LoadCursorW(0, (LPWSTR)IDC_ARROW);
9919 clsW.lpszMenuName = NULL;
9921 RegisterClassW(&clsW); /* ignore error, this fails on Win9x */
9922
9923 return TRUE;
9924}
9925
9927{
9928 char buf[256];
9929
9930 if (GetClassNameA(hwnd, buf, sizeof(buf)))
9931 {
9932 if (!lstrcmpiA(buf, "TestWindowClass") ||
9933 !lstrcmpiA(buf, "ShowWindowClass") ||
9934 !lstrcmpiA(buf, "RecursiveActivationClass") ||
9935 !lstrcmpiA(buf, "TestParentClass") ||
9936 !lstrcmpiA(buf, "TestPopupClass") ||
9937 !lstrcmpiA(buf, "SimpleWindowClass") ||
9938 !lstrcmpiA(buf, "TestDialogClass") ||
9939 !lstrcmpiA(buf, "MDI_frame_class") ||
9940 !lstrcmpiA(buf, "MDI_client_class") ||
9941 !lstrcmpiA(buf, "MDI_child_class") ||
9942 !lstrcmpiA(buf, "my_button_class") ||
9943 !lstrcmpiA(buf, "my_edit_class") ||
9944 !lstrcmpiA(buf, "static") ||
9945 !lstrcmpiA(buf, "ListBox") ||
9946 !lstrcmpiA(buf, "ComboBox") ||
9947 !lstrcmpiA(buf, "MyDialogClass") ||
9948 !lstrcmpiA(buf, "#32770") ||
9949 !lstrcmpiA(buf, "#32768"))
9950 return TRUE;
9951 }
9952 return FALSE;
9953}
9954
9956{
9957 HWND hwnd;
9958
9959 ok(cbt_hook_thread_id == GetCurrentThreadId(), "we didn't ask for events from other threads\n");
9960
9961 if (nCode == HCBT_CLICKSKIPPED)
9962 {
9963 /* ignore this event, XP sends it a lot when switching focus between windows */
9964 return CallNextHookEx(hCBT_hook, nCode, wParam, lParam);
9965 }
9966
9967 if (nCode == HCBT_SYSCOMMAND || nCode == HCBT_KEYSKIPPED)
9968 {
9969 struct recvd_message msg;
9970
9971 msg.hwnd = 0;
9972 msg.message = nCode;
9973 msg.flags = hook|wparam|lparam;
9974 msg.wParam = wParam;
9975 msg.lParam = lParam;
9976 msg.descr = "CBT";
9977 add_message(&msg);
9978
9979 return CallNextHookEx(hCBT_hook, nCode, wParam, lParam);
9980 }
9981
9982 if (nCode == HCBT_DESTROYWND)
9983 {
9985 {
9987 if (style & WS_CHILD)
9989 else if (style & WS_POPUP)
9991 else
9993 }
9994 }
9995
9996 /* Log also SetFocus(0) calls */
9997 hwnd = wParam ? (HWND)wParam : (HWND)lParam;
9998
10000 {
10001 struct recvd_message msg;
10002
10003 msg.hwnd = hwnd;
10004 msg.message = nCode;
10005 msg.flags = hook|wparam|lparam;
10006 msg.wParam = wParam;
10007 msg.lParam = lParam;
10008 msg.descr = "CBT";
10009 add_message(&msg);
10010 }
10011 return CallNextHookEx(hCBT_hook, nCode, wParam, lParam);
10012}
10013
10015 DWORD event,
10016 HWND hwnd,
10017 LONG object_id,
10018 LONG child_id,
10020 DWORD event_time)
10021{
10022 ok(thread_id == GetCurrentThreadId(), "we didn't ask for events from other threads\n");
10023
10024 /* ignore mouse cursor events */
10025 if (object_id == OBJID_CURSOR) return;
10026
10027 if (!hwnd || is_our_logged_class(hwnd))
10028 {
10029 struct recvd_message msg;
10030
10031 msg.hwnd = hwnd;
10032 msg.message = event;
10034 msg.wParam = object_id;
10035 msg.lParam = child_id;
10036 msg.descr = "WEH";
10037 add_message(&msg);
10038 }
10039}
10040
10041static const WCHAR wszUnicode[] = {'U','n','i','c','o','d','e',0};
10042static const WCHAR wszAnsi[] = {'U',0};
10043
10045{
10046 switch (uMsg)
10047 {
10048 case CB_FINDSTRINGEXACT:
10049 trace("String: %p\n", (LPCWSTR)lParam);
10051 return 1;
10053 return 0;
10054 return -1;
10055 }
10056 return DefWindowProcW(hwnd, uMsg, wParam, lParam);
10057}
10058
10059static const struct message WmGetTextLengthAfromW[] = {
10062 { 0 }
10063};
10064
10065static const WCHAR dummy_window_text[] = {'d','u','m','m','y',' ','t','e','x','t',0};
10066
10067/* dummy window proc for WM_GETTEXTLENGTH test */
10069{
10070 switch(msg)
10071 {
10072 case WM_GETTEXTLENGTH:
10073 return lstrlenW(dummy_window_text) + 37; /* some random length */
10074 case WM_GETTEXT:
10076 return lstrlenW( (LPWSTR)lp );
10077 default:
10078 return DefWindowProcW( hwnd, msg, wp, lp );
10079 }
10080}
10081
10083{
10084 static const WCHAR wszMsgConversionClass[] =
10085 {'M','s','g','C','o','n','v','e','r','s','i','o','n','C','l','a','s','s',0};
10086 WNDCLASSW cls;
10087 LRESULT lRes;
10088 HWND hwnd;
10089 WNDPROC wndproc, newproc;
10090 BOOL ret;
10091
10092 cls.style = 0;
10094 cls.cbClsExtra = 0;
10095 cls.cbWndExtra = 0;
10097 cls.hIcon = NULL;
10099 cls.hbrBackground = (HBRUSH)(COLOR_BTNFACE+1);
10100 cls.lpszMenuName = NULL;
10101 cls.lpszClassName = wszMsgConversionClass;
10102 /* this call will fail on Win9x, but that doesn't matter as this test is
10103 * meaningless on those platforms */
10104 if(!RegisterClassW(&cls)) return;
10105
10106 hwnd = CreateWindowExW(0, wszMsgConversionClass, NULL, WS_OVERLAPPED,
10107 100, 100, 200, 200, 0, 0, 0, NULL);
10108 ok(hwnd != NULL, "Window creation failed\n");
10109
10110 /* {W, A} -> A */
10111
10114 ok(lRes == 0, "String should have been converted\n");
10116 ok(lRes == 1, "String shouldn't have been converted\n");
10117
10118 /* {W, A} -> W */
10119
10122 ok(lRes == 1, "String shouldn't have been converted\n");
10124 ok(lRes == 1, "String shouldn't have been converted\n");
10125
10126 /* Synchronous messages */
10127
10129 ok(lRes == 0, "String should have been converted\n");
10131 ok(lRes == 1, "String shouldn't have been converted\n");
10132
10133 /* Asynchronous messages */
10134
10135 SetLastError(0);
10138 "PostMessage on sync only message returned %ld, last error %d\n", lRes, GetLastError());
10139 SetLastError(0);
10142 "PostMessage on sync only message returned %ld, last error %d\n", lRes, GetLastError());
10143 SetLastError(0);
10146 "PosThreadtMessage on sync only message returned %ld, last error %d\n", lRes, GetLastError());
10147 SetLastError(0);
10150 "PosThreadtMessage on sync only message returned %ld, last error %d\n", lRes, GetLastError());
10151 SetLastError(0);
10154 "SendNotifyMessage on sync only message returned %ld, last error %d\n", lRes, GetLastError());
10155 SetLastError(0);
10158 "SendNotifyMessage on sync only message returned %ld, last error %d\n", lRes, GetLastError());
10159 SetLastError(0);
10162 "SendMessageCallback on sync only message returned %ld, last error %d\n", lRes, GetLastError());
10163 SetLastError(0);
10166 "SendMessageCallback on sync only message returned %ld, last error %d\n", lRes, GetLastError());
10167
10168 /* Check WM_GETTEXTLENGTH A->W behaviour, whether WM_GETTEXT is also sent or not */
10169
10172 100, 100, 200, 200, 0, 0, 0, NULL);
10173 assert(hwnd);
10175 lRes = SendMessageA (hwnd, WM_GETTEXTLENGTH, 0, 0);
10176 ok_sequence(WmGetTextLengthAfromW, "ANSI WM_GETTEXTLENGTH to Unicode window", FALSE);
10178 "got bad length %ld\n", lRes );
10179
10182 hwnd, WM_GETTEXTLENGTH, 0, 0);
10183 ok_sequence(WmGetTextLengthAfromW, "ANSI WM_GETTEXTLENGTH to Unicode window", FALSE);
10185 "got bad length %ld\n", lRes );
10186
10189 lRes = CallWindowProcA( newproc, hwnd, WM_GETTEXTLENGTH, 0, 0 );
10191 NULL, 0, NULL, NULL ) ||
10192 broken(lRes == lstrlenW(dummy_window_text) + 37),
10193 "got bad length %ld\n", lRes );
10194
10195 SetWindowLongPtrW( hwnd, GWLP_WNDPROC, (LONG_PTR)wndproc ); /* restore old wnd proc */
10196 lRes = CallWindowProcA( newproc, hwnd, WM_GETTEXTLENGTH, 0, 0 );
10198 NULL, 0, NULL, NULL ) ||
10199 broken(lRes == lstrlenW(dummy_window_text) + 37),
10200 "got bad length %ld\n", lRes );
10201
10203 ok( ret, "DestroyWindow() error %d\n", GetLastError());
10204}
10205
10207{
10211};
10212
10214{
10215}
10216
10217#define TIMER_ID 0x19
10218#define TIMER_COUNT_EXPECTED 100
10219#define TIMER_COUNT_TOLERANCE 10
10220
10221static int count = 0;
10223{
10224 count++;
10225}
10226
10229{
10230 count++;
10232}
10233
10235{
10236 struct timer_info *info = x;
10237 DWORD r;
10238
10239 r = KillTimer(info->hWnd, 0x19);
10240 ok(r,"KillTimer failed in thread\n");
10241 r = SetTimer(info->hWnd,TIMER_ID,10000,tfunc);
10242 ok(r,"SetTimer failed in thread\n");
10243 ok(r==TIMER_ID,"SetTimer id different\n");
10244 r = SetEvent(info->handles[0]);
10245 ok(r,"SetEvent failed in thread\n");
10246 return 0;
10247}
10248
10249static void test_timers(void)
10250{
10251 struct timer_info info;
10252 DWORD start;
10253 DWORD id;
10254 MSG msg;
10255
10256 info.hWnd = CreateWindowA("TestWindowClass", NULL,
10258 CW_USEDEFAULT, CW_USEDEFAULT, 300, 300, 0,
10259 NULL, NULL, 0);
10260
10261 info.id = SetTimer(info.hWnd,TIMER_ID,10000,tfunc);
10262 ok(info.id, "SetTimer failed\n");
10263 ok(info.id==TIMER_ID, "SetTimer timer ID different\n");
10264 info.handles[0] = CreateEventW(NULL,0,0,NULL);
10265 info.handles[1] = CreateThread(NULL,0,timer_thread_proc,&info,0,&id);
10266
10268
10269 WaitForSingleObject(info.handles[1], INFINITE);
10270
10271 CloseHandle(info.handles[0]);
10272 CloseHandle(info.handles[1]);
10273
10274 ok( KillTimer(info.hWnd, TIMER_ID), "KillTimer failed\n");
10275
10276 /* Check the minimum allowed timeout for a timer. MSDN indicates that it should be 10.0 ms,
10277 * which occurs sometimes, but most testing on the VMs indicates a minimum timeout closer to
10278 * 15.6 ms. Since there is some measurement error between test runs we are allowing for
10279 * ±9 counts (~4 ms) around the expected value.
10280 */
10281 count = 0;
10282 id = SetTimer(info.hWnd, TIMER_ID, 0, callback_count);
10283 ok(id != 0, "did not get id from SetTimer.\n");
10284 ok(id==TIMER_ID, "SetTimer timer ID different\n");
10285 start = GetTickCount();
10286 while (GetTickCount()-start < 1001 && GetMessageA(&msg, info.hWnd, 0, 0))
10291 || broken(abs(count-64) < TIMER_COUNT_TOLERANCE) /* most common */
10292 || broken(abs(count-43) < TIMER_COUNT_TOLERANCE) /* w2k3, win8 */,
10293 "did not get expected count for minimum timeout (%d != ~%d).\n",
10295 ok(KillTimer(info.hWnd, id), "KillTimer failed\n");
10296 /* Perform the same check on SetSystemTimer (only available on w2k3 and older) */
10297 if (pSetSystemTimer)
10298 {
10299 int syscount = 0;
10300
10301 count = 0;
10302 id = pSetSystemTimer(info.hWnd, TIMER_ID, 0, callback_count);
10303 ok(id != 0, "did not get id from SetSystemTimer.\n");
10304 ok(id==TIMER_ID, "SetTimer timer ID different\n");
10305 start = GetTickCount();
10306 while (GetTickCount()-start < 1001 && GetMessageA(&msg, info.hWnd, 0, 0))
10307 {
10308 if (msg.message == WM_SYSTIMER)
10309 syscount++;
10311 }
10313 || broken(abs(syscount-64) < TIMER_COUNT_TOLERANCE) /* most common */
10314 || broken(syscount > 4000 && syscount < 12000) /* win2k3sp0 */,
10315 "did not get expected count for minimum timeout (%d != ~%d).\n",
10316 syscount, TIMER_COUNT_EXPECTED);
10317 todo_wine ok(count == 0, "did not get expected count for callback timeout (%d != 0).\n",
10318 count);
10319 ok(pKillSystemTimer(info.hWnd, id), "KillSystemTimer failed\n");
10320 }
10321
10322 ok(DestroyWindow(info.hWnd), "failed to destroy window\n");
10323}
10324
10325static void test_timers_no_wnd(void)
10326{
10327 static UINT_PTR ids[0xffff];
10328 UINT_PTR id, id2;
10329 DWORD start;
10330 MSG msg;
10331 int i;
10332
10333 count = 0;
10334 id = SetTimer(NULL, 0, 100, callback_count);
10335 ok(id != 0, "did not get id from SetTimer.\n");
10336 id2 = SetTimer(NULL, id, 200, callback_count);
10337 ok(id2 == id, "did not get same id from SetTimer when replacing (%li expected %li).\n", id2, id);
10338 Sleep(150);
10339 while (PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
10340 ok(count == 0, "did not get zero count as expected (%i).\n", count);
10341 Sleep(150);
10342 while (PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
10343 ok(count == 1, "did not get one count as expected (%i).\n", count);
10344 KillTimer(NULL, id);
10345 Sleep(250);
10346 while (PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
10347 ok(count == 1, "killing replaced timer did not work (%i).\n", count);
10348
10349 /* Check the minimum allowed timeout for a timer. MSDN indicates that it should be 10.0 ms,
10350 * which occurs sometimes, but most testing on the VMs indicates a minimum timeout closer to
10351 * 15.6 ms. Since there is some measurement error between test runs we are allowing for
10352 * ±9 counts (~4 ms) around the expected value.
10353 */
10354 count = 0;
10355 id = SetTimer(NULL, 0, 0, callback_count);
10356 ok(id != 0, "did not get id from SetTimer.\n");
10357 start = GetTickCount();
10358 while (GetTickCount()-start < 1001 && GetMessageA(&msg, NULL, 0, 0))
10362 || broken(abs(count-64) < TIMER_COUNT_TOLERANCE) /* most common */,
10363 "did not get expected count for minimum timeout (%d != ~%d).\n",
10365 KillTimer(NULL, id);
10366 /* Note: SetSystemTimer doesn't support a NULL window, see test_timers */
10367
10368 if (pSetCoalescableTimer)
10369 {
10370 count = 0;
10371 id = pSetCoalescableTimer(NULL, 0, 0, callback_count, 0);
10372 ok(id != 0, "SetCoalescableTimer failed with %u.\n", GetLastError());
10373 start = GetTickCount();
10374 while (GetTickCount()-start < 100 && GetMessageA(&msg, NULL, 0, 0))
10376 ok(count > 1, "expected count > 1, got %d.\n", count);
10377 KillTimer(NULL, id);
10378 }
10379 else
10380 win_skip("SetCoalescableTimer not available.\n");
10381
10382 /* Check what happens when we're running out of timers */
10383 for (i = 0; i < ARRAY_SIZE(ids); i++)
10384 {
10385 SetLastError(0xdeadbeef);
10387 if (!ids[i]) break;
10388 }
10389 ok(i != ARRAY_SIZE(ids), "all timers were created successfully\n");
10391 "GetLastError() = %d\n", GetLastError());
10392 while (i > 0) KillTimer(NULL, ids[--i]);
10393}
10394
10396{
10397 UINT_PTR id;
10398 MSG msg;
10399
10400 exception = code;
10401 id = SetTimer(NULL, 0, 1000, callback_exception);
10402 ok(id != 0, "did not get id from SetTimer.\n");
10403
10404 memset(&msg, 0, sizeof(msg));
10405 msg.message = WM_TIMER;
10406 msg.wParam = id;
10407 msg.lParam = (LPARAM)callback_exception;
10408
10409 count = 0;
10411 ok(count == 1, "did not get one count as expected (%i).\n", count);
10412
10413 KillTimer(NULL, id);
10414}
10415
10416static void test_timers_exceptions(void)
10417{
10427 test_timers_exception(0xE000BEEF); /* customer exception */
10428}
10429
10430/* Various win events with arbitrary parameters */
10431static const struct message WmWinEventsSeq[] = {
10432 { EVENT_SYSTEM_SOUND, winevent_hook|wparam|lparam, OBJID_WINDOW, 0 },
10433 { EVENT_SYSTEM_ALERT, winevent_hook|wparam|lparam, OBJID_SYSMENU, 1 },
10434 { EVENT_SYSTEM_FOREGROUND, winevent_hook|wparam|lparam, OBJID_TITLEBAR, 2 },
10435 { EVENT_SYSTEM_MENUSTART, winevent_hook|wparam|lparam, OBJID_MENU, 3 },
10436 { EVENT_SYSTEM_MENUEND, winevent_hook|wparam|lparam, OBJID_CLIENT, 4 },
10437 { EVENT_SYSTEM_MENUPOPUPSTART, winevent_hook|wparam|lparam, OBJID_VSCROLL, 5 },
10438 { EVENT_SYSTEM_MENUPOPUPEND, winevent_hook|wparam|lparam, OBJID_HSCROLL, 6 },
10439 { EVENT_SYSTEM_CAPTURESTART, winevent_hook|wparam|lparam, OBJID_SIZEGRIP, 7 },
10440 { EVENT_SYSTEM_CAPTUREEND, winevent_hook|wparam|lparam, OBJID_CARET, 8 },
10441 /* our win event hook ignores OBJID_CURSOR events */
10442 /*{ EVENT_SYSTEM_MOVESIZESTART, winevent_hook|wparam|lparam, OBJID_CURSOR, 9 },*/
10443 { EVENT_SYSTEM_MOVESIZEEND, winevent_hook|wparam|lparam, OBJID_ALERT, 10 },
10444 { EVENT_SYSTEM_CONTEXTHELPSTART, winevent_hook|wparam|lparam, OBJID_SOUND, 11 },
10445 { EVENT_SYSTEM_CONTEXTHELPEND, winevent_hook|wparam|lparam, OBJID_QUERYCLASSNAMEIDX, 12 },
10446 { EVENT_SYSTEM_DRAGDROPSTART, winevent_hook|wparam|lparam, OBJID_NATIVEOM, 13 },
10447 { EVENT_SYSTEM_DRAGDROPEND, winevent_hook|wparam|lparam, OBJID_WINDOW, 0 },
10448 { EVENT_SYSTEM_DIALOGSTART, winevent_hook|wparam|lparam, OBJID_SYSMENU, 1 },
10449 { EVENT_SYSTEM_DIALOGEND, winevent_hook|wparam|lparam, OBJID_TITLEBAR, 2 },
10450 { EVENT_SYSTEM_SCROLLINGSTART, winevent_hook|wparam|lparam, OBJID_MENU, 3 },
10451 { EVENT_SYSTEM_SCROLLINGEND, winevent_hook|wparam|lparam, OBJID_CLIENT, 4 },
10452 { EVENT_SYSTEM_SWITCHSTART, winevent_hook|wparam|lparam, OBJID_VSCROLL, 5 },
10453 { EVENT_SYSTEM_SWITCHEND, winevent_hook|wparam|lparam, OBJID_HSCROLL, 6 },
10454 { EVENT_SYSTEM_MINIMIZESTART, winevent_hook|wparam|lparam, OBJID_SIZEGRIP, 7 },
10455 { EVENT_SYSTEM_MINIMIZEEND, winevent_hook|wparam|lparam, OBJID_CARET, 8 },
10456 { 0 }
10457};
10458static const struct message WmWinEventCaretSeq[] = {
10459 { EVENT_OBJECT_CREATE, winevent_hook|wparam|lparam, OBJID_CARET, 0 }, /* hook 1 */
10460 { EVENT_OBJECT_SHOW, winevent_hook|wparam|lparam, OBJID_CARET, 0 }, /* hook 1 */
10461 { EVENT_OBJECT_SHOW, winevent_hook|wparam|lparam, OBJID_CARET, 0 }, /* hook 2 */
10462 { EVENT_OBJECT_NAMECHANGE, winevent_hook|wparam|lparam, OBJID_CARET, 0 }, /* hook 1 */
10463 { 0 }
10464};
10465static const struct message WmWinEventCaretSeq_2[] = {
10466 { EVENT_OBJECT_CREATE, winevent_hook|wparam|lparam, OBJID_CARET, 0 }, /* hook 1/2 */
10467 { EVENT_OBJECT_SHOW, winevent_hook|wparam|lparam, OBJID_CARET, 0 }, /* hook 1/2 */
10468 { EVENT_OBJECT_NAMECHANGE, winevent_hook|wparam|lparam, OBJID_CARET, 0 }, /* hook 1/2 */
10469 { 0 }
10470};
10471static const struct message WmWinEventAlertSeq[] = {
10472 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, OBJID_ALERT, 0 },
10473 { 0 }
10474};
10475static const struct message WmWinEventAlertSeq_2[] = {
10476 /* create window in the thread proc */
10477 { EVENT_OBJECT_CREATE, winevent_hook|wparam|lparam, OBJID_WINDOW, 2 },
10478 /* our test event */
10479 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, OBJID_ALERT, 2 },
10480 { 0 }
10481};
10482static const struct message WmGlobalHookSeq_1[] = {
10483 /* create window in the thread proc */
10484 { HCBT_CREATEWND, hook|lparam, 0, 2 },
10485 /* our test events */
10488 { 0 }
10489};
10490static const struct message WmGlobalHookSeq_2[] = {
10491 { HCBT_SYSCOMMAND, hook|wparam|lparam, SC_NEXTWINDOW, 0 }, /* old local hook */
10492 { HCBT_SYSCOMMAND, hook|wparam|lparam, SC_NEXTWINDOW, 2 }, /* new global hook */
10493 { HCBT_SYSCOMMAND, hook|wparam|lparam, SC_PREVWINDOW, 0 }, /* old local hook */
10494 { HCBT_SYSCOMMAND, hook|wparam|lparam, SC_PREVWINDOW, 2 }, /* new global hook */
10495 { 0 }
10496};
10497
10498static const struct message WmMouseLLHookSeq[] = {
10499 { WM_MOUSEMOVE, hook },
10500 { WM_LBUTTONUP, hook },
10501 { WM_MOUSEMOVE, hook },
10502 { 0 }
10503};
10504
10506 DWORD event,
10507 HWND hwnd,
10508 LONG object_id,
10509 LONG child_id,
10511 DWORD event_time)
10512{
10513 char buf[256];
10514
10515 if (GetClassNameA(hwnd, buf, sizeof(buf)))
10516 {
10517 if (!lstrcmpiA(buf, "TestWindowClass") ||
10518 !lstrcmpiA(buf, "static"))
10519 {
10520 struct recvd_message msg;
10521
10522 msg.hwnd = hwnd;
10523 msg.message = event;
10525 msg.wParam = object_id;
10526 msg.lParam = (thread_id == GetCurrentThreadId()) ? child_id : (child_id + 2);
10527 msg.descr = "WEH_2";
10528 add_message(&msg);
10529 }
10530 }
10531}
10532
10533static HHOOK hCBT_global_hook;
10535
10537{
10538 HWND hwnd;
10539 char buf[256];
10540
10541 if (nCode == HCBT_SYSCOMMAND)
10542 {
10543 struct recvd_message msg;
10544
10545 msg.hwnd = 0;
10546 msg.message = nCode;
10547 msg.flags = hook|wparam|lparam;
10548 msg.wParam = wParam;
10549 msg.lParam = (cbt_global_hook_thread_id == GetCurrentThreadId()) ? 1 : 2;
10550 msg.descr = "CBT_2";
10551 add_message(&msg);
10552
10554 }
10555 /* WH_MOUSE_LL hook */
10556 if (nCode == HC_ACTION)
10557 {
10559
10560 /* we can't test for real mouse events */
10561 if (mhll->flags & LLMHF_INJECTED)
10562 {
10563 struct recvd_message msg;
10564
10565 memset (&msg, 0, sizeof (msg));
10566 msg.message = wParam;
10567 msg.flags = hook;
10568 msg.descr = "CBT_2";
10569 add_message(&msg);
10570 }
10572 }
10573
10574 /* Log also SetFocus(0) calls */
10575 hwnd = wParam ? (HWND)wParam : (HWND)lParam;
10576
10577 if (GetClassNameA(hwnd, buf, sizeof(buf)))
10578 {
10579 if (!lstrcmpiA(buf, "TestWindowClass") ||
10580 !lstrcmpiA(buf, "static"))
10581 {
10582 struct recvd_message msg;
10583
10584 msg.hwnd = hwnd;
10585 msg.message = nCode;
10586 msg.flags = hook|wparam|lparam;
10587 msg.wParam = wParam;
10588 msg.lParam = (cbt_global_hook_thread_id == GetCurrentThreadId()) ? 1 : 2;
10589 msg.descr = "CBT_2";
10590 add_message(&msg);
10591 }
10592 }
10594}
10595
10597{
10598 HWND hwnd;
10599 MSG msg;
10600 HANDLE hevent = *(HANDLE *)param;
10601
10602 assert(pNotifyWinEvent);
10603
10604 hwnd = CreateWindowExA(0, "static", NULL, WS_POPUP, 0,0,0,0,0,0,0, NULL);
10605 assert(hwnd);
10606 trace("created thread window %p\n", hwnd);
10607
10608 *(HWND *)param = hwnd;
10609
10611 /* this event should be received only by our new hook proc,
10612 * an old one does not expect an event from another thread.
10613 */
10614 pNotifyWinEvent(EVENT_OBJECT_LOCATIONCHANGE, hwnd, OBJID_ALERT, 0);
10616
10617 while (GetMessageA(&msg, 0, 0, 0))
10618 {
10621 }
10622 return 0;
10623}
10624
10626{
10627 HWND hwnd;
10628 MSG msg;
10629 HANDLE hevent = *(HANDLE *)param;
10630
10632 /* these events should be received only by our new hook proc,
10633 * an old one does not expect an event from another thread.
10634 */
10635
10636 hwnd = CreateWindowExA(0, "static", NULL, WS_POPUP, 0,0,0,0,0,0,0, NULL);
10637 assert(hwnd);
10638 trace("created thread window %p\n", hwnd);
10639
10640 *(HWND *)param = hwnd;
10641
10642 /* Windows doesn't like when a thread plays games with the focus,
10643 that leads to all kinds of misbehaviours and failures to activate
10644 a window. So, better keep next lines commented out.
10645 SetFocus(0);
10646 SetFocus(hwnd);*/
10647
10650
10652
10653 while (GetMessageA(&msg, 0, 0, 0))
10654 {
10657 }
10658 return 0;
10659}
10660
10662{
10663 HWND hwnd;
10664 MSG msg;
10665 HANDLE hevent = *(HANDLE *)param;
10666
10667 hwnd = CreateWindowExA(0, "static", NULL, WS_POPUP, 0,0,0,0,0,0,0, NULL);
10668 assert(hwnd);
10669 trace("created thread window %p\n", hwnd);
10670
10671 *(HWND *)param = hwnd;
10672
10674
10675 /* Windows doesn't like when a thread plays games with the focus,
10676 * that leads to all kinds of misbehaviours and failures to activate
10677 * a window. So, better don't generate a mouse click message below.
10678 */
10679 mouse_event(MOUSEEVENTF_MOVE, -1, 0, 0, 0);
10680 mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
10681 mouse_event(MOUSEEVENTF_MOVE, 1, 0, 0, 0);
10682
10684 while (GetMessageA(&msg, 0, 0, 0))
10685 {
10688 }
10689 return 0;
10690}
10691
10692static void test_winevents(void)
10693{
10694 BOOL ret;
10695 MSG msg;
10696 HWND hwnd, hwnd2;
10697 UINT i;
10698 HANDLE hthread, hevent;
10699 DWORD tid;
10701 const struct message *events = WmWinEventsSeq;
10702
10703 hwnd = CreateWindowExA(0, "TestWindowClass", NULL,
10705 CW_USEDEFAULT, CW_USEDEFAULT, 300, 300, 0,
10706 NULL, NULL, 0);
10707 assert(hwnd);
10708
10709 /****** start of global hook test *************/
10711 if (!hCBT_global_hook)
10712 {
10713 ok(DestroyWindow(hwnd), "failed to destroy window\n");
10714 skip( "cannot set global hook\n" );
10715 return;
10716 }
10717
10718 hevent = CreateEventA(NULL, 0, 0, NULL);
10719 assert(hevent);
10720 hwnd2 = hevent;
10721
10722 hthread = CreateThread(NULL, 0, cbt_global_hook_thread_proc, &hwnd2, 0, &tid);
10723 ok(hthread != NULL, "CreateThread failed, error %d\n", GetLastError());
10724
10725 ok(WaitForSingleObject(hevent, INFINITE) == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
10726
10727 ok_sequence(WmGlobalHookSeq_1, "global hook 1", FALSE);
10728
10730 /* this one should be received only by old hook proc */
10732 /* this one should be received only by old hook proc */
10734
10735 ok_sequence(WmGlobalHookSeq_2, "global hook 2", FALSE);
10736
10738 ok( ret, "UnhookWindowsHookEx error %d\n", GetLastError());
10739
10741 ok(WaitForSingleObject(hthread, INFINITE) == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
10742 CloseHandle(hthread);
10744 ok(!IsWindow(hwnd2), "window should be destroyed on thread exit\n");
10745 /****** end of global hook test *************/
10746
10747 if (!pSetWinEventHook || !pNotifyWinEvent || !pUnhookWinEvent)
10748 {
10749 ok(DestroyWindow(hwnd), "failed to destroy window\n");
10750 return;
10751 }
10752
10754
10755 if (0)
10756 {
10757 /* this test doesn't pass under Win9x */
10758 /* win2k ignores events with hwnd == 0 */
10759 SetLastError(0xdeadbeef);
10760 pNotifyWinEvent(events[0].message, 0, events[0].wParam, events[0].lParam);
10761 ok(GetLastError() == ERROR_INVALID_WINDOW_HANDLE || /* Win2k */
10762 GetLastError() == 0xdeadbeef, /* Win9x */
10763 "unexpected error %d\n", GetLastError());
10764 ok_sequence(WmEmptySeq, "empty notify winevents", FALSE);
10765 }
10766
10767 for (i = 0; i < ARRAY_SIZE(WmWinEventsSeq); i++)
10768 pNotifyWinEvent(events[i].message, hwnd, events[i].wParam, events[i].lParam);
10769
10770 ok_sequence(WmWinEventsSeq, "notify winevents", FALSE);
10771
10772 /****** start of event filtering test *************/
10773 hhook = pSetWinEventHook(
10774 EVENT_OBJECT_SHOW, /* 0x8002 */
10775 EVENT_OBJECT_LOCATIONCHANGE, /* 0x800B */
10779 ok(hhook != 0, "SetWinEventHook error %d\n", GetLastError());
10780
10781 hevent = CreateEventA(NULL, 0, 0, NULL);
10782 assert(hevent);
10783 hwnd2 = hevent;
10784
10785 hthread = CreateThread(NULL, 0, win_event_global_thread_proc, &hwnd2, 0, &tid);
10786 ok(hthread != NULL, "CreateThread failed, error %d\n", GetLastError());
10787
10788 ok(WaitForSingleObject(hevent, INFINITE) == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
10789
10790 ok_sequence(WmWinEventAlertSeq, "alert winevent", FALSE);
10791
10793 /* this one should be received only by old hook proc */
10794 pNotifyWinEvent(EVENT_OBJECT_CREATE, hwnd, OBJID_CARET, 0); /* 0x8000 */
10795 pNotifyWinEvent(EVENT_OBJECT_SHOW, hwnd, OBJID_CARET, 0); /* 0x8002 */
10796 /* this one should be received only by old hook proc */
10797 pNotifyWinEvent(EVENT_OBJECT_NAMECHANGE, hwnd, OBJID_CARET, 0); /* 0x800C */
10798
10799 ok_sequence(WmWinEventCaretSeq, "caret winevent", FALSE);
10800
10801 ret = pUnhookWinEvent(hhook);
10802 ok( ret, "UnhookWinEvent error %d\n", GetLastError());
10803
10805 ok(WaitForSingleObject(hthread, INFINITE) == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
10806 CloseHandle(hthread);
10808 ok(!IsWindow(hwnd2), "window should be destroyed on thread exit\n");
10809 /****** end of event filtering test *************/
10810
10811 /****** start of out of context event test *************/
10812 hhook = pSetWinEventHook(EVENT_MIN, EVENT_MAX, 0,
10815 ok(hhook != 0, "SetWinEventHook error %d\n", GetLastError());
10816
10817 hevent = CreateEventA(NULL, 0, 0, NULL);
10818 assert(hevent);
10819 hwnd2 = hevent;
10820
10822
10823 hthread = CreateThread(NULL, 0, win_event_global_thread_proc, &hwnd2, 0, &tid);
10824 ok(hthread != NULL, "CreateThread failed, error %d\n", GetLastError());
10825
10826 ok(WaitForSingleObject(hevent, INFINITE) == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
10827
10828 ok_sequence(WmEmptySeq, "empty notify winevents", FALSE);
10829 /* process pending winevent messages */
10830 ok(!PeekMessageA(&msg, 0, 0, 0, PM_NOREMOVE), "msg queue should be empty\n");
10831 ok_sequence(WmWinEventAlertSeq_2, "alert winevent for out of context proc", FALSE);
10832
10834 /* this one should be received only by old hook proc */
10835 pNotifyWinEvent(EVENT_OBJECT_CREATE, hwnd, OBJID_CARET, 0); /* 0x8000 */
10836 pNotifyWinEvent(EVENT_OBJECT_SHOW, hwnd, OBJID_CARET, 0); /* 0x8002 */
10837 /* this one should be received only by old hook proc */
10838 pNotifyWinEvent(EVENT_OBJECT_NAMECHANGE, hwnd, OBJID_CARET, 0); /* 0x800C */
10839
10840 ok_sequence(WmWinEventCaretSeq_2, "caret winevent for incontext proc", FALSE);
10841 /* process pending winevent messages */
10842 ok(!PeekMessageA(&msg, 0, 0, 0, PM_NOREMOVE), "msg queue should be empty\n");
10843 ok_sequence(WmWinEventCaretSeq_2, "caret winevent for out of context proc", FALSE);
10844
10845 ret = pUnhookWinEvent(hhook);
10846 ok( ret, "UnhookWinEvent error %d\n", GetLastError());
10847
10849 ok(WaitForSingleObject(hthread, INFINITE) == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
10850 CloseHandle(hthread);
10852 ok(!IsWindow(hwnd2), "window should be destroyed on thread exit\n");
10853 /****** end of out of context event test *************/
10854
10855 /****** start of MOUSE_LL hook test *************/
10857 /* WH_MOUSE_LL is not supported on Win9x platforms */
10858 if (!hCBT_global_hook)
10859 {
10860 win_skip("Skipping WH_MOUSE_LL test on this platform\n");
10861 goto skip_mouse_ll_hook_test;
10862 }
10863
10864 hevent = CreateEventA(NULL, 0, 0, NULL);
10865 assert(hevent);
10866 hwnd2 = hevent;
10867
10868 hthread = CreateThread(NULL, 0, mouse_ll_global_thread_proc, &hwnd2, 0, &tid);
10869 ok(hthread != NULL, "CreateThread failed, error %d\n", GetLastError());
10870
10871 while (WaitForSingleObject(hevent, 100) == WAIT_TIMEOUT)
10872 while (PeekMessageA( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessageA( &msg );
10873
10874 ok_sequence(WmMouseLLHookSeq, "MOUSE_LL hook other thread", FALSE);
10876
10877 mouse_event(MOUSEEVENTF_MOVE, -1, 0, 0, 0);
10878 mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
10879 mouse_event(MOUSEEVENTF_MOVE, 1, 0, 0, 0);
10880
10881 ok_sequence(WmMouseLLHookSeq, "MOUSE_LL hook same thread", FALSE);
10882
10884 ok( ret, "UnhookWindowsHookEx error %d\n", GetLastError());
10885
10887 ok(WaitForSingleObject(hthread, INFINITE) == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
10888 CloseHandle(hthread);
10890 ok(!IsWindow(hwnd2), "window should be destroyed on thread exit\n");
10891 /****** end of MOUSE_LL hook test *************/
10892skip_mouse_ll_hook_test:
10893
10894 ok(DestroyWindow(hwnd), "failed to destroy window\n");
10895}
10896
10897static void test_set_hook(void)
10898{
10899 BOOL ret;
10900 HHOOK hhook;
10901 HWINEVENTHOOK hwinevent_hook;
10902
10904 ok(hhook != 0, "local hook does not require hModule set to 0\n");
10906
10907 if (0)
10908 {
10909 /* this test doesn't pass under Win9x: BUG! */
10910 SetLastError(0xdeadbeef);
10912 ok(!hhook, "global hook requires hModule != 0\n");
10913 ok(GetLastError() == ERROR_HOOK_NEEDS_HMOD, "unexpected error %d\n", GetLastError());
10914 }
10915
10916 SetLastError(0xdeadbeef);
10918 ok(!hhook, "SetWinEventHook with invalid proc should fail\n");
10919 ok(GetLastError() == ERROR_INVALID_FILTER_PROC || /* Win2k */
10920 GetLastError() == 0xdeadbeef, /* Win9x */
10921 "unexpected error %d\n", GetLastError());
10922
10923 SetLastError(0xdeadbeef);
10924 ok(!UnhookWindowsHookEx((HHOOK)0xdeadbeef), "UnhookWindowsHookEx succeeded\n");
10925 ok(GetLastError() == ERROR_INVALID_HOOK_HANDLE || /* Win2k */
10926 GetLastError() == 0xdeadbeef, /* Win9x */
10927 "unexpected error %d\n", GetLastError());
10928
10929 if (!pSetWinEventHook || !pUnhookWinEvent) return;
10930
10931 /* even process local incontext hooks require hmodule */
10932 SetLastError(0xdeadbeef);
10933 hwinevent_hook = pSetWinEventHook(EVENT_MIN, EVENT_MAX, 0, win_event_proc,
10935 ok(!hwinevent_hook, "WINEVENT_INCONTEXT requires hModule != 0\n");
10936 ok(GetLastError() == ERROR_HOOK_NEEDS_HMOD || /* Win2k */
10937 GetLastError() == 0xdeadbeef, /* Win9x */
10938 "unexpected error %d\n", GetLastError());
10939
10940 /* even thread local incontext hooks require hmodule */
10941 SetLastError(0xdeadbeef);
10942 hwinevent_hook = pSetWinEventHook(EVENT_MIN, EVENT_MAX, 0, win_event_proc,
10944 ok(!hwinevent_hook, "WINEVENT_INCONTEXT requires hModule != 0\n");
10945 ok(GetLastError() == ERROR_HOOK_NEEDS_HMOD || /* Win2k */
10946 GetLastError() == 0xdeadbeef, /* Win9x */
10947 "unexpected error %d\n", GetLastError());
10948
10949 if (0)
10950 {
10951 /* these 3 tests don't pass under Win9x */
10952 SetLastError(0xdeadbeef);
10953 hwinevent_hook = pSetWinEventHook(1, 0, 0, win_event_proc,
10955 ok(!hwinevent_hook, "SetWinEventHook with invalid event range should fail\n");
10956 ok(GetLastError() == ERROR_INVALID_HOOK_FILTER, "unexpected error %d\n", GetLastError());
10957
10958 SetLastError(0xdeadbeef);
10959 hwinevent_hook = pSetWinEventHook(-1, 1, 0, win_event_proc,
10961 ok(!hwinevent_hook, "SetWinEventHook with invalid event range should fail\n");
10962 ok(GetLastError() == ERROR_INVALID_HOOK_FILTER, "unexpected error %d\n", GetLastError());
10963
10964 SetLastError(0xdeadbeef);
10965 hwinevent_hook = pSetWinEventHook(EVENT_MIN, EVENT_MAX, 0, win_event_proc,
10966 0, 0xdeadbeef, WINEVENT_OUTOFCONTEXT);
10967 ok(!hwinevent_hook, "SetWinEventHook with invalid tid should fail\n");
10968 ok(GetLastError() == ERROR_INVALID_THREAD_ID, "unexpected error %d\n", GetLastError());
10969 }
10970
10971 SetLastError(0xdeadbeef);
10972 hwinevent_hook = pSetWinEventHook(0, 0, 0, win_event_proc,
10974 ok(hwinevent_hook != 0, "SetWinEventHook error %d\n", GetLastError());
10975 ok(GetLastError() == 0xdeadbeef, "unexpected error %d\n", GetLastError());
10976 ret = pUnhookWinEvent(hwinevent_hook);
10977 ok( ret, "UnhookWinEvent error %d\n", GetLastError());
10978
10979todo_wine {
10980 /* This call succeeds under win2k SP4, but fails under Wine.
10981 Does win2k test/use passed process id? */
10982 SetLastError(0xdeadbeef);
10983 hwinevent_hook = pSetWinEventHook(EVENT_MIN, EVENT_MAX, 0, win_event_proc,
10984 0xdeadbeef, 0, WINEVENT_OUTOFCONTEXT);
10985 ok(hwinevent_hook != 0, "SetWinEventHook error %d\n", GetLastError());
10986 ok(GetLastError() == 0xdeadbeef, "unexpected error %d\n", GetLastError());
10987 ret = pUnhookWinEvent(hwinevent_hook);
10988 ok( ret, "UnhookWinEvent error %d\n", GetLastError());
10989}
10990
10991 SetLastError(0xdeadbeef);
10992 ok(!pUnhookWinEvent((HWINEVENTHOOK)0xdeadbeef), "UnhookWinEvent succeeded\n");
10993 ok(GetLastError() == ERROR_INVALID_HANDLE || /* Win2k */
10994 GetLastError() == 0xdeadbeef, /* Win9x */
10995 "unexpected error %d\n", GetLastError());
10996}
10997
10999static HHOOK recursive_hook;
11001
11003{
11004 LRESULT res;
11005 MSG msg;
11006 BOOL b;
11007
11008 hook_depth++;
11011
11013 ok(b, "PeekMessage failed\n");
11014
11016
11017 hook_depth--;
11018 return res;
11019}
11020
11021static void test_recursive_hook(void)
11022{
11023 MSG msg;
11024 BOOL b;
11025
11026 hook_hwnd = CreateWindowA("Static", NULL, WS_POPUP, 0, 0, 200, 60, NULL, NULL, NULL, NULL);
11027 ok(hook_hwnd != NULL, "CreateWindow failed\n");
11028
11030 ok(recursive_hook != NULL, "SetWindowsHookEx failed\n");
11031
11033 PostMessageW(hook_hwnd, WM_USER+1, 0, 0);
11034
11035 hook_depth = 0;
11036 GetMessageW(&msg, hook_hwnd, 0, 0);
11037 ok(15 <= max_hook_depth && max_hook_depth < 45, "max_hook_depth = %d\n", max_hook_depth);
11038 trace("max_hook_depth = %d\n", max_hook_depth);
11039
11041 ok(b, "UnhokWindowsHookEx failed\n");
11042
11044}
11045
11046static const struct message ScrollWindowPaint1[] = {
11047 { WM_PAINT, sent },
11050 { WM_PAINT, sent|optional },
11057 { 0 }
11058};
11059
11060static const struct message ScrollWindowPaint2[] = {
11061 { WM_PAINT, sent },
11062 { 0 }
11063};
11064
11065static void test_scrollwindowex(void)
11066{
11067 HWND hwnd, hchild;
11068 RECT rect={0,0,130,130};
11069
11070 hwnd = CreateWindowExA(0, "TestWindowClass", "Test Scroll",
11072 100, 100, 200, 200, 0, 0, 0, NULL);
11073 ok (hwnd != 0, "Failed to create overlapped window\n");
11074 hchild = CreateWindowExA(0, "TestWindowClass", "Test child",
11076 10, 10, 150, 150, hwnd, 0, 0, NULL);
11077 ok (hchild != 0, "Failed to create child\n");
11079 flush_events();
11081
11082 /* scroll without the child window */
11083 trace("start scroll\n");
11084 ScrollWindowEx( hwnd, 10, 10, &rect, NULL, NULL, NULL,
11086 ok_sequence(WmEmptySeq, "ScrollWindowEx", FALSE);
11087 trace("end scroll\n");
11089 flush_events();
11090 ok_sequence(ScrollWindowPaint1, "ScrollWindowEx", FALSE);
11091 flush_events();
11093
11094 /* Now without the SW_ERASE flag */
11095 trace("start scroll\n");
11097 ok_sequence(WmEmptySeq, "ScrollWindowEx", FALSE);
11098 trace("end scroll\n");
11100 flush_events();
11101 ok_sequence(ScrollWindowPaint2, "ScrollWindowEx", FALSE);
11102 flush_events();
11104
11105 /* now scroll the child window as well */
11106 trace("start scroll\n");
11107 ScrollWindowEx( hwnd, 10, 10, &rect, NULL, NULL, NULL,
11109 /* wine sends WM_POSCHANGING, WM_POSCHANGED messages */
11110 /* windows sometimes a WM_MOVE */
11111 ok_sequence(WmEmptySeq, "ScrollWindowEx", TRUE);
11112 trace("end scroll\n");
11114 flush_events();
11115 ok_sequence(ScrollWindowPaint1, "ScrollWindowEx", FALSE);
11116 flush_events();
11118
11119 /* now scroll with ScrollWindow() */
11120 trace("start scroll with ScrollWindow\n");
11121 ScrollWindow( hwnd, 5, 5, NULL, NULL);
11122 trace("end scroll\n");
11124 flush_events();
11125 ok_sequence(ScrollWindowPaint1, "ScrollWindow", FALSE);
11126
11127 ok(DestroyWindow(hchild), "failed to destroy window\n");
11128 ok(DestroyWindow(hwnd), "failed to destroy window\n");
11130}
11131
11132static const struct message destroy_window_with_children[] = {
11133 { EVENT_SYSTEM_CAPTURESTART, winevent_hook|wparam|lparam, 0, 0 }, /* popup */
11134 { HCBT_DESTROYWND, hook|lparam, 0, WND_PARENT_ID }, /* parent */
11135 { 0x0090, sent|optional },
11136 { HCBT_DESTROYWND, hook|lparam, 0, WND_POPUP_ID }, /* popup */
11137 { 0x0090, sent|optional },
11138 { EVENT_OBJECT_DESTROY, winevent_hook|wparam|lparam, 0, 0 }, /* popup */
11139 { WM_DESTROY, sent|wparam|lparam, 0, WND_POPUP_ID }, /* popup */
11140 { WM_CAPTURECHANGED, sent|wparam|lparam, 0, WND_POPUP_ID }, /* popup */
11141 { WM_NCDESTROY, sent|wparam|lparam, 0, WND_POPUP_ID }, /* popup */
11142 { EVENT_OBJECT_DESTROY, winevent_hook|wparam|lparam, 0, 0 }, /* parent */
11143 { WM_DESTROY, sent|wparam|lparam, 0, WND_PARENT_ID }, /* parent */
11144 { WM_DESTROY, sent|wparam|lparam, 0, WND_CHILD_ID + 2 }, /* child2 */
11145 { WM_DESTROY, sent|wparam|lparam, 0, WND_CHILD_ID + 1 }, /* child1 */
11146 { WM_DESTROY, sent|wparam|lparam, 0, WND_CHILD_ID + 3 }, /* child3 */
11147 { WM_NCDESTROY, sent|wparam|lparam, 0, WND_CHILD_ID + 2 }, /* child2 */
11148 { WM_NCDESTROY, sent|wparam|lparam, 0, WND_CHILD_ID + 3 }, /* child3 */
11149 { WM_NCDESTROY, sent|wparam|lparam, 0, WND_CHILD_ID + 1 }, /* child1 */
11150 { WM_NCDESTROY, sent|wparam|lparam, 0, WND_PARENT_ID }, /* parent */
11151 { 0 }
11152};
11153
11154static void test_DestroyWindow(void)
11155{
11156 BOOL ret;
11157 HWND parent, child1, child2, child3, child4, test;
11158 UINT_PTR child_id = WND_CHILD_ID + 1;
11159
11160 parent = CreateWindowExA(0, "TestWindowClass", NULL, WS_OVERLAPPEDWINDOW,
11161 100, 100, 200, 200, 0, 0, 0, NULL);
11162 assert(parent != 0);
11163 child1 = CreateWindowExA(0, "TestWindowClass", NULL, WS_CHILD,
11164 0, 0, 50, 50, parent, (HMENU)child_id++, 0, NULL);
11165 assert(child1 != 0);
11166 child2 = CreateWindowExA(0, "TestWindowClass", NULL, WS_CHILD,
11167 0, 0, 50, 50, GetDesktopWindow(), (HMENU)child_id++, 0, NULL);
11168 assert(child2 != 0);
11169 child3 = CreateWindowExA(0, "TestWindowClass", NULL, WS_CHILD,
11170 0, 0, 50, 50, child1, (HMENU)child_id++, 0, NULL);
11171 assert(child3 != 0);
11172 child4 = CreateWindowExA(0, "TestWindowClass", NULL, WS_POPUP,
11173 0, 0, 50, 50, parent, 0, 0, NULL);
11174 assert(child4 != 0);
11175
11176 /* test owner/parent of child2 */
11177 test = GetParent(child2);
11178 ok(test == GetDesktopWindow(), "wrong parent %p\n", test);
11179 ok(!IsChild(parent, child2), "wrong parent/child %p/%p\n", parent, child2);
11180 if(pGetAncestor) {
11181 test = pGetAncestor(child2, GA_PARENT);
11182 ok(test == GetDesktopWindow(), "wrong parent %p\n", test);
11183 }
11184 test = GetWindow(child2, GW_OWNER);
11185 ok(!test, "wrong owner %p\n", test);
11186
11187 test = SetParent(child2, parent);
11188 ok(test == GetDesktopWindow(), "wrong old parent %p\n", test);
11189
11190 /* test owner/parent of the parent */
11192 ok(!test, "wrong parent %p\n", test);
11193 ok(!IsChild(GetDesktopWindow(), parent), "wrong parent/child %p/%p\n", GetDesktopWindow(), parent);
11194 if(pGetAncestor) {
11195 test = pGetAncestor(parent, GA_PARENT);
11196 ok(test == GetDesktopWindow(), "wrong parent %p\n", test);
11197 }
11199 ok(!test, "wrong owner %p\n", test);
11200
11201 /* test owner/parent of child1 */
11202 test = GetParent(child1);
11203 ok(test == parent, "wrong parent %p\n", test);
11204 ok(IsChild(parent, child1), "wrong parent/child %p/%p\n", parent, child1);
11205 if(pGetAncestor) {
11206 test = pGetAncestor(child1, GA_PARENT);
11207 ok(test == parent, "wrong parent %p\n", test);
11208 }
11209 test = GetWindow(child1, GW_OWNER);
11210 ok(!test, "wrong owner %p\n", test);
11211
11212 /* test owner/parent of child2 */
11213 test = GetParent(child2);
11214 ok(test == parent, "wrong parent %p\n", test);
11215 ok(IsChild(parent, child2), "wrong parent/child %p/%p\n", parent, child2);
11216 if(pGetAncestor) {
11217 test = pGetAncestor(child2, GA_PARENT);
11218 ok(test == parent, "wrong parent %p\n", test);
11219 }
11220 test = GetWindow(child2, GW_OWNER);
11221 ok(!test, "wrong owner %p\n", test);
11222
11223 /* test owner/parent of child3 */
11224 test = GetParent(child3);
11225 ok(test == child1, "wrong parent %p\n", test);
11226 ok(IsChild(parent, child3), "wrong parent/child %p/%p\n", parent, child3);
11227 if(pGetAncestor) {
11228 test = pGetAncestor(child3, GA_PARENT);
11229 ok(test == child1, "wrong parent %p\n", test);
11230 }
11231 test = GetWindow(child3, GW_OWNER);
11232 ok(!test, "wrong owner %p\n", test);
11233
11234 /* test owner/parent of child4 */
11235 test = GetParent(child4);
11236 ok(test == parent, "wrong parent %p\n", test);
11237 ok(!IsChild(parent, child4), "wrong parent/child %p/%p\n", parent, child4);
11238 if(pGetAncestor) {
11239 test = pGetAncestor(child4, GA_PARENT);
11240 ok(test == GetDesktopWindow(), "wrong parent %p\n", test);
11241 }
11242 test = GetWindow(child4, GW_OWNER);
11243 ok(test == parent, "wrong owner %p\n", test);
11244
11246
11247 trace("parent %p, child1 %p, child2 %p, child3 %p, child4 %p\n",
11248 parent, child1, child2, child3, child4);
11249
11250 SetCapture(child4);
11251 test = GetCapture();
11252 ok(test == child4, "wrong capture window %p\n", test);
11253
11256 ok( ret, "DestroyWindow() error %d\n", GetLastError());
11258 ok_sequence(destroy_window_with_children, "destroy window with children", FALSE);
11259
11260 ok(!IsWindow(parent), "parent still exists\n");
11261 ok(!IsWindow(child1), "child1 still exists\n");
11262 ok(!IsWindow(child2), "child2 still exists\n");
11263 ok(!IsWindow(child3), "child3 still exists\n");
11264 ok(!IsWindow(child4), "child4 still exists\n");
11265
11266 test = GetCapture();
11267 ok(!test, "wrong capture window %p\n", test);
11268}
11269
11270
11271static const struct message WmDispatchPaint[] = {
11272 { WM_NCPAINT, sent },
11275 { WM_ERASEBKGND, sent },
11276 { 0 }
11277};
11278
11280{
11281 if (message == WM_PAINT) return 0;
11282 return MsgCheckProcA( hwnd, message, wParam, lParam );
11283}
11284
11285static void test_DispatchMessage(void)
11286{
11287 RECT rect;
11288 MSG msg;
11289 int count;
11290 HWND hwnd = CreateWindowA( "TestWindowClass", NULL, WS_OVERLAPPEDWINDOW,
11291 100, 100, 200, 200, 0, 0, 0, NULL);
11293 UpdateWindow( hwnd );
11294 flush_events();
11297
11298 SetRect( &rect, -5, -5, 5, 5 );
11300 count = 0;
11301 while (PeekMessageA( &msg, 0, 0, 0, PM_REMOVE ))
11302 {
11303 if (msg.message != WM_PAINT) DispatchMessageA( &msg );
11304 else
11305 {
11308 /* DispatchMessage will send WM_NCPAINT if non client area is still invalid after WM_PAINT */
11309 if (!count) ok_sequence( WmDispatchPaint, "WmDispatchPaint", FALSE );
11310 else ok_sequence( WmEmptySeq, "WmEmpty", FALSE );
11311 if (++count > 10) break;
11312 }
11313 }
11314 ok( msg.message == WM_PAINT && count > 10, "WM_PAINT messages stopped\n" );
11315
11316 trace("now without DispatchMessage\n");
11319 count = 0;
11320 while (PeekMessageA( &msg, 0, 0, 0, PM_REMOVE ))
11321 {
11322 if (msg.message != WM_PAINT) DispatchMessageA( &msg );
11323 else
11324 {
11325 HRGN hrgn = CreateRectRgn( 0, 0, 0, 0 );
11327 /* this will send WM_NCCPAINT just like DispatchMessage does */
11329 ok_sequence( WmDispatchPaint, "WmDispatchPaint", FALSE );
11330 DeleteObject( hrgn );
11331 GetClientRect( hwnd, &rect );
11332 ValidateRect( hwnd, &rect ); /* this will stop WM_PAINTs */
11333 ok( !count, "Got multiple WM_PAINTs\n" );
11334 if (++count > 10) break;
11335 }
11336 }
11337
11340 count = 0;
11341 while (PeekMessageA( &msg, 0, 0, 0, PM_REMOVE ))
11342 {
11343 if (msg.message != WM_PAINT) DispatchMessageA( &msg );
11344 else
11345 {
11346 HDC hdc;
11347
11349 hdc = BeginPaint( hwnd, NULL );
11350 ok( !hdc, "got valid hdc %p from BeginPaint\n", hdc );
11351 ok( !EndPaint( hwnd, NULL ), "EndPaint succeeded\n" );
11352 ok_sequence( WmDispatchPaint, "WmDispatchPaint", FALSE );
11353 ok( !count, "Got multiple WM_PAINTs\n" );
11354 if (++count > 10) break;
11355 }
11356 }
11358}
11359
11360
11361static const struct message WmUser[] = {
11362 { WM_USER, sent },
11363 { 0 }
11364};
11365
11367{
11371};
11372
11374{
11375 struct sendmsg_info *info = arg;
11376 SetLastError( 0xdeadbeef );
11377 info->ret = SendMessageTimeoutA( info->hwnd, WM_USER, 0, 0, 0, info->timeout, NULL );
11378 if (!info->ret) ok( GetLastError() == ERROR_TIMEOUT ||
11379 broken(GetLastError() == 0), /* win9x */
11380 "unexpected error %d\n", GetLastError());
11381 return 0;
11382}
11383
11385{
11387 {
11388 MSG msg;
11389 while (PeekMessageA( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessageA(&msg);
11390 }
11391}
11392
11394{
11395 if (message == WM_USER) Sleep(200);
11396 return MsgCheckProcA( hwnd, message, wParam, lParam );
11397}
11398
11400{
11401 HANDLE thread;
11402 struct sendmsg_info info;
11403 DWORD tid;
11404 BOOL is_win9x;
11405
11406 info.hwnd = CreateWindowA( "TestWindowClass", NULL, WS_OVERLAPPEDWINDOW,
11407 100, 100, 200, 200, 0, 0, 0, NULL);
11408 flush_events();
11410
11411 info.timeout = 1000;
11412 info.ret = 0xdeadbeef;
11416 ok( info.ret == 1, "SendMessageTimeout failed\n" );
11417 ok_sequence( WmUser, "WmUser", FALSE );
11418
11419 info.timeout = 1;
11420 info.ret = 0xdeadbeef;
11422 Sleep(100); /* SendMessageTimeout should time out here */
11425 ok( info.ret == 0, "SendMessageTimeout succeeded\n" );
11426 ok_sequence( WmEmptySeq, "WmEmptySeq", FALSE );
11427
11428 /* 0 means infinite timeout (but not on win9x) */
11429 info.timeout = 0;
11430 info.ret = 0xdeadbeef;
11432 Sleep(100);
11435 is_win9x = !info.ret;
11436 if (is_win9x) ok_sequence( WmEmptySeq, "WmEmptySeq", FALSE );
11437 else ok_sequence( WmUser, "WmUser", FALSE );
11438
11439 /* timeout is treated as signed despite the prototype (but not on win9x) */
11440 info.timeout = 0x7fffffff;
11441 info.ret = 0xdeadbeef;
11443 Sleep(100);
11446 ok( info.ret == 1, "SendMessageTimeout failed\n" );
11447 ok_sequence( WmUser, "WmUser", FALSE );
11448
11449 info.timeout = 0x80000000;
11450 info.ret = 0xdeadbeef;
11452 Sleep(100);
11455 if (is_win9x)
11456 {
11457 ok( info.ret == 1, "SendMessageTimeout failed\n" );
11458 ok_sequence( WmUser, "WmUser", FALSE );
11459 }
11460 else
11461 {
11462 ok( info.ret == 0, "SendMessageTimeout succeeded\n" );
11463 ok_sequence( WmEmptySeq, "WmEmptySeq", FALSE );
11464 }
11465
11466 /* now check for timeout during message processing */
11468 info.timeout = 100;
11469 info.ret = 0xdeadbeef;
11473 /* we should time out but still get the message */
11474 ok( info.ret == 0, "SendMessageTimeout failed\n" );
11475 ok_sequence( WmUser, "WmUser", FALSE );
11476
11477 DestroyWindow( info.hwnd );
11478}
11479
11480
11481/****************** edit message test *************************/
11482#define ID_EDIT 0x1234
11483static const struct message sl_edit_setfocus[] =
11484{
11485 { HCBT_SETFOCUS, hook },
11488 { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
11489 { WM_SETFOCUS, sent|wparam, 0 },
11494 { EVENT_OBJECT_CREATE, winevent_hook|wparam|lparam, OBJID_CARET, 0 },
11495 { EVENT_OBJECT_SHOW, winevent_hook|wparam|lparam, OBJID_CARET, 0 },
11497 { 0 }
11498};
11499static const struct message sl_edit_invisible[] =
11500{
11501 { HCBT_SETFOCUS, hook },
11504 { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
11506 { WM_SETFOCUS, sent },
11508 { 0 }
11509};
11510static const struct message ml_edit_setfocus[] =
11511{
11512 { HCBT_SETFOCUS, hook },
11515 { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
11516 { WM_SETFOCUS, sent|wparam, 0 },
11519 { EVENT_OBJECT_CREATE, winevent_hook|wparam|lparam, OBJID_CARET, 0 },
11520 { EVENT_OBJECT_SHOW, winevent_hook|wparam|lparam, OBJID_CARET, 0 },
11522 { 0 }
11523};
11524static const struct message sl_edit_killfocus[] =
11525{
11526 { HCBT_SETFOCUS, hook },
11527 { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
11528 { WM_KILLFOCUS, sent|wparam, 0 },
11529 { EVENT_OBJECT_HIDE, winevent_hook|wparam|lparam, OBJID_CARET, 0 },
11530 { EVENT_OBJECT_DESTROY, winevent_hook|wparam|lparam, OBJID_CARET, 0 },
11534 { 0 }
11535};
11536static const struct message sl_edit_lbutton_dblclk[] =
11537{
11539 { EVENT_SYSTEM_CAPTURESTART, winevent_hook|wparam|lparam, 0, 0 },
11540 { 0 }
11541};
11542static const struct message sl_edit_lbutton_down[] =
11543{
11544 { WM_LBUTTONDOWN, sent|wparam|lparam, 0, 0 },
11545 { HCBT_SETFOCUS, hook },
11548 { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
11553 { EVENT_OBJECT_CREATE, winevent_hook|wparam|lparam, OBJID_CARET, 0 },
11554 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, OBJID_CARET, 0 },
11555 { EVENT_OBJECT_SHOW, winevent_hook|wparam|lparam, OBJID_CARET, 0 },
11557 { EVENT_SYSTEM_CAPTURESTART, winevent_hook|wparam|lparam, 0, 0 },
11558 { EVENT_OBJECT_HIDE, winevent_hook|wparam|lparam, OBJID_CARET, 0 },
11561 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, OBJID_CARET, 0 },
11562 { EVENT_OBJECT_SHOW, winevent_hook|wparam|lparam, OBJID_CARET, 0 },
11563 { 0 }
11564};
11565static const struct message ml_edit_lbutton_down[] =
11566{
11567 { WM_LBUTTONDOWN, sent|wparam|lparam, 0, 0 },
11568 { EVENT_SYSTEM_CAPTURESTART, winevent_hook|wparam|lparam, 0, 0 },
11569 { HCBT_SETFOCUS, hook },
11572 { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
11576 { EVENT_OBJECT_CREATE, winevent_hook|wparam|lparam, OBJID_CARET, 0 },
11577 { EVENT_OBJECT_SHOW, winevent_hook|wparam|lparam, OBJID_CARET, 0 },
11579 { 0 }
11580};
11581static const struct message sl_edit_lbutton_up[] =
11582{
11583 { WM_LBUTTONUP, sent|wparam|lparam, 0, 0 },
11584 { EVENT_OBJECT_HIDE, winevent_hook|wparam|lparam, OBJID_CARET, 0 },
11585 { EVENT_SYSTEM_CAPTUREEND, winevent_hook|wparam|lparam, 0, 0 },
11587 { EVENT_OBJECT_SHOW, winevent_hook|wparam|lparam, OBJID_CARET, 0 },
11588 { 0 }
11589};
11590static const struct message ml_edit_lbutton_up[] =
11591{
11592 { WM_LBUTTONUP, sent|wparam|lparam, 0, 0 },
11593 { EVENT_SYSTEM_CAPTUREEND, winevent_hook|wparam|lparam, 0, 0 },
11595 { 0 }
11596};
11597
11599
11601{
11602 static LONG defwndproc_counter = 0;
11603 LRESULT ret;
11604 struct recvd_message msg;
11605
11606 if (ignore_message( message )) return 0;
11607
11608 msg.hwnd = hwnd;
11609 msg.message = message;
11610 msg.flags = sent|wparam|lparam;
11611 if (defwndproc_counter) msg.flags |= defwinproc;
11612 msg.wParam = wParam;
11613 msg.lParam = lParam;
11614 msg.descr = "edit";
11615 add_message(&msg);
11616
11617 defwndproc_counter++;
11619 defwndproc_counter--;
11620
11621 return ret;
11622}
11623
11624static void subclass_edit(void)
11625{
11626 WNDCLASSA cls;
11627
11628 if (!GetClassInfoA(0, "edit", &cls)) assert(0);
11629
11631
11634 cls.lpszClassName = "my_edit_class";
11636 if (!RegisterClassA(&cls)) assert(0);
11637}
11638
11639static void test_edit_messages(void)
11640{
11641 HWND hwnd, parent;
11642 DWORD dlg_code;
11643
11644 subclass_edit();
11646
11647 parent = CreateWindowExA(0, "TestParentClass", "Test parent", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
11648 100, 100, 200, 200, 0, 0, 0, NULL);
11649 ok (parent != 0, "Failed to create parent window\n");
11650
11651 /* test single line edit */
11652 hwnd = CreateWindowExA(0, "my_edit_class", "test", WS_CHILD,
11653 0, 0, 80, 20, parent, (HMENU)ID_EDIT, 0, NULL);
11654 ok(hwnd != 0, "Failed to create edit window\n");
11655
11656 dlg_code = SendMessageA(hwnd, WM_GETDLGCODE, 0, 0);
11657 ok(dlg_code == (DLGC_WANTCHARS|DLGC_HASSETSEL|DLGC_WANTARROWS), "wrong dlg_code %08x\n", dlg_code);
11658
11660 SetFocus(hwnd);
11661 ok_sequence(sl_edit_invisible, "SetFocus(hwnd) on an invisible edit", FALSE);
11662
11665 SetFocus(0);
11667
11668 SetFocus(hwnd);
11669 ok_sequence(sl_edit_setfocus, "SetFocus(hwnd) on an edit", FALSE);
11670
11671 SetFocus(0);
11672 ok_sequence(sl_edit_killfocus, "SetFocus(0) on an edit", FALSE);
11673
11674 SetFocus(0);
11677
11679 ok_sequence(sl_edit_lbutton_dblclk, "WM_LBUTTONDBLCLK on an edit", FALSE);
11680
11681 SetFocus(0);
11684
11686 ok_sequence(sl_edit_lbutton_down, "WM_LBUTTONDOWN on an edit", FALSE);
11687
11689 ok_sequence(sl_edit_lbutton_up, "WM_LBUTTONUP on an edit", FALSE);
11690
11692
11693 /* test multiline edit */
11694 hwnd = CreateWindowExA(0, "my_edit_class", "test", WS_CHILD | ES_MULTILINE,
11695 0, 0, 80, 20, parent, (HMENU)ID_EDIT, 0, NULL);
11696 ok(hwnd != 0, "Failed to create edit window\n");
11697
11698 dlg_code = SendMessageA(hwnd, WM_GETDLGCODE, 0, 0);
11700 "wrong dlg_code %08x\n", dlg_code);
11701
11704 SetFocus(0);
11706
11707 SetFocus(hwnd);
11708 ok_sequence(ml_edit_setfocus, "SetFocus(hwnd) on multiline edit", FALSE);
11709
11710 SetFocus(0);
11711 ok_sequence(sl_edit_killfocus, "SetFocus(0) on multiline edit", FALSE);
11712
11713 SetFocus(0);
11716
11718 ok_sequence(sl_edit_lbutton_dblclk, "WM_LBUTTONDBLCLK on multiline edit", FALSE);
11719
11720 SetFocus(0);
11723
11725 ok_sequence(ml_edit_lbutton_down, "WM_LBUTTONDOWN on multiline edit", FALSE);
11726
11728 ok_sequence(ml_edit_lbutton_up, "WM_LBUTTONUP on multiline edit", FALSE);
11729
11732
11734}
11735
11736/**************************** End of Edit test ******************************/
11737
11738static const struct message WmKeyDownSkippedSeq[] =
11739{
11740 { HCBT_KEYSKIPPED, hook|wparam|lparam|optional, 'N', 1 }, /* XP */
11741 { 0 }
11742};
11744{
11745 { HCBT_KEYSKIPPED, hook|wparam|lparam|optional, 'N', 0x40000001 }, /* XP */
11746 { 0 }
11747};
11748static const struct message WmKeyUpSkippedSeq[] =
11749{
11750 { HCBT_KEYSKIPPED, hook|wparam|lparam|optional, 'N', 0xc0000001 }, /* XP */
11751 { 0 }
11752};
11753static const struct message WmUserKeyUpSkippedSeq[] =
11754{
11755 { WM_USER, sent },
11756 { HCBT_KEYSKIPPED, hook|wparam|lparam|optional, 'N', 0xc0000001 }, /* XP */
11757 { 0 }
11758};
11759
11760#define EV_STOP 0
11761#define EV_SENDMSG 1
11762#define EV_ACK 2
11763
11765{
11767 HANDLE hevent[3]; /* 0 - start/stop, 1 - SendMessage, 2 - ack */
11768};
11769
11771{
11772 DWORD ret;
11773 struct peekmsg_info *info = param;
11774
11775 trace("thread: looping\n");
11776 SetEvent(info->hevent[EV_ACK]);
11777
11778 while (1)
11779 {
11781
11782 switch (ret)
11783 {
11784 case WAIT_OBJECT_0 + EV_STOP:
11785 trace("thread: exiting\n");
11786 return 0;
11787
11789 trace("thread: sending message\n");
11790 ret = SendNotifyMessageA(info->hwnd, WM_USER, 0, 0);
11791 ok(ret, "SendNotifyMessageA failed error %u\n", GetLastError());
11792 SetEvent(info->hevent[EV_ACK]);
11793 break;
11794
11795 default:
11796 trace("unexpected return: %04x\n", ret);
11797 assert(0);
11798 break;
11799 }
11800 }
11801 return 0;
11802}
11803
11804static void test_PeekMessage(void)
11805{
11806 MSG msg;
11807 HANDLE hthread;
11808 DWORD tid, qstatus;
11809 UINT qs_all_input = QS_ALLINPUT;
11810 UINT qs_input = QS_INPUT;
11811 BOOL ret;
11812 struct peekmsg_info info;
11813
11814 info.hwnd = CreateWindowA("TestWindowClass", NULL, WS_OVERLAPPEDWINDOW,
11815 100, 100, 200, 200, 0, 0, 0, NULL);
11816 assert(info.hwnd);
11817 ShowWindow(info.hwnd, SW_SHOW);
11818 UpdateWindow(info.hwnd);
11819 SetFocus(info.hwnd);
11820
11821 info.hevent[EV_STOP] = CreateEventA(NULL, 0, 0, NULL);
11822 info.hevent[EV_SENDMSG] = CreateEventA(NULL, 0, 0, NULL);
11823 info.hevent[EV_ACK] = CreateEventA(NULL, 0, 0, NULL);
11824
11825 hthread = CreateThread(NULL, 0, send_msg_thread_2, &info, 0, &tid);
11826 WaitForSingleObject(info.hevent[EV_ACK], 10000);
11827
11828 flush_events();
11830
11831 SetLastError(0xdeadbeef);
11832 qstatus = GetQueueStatus(qs_all_input);
11834 {
11835 trace("QS_RAWINPUT not supported on this platform\n");
11836 qs_all_input &= ~QS_RAWINPUT;
11837 qs_input &= ~QS_RAWINPUT;
11838 }
11839 if (qstatus & QS_POSTMESSAGE)
11840 {
11841 while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) /* nothing */ ;
11842 qstatus = GetQueueStatus(qs_all_input);
11843 }
11844 ok(qstatus == 0, "wrong qstatus %08x\n", qstatus);
11845
11846 trace("signalling to send message\n");
11847 SetEvent(info.hevent[EV_SENDMSG]);
11849
11850 /* pass invalid QS_xxxx flags */
11851 SetLastError(0xdeadbeef);
11852 qstatus = GetQueueStatus(0xffffffff);
11853 ok(qstatus == 0 || broken(qstatus) /* win9x */, "GetQueueStatus should fail: %08x\n", qstatus);
11854 if (!qstatus)
11855 {
11856 ok(GetLastError() == ERROR_INVALID_FLAGS, "wrong error %d\n", GetLastError());
11857 qstatus = GetQueueStatus(qs_all_input);
11858 }
11859 qstatus &= ~MAKELONG( 0x4000, 0x4000 ); /* sometimes set on Win95 */
11861 "wrong qstatus %08x\n", qstatus);
11862
11863 msg.message = 0;
11864 ret = PeekMessageA(&msg, 0, 0, 0, PM_REMOVE);
11865 ok(!ret,
11866 "PeekMessageA should have returned FALSE instead of msg %04x\n",
11867 msg.message);
11868 ok_sequence(WmUser, "WmUser", FALSE);
11869
11870 qstatus = GetQueueStatus(qs_all_input);
11871 ok(qstatus == 0, "wrong qstatus %08x\n", qstatus);
11872
11873 keybd_event('N', 0, 0, 0);
11874 keybd_event('N', 0, KEYEVENTF_KEYUP, 0);
11875 qstatus = GetQueueStatus(qs_all_input);
11876 if (!(qstatus & MAKELONG(QS_KEY, QS_KEY)))
11877 {
11878 skip( "queuing key events not supported\n" );
11879 goto done;
11880 }
11881 ok(qstatus == MAKELONG(QS_KEY, QS_KEY) ||
11882 /* keybd_event seems to trigger a sent message on NT4 */
11884 "wrong qstatus %08x\n", qstatus);
11885
11886 PostMessageA(info.hwnd, WM_CHAR, 'z', 0);
11887 qstatus = GetQueueStatus(qs_all_input);
11890 "wrong qstatus %08x\n", qstatus);
11891
11892 InvalidateRect(info.hwnd, NULL, FALSE);
11893 qstatus = GetQueueStatus(qs_all_input);
11896 "wrong qstatus %08x\n", qstatus);
11897
11898 trace("signalling to send message\n");
11899 SetEvent(info.hevent[EV_SENDMSG]);
11901
11902 qstatus = GetQueueStatus(qs_all_input);
11904 "wrong qstatus %08x\n", qstatus);
11905
11906 msg.message = 0;
11907 ret = PeekMessageA(&msg, 0, 0, 0, PM_REMOVE | (qs_input << 16));
11908 if (ret && msg.message == WM_CHAR)
11909 {
11910 win_skip( "PM_QS_* flags not supported in PeekMessage\n" );
11911 goto done;
11912 }
11913 ok(!ret,
11914 "PeekMessageA should have returned FALSE instead of msg %04x\n",
11915 msg.message);
11916 if (!sequence_cnt) /* nt4 doesn't fetch anything with PM_QS_* flags */
11917 {
11918 win_skip( "PM_QS_* flags not supported in PeekMessage\n" );
11919 goto done;
11920 }
11921 ok_sequence(WmUser, "WmUser", FALSE);
11922
11923 qstatus = GetQueueStatus(qs_all_input);
11924 ok(qstatus == MAKELONG(0, QS_PAINT|QS_POSTMESSAGE|QS_KEY),
11925 "wrong qstatus %08x\n", qstatus);
11926
11927 trace("signalling to send message\n");
11928 SetEvent(info.hevent[EV_SENDMSG]);
11930
11931 qstatus = GetQueueStatus(qs_all_input);
11933 "wrong qstatus %08x\n", qstatus);
11934
11935 msg.message = 0;
11936 ret = PeekMessageA(&msg, 0, 0, 0, PM_REMOVE | PM_QS_POSTMESSAGE );
11937 ok(!ret,
11938 "PeekMessageA should have returned FALSE instead of msg %04x\n",
11939 msg.message);
11940 ok_sequence(WmUser, "WmUser", FALSE);
11941
11942 qstatus = GetQueueStatus(qs_all_input);
11943 ok(qstatus == MAKELONG(0, QS_PAINT|QS_POSTMESSAGE|QS_KEY),
11944 "wrong qstatus %08x\n", qstatus);
11945
11946 msg.message = 0;
11947 ret = PeekMessageA(&msg, 0, 0, 0, PM_REMOVE | PM_QS_POSTMESSAGE);
11948 ok(ret && msg.message == WM_CHAR && msg.wParam == 'z',
11949 "got %d and %04x wParam %08lx instead of TRUE and WM_CHAR wParam 'z'\n",
11950 ret, msg.message, msg.wParam);
11951 ok_sequence(WmEmptySeq, "WmEmptySeq", FALSE);
11952
11953 qstatus = GetQueueStatus(qs_all_input);
11954 ok(qstatus == MAKELONG(0, QS_PAINT|QS_KEY),
11955 "wrong qstatus %08x\n", qstatus);
11956
11957 msg.message = 0;
11958 ret = PeekMessageA(&msg, 0, 0, 0, PM_REMOVE | PM_QS_POSTMESSAGE);
11959 ok(!ret,
11960 "PeekMessageA should have returned FALSE instead of msg %04x\n",
11961 msg.message);
11962 ok_sequence(WmEmptySeq, "WmEmptySeq", FALSE);
11963
11964 qstatus = GetQueueStatus(qs_all_input);
11965 ok(qstatus == MAKELONG(0, QS_PAINT|QS_KEY),
11966 "wrong qstatus %08x\n", qstatus);
11967
11968 msg.message = 0;
11969 ret = PeekMessageA(&msg, 0, 0, 0, PM_REMOVE | PM_QS_PAINT);
11970 ok(ret && msg.message == WM_PAINT,
11971 "got %d and %04x instead of TRUE and WM_PAINT\n", ret, msg.message);
11973 ok_sequence(WmPaint, "WmPaint", FALSE);
11974
11975 qstatus = GetQueueStatus(qs_all_input);
11976 ok(qstatus == MAKELONG(0, QS_KEY),
11977 "wrong qstatus %08x\n", qstatus);
11978
11979 msg.message = 0;
11980 ret = PeekMessageA(&msg, 0, 0, 0, PM_REMOVE | PM_QS_PAINT);
11981 ok(!ret,
11982 "PeekMessageA should have returned FALSE instead of msg %04x\n",
11983 msg.message);
11984 ok_sequence(WmEmptySeq, "WmEmptySeq", FALSE);
11985
11986 qstatus = GetQueueStatus(qs_all_input);
11987 ok(qstatus == MAKELONG(0, QS_KEY),
11988 "wrong qstatus %08x\n", qstatus);
11989
11990 trace("signalling to send message\n");
11991 SetEvent(info.hevent[EV_SENDMSG]);
11993
11994 qstatus = GetQueueStatus(qs_all_input);
11996 "wrong qstatus %08x\n", qstatus);
11997
11998 PostMessageA(info.hwnd, WM_CHAR, 'z', 0);
11999
12000 qstatus = GetQueueStatus(qs_all_input);
12002 "wrong qstatus %08x\n", qstatus);
12003
12004 msg.message = 0;
12006 ok(ret && msg.message == WM_CHAR && msg.wParam == 'z',
12007 "got %d and %04x wParam %08lx instead of TRUE and WM_CHAR wParam 'z'\n",
12008 ret, msg.message, msg.wParam);
12009 ok_sequence(WmUser, "WmUser", FALSE);
12010
12011 qstatus = GetQueueStatus(qs_all_input);
12012 ok(qstatus == MAKELONG(0, QS_KEY),
12013 "wrong qstatus %08x\n", qstatus);
12014
12015 msg.message = 0;
12017 ok(!ret,
12018 "PeekMessageA should have returned FALSE instead of msg %04x\n",
12019 msg.message);
12020 ok_sequence(WmEmptySeq, "WmEmptySeq", FALSE);
12021
12022 qstatus = GetQueueStatus(qs_all_input);
12023 ok(qstatus == MAKELONG(0, QS_KEY),
12024 "wrong qstatus %08x\n", qstatus);
12025
12026 PostMessageA(info.hwnd, WM_CHAR, 'z', 0);
12027
12028 qstatus = GetQueueStatus(qs_all_input);
12030 "wrong qstatus %08x\n", qstatus);
12031
12032 trace("signalling to send message\n");
12033 SetEvent(info.hevent[EV_SENDMSG]);
12035
12036 qstatus = GetQueueStatus(qs_all_input);
12038 "wrong qstatus %08x\n", qstatus);
12039
12040 msg.message = 0;
12041 ret = PeekMessageA(&msg, 0, 0, 0, PM_REMOVE | (QS_KEY << 16));
12042 ok(!ret,
12043 "PeekMessageA should have returned FALSE instead of msg %04x\n",
12044 msg.message);
12045 ok_sequence(WmUser, "WmUser", FALSE);
12046
12047 qstatus = GetQueueStatus(qs_all_input);
12048 ok(qstatus == MAKELONG(0, QS_POSTMESSAGE|QS_KEY),
12049 "wrong qstatus %08x\n", qstatus);
12050
12051 msg.message = 0;
12052 if (qs_all_input & QS_RAWINPUT) /* use QS_RAWINPUT only if supported */
12053 ret = PeekMessageA(&msg, 0, 0, 0, PM_REMOVE | (QS_RAWINPUT << 16));
12054 else /* workaround for a missing QS_RAWINPUT support */
12056 ok(ret && msg.message == WM_KEYDOWN && msg.wParam == 'N',
12057 "got %d and %04x wParam %08lx instead of TRUE and WM_KEYDOWN wParam 'N'\n",
12058 ret, msg.message, msg.wParam);
12059 ok_sequence(WmKeyDownSkippedSeq, "WmKeyDownSkippedSeq", FALSE);
12060
12061 qstatus = GetQueueStatus(qs_all_input);
12062 ok(qstatus == MAKELONG(0, QS_POSTMESSAGE|QS_KEY),
12063 "wrong qstatus %08x\n", qstatus);
12064
12065 msg.message = 0;
12066 if (qs_all_input & QS_RAWINPUT) /* use QS_RAWINPUT only if supported */
12067 ret = PeekMessageA(&msg, 0, 0, 0, PM_REMOVE | (QS_RAWINPUT << 16));
12068 else /* workaround for a missing QS_RAWINPUT support */
12070 ok(ret && msg.message == WM_KEYUP && msg.wParam == 'N',
12071 "got %d and %04x wParam %08lx instead of TRUE and WM_KEYUP wParam 'N'\n",
12072 ret, msg.message, msg.wParam);
12073 ok_sequence(WmKeyUpSkippedSeq, "WmKeyUpSkippedSeq", FALSE);
12074
12075 qstatus = GetQueueStatus(qs_all_input);
12076 ok(qstatus == MAKELONG(0, QS_POSTMESSAGE),
12077 "wrong qstatus %08x\n", qstatus);
12078
12079 msg.message = 0;
12080 ret = PeekMessageA(&msg, 0, 0, 0, PM_REMOVE | PM_QS_SENDMESSAGE);
12081 ok(!ret,
12082 "PeekMessageA should have returned FALSE instead of msg %04x\n",
12083 msg.message);
12084 ok_sequence(WmEmptySeq, "WmEmptySeq", FALSE);
12085
12086 qstatus = GetQueueStatus(qs_all_input);
12087 ok(qstatus == MAKELONG(0, QS_POSTMESSAGE),
12088 "wrong qstatus %08x\n", qstatus);
12089
12090 msg.message = 0;
12091 ret = PeekMessageA(&msg, 0, 0, 0, PM_REMOVE);
12092 ok(ret && msg.message == WM_CHAR && msg.wParam == 'z',
12093 "got %d and %04x wParam %08lx instead of TRUE and WM_CHAR wParam 'z'\n",
12094 ret, msg.message, msg.wParam);
12095 ok_sequence(WmEmptySeq, "WmEmptySeq", FALSE);
12096
12097 qstatus = GetQueueStatus(qs_all_input);
12098 ok(qstatus == 0,
12099 "wrong qstatus %08x\n", qstatus);
12100
12101 msg.message = 0;
12102 ret = PeekMessageA(&msg, 0, 0, 0, PM_REMOVE);
12103 ok(!ret,
12104 "PeekMessageA should have returned FALSE instead of msg %04x\n",
12105 msg.message);
12106 ok_sequence(WmEmptySeq, "WmEmptySeq", FALSE);
12107
12108 qstatus = GetQueueStatus(qs_all_input);
12109 ok(qstatus == 0,
12110 "wrong qstatus %08x\n", qstatus);
12111
12112 /* test whether presence of the quit flag in the queue affects
12113 * the queue state
12114 */
12115 PostQuitMessage(0x1234abcd);
12116
12117 qstatus = GetQueueStatus(qs_all_input);
12119 "wrong qstatus %08x\n", qstatus);
12120
12121 PostMessageA(info.hwnd, WM_USER, 0, 0);
12122
12123 qstatus = GetQueueStatus(qs_all_input);
12125 "wrong qstatus %08x\n", qstatus);
12126
12127 msg.message = 0;
12128 ret = PeekMessageA(&msg, 0, 0, 0, PM_REMOVE);
12129 ok(ret && msg.message == WM_USER,
12130 "got %d and %04x instead of TRUE and WM_USER\n", ret, msg.message);
12131 ok_sequence(WmEmptySeq, "WmEmptySeq", FALSE);
12132
12133 qstatus = GetQueueStatus(qs_all_input);
12134 ok(qstatus == MAKELONG(0, QS_POSTMESSAGE),
12135 "wrong qstatus %08x\n", qstatus);
12136
12137 msg.message = 0;
12138 ret = PeekMessageA(&msg, 0, 0, 0, PM_REMOVE);
12139 ok(ret && msg.message == WM_QUIT,
12140 "got %d and %04x instead of TRUE and WM_QUIT\n", ret, msg.message);
12141 ok(msg.wParam == 0x1234abcd, "got wParam %08lx instead of 0x1234abcd\n", msg.wParam);
12142 ok(msg.lParam == 0, "got lParam %08lx instead of 0\n", msg.lParam);
12143 ok_sequence(WmEmptySeq, "WmEmptySeq", FALSE);
12144
12145 qstatus = GetQueueStatus(qs_all_input);
12146todo_wine {
12147 ok(qstatus == MAKELONG(0, QS_POSTMESSAGE),
12148 "wrong qstatus %08x\n", qstatus);
12149}
12150
12151 msg.message = 0;
12152 ret = PeekMessageA(&msg, 0, 0, 0, PM_REMOVE);
12153 ok(!ret,
12154 "PeekMessageA should have returned FALSE instead of msg %04x\n",
12155 msg.message);
12156 ok_sequence(WmEmptySeq, "WmEmptySeq", FALSE);
12157
12158 qstatus = GetQueueStatus(qs_all_input);
12159 ok(qstatus == 0,
12160 "wrong qstatus %08x\n", qstatus);
12161
12162 /* some GetMessage tests */
12163
12164 keybd_event('N', 0, 0, 0);
12165 qstatus = GetQueueStatus(qs_all_input);
12166 ok(qstatus == MAKELONG(QS_KEY, QS_KEY), "wrong qstatus %08x\n", qstatus);
12167
12168 PostMessageA(info.hwnd, WM_CHAR, 'z', 0);
12169 qstatus = GetQueueStatus(qs_all_input);
12170 ok(qstatus == MAKELONG(QS_POSTMESSAGE, QS_POSTMESSAGE|QS_KEY), "wrong qstatus %08x\n", qstatus);
12171
12172 if (qstatus)
12173 {
12174 ret = GetMessageA( &msg, 0, 0, 0 );
12175 ok(ret && msg.message == WM_CHAR && msg.wParam == 'z',
12176 "got %d and %04x wParam %08lx instead of TRUE and WM_CHAR wParam 'z'\n",
12177 ret, msg.message, msg.wParam);
12178 qstatus = GetQueueStatus(qs_all_input);
12179 ok(qstatus == MAKELONG(0, QS_KEY), "wrong qstatus %08x\n", qstatus);
12180 }
12181
12182 if (qstatus)
12183 {
12184 ret = GetMessageA( &msg, 0, 0, 0 );
12185 ok(ret && msg.message == WM_KEYDOWN && msg.wParam == 'N',
12186 "got %d and %04x wParam %08lx instead of TRUE and WM_KEYDOWN wParam 'N'\n",
12187 ret, msg.message, msg.wParam);
12188 ok_sequence(WmKeyDownSkippedSeq, "WmKeyDownSkippedSeq", FALSE);
12189 qstatus = GetQueueStatus(qs_all_input);
12190 ok(qstatus == 0, "wrong qstatus %08x\n", qstatus);
12191 }
12192
12193 keybd_event('N', 0, 0, 0);
12194 qstatus = GetQueueStatus(qs_all_input);
12195 ok(qstatus == MAKELONG(QS_KEY, QS_KEY), "wrong qstatus %08x\n", qstatus);
12196
12197 PostMessageA(info.hwnd, WM_CHAR, 'z', 0);
12198 qstatus = GetQueueStatus(qs_all_input);
12199 ok(qstatus == MAKELONG(QS_POSTMESSAGE, QS_POSTMESSAGE|QS_KEY), "wrong qstatus %08x\n", qstatus);
12200
12201 if (qstatus & (QS_KEY << 16))
12202 {
12204 ok(ret && msg.message == WM_KEYDOWN && msg.wParam == 'N',
12205 "got %d and %04x wParam %08lx instead of TRUE and WM_KEYDOWN wParam 'N'\n",
12206 ret, msg.message, msg.wParam);
12207 ok_sequence(WmKeyDownWasDownSkippedSeq, "WmKeyDownWasDownSkippedSeq", FALSE);
12208 qstatus = GetQueueStatus(qs_all_input);
12209 ok(qstatus == MAKELONG(0, QS_POSTMESSAGE), "wrong qstatus %08x\n", qstatus);
12210 }
12211
12212 if (qstatus)
12213 {
12214 ret = GetMessageA( &msg, 0, WM_CHAR, WM_CHAR );
12215 ok(ret && msg.message == WM_CHAR && msg.wParam == 'z',
12216 "got %d and %04x wParam %08lx instead of TRUE and WM_CHAR wParam 'z'\n",
12217 ret, msg.message, msg.wParam);
12218 qstatus = GetQueueStatus(qs_all_input);
12219 ok(qstatus == 0, "wrong qstatus %08x\n", qstatus);
12220 }
12221
12222 keybd_event('N', 0, KEYEVENTF_KEYUP, 0);
12223 qstatus = GetQueueStatus(qs_all_input);
12224 ok(qstatus == MAKELONG(QS_KEY, QS_KEY), "wrong qstatus %08x\n", qstatus);
12225
12226 PostMessageA(info.hwnd, WM_CHAR, 'z', 0);
12227 qstatus = GetQueueStatus(qs_all_input);
12228 ok(qstatus == MAKELONG(QS_POSTMESSAGE, QS_POSTMESSAGE|QS_KEY), "wrong qstatus %08x\n", qstatus);
12229
12230 trace("signalling to send message\n");
12231 SetEvent(info.hevent[EV_SENDMSG]);
12233 qstatus = GetQueueStatus(qs_all_input);
12235 "wrong qstatus %08x\n", qstatus);
12236
12237 if (qstatus & (QS_KEY << 16))
12238 {
12240 ok(ret && msg.message == WM_KEYUP && msg.wParam == 'N',
12241 "got %d and %04x wParam %08lx instead of TRUE and WM_KEYDOWN wParam 'N'\n",
12242 ret, msg.message, msg.wParam);
12243 ok_sequence(WmUserKeyUpSkippedSeq, "WmUserKeyUpSkippedSeq", FALSE);
12244 qstatus = GetQueueStatus(qs_all_input);
12245 ok(qstatus == MAKELONG(0, QS_POSTMESSAGE), "wrong qstatus %08x\n", qstatus);
12246 }
12247
12248 if (qstatus)
12249 {
12250 ret = GetMessageA( &msg, 0, WM_CHAR, WM_CHAR );
12251 ok(ret && msg.message == WM_CHAR && msg.wParam == 'z',
12252 "got %d and %04x wParam %08lx instead of TRUE and WM_CHAR wParam 'z'\n",
12253 ret, msg.message, msg.wParam);
12254 qstatus = GetQueueStatus(qs_all_input);
12255 ok(qstatus == 0, "wrong qstatus %08x\n", qstatus);
12256 }
12257
12259 ret = PeekMessageA(&msg, (HWND)-1, 0, 0, PM_NOREMOVE);
12260 ok(ret == TRUE, "wrong ret %d\n", ret);
12261 ok(msg.message == WM_USER, "wrong message %u\n", msg.message);
12262 ret = GetMessageA(&msg, (HWND)-1, 0, 0);
12263 ok(ret == TRUE, "wrong ret %d\n", ret);
12264 ok(msg.message == WM_USER, "wrong message %u\n", msg.message);
12265
12267 ret = PeekMessageA(&msg, (HWND)1, 0, 0, PM_NOREMOVE);
12268 ok(ret == TRUE, "wrong ret %d\n", ret);
12269 ok(msg.message == WM_USER, "wrong message %u\n", msg.message);
12270 ret = GetMessageA(&msg, (HWND)1, 0, 0);
12271 ok(ret == TRUE, "wrong ret %d\n", ret);
12272 ok(msg.message == WM_USER, "wrong message %u\n", msg.message);
12273
12275 ret = PeekMessageA(&msg, (HWND)0xffff, 0, 0, PM_NOREMOVE);
12276 ok(ret == TRUE, "wrong ret %d\n", ret);
12277 ok(msg.message == WM_USER, "wrong message %u\n", msg.message);
12278 ret = GetMessageA(&msg, (HWND)0xffff, 0, 0);
12279 ok(ret == TRUE, "wrong ret %d\n", ret);
12280 ok(msg.message == WM_USER, "wrong message %u\n", msg.message);
12281
12282done:
12283 trace("signalling to exit\n");
12284 SetEvent(info.hevent[EV_STOP]);
12285
12286 WaitForSingleObject(hthread, INFINITE);
12287
12288 CloseHandle(hthread);
12289 CloseHandle(info.hevent[0]);
12290 CloseHandle(info.hevent[1]);
12291 CloseHandle(info.hevent[2]);
12292
12293 DestroyWindow(info.hwnd);
12294}
12295
12296static void wait_move_event(HWND hwnd, int x, int y)
12297{
12298 MSG msg;
12299 DWORD time;
12300 BOOL ret;
12301
12302 time = GetTickCount();
12303 while (GetTickCount() - time < 200) {
12305 if (ret && msg.pt.x > x && msg.pt.y > y) break;
12307 else Sleep( GetTickCount() - time );
12308 }
12309}
12310
12311#define STEP 5
12312static void test_PeekMessage2(void)
12313{
12314 HWND hwnd;
12315 BOOL ret;
12316 MSG msg;
12317 UINT message;
12318 DWORD time1, time2, time3;
12319 int x1, y1, x2, y2, x3, y3;
12320 POINT pos;
12321
12322 time1 = time2 = time3 = 0;
12323 x1 = y1 = x2 = y2 = x3 = y3 = 0;
12324
12325 /* Initialise window and make sure it is ready for events */
12326 hwnd = CreateWindowA("TestWindowClass", "PeekMessage2", WS_OVERLAPPEDWINDOW,
12327 10, 10, 800, 800, NULL, NULL, NULL, NULL);
12328 assert(hwnd);
12329 trace("Window for test_PeekMessage2 %p\n", hwnd);
12332 SetFocus(hwnd);
12333 GetCursorPos(&pos);
12334 SetCursorPos(100, 100);
12336 flush_events();
12337
12338 /* Do initial mousemove, wait until we can see it
12339 and then do our test peek with PM_NOREMOVE. */
12341 wait_move_event(hwnd, 100-STEP, 100-STEP);
12342
12344 if (!ret)
12345 {
12346 skip( "queuing mouse events not supported\n" );
12347 goto done;
12348 }
12349 else
12350 {
12351 trace("1st move event: %04x %x %d %d\n", msg.message, msg.time, msg.pt.x, msg.pt.y);
12352 message = msg.message;
12353 time1 = msg.time;
12354 x1 = msg.pt.x;
12355 y1 = msg.pt.y;
12356 ok(message == WM_MOUSEMOVE, "message not WM_MOUSEMOVE, %04x instead\n", message);
12357 }
12358
12359 /* Allow time to advance a bit, and then simulate the user moving their
12360 * mouse around. After that we peek again with PM_NOREMOVE.
12361 * Although the previous mousemove message was never removed, the
12362 * mousemove we now peek should reflect the recent mouse movements
12363 * because the input queue will merge the move events. */
12364 Sleep(100);
12367
12369 ok(ret, "no message available\n");
12370 if (ret) {
12371 trace("2nd move event: %04x %x %d %d\n", msg.message, msg.time, msg.pt.x, msg.pt.y);
12372 message = msg.message;
12373 time2 = msg.time;
12374 x2 = msg.pt.x;
12375 y2 = msg.pt.y;
12376 ok(message == WM_MOUSEMOVE, "message not WM_MOUSEMOVE, %04x instead\n", message);
12377 ok(time2 > time1, "message time not advanced: %x %x\n", time1, time2);
12378 ok(x2 != x1 && y2 != y1, "coords not changed: (%d %d) (%d %d)\n", x1, y1, x2, y2);
12379 }
12380
12381 /* Have another go, to drive the point home */
12382 Sleep(100);
12385
12387 ok(ret, "no message available\n");
12388 if (ret) {
12389 trace("3rd move event: %04x %x %d %d\n", msg.message, msg.time, msg.pt.x, msg.pt.y);
12390 message = msg.message;
12391 time3 = msg.time;
12392 x3 = msg.pt.x;
12393 y3 = msg.pt.y;
12394 ok(message == WM_MOUSEMOVE, "message not WM_MOUSEMOVE, %04x instead\n", message);
12395 ok(time3 > time2, "message time not advanced: %x %x\n", time2, time3);
12396 ok(x3 != x2 && y3 != y2, "coords not changed: (%d %d) (%d %d)\n", x2, y2, x3, y3);
12397 }
12398
12399done:
12401 SetCursorPos(pos.x, pos.y);
12402 flush_events();
12403}
12404
12405static void test_PeekMessage3(void)
12406{
12407 HWND hwnd;
12408 BOOL ret;
12409 MSG msg;
12410
12411 hwnd = CreateWindowA("TestWindowClass", "PeekMessage3", WS_OVERLAPPEDWINDOW,
12412 10, 10, 800, 800, NULL, NULL, NULL, NULL);
12413 ok(hwnd != NULL, "expected hwnd != NULL\n");
12414 flush_events();
12415
12416 /* GetMessage() and PeekMessage(..., PM_REMOVE) should prefer messages which
12417 * were already seen. */
12418
12419 SetTimer(hwnd, 1, 0, NULL);
12420 while (!PeekMessageA(&msg, NULL, 0, 0, PM_NOREMOVE));
12421 ok(msg.message == WM_TIMER, "msg.message = %u instead of WM_TIMER\n", msg.message);
12422 PostMessageA(hwnd, WM_USER, 0, 0);
12423 ret = PeekMessageA(&msg, NULL, 0, 0, PM_NOREMOVE);
12424 ok(ret && msg.message == WM_TIMER, "msg.message = %u instead of WM_TIMER\n", msg.message);
12425 ret = GetMessageA(&msg, NULL, 0, 0);
12426 ok(ret && msg.message == WM_TIMER, "msg.message = %u instead of WM_TIMER\n", msg.message);
12427 ret = GetMessageA(&msg, NULL, 0, 0);
12428 ok(ret && msg.message == WM_USER, "msg.message = %u instead of WM_USER\n", msg.message);
12429 ret = PeekMessageA(&msg, NULL, 0, 0, 0);
12430 ok(!ret, "expected PeekMessage to return FALSE, got %u\n", ret);
12431
12432 SetTimer(hwnd, 1, 0, NULL);
12433 while (!PeekMessageA(&msg, NULL, 0, 0, PM_NOREMOVE));
12434 ok(msg.message == WM_TIMER, "msg.message = %u instead of WM_TIMER\n", msg.message);
12435 PostMessageA(hwnd, WM_USER, 0, 0);
12436 ret = PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE);
12437 ok(ret && msg.message == WM_TIMER, "msg.message = %u instead of WM_TIMER\n", msg.message);
12438 ret = PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE);
12439 ok(ret && msg.message == WM_USER, "msg.message = %u instead of WM_USER\n", msg.message);
12440 ret = PeekMessageA(&msg, NULL, 0, 0, 0);
12441 ok(!ret, "expected PeekMessage to return FALSE, got %u\n", ret);
12442
12443 /* It doesn't matter if a message range is specified or not. */
12444
12445 SetTimer(hwnd, 1, 0, NULL);
12447 ok(msg.message == WM_TIMER, "msg.message = %u instead of WM_TIMER\n", msg.message);
12448 PostMessageA(hwnd, WM_USER, 0, 0);
12449 ret = GetMessageA(&msg, NULL, 0, 0);
12450 ok(ret && msg.message == WM_TIMER, "msg.message = %u instead of WM_TIMER\n", msg.message);
12451 ret = GetMessageA(&msg, NULL, 0, 0);
12452 ok(ret && msg.message == WM_USER, "msg.message = %u instead of WM_USER\n", msg.message);
12453 ret = PeekMessageA(&msg, NULL, 0, 0, 0);
12454 ok(!ret, "expected PeekMessage to return FALSE, got %u\n", ret);
12455
12456 /* But not if the post messages were added before the PeekMessage() call. */
12457
12458 PostMessageA(hwnd, WM_USER, 0, 0);
12459 SetTimer(hwnd, 1, 0, NULL);
12461 ok(msg.message == WM_TIMER, "msg.message = %u instead of WM_TIMER\n", msg.message);
12462 ret = GetMessageA(&msg, NULL, 0, 0);
12463 ok(ret && msg.message == WM_USER, "msg.message = %u instead of WM_USER\n", msg.message);
12464 ret = GetMessageA(&msg, NULL, 0, 0);
12465 ok(ret && msg.message == WM_TIMER, "msg.message = %u instead of WM_TIMER\n", msg.message);
12466 ret = PeekMessageA(&msg, NULL, 0, 0, 0);
12467 ok(!ret, "expected PeekMessage to return FALSE, got %u\n", ret);
12468
12469 /* More complicated test with multiple messages. */
12470
12471 PostMessageA(hwnd, WM_USER, 0, 0);
12472 SetTimer(hwnd, 1, 0, NULL);
12474 ok(msg.message == WM_TIMER, "msg.message = %u instead of WM_TIMER\n", msg.message);
12475 PostMessageA(hwnd, WM_USER + 1, 0, 0);
12476 ret = GetMessageA(&msg, NULL, 0, 0);
12477 ok(ret && msg.message == WM_USER, "msg.message = %u instead of WM_USER\n", msg.message);
12478 ret = GetMessageA(&msg, NULL, 0, 0);
12479 ok(ret && msg.message == WM_TIMER, "msg.message = %u instead of WM_TIMER\n", msg.message);
12480 ret = GetMessageA(&msg, NULL, 0, 0);
12481 ok(ret && msg.message == WM_USER + 1, "msg.message = %u instead of WM_USER + 1\n", msg.message);
12482 ret = PeekMessageA(&msg, NULL, 0, 0, 0);
12483 ok(!ret, "expected PeekMessage to return FALSE, got %u\n", ret);
12484
12485 /* Newer messages are still returned when specifying a message range. */
12486
12487 SetTimer(hwnd, 1, 0, NULL);
12489 ok(msg.message == WM_TIMER, "msg.message = %u instead of WM_TIMER\n", msg.message);
12490 PostMessageA(hwnd, WM_USER + 1, 0, 0);
12491 PostMessageA(hwnd, WM_USER, 0, 0);
12493 ok(ret && msg.message == WM_USER, "msg.message = %u instead of WM_USER\n", msg.message);
12495 ok(ret && msg.message == WM_USER + 1, "msg.message = %u instead of WM_USER + 1\n", msg.message);
12496 ret = PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE);
12497 ok(ret && msg.message == WM_TIMER, "msg.message = %u instead of WM_TIMER\n", msg.message);
12498 ret = PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE);
12499 ok(ret && msg.message == WM_USER + 1, "msg.message = %u instead of WM_USER + 1\n", msg.message);
12500 ret = PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE);
12501 ok(ret && msg.message == WM_USER, "msg.message = %u instead of WM_USER\n", msg.message);
12502 ret = PeekMessageA(&msg, NULL, 0, 0, 0);
12503 ok(!ret, "expected PeekMessage to return FALSE, got %u\n", ret);
12504
12505 /* Also works for posted messages, but the situation is a bit different,
12506 * because both messages are in the same queue. */
12507
12508 PostMessageA(hwnd, WM_TIMER, 0, 0);
12510 ok(msg.message == WM_TIMER, "msg.message = %u instead of WM_TIMER\n", msg.message);
12511 PostMessageA(hwnd, WM_USER, 0, 0);
12512 ret = GetMessageA(&msg, NULL, 0, 0);
12513 ok(ret && msg.message == WM_TIMER, "msg.message = %u instead of WM_TIMER\n", msg.message);
12514 ret = GetMessageA(&msg, NULL, 0, 0);
12515 ok(ret && msg.message == WM_USER, "msg.message = %u instead of WM_USER\n", msg.message);
12516 ret = PeekMessageA(&msg, NULL, 0, 0, 0);
12517 ok(!ret, "expected PeekMessage to return FALSE, got %u\n", ret);
12518
12519 PostMessageA(hwnd, WM_USER, 0, 0);
12520 PostMessageA(hwnd, WM_TIMER, 0, 0);
12522 ok(msg.message == WM_TIMER, "msg.message = %u instead of WM_TIMER\n", msg.message);
12523 ret = GetMessageA(&msg, NULL, 0, 0);
12524 ok(ret && msg.message == WM_USER, "msg.message = %u instead of WM_USER\n", msg.message);
12525 ret = GetMessageA(&msg, NULL, 0, 0);
12526 ok(ret && msg.message == WM_TIMER, "msg.message = %u instead of WM_TIMER\n", msg.message);
12527 ret = PeekMessageA(&msg, NULL, 0, 0, 0);
12528 ok(!ret, "expected PeekMessage to return FALSE, got %u\n", ret);
12529
12531 flush_events();
12532}
12533
12535{
12536 struct recvd_message msg;
12537
12538 if (ignore_message( message )) return 0;
12539
12540 msg.hwnd = hwnd;
12541 msg.message = message;
12542 msg.flags = sent|wparam|lparam;
12543 msg.wParam = wp;
12544 msg.lParam = lp;
12545 msg.descr = "dialog";
12546 add_message(&msg);
12547
12548 switch (message)
12549 {
12550 case WM_INITDIALOG:
12551 PostMessageA(hwnd, WM_QUIT, 0x1234, 0x5678);
12552 PostMessageA(hwnd, WM_USER, 0xdead, 0xbeef);
12553 return 0;
12554
12555 case WM_GETDLGCODE:
12556 return 0;
12557
12558 case WM_USER:
12559 EndDialog(hwnd, 0);
12560 break;
12561 }
12562
12563 return 1;
12564}
12565
12566static const struct message WmQuitDialogSeq[] = {
12567 { HCBT_CREATEWND, hook },
12568 { WM_SETFONT, sent },
12569 { WM_INITDIALOG, sent },
12570 { WM_CHANGEUISTATE, sent|optional },
12571 { HCBT_DESTROYWND, hook },
12572 { 0x0090, sent|optional }, /* Vista */
12573 { WM_DESTROY, sent },
12574 { WM_NCDESTROY, sent },
12575 { 0 }
12576};
12577
12578static const struct message WmStopQuitSeq[] = {
12580 { WM_CLOSE, posted },
12581 { WM_QUIT, posted|wparam|lparam, 0x1234, 0 },
12582 { 0 }
12583};
12584
12585static void test_quit_message(void)
12586{
12587 MSG msg;
12588 BOOL ret;
12589
12590 /* test using PostQuitMessage */
12591 flush_events();
12592 PostQuitMessage(0xbeef);
12593
12594 msg.message = 0;
12595 ret = PeekMessageA(&msg, 0, 0, 0, PM_QS_SENDMESSAGE);
12596 ok(!ret, "got %x message\n", msg.message);
12597
12598 ret = PeekMessageA(&msg, NULL, 0, 0, PM_NOREMOVE);
12599 ok(ret, "PeekMessage failed with error %d\n", GetLastError());
12600 ok(msg.message == WM_QUIT, "Received message 0x%04x instead of WM_QUIT\n", msg.message);
12601 ok(msg.wParam == 0xbeef, "wParam was 0x%lx instead of 0xbeef\n", msg.wParam);
12602
12604 ok(ret, "PostMessage failed with error %d\n", GetLastError());
12605
12606 ret = GetMessageA(&msg, NULL, 0, 0);
12607 ok(ret > 0, "GetMessage failed with error %d\n", GetLastError());
12608 ok(msg.message == WM_USER, "Received message 0x%04x instead of WM_USER\n", msg.message);
12609
12610 /* note: WM_QUIT message received after WM_USER message */
12611 ret = GetMessageA(&msg, NULL, 0, 0);
12612 ok(!ret, "GetMessage return %d with error %d instead of FALSE\n", ret, GetLastError());
12613 ok(msg.message == WM_QUIT, "Received message 0x%04x instead of WM_QUIT\n", msg.message);
12614 ok(msg.wParam == 0xbeef, "wParam was 0x%lx instead of 0xbeef\n", msg.wParam);
12615
12616 ret = PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE);
12617 ok( !ret || msg.message != WM_QUIT, "Received WM_QUIT again\n" );
12618
12619 /* now test with PostThreadMessage - different behaviour! */
12621
12622 ret = PeekMessageA(&msg, NULL, 0, 0, PM_NOREMOVE);
12623 ok(ret, "PeekMessage failed with error %d\n", GetLastError());
12624 ok(msg.message == WM_QUIT, "Received message 0x%04x instead of WM_QUIT\n", msg.message);
12625 ok(msg.wParam == 0xdead, "wParam was 0x%lx instead of 0xdead\n", msg.wParam);
12626
12628 ok(ret, "PostMessage failed with error %d\n", GetLastError());
12629
12630 /* note: we receive the WM_QUIT message first this time */
12631 ret = GetMessageA(&msg, NULL, 0, 0);
12632 ok(!ret, "GetMessage return %d with error %d instead of FALSE\n", ret, GetLastError());
12633 ok(msg.message == WM_QUIT, "Received message 0x%04x instead of WM_QUIT\n", msg.message);
12634 ok(msg.wParam == 0xdead, "wParam was 0x%lx instead of 0xdead\n", msg.wParam);
12635
12636 ret = GetMessageA(&msg, NULL, 0, 0);
12637 ok(ret > 0, "GetMessage failed with error %d\n", GetLastError());
12638 ok(msg.message == WM_USER, "Received message 0x%04x instead of WM_USER\n", msg.message);
12639
12640 flush_events();
12642 ret = DialogBoxParamA(GetModuleHandleA(NULL), "TEST_EMPTY_DIALOG", 0, wm_quit_dlg_proc, 0);
12643 ok(ret == 1, "expected 1, got %d\n", ret);
12644 ok_sequence(WmQuitDialogSeq, "WmQuitDialogSeq", FALSE);
12645 memset(&msg, 0xab, sizeof(msg));
12646 ret = PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE);
12647 ok(ret, "PeekMessage failed\n");
12648 ok(msg.message == WM_QUIT, "Received message 0x%04x instead of WM_QUIT\n", msg.message);
12649 ok(msg.wParam == 0x1234, "wParam was 0x%lx instead of 0x1234\n", msg.wParam);
12650 ok(msg.lParam == 0, "lParam was 0x%lx instead of 0\n", msg.lParam);
12651
12652 /* Check what happens to a WM_QUIT message posted to a window that gets
12653 * destroyed.
12654 */
12655 CreateWindowExA(0, "StopQuitClass", "Stop Quit Test", WS_OVERLAPPEDWINDOW,
12656 0, 0, 100, 100, NULL, NULL, NULL, NULL);
12658 while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE))
12659 {
12660 struct recvd_message rmsg;
12661 rmsg.hwnd = msg.hwnd;
12662 rmsg.message = msg.message;
12663 rmsg.flags = posted|wparam|lparam;
12664 rmsg.wParam = msg.wParam;
12665 rmsg.lParam = msg.lParam;
12666 rmsg.descr = "stop/quit";
12667 if (msg.message == WM_QUIT)
12668 /* The hwnd can only be checked here */
12669 ok(!msg.hwnd, "The WM_QUIT hwnd was %p instead of NULL\n", msg.hwnd);
12670 add_message(&rmsg);
12672 }
12673 ok_sequence(WmStopQuitSeq, "WmStopQuitSeq", FALSE);
12674}
12675
12676static const struct message WmNotifySeq[] = {
12677 { WM_NOTIFY, sent|wparam|lparam, 0x1234, 0xdeadbeef },
12678 { 0 }
12679};
12680
12681static void test_notify_message(void)
12682{
12683 HWND hwnd;
12684 BOOL ret;
12685 MSG msg;
12686
12687 hwnd = CreateWindowExA(0, "TestWindowClass", NULL, WS_OVERLAPPEDWINDOW,
12688 CW_USEDEFAULT, CW_USEDEFAULT, 300, 300, 0, NULL, NULL, 0);
12689 ok(hwnd != 0, "Failed to create window\n");
12690 flush_events();
12692
12693 ret = SendNotifyMessageA(hwnd, WM_NOTIFY, 0x1234, 0xdeadbeef);
12694 ok(ret == TRUE, "SendNotifyMessageA failed with error %u\n", GetLastError());
12695 ok_sequence(WmNotifySeq, "WmNotifySeq", FALSE);
12696
12697 ret = SendNotifyMessageW(hwnd, WM_NOTIFY, 0x1234, 0xdeadbeef);
12698 ok(ret == TRUE, "SendNotifyMessageW failed with error %u\n", GetLastError());
12699 ok_sequence(WmNotifySeq, "WmNotifySeq", FALSE);
12700
12701 ret = SendMessageCallbackA(hwnd, WM_NOTIFY, 0x1234, 0xdeadbeef, NULL, 0);
12702 ok(ret == TRUE, "SendMessageCallbackA failed with error %u\n", GetLastError());
12703 ok_sequence(WmNotifySeq, "WmNotifySeq", FALSE);
12704
12705 ret = SendMessageCallbackW(hwnd, WM_NOTIFY, 0x1234, 0xdeadbeef, NULL, 0);
12706 ok(ret == TRUE, "SendMessageCallbackW failed with error %u\n", GetLastError());
12707 ok_sequence(WmNotifySeq, "WmNotifySeq", FALSE);
12708
12709 ret = PostMessageA(hwnd, WM_NOTIFY, 0x1234, 0xdeadbeef);
12710 ok(ret == TRUE, "PostMessageA failed with error %u\n", GetLastError());
12711 flush_events();
12712 ok_sequence(WmNotifySeq, "WmNotifySeq", FALSE);
12713
12714 ret = PostMessageW(hwnd, WM_NOTIFY, 0x1234, 0xdeadbeef);
12715 ok(ret == TRUE, "PostMessageW failed with error %u\n", GetLastError());
12716 flush_events();
12717 ok_sequence(WmNotifySeq, "WmNotifySeq", FALSE);
12718
12719 ret = PostThreadMessageA(GetCurrentThreadId(), WM_NOTIFY, 0x1234, 0xdeadbeef);
12720 ok(ret == TRUE, "PostThreadMessageA failed with error %u\n", GetLastError());
12721 while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE))
12722 {
12723 msg.hwnd = hwnd;
12725 }
12726 ok_sequence(WmNotifySeq, "WmNotifySeq", FALSE);
12727
12728 ret = PostThreadMessageW(GetCurrentThreadId(), WM_NOTIFY, 0x1234, 0xdeadbeef);
12729 ok(ret == TRUE, "PostThreadMessageW failed with error %u\n", GetLastError());
12730 while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE))
12731 {
12732 msg.hwnd = hwnd;
12734 }
12735 ok_sequence(WmNotifySeq, "WmNotifySeq", FALSE);
12736
12738}
12739
12740static const struct message WmMouseHoverSeq[] = {
12741 { WM_MOUSEACTIVATE, sent|optional }, /* we can get those when moving the mouse in focus-follow-mouse mode under X11 */
12743 { WM_TIMER, sent|optional }, /* XP sends it */
12744 { WM_SYSTIMER, sent },
12745 { WM_MOUSEHOVER, sent|wparam, 0 },
12746 { 0 }
12747};
12748
12749static void pump_msg_loop_timeout(DWORD timeout, BOOL inject_mouse_move)
12750{
12751 MSG msg;
12752 DWORD start_ticks, end_ticks;
12753
12754 start_ticks = GetTickCount();
12755 /* add some deviation (50%) to cover not expected delays */
12756 start_ticks += timeout / 2;
12757
12758 do
12759 {
12760 while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE))
12761 {
12762 /* Timer proc messages are not dispatched to the window proc,
12763 * and therefore not logged.
12764 */
12765 if ((msg.message == WM_TIMER || msg.message == WM_SYSTIMER) && msg.hwnd)
12766 {
12767 struct recvd_message s_msg;
12768
12769 s_msg.hwnd = msg.hwnd;
12770 s_msg.message = msg.message;
12771 s_msg.flags = sent|wparam|lparam;
12772 s_msg.wParam = msg.wParam;
12773 s_msg.lParam = msg.lParam;
12774 s_msg.descr = "msg_loop";
12775 add_message(&s_msg);
12776 }
12778 }
12779
12780 end_ticks = GetTickCount();
12781
12782 /* inject WM_MOUSEMOVE to see how it changes tracking */
12783 if (inject_mouse_move && start_ticks + timeout / 2 >= end_ticks)
12784 {
12785 mouse_event(MOUSEEVENTF_MOVE, -1, 0, 0, 0);
12786 mouse_event(MOUSEEVENTF_MOVE, 1, 0, 0, 0);
12787
12788 inject_mouse_move = FALSE;
12789 }
12790 } while (start_ticks + timeout >= end_ticks);
12791}
12792
12793static void test_TrackMouseEvent(void)
12794{
12795 TRACKMOUSEEVENT tme;
12796 BOOL ret;
12797 HWND hwnd, hchild;
12798 RECT rc_parent, rc_child;
12799 UINT default_hover_time, hover_width = 0, hover_height = 0;
12800
12801#define track_hover(track_hwnd, track_hover_time) \
12802 tme.cbSize = sizeof(tme); \
12803 tme.dwFlags = TME_HOVER; \
12804 tme.hwndTrack = track_hwnd; \
12805 tme.dwHoverTime = track_hover_time; \
12806 SetLastError(0xdeadbeef); \
12807 ret = pTrackMouseEvent(&tme); \
12808 ok(ret, "TrackMouseEvent(TME_HOVER) error %d\n", GetLastError())
12809
12810#define track_query(expected_track_flags, expected_track_hwnd, expected_hover_time) \
12811 tme.cbSize = sizeof(tme); \
12812 tme.dwFlags = TME_QUERY; \
12813 tme.hwndTrack = (HWND)0xdeadbeef; \
12814 tme.dwHoverTime = 0xdeadbeef; \
12815 SetLastError(0xdeadbeef); \
12816 ret = pTrackMouseEvent(&tme); \
12817 ok(ret, "TrackMouseEvent(TME_QUERY) error %d\n", GetLastError());\
12818 ok(tme.cbSize == sizeof(tme), "wrong tme.cbSize %u\n", tme.cbSize); \
12819 ok(tme.dwFlags == (expected_track_flags), \
12820 "wrong tme.dwFlags %08x, expected %08x\n", tme.dwFlags, (expected_track_flags)); \
12821 ok(tme.hwndTrack == (expected_track_hwnd), \
12822 "wrong tme.hwndTrack %p, expected %p\n", tme.hwndTrack, (expected_track_hwnd)); \
12823 ok(tme.dwHoverTime == (expected_hover_time), \
12824 "wrong tme.dwHoverTime %u, expected %u\n", tme.dwHoverTime, (expected_hover_time))
12825
12826#define track_hover_cancel(track_hwnd) \
12827 tme.cbSize = sizeof(tme); \
12828 tme.dwFlags = TME_HOVER | TME_CANCEL; \
12829 tme.hwndTrack = track_hwnd; \
12830 tme.dwHoverTime = 0xdeadbeef; \
12831 SetLastError(0xdeadbeef); \
12832 ret = pTrackMouseEvent(&tme); \
12833 ok(ret, "TrackMouseEvent(TME_HOVER | TME_CANCEL) error %d\n", GetLastError())
12834
12835 default_hover_time = 0xdeadbeef;
12836 SetLastError(0xdeadbeef);
12837 ret = SystemParametersInfoA(SPI_GETMOUSEHOVERTIME, 0, &default_hover_time, 0);
12838 ok(ret || broken(GetLastError() == 0xdeadbeef), /* win9x */
12839 "SystemParametersInfo(SPI_GETMOUSEHOVERTIME) error %u\n", GetLastError());
12840 if (!ret) default_hover_time = 400;
12841 trace("SPI_GETMOUSEHOVERTIME returned %u ms\n", default_hover_time);
12842
12843 SetLastError(0xdeadbeef);
12844 ret = SystemParametersInfoA(SPI_GETMOUSEHOVERWIDTH, 0, &hover_width, 0);
12845 ok(ret || broken(GetLastError() == 0xdeadbeef), /* win9x */
12846 "SystemParametersInfo(SPI_GETMOUSEHOVERWIDTH) error %u\n", GetLastError());
12847 if (!ret) hover_width = 4;
12848 SetLastError(0xdeadbeef);
12849 ret = SystemParametersInfoA(SPI_GETMOUSEHOVERHEIGHT, 0, &hover_height, 0);
12850 ok(ret || broken(GetLastError() == 0xdeadbeef), /* win9x */
12851 "SystemParametersInfo(SPI_GETMOUSEHOVERHEIGHT) error %u\n", GetLastError());
12852 if (!ret) hover_height = 4;
12853 trace("hover rect is %u x %d\n", hover_width, hover_height);
12854
12855 hwnd = CreateWindowExA(0, "TestWindowClass", NULL,
12857 CW_USEDEFAULT, CW_USEDEFAULT, 300, 300, 0,
12858 NULL, NULL, 0);
12859 assert(hwnd);
12860
12861 hchild = CreateWindowExA(0, "TestWindowClass", NULL,
12863 50, 50, 200, 200, hwnd,
12864 NULL, NULL, 0);
12865 assert(hchild);
12866
12868 flush_events();
12870
12871 tme.cbSize = 0;
12872 tme.dwFlags = TME_QUERY;
12873 tme.hwndTrack = (HWND)0xdeadbeef;
12874 tme.dwHoverTime = 0xdeadbeef;
12875 SetLastError(0xdeadbeef);
12876 ret = pTrackMouseEvent(&tme);
12877 ok(!ret, "TrackMouseEvent should fail\n");
12879 "not expected error %u\n", GetLastError());
12880
12881 tme.cbSize = sizeof(tme);
12882 tme.dwFlags = TME_HOVER;
12883 tme.hwndTrack = (HWND)0xdeadbeef;
12884 tme.dwHoverTime = 0xdeadbeef;
12885 SetLastError(0xdeadbeef);
12886 ret = pTrackMouseEvent(&tme);
12887 ok(!ret, "TrackMouseEvent should fail\n");
12889 "not expected error %u\n", GetLastError());
12890
12891 tme.cbSize = sizeof(tme);
12893 tme.hwndTrack = (HWND)0xdeadbeef;
12894 tme.dwHoverTime = 0xdeadbeef;
12895 SetLastError(0xdeadbeef);
12896 ret = pTrackMouseEvent(&tme);
12897 ok(!ret, "TrackMouseEvent should fail\n");
12899 "not expected error %u\n", GetLastError());
12900
12901 GetWindowRect(hwnd, &rc_parent);
12902 GetWindowRect(hchild, &rc_child);
12903 SetCursorPos(rc_child.left - 10, rc_child.top - 10);
12904
12905 /* Process messages so that the system updates its internal current
12906 * window and hittest, otherwise TrackMouseEvent calls don't have any
12907 * effect.
12908 */
12909 flush_events();
12911
12912 track_query(0, NULL, 0);
12913 track_hover(hchild, 0);
12914 track_query(0, NULL, 0);
12915
12916 flush_events();
12918
12919 track_hover(hwnd, 0);
12920 tme.cbSize = sizeof(tme);
12921 tme.dwFlags = TME_QUERY;
12922 tme.hwndTrack = (HWND)0xdeadbeef;
12923 tme.dwHoverTime = 0xdeadbeef;
12924 SetLastError(0xdeadbeef);
12925 ret = pTrackMouseEvent(&tme);
12926 ok(ret, "TrackMouseEvent(TME_QUERY) error %d\n", GetLastError());
12927 ok(tme.cbSize == sizeof(tme), "wrong tme.cbSize %u\n", tme.cbSize);
12928 if (!tme.dwFlags)
12929 {
12930 skip( "Cursor not inside window, skipping TrackMouseEvent tests\n" );
12932 return;
12933 }
12934 ok(tme.dwFlags == TME_HOVER, "wrong tme.dwFlags %08x, expected TME_HOVER\n", tme.dwFlags);
12935 ok(tme.hwndTrack == hwnd, "wrong tme.hwndTrack %p, expected %p\n", tme.hwndTrack, hwnd);
12936 ok(tme.dwHoverTime == default_hover_time, "wrong tme.dwHoverTime %u, expected %u\n",
12937 tme.dwHoverTime, default_hover_time);
12938
12939 pump_msg_loop_timeout(default_hover_time, FALSE);
12940 ok_sequence(WmMouseHoverSeq, "WmMouseHoverSeq", FALSE);
12941
12942 track_query(0, NULL, 0);
12943
12945 track_query(TME_HOVER, hwnd, default_hover_time);
12946
12947 Sleep(default_hover_time / 2);
12948 mouse_event(MOUSEEVENTF_MOVE, -1, 0, 0, 0);
12949 mouse_event(MOUSEEVENTF_MOVE, 1, 0, 0, 0);
12950
12951 track_query(TME_HOVER, hwnd, default_hover_time);
12952
12953 pump_msg_loop_timeout(default_hover_time, FALSE);
12954 ok_sequence(WmMouseHoverSeq, "WmMouseHoverSeq", FALSE);
12955
12956 track_query(0, NULL, 0);
12957
12959 track_query(TME_HOVER, hwnd, default_hover_time);
12960
12961 pump_msg_loop_timeout(default_hover_time, TRUE);
12962 ok_sequence(WmMouseHoverSeq, "WmMouseHoverSeq", FALSE);
12963
12964 track_query(0, NULL, 0);
12965
12967 track_query(TME_HOVER, hwnd, default_hover_time);
12969
12971
12972#undef track_hover
12973#undef track_query
12974#undef track_hover_cancel
12975}
12976
12977
12978static const struct message WmSetWindowRgn[] = {
12980 { WM_NCCALCSIZE, sent|wparam, 1 },
12981 { WM_NCPAINT, sent|optional }, /* wparam != 1 */
12985 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 },
12986 { 0 }
12987};
12988
12989static const struct message WmSetWindowRgn_no_redraw[] = {
12991 { WM_NCCALCSIZE, sent|wparam, 1 },
12993 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 },
12994 { 0 }
12995};
12996
12997static const struct message WmSetWindowRgn_clear[] = {
12998 { WM_WINDOWPOSCHANGING, sent/*|wparam*/, SWP_NOACTIVATE|SWP_FRAMECHANGED|SWP_NOSIZE|SWP_NOMOVE/*|SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE only on some Windows versions */ },
12999 { WM_NCCALCSIZE, sent|wparam, 1 },
13002 { WM_ERASEBKGND, sent|optional }, /* FIXME: remove optional once Wine is fixed */
13018 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 },
13019 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 },
13020 { 0 }
13021};
13022
13023static void test_SetWindowRgn(void)
13024{
13025 HRGN hrgn;
13026 HWND hwnd = CreateWindowExA(0, "TestWindowClass", "Test overlapped", WS_OVERLAPPEDWINDOW,
13027 100, 100, 200, 200, 0, 0, 0, NULL);
13028 ok( hwnd != 0, "Failed to create overlapped window\n" );
13029
13031 UpdateWindow( hwnd );
13032 flush_events();
13034
13035 trace("testing SetWindowRgn\n");
13036 hrgn = CreateRectRgn( 0, 0, 150, 150 );
13038 ok_sequence( WmSetWindowRgn, "WmSetWindowRgn", FALSE );
13039
13040 hrgn = CreateRectRgn( 30, 30, 160, 160 );
13042 ok_sequence( WmSetWindowRgn_no_redraw, "WmSetWindowRgn_no_redraw", FALSE );
13043
13044 hrgn = CreateRectRgn( 0, 0, 180, 180 );
13046 ok_sequence( WmSetWindowRgn, "WmSetWindowRgn2", FALSE );
13047
13048 SetWindowRgn( hwnd, 0, TRUE );
13049 ok_sequence( WmSetWindowRgn_clear, "WmSetWindowRgn_clear", FALSE );
13050
13052}
13053
13054/*************************** ShowWindow() test ******************************/
13055static const struct message WmShowNormal[] = {
13056 { WM_SHOWWINDOW, sent|wparam, 1 },
13058 { HCBT_ACTIVATE, hook },
13059 { WM_WINDOWPOSCHANGING, sent|wparam|optional, SWP_NOSIZE|SWP_NOMOVE }, /* win2003 doesn't send it */
13060 { HCBT_SETFOCUS, hook },
13062 { 0 }
13063};
13064static const struct message WmShow[] = {
13065 { WM_SHOWWINDOW, sent|wparam, 1 },
13067 { HCBT_ACTIVATE, hook|optional }, /* win2000 doesn't send it */
13068 { WM_WINDOWPOSCHANGING, sent|wparam|optional, SWP_NOSIZE|SWP_NOMOVE }, /* win2000 doesn't send it */
13069 { HCBT_SETFOCUS, hook|optional }, /* win2000 doesn't send it */
13071 { 0 }
13072};
13073static const struct message WmShowNoActivate_1[] = {
13079 { 0 }
13080};
13081static const struct message WmShowNoActivate_2[] = {
13088 { WM_MOVE, sent|defwinproc },
13091 { HCBT_ACTIVATE, hook|optional }, /* win2003 doesn't send it */
13092 { WM_WINDOWPOSCHANGING, sent|wparam|optional, SWP_NOSIZE|SWP_NOMOVE }, /* win2003 doesn't send it */
13094 { HCBT_SETFOCUS, hook|optional }, /* win2003 doesn't send it */
13095 { 0 }
13096};
13097static const struct message WmShowNA_1[] = {
13098 { WM_SHOWWINDOW, sent|wparam, 1 },
13101 { 0 }
13102};
13103static const struct message WmShowNA_2[] = {
13104 { WM_SHOWWINDOW, sent|wparam, 1 },
13107 { 0 }
13108};
13109static const struct message WmRestore_1[] = {
13112 { HCBT_ACTIVATE, hook|optional }, /* win2000 doesn't send it */
13113 { WM_WINDOWPOSCHANGING, sent|wparam|optional, SWP_NOSIZE|SWP_NOMOVE }, /* win2000 doesn't send it */
13114 { HCBT_SETFOCUS, hook|optional }, /* win2000 doesn't send it */
13116 { WM_MOVE, sent|defwinproc },
13118 { HCBT_SETFOCUS, hook|optional }, /* win2000 sends it */
13119 { 0 }
13120};
13121static const struct message WmRestore_2[] = {
13122 { WM_SHOWWINDOW, sent|wparam, 1 },
13124 { HCBT_ACTIVATE, hook|optional }, /* win2000 doesn't send it */
13125 { WM_WINDOWPOSCHANGING, sent|wparam|optional, SWP_NOSIZE|SWP_NOMOVE }, /* win2000 doesn't send it */
13126 { HCBT_SETFOCUS, hook|optional }, /* win2000 doesn't send it */
13128 { 0 }
13129};
13130static const struct message WmRestore_3[] = {
13134 { HCBT_ACTIVATE, hook|optional }, /* win2003 doesn't send it */
13135 { WM_WINDOWPOSCHANGING, sent|wparam|optional, SWP_NOSIZE|SWP_NOMOVE }, /* win2003 doesn't send it */
13136 { HCBT_SETFOCUS, hook|optional }, /* win2003 doesn't send it */
13138 { WM_MOVE, sent|defwinproc },
13140 { HCBT_SETFOCUS, hook|optional }, /* win2003 sends it */
13141 { 0 }
13142};
13143static const struct message WmRestore_4[] = {
13149 { 0 }
13150};
13151static const struct message WmRestore_5[] = {
13159 { 0 }
13160};
13161static const struct message WmHide_1[] = {
13162 { WM_SHOWWINDOW, sent|wparam, 0 },
13166 { HCBT_SETFOCUS, hook|optional }, /* win2000 sends it */
13167 { 0 }
13168};
13169static const struct message WmHide_2[] = {
13170 { WM_SHOWWINDOW, sent|wparam, 0 },
13171 { WM_WINDOWPOSCHANGING, sent /*|wparam, SWP_HIDEWINDOW|SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOMOVE*/ }, /* win2000 doesn't add SWP_NOACTIVATE */
13172 { WM_WINDOWPOSCHANGED, sent /*|wparam, SWP_HIDEWINDOW|SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOMOVE|SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE*/ }, /* win2000 doesn't add SWP_NOACTIVATE */
13174 { 0 }
13175};
13176static const struct message WmHide_3[] = {
13177 { WM_SHOWWINDOW, sent|wparam, 0 },
13181 { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
13182 { 0 }
13183};
13184static const struct message WmShowMinimized_1[] = {
13187 { HCBT_ACTIVATE, hook|optional }, /* win2000 doesn't send it */
13188 { WM_WINDOWPOSCHANGING, sent|wparam|optional, SWP_NOSIZE|SWP_NOMOVE }, /* win2000 doesn't send it */
13190 { WM_MOVE, sent|defwinproc },
13192 { 0 }
13193};
13194static const struct message WmMinimize_1[] = {
13196 { HCBT_SETFOCUS, hook|optional }, /* win2000 doesn't send it */
13197 { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
13200 { WM_MOVE, sent|defwinproc },
13202 { 0 }
13203};
13204static const struct message WmMinimize_2[] = {
13209 { WM_MOVE, sent|defwinproc },
13211 { 0 }
13212};
13213static const struct message WmMinimize_3[] = {
13219 { WM_MOVE, sent|defwinproc },
13221 { 0 }
13222};
13223static const struct message WmShowMinNoActivate[] = {
13229 { 0 }
13230};
13231static const struct message WmMinMax_1[] = {
13233 { 0 }
13234};
13235static const struct message WmMinMax_2[] = {
13246 { 0 }
13247};
13248static const struct message WmMinMax_3[] = {
13255 { 0 }
13256};
13257static const struct message WmMinMax_4[] = {
13259 { 0 }
13260};
13261static const struct message WmShowMaximized_1[] = {
13265 { HCBT_ACTIVATE, hook|optional }, /* win2000 doesn't send it */
13266 { WM_WINDOWPOSCHANGING, sent|wparam|optional, SWP_NOSIZE|SWP_NOMOVE }, /* win2000 doesn't send it */
13267 { HCBT_SETFOCUS, hook|optional }, /* win2000 doesn't send it */
13269 { WM_MOVE, sent|defwinproc },
13271 { HCBT_SETFOCUS, hook|optional }, /* win2003 sends it */
13272 { 0 }
13273};
13274static const struct message WmShowMaximized_2[] = {
13280 { WM_MOVE, sent|optional }, /* Win9x doesn't send it */
13281 { WM_SIZE, sent|wparam|optional, SIZE_MAXIMIZED }, /* Win9x doesn't send it */
13285 { WM_MOVE, sent|defwinproc },
13288 { 0 }
13289};
13290static const struct message WmShowMaximized_3[] = {
13294 { HCBT_ACTIVATE, hook|optional }, /* win2000 doesn't send it */
13295 { WM_WINDOWPOSCHANGING, sent|wparam|optional, SWP_NOSIZE|SWP_NOMOVE }, /* win2000 doesn't send it */
13296 { HCBT_SETFOCUS, hook|optional }, /* win2000 doesn't send it */
13300 { 0 }
13301};
13302
13303static void test_ShowWindow(void)
13304{
13305 /* ShowWindow commands in random order */
13306 static const struct
13307 {
13308 INT cmd; /* ShowWindow command */
13309 LPARAM ret; /* ShowWindow return value */
13310 DWORD style; /* window style after the command */
13311 const struct message *msg; /* message sequence the command produces */
13312 INT wp_cmd, wp_flags; /* window placement after the command */
13313 POINT wp_min, wp_max; /* window placement after the command */
13314 BOOL todo_msg; /* message sequence doesn't match what Wine does */
13315 } sw[] =
13316 {
13318 SW_SHOWNORMAL, 0, {-1,-1}, {-1,-1}, FALSE },
13320 SW_SHOWNORMAL, 0, {-1,-1}, {-1,-1}, FALSE },
13321/* 3 */ { SW_HIDE, TRUE, 0, WmHide_1,
13322 SW_SHOWNORMAL, 0, {-1,-1}, {-1,-1}, FALSE },
13323/* 4 */ { SW_HIDE, FALSE, 0, WmEmptySeq,
13324 SW_SHOWNORMAL, 0, {-1,-1}, {-1,-1}, FALSE },
13326 SW_SHOWMINIMIZED, 0, {-32000,-32000}, {-1,-1}, FALSE },
13328 SW_SHOWMINIMIZED, 0, {-32000,-32000}, {-1,-1}, FALSE },
13329/* 7 */ { SW_HIDE, TRUE, WS_MINIMIZE, WmHide_1,
13330 SW_SHOWMINIMIZED, 0, {-32000,-32000}, {-1,-1}, FALSE },
13331/* 8 */ { SW_HIDE, FALSE, WS_MINIMIZE, WmEmptySeq,
13332 SW_SHOWMINIMIZED, 0, {-32000,-32000}, {-1,-1}, FALSE },
13334 SW_SHOWMAXIMIZED, WPF_RESTORETOMAXIMIZED, {-32000,-32000}, {-1,-1}, FALSE },
13336 SW_SHOWMAXIMIZED, WPF_RESTORETOMAXIMIZED, {-32000,-32000}, {-1,-1}, FALSE },
13337/* 11 */ { SW_HIDE, TRUE, WS_MAXIMIZE, WmHide_1,
13338 SW_SHOWMAXIMIZED, WPF_RESTORETOMAXIMIZED, {-32000,-32000}, {-1,-1}, FALSE },
13339/* 12 */ { SW_HIDE, FALSE, WS_MAXIMIZE, WmEmptySeq,
13340 SW_SHOWMAXIMIZED, WPF_RESTORETOMAXIMIZED, {-32000,-32000}, {-1,-1}, FALSE },
13342 SW_SHOWNORMAL, 0, {-32000,-32000}, {-1,-1}, FALSE },
13344 SW_SHOWNORMAL, 0, {-32000,-32000}, {-1,-1}, FALSE },
13345/* 15 */ { SW_HIDE, TRUE, 0, WmHide_2,
13346 SW_SHOWNORMAL, 0, {-32000,-32000}, {-1,-1}, FALSE },
13347/* 16 */ { SW_HIDE, FALSE, 0, WmEmptySeq,
13348 SW_SHOWNORMAL, 0, {-32000,-32000}, {-1,-1}, FALSE },
13349/* 17 */ { SW_SHOW, FALSE, WS_VISIBLE, WmShow,
13350 SW_SHOWNORMAL, 0, {-32000,-32000}, {-1,-1}, FALSE },
13351/* 18 */ { SW_SHOW, TRUE, WS_VISIBLE, WmEmptySeq,
13352 SW_SHOWNORMAL, 0, {-32000,-32000}, {-1,-1}, FALSE },
13354 SW_SHOWMINIMIZED, 0, {-32000,-32000}, {-1,-1}, FALSE },
13356 SW_SHOWMINIMIZED, 0, {-32000,-32000}, {-1,-1}, FALSE },
13357/* 21 */ { SW_HIDE, TRUE, WS_MINIMIZE, WmHide_2,
13358 SW_SHOWMINIMIZED, 0, {-32000,-32000}, {-1,-1}, FALSE },
13360 SW_SHOWMINIMIZED, 0, {-32000,-32000}, {-1,-1}, TRUE },
13362 SW_SHOWMINIMIZED, 0, {-32000,-32000}, {-1,-1}, FALSE },
13363/* 24 */ { SW_HIDE, TRUE, WS_MINIMIZE, WmHide_2,
13364 SW_SHOWMINIMIZED, 0, {-32000,-32000}, {-1,-1}, FALSE },
13365/* 25 */ { SW_HIDE, FALSE, WS_MINIMIZE, WmEmptySeq,
13366 SW_SHOWMINIMIZED, 0, {-32000,-32000}, {-1,-1}, FALSE },
13368 SW_SHOWMINIMIZED, 0, {-32000,-32000}, {-1,-1}, FALSE },
13370 SW_SHOWMINIMIZED, 0, {-32000,-32000}, {-1,-1}, FALSE },
13371/* 28 */ { SW_HIDE, TRUE, WS_MINIMIZE, WmHide_2,
13372 SW_SHOWMINIMIZED, 0, {-32000,-32000}, {-1,-1}, FALSE },
13373/* 29 */ { SW_HIDE, FALSE, WS_MINIMIZE, WmEmptySeq,
13374 SW_SHOWMINIMIZED, 0, {-32000,-32000}, {-1,-1}, FALSE },
13376 SW_SHOWNORMAL, 0, {-32000,-32000}, {-1,-1}, FALSE },
13377/* 31 */ { SW_RESTORE, TRUE, WS_VISIBLE, WmEmptySeq,
13378 SW_SHOWNORMAL, 0, {-32000,-32000}, {-1,-1}, FALSE },
13379/* 32 */ { SW_HIDE, TRUE, 0, WmHide_3,
13380 SW_SHOWNORMAL, 0, {-32000,-32000}, {-1,-1}, FALSE },
13381/* 33 */ { SW_HIDE, FALSE, 0, WmEmptySeq,
13382 SW_SHOWNORMAL, 0, {-32000,-32000}, {-1,-1}, FALSE },
13383/* 34 */ { SW_NORMALNA, FALSE, 0, WmEmptySeq, /* what does this mean?! */
13384 SW_SHOWNORMAL, 0, {-32000,-32000}, {-1,-1}, FALSE },
13385/* 35 */ { SW_NORMALNA, FALSE, 0, WmEmptySeq,
13386 SW_SHOWNORMAL, 0, {-32000,-32000}, {-1,-1}, FALSE },
13387/* 36 */ { SW_HIDE, FALSE, 0, WmEmptySeq,
13388 SW_SHOWNORMAL, 0, {-32000,-32000}, {-1,-1}, FALSE },
13390 SW_SHOWNORMAL, 0, {-32000,-32000}, {-1,-1}, FALSE },
13391/* 38 */ { SW_RESTORE, TRUE, WS_VISIBLE, WmEmptySeq,
13392 SW_SHOWNORMAL, 0, {-32000,-32000}, {-1,-1}, FALSE },
13394 SW_SHOWNORMAL, 0, {-32000,-32000}, {-1,-1}, FALSE },
13396 SW_SHOWMINIMIZED, 0, {-32000,-32000}, {-1,-1}, FALSE },
13398 SW_SHOWMINIMIZED, 0, {-32000,-32000}, {-1,-1}, FALSE },
13400 SW_SHOWMAXIMIZED, WPF_RESTORETOMAXIMIZED, {-32000,-32000}, {-1,-1}, FALSE },
13402 SW_SHOWMAXIMIZED, WPF_RESTORETOMAXIMIZED, {-32000,-32000}, {-1,-1}, FALSE },
13404 SW_SHOWMINIMIZED, WPF_RESTORETOMAXIMIZED, {-32000,-32000}, {-1,-1}, FALSE },
13406 SW_SHOWMINIMIZED, WPF_RESTORETOMAXIMIZED, {-32000,-32000}, {-1,-1}, FALSE },
13408 SW_SHOWMAXIMIZED, WPF_RESTORETOMAXIMIZED, {-32000,-32000}, {-1,-1}, FALSE },
13410 SW_SHOWNORMAL, WPF_RESTORETOMAXIMIZED, {-32000,-32000}, {-1,-1}, FALSE },
13412 SW_SHOWMAXIMIZED, WPF_RESTORETOMAXIMIZED, {-32000,-32000}, {-1,-1}, FALSE },
13414 SW_SHOWMAXIMIZED, WPF_RESTORETOMAXIMIZED, {-32000,-32000}, {-1,-1}, FALSE },
13416 SW_SHOWNORMAL, WPF_RESTORETOMAXIMIZED, {-32000,-32000}, {-1,-1}, FALSE },
13418 SW_SHOWNORMAL, WPF_RESTORETOMAXIMIZED, {-32000,-32000}, {-1,-1}, FALSE },
13419/* 52 */ { SW_HIDE, TRUE, 0, WmHide_1,
13420 SW_SHOWNORMAL, WPF_RESTORETOMAXIMIZED, {-32000,-32000}, {-1,-1}, FALSE },
13421/* 53 */ { SW_HIDE, FALSE, 0, WmEmptySeq,
13422 SW_SHOWNORMAL, WPF_RESTORETOMAXIMIZED, {-32000,-32000}, {-1,-1}, FALSE },
13424 SW_SHOWMINIMIZED, 0, {-32000,-32000}, {-1,-1}, FALSE },
13425/* 55 */ { SW_HIDE, TRUE, WS_MINIMIZE, WmHide_2,
13426 SW_SHOWMINIMIZED, 0, {-32000,-32000}, {-1,-1}, FALSE },
13428 SW_SHOWNORMAL, 0, {-32000,-32000}, {-1,-1}, FALSE },
13429/* 57 */ { SW_SHOW, TRUE, WS_VISIBLE, WmEmptySeq,
13430 SW_SHOWNORMAL, 0, {-32000,-32000}, {-1,-1}, FALSE }
13431 };
13432 HWND hwnd;
13433 DWORD style;
13434 LPARAM ret;
13435 INT i;
13436 WINDOWPLACEMENT wp;
13437 RECT win_rc, work_rc = {0, 0, 0, 0};
13438
13439#define WS_BASE (WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX|WS_MAXIMIZEBOX|WS_POPUP|WS_CLIPSIBLINGS)
13440 hwnd = CreateWindowExA(0, "ShowWindowClass", NULL, WS_BASE,
13441 120, 120, 90, 90,
13442 0, 0, 0, NULL);
13443 assert(hwnd);
13444
13445 style = GetWindowLongA(hwnd, GWL_STYLE) & ~WS_BASE;
13446 ok(style == 0, "expected style 0, got %08x\n", style);
13447
13448 flush_events();
13450
13451 if (pGetMonitorInfoA && pMonitorFromPoint)
13452 {
13453 HMONITOR hmon;
13455 POINT pt = {0, 0};
13456
13457 SetLastError(0xdeadbeef);
13458 hmon = pMonitorFromPoint(pt, MONITOR_DEFAULTTOPRIMARY);
13459 ok(hmon != 0, "MonitorFromPoint error %u\n", GetLastError());
13460
13461 mi.cbSize = sizeof(mi);
13462 SetLastError(0xdeadbeef);
13463 ret = pGetMonitorInfoA(hmon, &mi);
13464 ok(ret, "GetMonitorInfo error %u\n", GetLastError());
13465 trace("monitor %s, work %s\n", wine_dbgstr_rect(&mi.rcMonitor),
13467 work_rc = mi.rcWork;
13468 }
13469
13470 GetWindowRect(hwnd, &win_rc);
13471 OffsetRect(&win_rc, -work_rc.left, -work_rc.top);
13472
13473 wp.length = sizeof(wp);
13474 SetLastError(0xdeadbeaf);
13475 ret = GetWindowPlacement(hwnd, &wp);
13476 ok(ret, "GetWindowPlacement error %u\n", GetLastError());
13477 ok(wp.flags == 0, "expected 0, got %#x\n", wp.flags);
13478 ok(wp.showCmd == SW_SHOWNORMAL, "expected SW_SHOWNORMAL, got %d\n", wp.showCmd);
13479 ok(wp.ptMinPosition.x == -1 && wp.ptMinPosition.y == -1,
13480 "expected -1,-1 got %d,%d\n", wp.ptMinPosition.x, wp.ptMinPosition.y);
13481 ok(wp.ptMaxPosition.x == -1 && wp.ptMaxPosition.y == -1,
13482 "expected -1,-1 got %d,%d\n", wp.ptMaxPosition.x, wp.ptMaxPosition.y);
13483 todo_wine_if (work_rc.left || work_rc.top) /* FIXME: remove once Wine is fixed */
13484 ok(EqualRect(&win_rc, &wp.rcNormalPosition), "expected %s got %s\n", wine_dbgstr_rect(&win_rc),
13486
13487 for (i = 0; i < ARRAY_SIZE(sw); i++)
13488 {
13489 static const char * const sw_cmd_name[13] =
13490 {
13491 "SW_HIDE", "SW_SHOWNORMAL", "SW_SHOWMINIMIZED", "SW_SHOWMAXIMIZED",
13492 "SW_SHOWNOACTIVATE", "SW_SHOW", "SW_MINIMIZE", "SW_SHOWMINNOACTIVE",
13493 "SW_SHOWNA", "SW_RESTORE", "SW_SHOWDEFAULT", "SW_FORCEMINIMIZE",
13494 "SW_NORMALNA" /* 0xCC */
13495 };
13496 char comment[64];
13497 INT idx; /* index into the above array of names */
13498
13499 idx = (sw[i].cmd == SW_NORMALNA) ? 12 : sw[i].cmd;
13500
13502 trace("%d: sending %s, current window style %08x\n", i+1, sw_cmd_name[idx], style);
13503 ret = ShowWindow(hwnd, sw[i].cmd);
13504 ok(!ret == !sw[i].ret, "%d: cmd %s: expected ret %lu, got %lu\n", i+1, sw_cmd_name[idx], sw[i].ret, ret);
13505 style = GetWindowLongA(hwnd, GWL_STYLE) & ~WS_BASE;
13506 ok(style == sw[i].style, "%d: expected style %08x, got %08x\n", i+1, sw[i].style, style);
13507
13508 sprintf(comment, "%d: ShowWindow(%s)", i+1, sw_cmd_name[idx]);
13509 ok_sequence(sw[i].msg, comment, sw[i].todo_msg);
13510
13511 wp.length = sizeof(wp);
13512 SetLastError(0xdeadbeaf);
13513 ret = GetWindowPlacement(hwnd, &wp);
13514 ok(ret, "GetWindowPlacement error %u\n", GetLastError());
13515 ok(wp.flags == sw[i].wp_flags, "expected %#x, got %#x\n", sw[i].wp_flags, wp.flags);
13516 ok(wp.showCmd == sw[i].wp_cmd, "expected %d, got %d\n", sw[i].wp_cmd, wp.showCmd);
13517
13518 /* NT moves the minimized window to -32000,-32000, win9x to 3000,3000 */
13519 if ((wp.ptMinPosition.x + work_rc.left == -32000 && wp.ptMinPosition.y + work_rc.top == -32000) ||
13520 (wp.ptMinPosition.x + work_rc.left == 3000 && wp.ptMinPosition.y + work_rc.top == 3000))
13521 {
13522 ok((wp.ptMinPosition.x + work_rc.left == sw[i].wp_min.x && wp.ptMinPosition.y + work_rc.top == sw[i].wp_min.y) ||
13523 (wp.ptMinPosition.x + work_rc.left == 3000 && wp.ptMinPosition.y + work_rc.top == 3000),
13524 "expected %d,%d got %d,%d\n", sw[i].wp_min.x, sw[i].wp_min.y, wp.ptMinPosition.x, wp.ptMinPosition.y);
13525 }
13526 else
13527 {
13528 ok(wp.ptMinPosition.x == sw[i].wp_min.x && wp.ptMinPosition.y == sw[i].wp_min.y,
13529 "expected %d,%d got %d,%d\n", sw[i].wp_min.x, sw[i].wp_min.y, wp.ptMinPosition.x, wp.ptMinPosition.y);
13530 }
13531
13532 todo_wine_if(wp.ptMaxPosition.x != sw[i].wp_max.x || wp.ptMaxPosition.y != sw[i].wp_max.y)
13533 ok(wp.ptMaxPosition.x == sw[i].wp_max.x && wp.ptMaxPosition.y == sw[i].wp_max.y,
13534 "expected %d,%d got %d,%d\n", sw[i].wp_max.x, sw[i].wp_max.y, wp.ptMaxPosition.x, wp.ptMaxPosition.y);
13535
13536if (0) /* FIXME: Wine behaves completely different here */
13537 ok(EqualRect(&win_rc, &wp.rcNormalPosition), "expected %s got %s\n",
13539 }
13541 flush_events();
13542}
13543
13545{
13546 struct recvd_message msg;
13547
13548 if (ignore_message( message )) return 0;
13549
13550 msg.hwnd = hwnd;
13551 msg.message = message;
13552 msg.flags = sent|wparam|lparam;
13553 msg.wParam = wParam;
13554 msg.lParam = lParam;
13555 msg.descr = "dialog";
13556 add_message(&msg);
13557
13558 /* calling DefDlgProc leads to a recursion under XP */
13559
13560 switch (message)
13561 {
13562 case WM_INITDIALOG:
13563 return lParam;
13564
13565 case WM_GETDLGCODE:
13566 return 0;
13567 }
13568 return 1;
13569}
13570
13573{
13574 struct recvd_message msg;
13575
13576 if (ignore_message( message )) return 0;
13577
13578 msg.hwnd = hwnd;
13579 msg.message = message;
13580 msg.flags = sent|wparam|lparam;
13581 msg.wParam = wp;
13582 msg.lParam = lp;
13583 msg.descr = "edit";
13584 add_message(&msg);
13585
13586 return CallWindowProcW(orig_edit_proc, hwnd, message, wp, lp);
13587}
13588
13590{
13591 struct recvd_message msg;
13592
13593 if (ignore_message( message )) return 0;
13594
13595 msg.hwnd = hwnd;
13596 msg.message = message;
13597 msg.flags = sent|wparam|lparam|parent;
13598 msg.wParam = wParam;
13599 msg.lParam = lParam;
13600 msg.descr = "dialog";
13601 add_message(&msg);
13602
13603 if (message == WM_INITDIALOG)
13604 {
13607 }
13608
13609 return 1;
13610}
13611
13613{
13614 ok( 0, "should not be called since DefDlgProc is not used\n" );
13615 return 0;
13616}
13617
13619{
13620 struct recvd_message msg;
13621
13622 if (!ignore_message( message ))
13623 {
13624 msg.hwnd = hwnd;
13625 msg.message = message;
13626 msg.flags = sent|wparam|lparam|parent;
13627 msg.wParam = wParam;
13628 msg.lParam = lParam;
13629 msg.descr = "dialog";
13630 add_message(&msg);
13631 }
13632 if (message == WM_INITDIALOG)
13633 {
13636 return 1;
13637 }
13639}
13640
13641static const struct message WmDefDlgSetFocus_1[] = {
13642 { WM_GETDLGCODE, sent|wparam|lparam, 0, 0 },
13643 { WM_GETTEXTLENGTH, sent|wparam|lparam|optional, 0, 0 }, /* XP */
13644 { WM_GETTEXT, sent|wparam|optional, 6 }, /* XP */
13645 { WM_GETTEXT, sent|wparam|optional, 12 }, /* XP */
13646 { EM_SETSEL, sent|wparam, 0 }, /* XP sets lparam to text length, Win9x to -2 */
13647 { HCBT_SETFOCUS, hook },
13650 { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
13651 { WM_SETFOCUS, sent|wparam, 0 },
13653 { WM_CTLCOLOREDIT, sent },
13655 { EVENT_OBJECT_CREATE, winevent_hook|wparam|lparam, OBJID_CARET, 0 },
13656 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, OBJID_CARET, 0 },
13657 { EVENT_OBJECT_SHOW, winevent_hook|wparam|lparam, OBJID_CARET, 0 },
13659 { 0 }
13660};
13661static const struct message WmDefDlgSetFocus_2[] = {
13662 { WM_GETDLGCODE, sent|wparam|lparam, 0, 0 },
13663 { WM_GETTEXTLENGTH, sent|wparam|lparam|optional, 0, 0 }, /* XP */
13664 { WM_GETTEXT, sent|wparam|optional, 6 }, /* XP */
13665 { WM_GETTEXT, sent|wparam|optional, 12 }, /* XP */
13666 { EM_SETSEL, sent|wparam, 0 }, /* XP sets lparam to text length, Win9x to -2 */
13667 { EVENT_OBJECT_HIDE, winevent_hook|wparam|lparam, OBJID_CARET, 0 },
13668 { WM_CTLCOLOREDIT, sent|optional }, /* XP */
13669 { EVENT_OBJECT_SHOW, winevent_hook|wparam|lparam, OBJID_CARET, 0 },
13670 { 0 }
13671};
13672/* Creation of a dialog */
13673static const struct message WmCreateDialogParamSeq_0[] = {
13674 { HCBT_CREATEWND, hook },
13675 { WM_NCCREATE, sent },
13676 { WM_NCCALCSIZE, sent|wparam, 0 },
13677 { WM_CREATE, sent },
13678 { EVENT_OBJECT_CREATE, winevent_hook|wparam|lparam, 0, 0 },
13680 { WM_MOVE, sent },
13681 { WM_SETFONT, sent },
13682 { WM_INITDIALOG, sent },
13683 { WM_CHANGEUISTATE, sent|optional },
13684 { 0 }
13685};
13686/* Creation of a dialog */
13687static const struct message WmCreateDialogParamSeq_1[] = {
13688 { HCBT_CREATEWND, hook },
13689 { WM_NCCREATE, sent },
13690 { WM_NCCALCSIZE, sent|wparam, 0 },
13691 { WM_CREATE, sent },
13692 { EVENT_OBJECT_CREATE, winevent_hook|wparam|lparam, 0, 0 },
13694 { WM_MOVE, sent },
13695 { WM_SETFONT, sent },
13696 { WM_INITDIALOG, sent },
13697 { WM_GETDLGCODE, sent|wparam|lparam|optional, 0, 0 }, /* FIXME: Wine doesn't send it */
13698 { HCBT_SETFOCUS, hook },
13699 { HCBT_ACTIVATE, hook },
13703 { WM_ACTIVATEAPP, sent|wparam, 1 },
13704 { WM_NCACTIVATE, sent },
13705 { WM_ACTIVATE, sent|wparam, 1 },
13706 { WM_SETFOCUS, sent },
13707 { WM_CHANGEUISTATE, sent|optional },
13708 { 0 }
13709};
13710/* Creation of a dialog */
13711static const struct message WmCreateDialogParamSeq_2[] = {
13712 { HCBT_CREATEWND, hook },
13713 { WM_NCCREATE, sent },
13714 { WM_NCCALCSIZE, sent|wparam, 0 },
13715 { WM_CREATE, sent },
13716 { EVENT_OBJECT_CREATE, winevent_hook|wparam|lparam, 0, 0 },
13718 { WM_MOVE, sent },
13719 { WM_CHANGEUISTATE, sent|optional },
13720 { 0 }
13721};
13722
13723static const struct message WmCreateDialogParamSeq_3[] = {
13724 { HCBT_CREATEWND, hook },
13725 { WM_SETFONT, sent|parent },
13727 { WM_GETDLGCODE, sent|wparam|lparam, 0, 0 },
13732 { HCBT_ACTIVATE, hook },
13733 { WM_QUERYNEWPALETTE, sent|parent|optional }, /* TODO: this message should not be sent */
13740 { WM_ACTIVATE, sent|parent|wparam, 1 },
13741 { WM_SETFOCUS, sent },
13743 { WM_GETDLGCODE, sent|wparam|lparam, 0, 0 },
13744 { WM_USER, sent|parent },
13745 { WM_CHANGEUISTATE, sent|parent|optional },
13746 { 0 }
13747};
13748
13749static const struct message WmCreateDialogParamSeq_4[] = {
13750 { HCBT_CREATEWND, hook },
13751 { WM_NCCREATE, sent|parent },
13753 { WM_CREATE, sent|parent },
13754 { EVENT_OBJECT_CREATE, winevent_hook|wparam|lparam, 0, 0 },
13756 { WM_MOVE, sent|parent },
13757 { WM_SETFONT, sent|parent },
13759 { WM_GETDLGCODE, sent|wparam|lparam, 0, 0 },
13764 { HCBT_ACTIVATE, hook },
13765 { WM_QUERYNEWPALETTE, sent|parent|optional }, /* TODO: this message should not be sent */
13770 { WM_ACTIVATE, sent|parent|wparam, 1 },
13771 { HCBT_SETFOCUS, hook },
13772 { WM_SETFOCUS, sent|parent },
13774 { WM_SETFOCUS, sent },
13776 { WM_GETDLGCODE, sent|wparam|lparam, 0, 0 },
13777 { WM_USER, sent|parent },
13778 { WM_CHANGEUISTATE, sent|parent|optional },
13779 { WM_UPDATEUISTATE, sent|parent|optional },
13780 { WM_UPDATEUISTATE, sent|optional },
13781 { 0 }
13782};
13783
13784static void test_dialog_messages(void)
13785{
13786 WNDCLASSA cls;
13787 HWND hdlg, hedit1, hedit2, hfocus, parent, child, child2;
13788 LRESULT ret;
13789
13790#define set_selection(hctl, start, end) \
13791 ret = SendMessageA(hctl, EM_SETSEL, start, end); \
13792 ok(ret == 1, "EM_SETSEL returned %ld\n", ret);
13793
13794#define check_selection(hctl, start, end) \
13795 ret = SendMessageA(hctl, EM_GETSEL, 0, 0); \
13796 ok(ret == MAKELRESULT(start, end), "wrong selection (%d - %d)\n", LOWORD(ret), HIWORD(ret));
13797
13798 subclass_edit();
13799
13800 hdlg = CreateWindowExA(WS_EX_DLGMODALFRAME, "TestDialogClass", NULL,
13802 0, 0, 100, 100, 0, 0, 0, NULL);
13803 ok(hdlg != 0, "Failed to create custom dialog window\n");
13804
13805 hedit1 = CreateWindowExA(0, "my_edit_class", NULL,
13807 0, 0, 80, 20, hdlg, (HMENU)1, 0, NULL);
13808 ok(hedit1 != 0, "Failed to create edit control\n");
13809 hedit2 = CreateWindowExA(0, "my_edit_class", NULL,
13811 0, 40, 80, 20, hdlg, (HMENU)2, 0, NULL);
13812 ok(hedit2 != 0, "Failed to create edit control\n");
13813
13814 SendMessageA(hedit1, WM_SETTEXT, 0, (LPARAM)"hello");
13815 SendMessageA(hedit2, WM_SETTEXT, 0, (LPARAM)"bye");
13816
13817 hfocus = GetFocus();
13818 ok(hfocus == hdlg, "wrong focus %p\n", hfocus);
13819
13820 SetFocus(hedit2);
13821 hfocus = GetFocus();
13822 ok(hfocus == hedit2, "wrong focus %p\n", hfocus);
13823
13824 check_selection(hedit1, 0, 0);
13825 check_selection(hedit2, 0, 0);
13826
13827 set_selection(hedit2, 0, -1);
13828 check_selection(hedit2, 0, 3);
13829
13830 SetFocus(0);
13831 hfocus = GetFocus();
13832 ok(hfocus == 0, "wrong focus %p\n", hfocus);
13833
13835 ret = DefDlgProcA(hdlg, WM_SETFOCUS, 0, 0);
13836 ok(ret == 0, "WM_SETFOCUS returned %ld\n", ret);
13837 ok_sequence(WmDefDlgSetFocus_1, "DefDlgProc(WM_SETFOCUS) 1", FALSE);
13838
13839 hfocus = GetFocus();
13840 ok(hfocus == hedit1, "wrong focus %p\n", hfocus);
13841
13842 check_selection(hedit1, 0, 5);
13843 check_selection(hedit2, 0, 3);
13844
13846 ret = DefDlgProcA(hdlg, WM_SETFOCUS, 0, 0);
13847 ok(ret == 0, "WM_SETFOCUS returned %ld\n", ret);
13848 ok_sequence(WmDefDlgSetFocus_2, "DefDlgProc(WM_SETFOCUS) 2", FALSE);
13849
13850 hfocus = GetFocus();
13851 ok(hfocus == hedit1, "wrong focus %p\n", hfocus);
13852
13853 check_selection(hedit1, 0, 5);
13854 check_selection(hedit2, 0, 3);
13855
13856 EndDialog(hdlg, 0);
13857 DestroyWindow(hedit1);
13858 DestroyWindow(hedit2);
13859 DestroyWindow(hdlg);
13861
13862#undef set_selection
13863#undef check_selection
13864
13865 ok(GetClassInfoA(0, "#32770", &cls), "GetClassInfo failed\n");
13866 cls.lpszClassName = "MyDialogClass";
13868 /* need a cast since a dlgproc is used as a wndproc */
13870 if (!RegisterClassA(&cls)) assert(0);
13871
13872 SetFocus(0);
13874 hdlg = CreateDialogParamA(0, "CLASS_TEST_DIALOG_2", 0, test_dlg_proc, 0);
13875 ok(IsWindow(hdlg), "CreateDialogParam failed\n");
13876 ok_sequence(WmCreateDialogParamSeq_0, "CreateDialogParam_0", FALSE);
13877 hfocus = GetFocus();
13878 ok(hfocus == 0, "wrong focus %p\n", hfocus);
13879 EndDialog(hdlg, 0);
13880 DestroyWindow(hdlg);
13882
13883 SetFocus(0);
13885 hdlg = CreateDialogParamA(0, "CLASS_TEST_DIALOG_2", 0, test_dlg_proc, 1);
13886 ok(IsWindow(hdlg), "CreateDialogParam failed\n");
13887 ok_sequence(WmCreateDialogParamSeq_1, "CreateDialogParam_1", FALSE);
13888 hfocus = GetFocus();
13889 ok(hfocus == hdlg, "wrong focus %p\n", hfocus);
13890 EndDialog(hdlg, 0);
13891 DestroyWindow(hdlg);
13893
13894 hdlg = CreateDialogParamA(0, "CLASS_TEST_DIALOG_2", 0, NULL, 0);
13895 ok(IsWindow(hdlg), "CreateDialogParam failed\n");
13896 ok_sequence(WmCreateDialogParamSeq_2, "CreateDialogParam_2", FALSE);
13897 EndDialog(hdlg, 0);
13898 DestroyWindow(hdlg);
13900
13901 hdlg = CreateDialogParamA(0, "FOCUS_TEST_DIALOG_3", 0, test_dlg_proc2, 0);
13902 ok(IsWindow(hdlg), "CreateDialogParam failed\n");
13903 ok_sequence(WmCreateDialogParamSeq_3, "CreateDialogParam_3", TRUE);
13904 EndDialog(hdlg, 0);
13905 DestroyWindow(hdlg);
13907
13910 ok( RegisterClassA(&cls), "failed to register class again\n" );
13911 hdlg = CreateDialogParamA(0, "FOCUS_TEST_DIALOG_4", 0, test_dlg_proc3, 0);
13912 ok(IsWindow(hdlg), "CreateDialogParam failed\n");
13913 ok_sequence(WmCreateDialogParamSeq_4, "CreateDialogParam_4", TRUE);
13914 EndDialog(hdlg, 0);
13915 DestroyWindow(hdlg);
13917
13919
13920 parent = CreateWindowExA(0, "TestParentClass", "Test parent",
13922 100, 100, 200, 200, 0, 0, 0, NULL);
13923 ok (parent != 0, "Failed to create parent window\n");
13924
13925 /* This child has no parent set. We will later call SetParent on it,
13926 * so that it will have a parent set, but no WS_CHILD style. */
13927 child = CreateWindowExA(0, "TestWindowClass", "Test child",
13929 100, 100, 200, 200, 0, 0, 0, NULL);
13930 ok (child != 0, "Failed to create child window\n");
13931
13932 /* This is a regular child window. When used as an owner, the other
13933 * child window will be used. */
13934 child2 = CreateWindowExA(0, "SimpleWindowClass", "Test child2",
13936 100, 100, 200, 200, child, 0, 0, NULL);
13937 ok (child2 != 0, "Failed to create child window\n");
13938
13940 SetFocus(child);
13941
13943 DialogBoxA( 0, "TEST_DIALOG", child2, TestModalDlgProc2 );
13944 ok_sequence(WmModalDialogSeq_2, "ModalDialog2", TRUE);
13945
13946 DestroyWindow(child2);
13950}
13951
13953{
13954 const struct message seq[] = {
13955 { WM_ENABLE, sent },
13957 { HCBT_ACTIVATE, hook|wparam, (WPARAM)owner },
13960 /* FIXME: Following two are optional because Wine sends WM_QUERYNEWPALETTE instead of WM_WINDOWPOSCHANGING */
13966 { HCBT_SETFOCUS, hook|wparam, (WPARAM)owner },
13967 { WM_KILLFOCUS, sent|wparam, (WPARAM)owner },
13969 { 0 }
13970 };
13971
13973 EndDialog(dialog, 0);
13974 ok_sequence(seq, "EndDialog", FALSE);
13975}
13976
13978{
13979 const struct message seq[] = {
13980 { WM_ENABLE, parent|sent },
13982 { HCBT_ACTIVATE, hook|wparam, (WPARAM)owner },
13987 { HCBT_SETFOCUS, hook|wparam, (WPARAM)owner },
13988 { WM_KILLFOCUS, sent|wparam, (WPARAM)owner },
13990 { 0 }
13991 };
13992
13994 EndDialog(dialog, 0);
13995 ok_sequence(seq, "EndDialog2", FALSE);
13996}
13997
13998static void test_EndDialog(void)
13999{
14000 HWND hparent, hother, hactive, hdlg, hchild;
14001 WNDCLASSA cls;
14002
14003 hparent = CreateWindowExA(0, "TestParentClass", "Test parent",
14005 100, 100, 200, 200, 0, 0, 0, NULL);
14006 ok (hparent != 0, "Failed to create parent window\n");
14007
14008 hother = CreateWindowExA(0, "TestParentClass", "Test parent 2",
14010 200, 100, 200, 200, 0, 0, 0, NULL);
14011 ok (hother != 0, "Failed to create parent window\n");
14012
14013 ok(GetClassInfoA(0, "#32770", &cls), "GetClassInfo failed\n");
14014 cls.lpszClassName = "MyDialogClass";
14017 if (!RegisterClassA(&cls)) assert(0);
14018
14020 SetForegroundWindow(hother);
14021 hactive = GetForegroundWindow();
14022 ok(hother == hactive, "Wrong window has focus (%p != %p)\n", hother, hactive);
14023
14024 /* create a dialog where the parent is disabled, this parent should be
14025 * enabled and receive focus when dialog exits */
14026 hdlg = CreateDialogParamA(0, "CLASS_TEST_DIALOG_2", hparent, test_dlg_proc, 0);
14027 ok(IsWindow(hdlg), "CreateDialogParam failed\n");
14028 SetForegroundWindow(hdlg);
14029 hactive = GetForegroundWindow();
14030 ok(hdlg == hactive, "Wrong window has focus (%p != %p)\n", hdlg, hactive);
14031 EndDialog(hdlg, 0);
14032 ok(IsWindowEnabled(hparent), "parent is not enabled\n");
14033 hactive = GetForegroundWindow();
14034 ok(hparent == hactive, "Wrong window has focus (parent != active) (active: %p, parent: %p, dlg: %p, other: %p)\n", hactive, hparent, hdlg, hother);
14035 DestroyWindow(hdlg);
14037
14038 /* create a dialog where the parent is disabled and set active window to other window before calling EndDialog */
14039 EnableWindow(hparent, FALSE);
14040 hdlg = CreateWindowExA(0, "TestDialogClass", NULL,
14042 0, 0, 100, 100, hparent, 0, 0, NULL);
14043 ok(IsWindow(hdlg), "CreateDialogParam failed\n");
14045 SetForegroundWindow(hother);
14047 hactive = GetForegroundWindow();
14048 ok(hactive == hother, "Wrong foreground (%p != %p)\n", hactive, hother);
14049 hactive = GetActiveWindow();
14050 ok(hactive == hother, "Wrong active window (%p != %p)\n", hactive, hother);
14051 EndDialog(hdlg, 0);
14052 ok(IsWindowEnabled(hparent), "parent is not enabled\n");
14053 hactive = GetForegroundWindow();
14054 ok(hother == hactive, "Wrong window has focus (other != active) (active: %p, parent: %p, dlg: %p, other: %p)\n", hactive, hparent, hdlg, hother);
14055 DestroyWindow(hdlg);
14057
14058 DestroyWindow( hparent );
14059
14060 hparent = CreateWindowExA(0, "TestParentClass", "Test parent",
14062 100, 100, 200, 200, 0, 0, 0, NULL);
14063 ok (hparent != 0, "Failed to create parent window\n");
14064
14065 hchild = CreateWindowExA(0, "TestWindowClass", "Test child",
14067 0, 0, 0, 0, 0, 0, 0, NULL);
14068 ok (hchild != 0, "Failed to create child window\n");
14069
14070 SetParent(hchild, hparent);
14071
14073 SetForegroundWindow(hother);
14074 hactive = GetForegroundWindow();
14075 ok(hother == hactive, "Wrong foreground window (%p != %p)\n", hother, hactive);
14076
14077 hdlg = CreateDialogParamA(0, "CLASS_TEST_DIALOG_2", hchild, test_dlg_proc, 0);
14078 ok(IsWindow(hdlg), "CreateDialogParam failed\n");
14079
14080 SetForegroundWindow(hdlg);
14081 test_enddialog_seq(hdlg, hchild);
14082
14083 hactive = GetForegroundWindow();
14084 ok(hactive == hchild, "Wrong foreground window (active: %p, parent: %p, dlg: %p, other: %p child: %p)\n", hactive, hparent, hdlg, hother, hchild);
14085
14086 DestroyWindow(hdlg);
14087
14088 /* Now set WS_CHILD style flag so that it's a real child and its parent will be dialog's owner. */
14090
14091 SetForegroundWindow(hother);
14092 hactive = GetForegroundWindow();
14093 ok(hother == hactive, "Wrong foreground window (%p != %p)\n", hother, hactive);
14094
14095 hdlg = CreateDialogParamA(0, "CLASS_TEST_DIALOG_2", hchild, test_dlg_proc, 0);
14096 ok(IsWindow(hdlg), "CreateDialogParam failed\n");
14097
14098 SetForegroundWindow(hdlg);
14099 test_enddialog_seq2(hdlg, hparent);
14100
14101 hactive = GetForegroundWindow();
14102 ok(hactive == hparent, "Wrong foreground window (active: %p, parent: %p, dlg: %p, other: %p child: %p)\n", hactive, hparent, hdlg, hother, hchild);
14103 DestroyWindow(hdlg);
14104 DestroyWindow(hchild);
14105 DestroyWindow(hparent);
14106 DestroyWindow(hother);
14108
14110}
14111
14112static void test_nullCallback(void)
14113{
14114 HWND hwnd;
14115
14116 hwnd = CreateWindowExA(0, "TestWindowClass", "Test overlapped", WS_OVERLAPPEDWINDOW,
14117 100, 100, 200, 200, 0, 0, 0, NULL);
14118 ok (hwnd != 0, "Failed to create overlapped window\n");
14119
14121 flush_events();
14123}
14124
14125/* SetActiveWindow( 0 ) hwnd visible */
14126static const struct message SetActiveWindowSeq0[] =
14127{
14129 { WM_NCACTIVATE, sent|wparam, 0 },
14131 { WM_ACTIVATE, sent|wparam, 0 },
14151 { 0 }
14152};
14153/* SetActiveWindow( hwnd ) hwnd visible */
14154static const struct message SetActiveWindowSeq1[] =
14155{
14157 { 0 }
14158};
14159/* SetActiveWindow( popup ) hwnd visible, popup visible */
14160static const struct message SetActiveWindowSeq2[] =
14161{
14162 { HCBT_ACTIVATE, hook },
14163 { WM_NCACTIVATE, sent|wparam, 0 },
14165 { WM_ACTIVATE, sent|wparam, 0 },
14173 { WM_NCACTIVATE, sent|wparam, 1 },
14175 { WM_ACTIVATE, sent|wparam, 1 },
14176 { HCBT_SETFOCUS, hook },
14184 { 0 }
14185};
14186
14187/* SetActiveWindow( hwnd ) hwnd not visible */
14188static const struct message SetActiveWindowSeq3[] =
14189{
14190 { HCBT_ACTIVATE, hook },
14196 { WM_ACTIVATEAPP, sent|wparam, 1 },
14197 { WM_ACTIVATEAPP, sent|wparam, 1 },
14198 { WM_NCACTIVATE, sent|wparam, 1 },
14199 { WM_ACTIVATE, sent|wparam, 1 },
14200 { HCBT_SETFOCUS, hook },
14204 { 0 }
14205};
14206/* SetActiveWindow( popup ) hwnd not visible, popup not visible */
14207static const struct message SetActiveWindowSeq4[] =
14208{
14209 { HCBT_ACTIVATE, hook },
14210 { WM_NCACTIVATE, sent|wparam, 0 },
14212 { WM_ACTIVATE, sent|wparam, 0 },
14218 { WM_NCACTIVATE, sent|wparam, 1 },
14220 { WM_ACTIVATE, sent|wparam, 1 },
14221 { HCBT_SETFOCUS, hook },
14228 { 0 }
14229};
14230
14231
14232static void test_SetActiveWindow(void)
14233{
14234 HWND hwnd, popup, ret;
14235
14236 hwnd = CreateWindowExA(0, "TestWindowClass", "Test SetActiveWindow",
14238 100, 100, 200, 200, 0, 0, 0, NULL);
14239
14240 popup = CreateWindowExA(0, "TestWindowClass", "Test SetActiveWindow",
14242 100, 100, 200, 200, hwnd, 0, 0, NULL);
14243
14244 ok(hwnd != 0, "Failed to create overlapped window\n");
14245 ok(popup != 0, "Failed to create popup window\n");
14246 SetForegroundWindow( popup );
14248
14249 trace("SetActiveWindow(0)\n");
14250 ret = SetActiveWindow(0);
14251 ok( ret == popup, "Failed to SetActiveWindow(0)\n");
14252 ok_sequence(SetActiveWindowSeq0, "SetActiveWindow(0)", FALSE);
14254
14255 trace("SetActiveWindow(hwnd), hwnd visible\n");
14257 if (ret == hwnd) ok_sequence(SetActiveWindowSeq1, "SetActiveWindow(hwnd), hwnd visible", TRUE);
14259
14260 trace("SetActiveWindow(popup), hwnd visible, popup visible\n");
14261 ret = SetActiveWindow(popup);
14262 ok( ret == hwnd, "Failed to SetActiveWindow(popup), popup visible\n");
14263 ok_sequence(SetActiveWindowSeq2, "SetActiveWindow(popup), hwnd visible, popup visible", FALSE);
14265
14267 ShowWindow(popup, SW_HIDE);
14269
14270 trace("SetActiveWindow(hwnd), hwnd not visible\n");
14272 ok( ret == NULL, "SetActiveWindow(hwnd), hwnd not visible, previous is %p\n", ret );
14273 ok_sequence(SetActiveWindowSeq3, "SetActiveWindow(hwnd), hwnd not visible", TRUE);
14275
14276 trace("SetActiveWindow(popup), hwnd not visible, popup not visible\n");
14277 ret = SetActiveWindow(popup);
14278 ok( ret == hwnd, "Failed to SetActiveWindow(popup)\n");
14279 ok_sequence(SetActiveWindowSeq4, "SetActiveWindow(popup), hwnd not visible, popup not visible", TRUE);
14281
14282 trace("done\n");
14283
14285}
14286
14287static const struct message SetForegroundWindowSeq[] =
14288{
14289 { WM_NCACTIVATE, sent|wparam, 0 },
14291 { WM_ACTIVATE, sent|wparam, 0 },
14292 { WM_ACTIVATEAPP, sent|wparam, 0 },
14293 { WM_KILLFOCUS, sent },
14296 { 0 }
14297};
14298
14300{
14301 HWND hwnd;
14302
14303 hwnd = CreateWindowExA(0, "TestWindowClass", "Test SetForegroundWindow",
14305 100, 100, 200, 200, 0, 0, 0, NULL);
14306 ok (hwnd != 0, "Failed to create overlapped window\n");
14309
14310 trace("SetForegroundWindow( 0 )\n");
14312 ok_sequence(WmEmptySeq, "SetForegroundWindow( 0 ) away from foreground top level window", FALSE);
14313 trace("SetForegroundWindow( GetDesktopWindow() )\n");
14315 ok_sequence(SetForegroundWindowSeq, "SetForegroundWindow( desktop ) away from "
14316 "foreground top level window", FALSE);
14317 trace("done\n");
14318
14320}
14321
14323{
14324 DWORD cp;
14325 int ret;
14326 HKL hkl = GetKeyboardLayout( 0 );
14327
14328 ret = GetLocaleInfoW( LOWORD(hkl), LOCALE_IDEFAULTANSICODEPAGE | LOCALE_RETURN_NUMBER,
14329 (WCHAR *)&cp, sizeof(cp) / sizeof(WCHAR) );
14330 if (!ret) cp = CP_ACP;
14331 return cp;
14332}
14333
14334static void test_dbcs_wm_char(void)
14335{
14336 BYTE dbch[2];
14337 WCHAR wch, bad_wch;
14338 HWND hwnd, hwnd2;
14339 MSG msg;
14340 DWORD time;
14341 POINT pt;
14342 DWORD_PTR res;
14343 CPINFOEXA cpinfo;
14344 UINT i, j, k;
14345 struct message wmCharSeq[2];
14346 BOOL ret;
14348
14349 if (!pGetCPInfoExA)
14350 {
14351 win_skip("GetCPInfoExA is not available\n");
14352 return;
14353 }
14354
14355 pGetCPInfoExA( cp, 0, &cpinfo );
14356 if (cpinfo.MaxCharSize != 2)
14357 {
14358 skip( "Skipping DBCS WM_CHAR test in SBCS codepage '%s'\n", cpinfo.CodePageName );
14359 return;
14360 }
14361
14362 dbch[0] = dbch[1] = 0;
14363 wch = 0;
14364 bad_wch = cpinfo.UnicodeDefaultChar;
14365 for (i = 0; !wch && i < MAX_LEADBYTES && cpinfo.LeadByte[i]; i += 2)
14366 for (j = cpinfo.LeadByte[i]; !wch && j <= cpinfo.LeadByte[i+1]; j++)
14367 for (k = 128; k <= 255; k++)
14368 {
14369 char str[2];
14370 WCHAR wstr[2];
14371 str[0] = j;
14372 str[1] = k;
14373 if (MultiByteToWideChar( cp, 0, str, 2, wstr, 2 ) == 1 &&
14374 WideCharToMultiByte( cp, 0, wstr, 1, str, 2, NULL, NULL ) == 2 &&
14375 (BYTE)str[0] == j && (BYTE)str[1] == k &&
14376 HIBYTE(wstr[0]) && HIBYTE(wstr[0]) != 0xff)
14377 {
14378 dbch[0] = j;
14379 dbch[1] = k;
14380 wch = wstr[0];
14381 break;
14382 }
14383 }
14384
14385 if (!wch)
14386 {
14387 skip( "Skipping DBCS WM_CHAR test, no appropriate char found\n" );
14388 return;
14389 }
14390 trace( "using dbcs char %02x,%02x wchar %04x bad wchar %04x codepage '%s'\n",
14391 dbch[0], dbch[1], wch, bad_wch, cpinfo.CodePageName );
14392
14394 WS_OVERLAPPEDWINDOW, 100, 100, 200, 200, 0, 0, 0, NULL);
14396 WS_OVERLAPPEDWINDOW, 100, 100, 200, 200, 0, 0, 0, NULL);
14397 ok (hwnd != 0, "Failed to create overlapped window\n");
14398 ok (hwnd2 != 0, "Failed to create overlapped window\n");
14400
14401 memset( wmCharSeq, 0, sizeof(wmCharSeq) );
14402 wmCharSeq[0].message = WM_CHAR;
14403 wmCharSeq[0].flags = sent|wparam;
14404 wmCharSeq[0].wParam = wch;
14405
14406 /* posted message */
14407 PostMessageA( hwnd, WM_CHAR, dbch[0], 0 );
14408 ret = PeekMessageW( &msg, hwnd, 0, 0, PM_REMOVE );
14409 ok( !ret, "got message %x\n", msg.message );
14410 PostMessageA( hwnd, WM_CHAR, dbch[1], 0 );
14411 ret = PeekMessageW( &msg, hwnd, 0, 0, PM_REMOVE );
14412 ok( ret, "no message\n" );
14413 ok( msg.message == WM_CHAR, "unexpected message %x\n", msg.message );
14414 ok( msg.wParam == wch, "bad wparam %lx/%x\n", msg.wParam, wch );
14415 ret = PeekMessageW( &msg, hwnd, 0, 0, PM_REMOVE );
14416 ok( !ret, "got message %x\n", msg.message );
14417
14418 /* posted thread message */
14420 ret = PeekMessageW( &msg, hwnd, 0, 0, PM_REMOVE );
14421 ok( !ret, "got message %x\n", msg.message );
14422 PostMessageA( hwnd, WM_CHAR, dbch[1], 0 );
14423 ret = PeekMessageW( &msg, hwnd, 0, 0, PM_REMOVE );
14424 ok( ret, "no message\n" );
14425 ok( msg.message == WM_CHAR, "unexpected message %x\n", msg.message );
14426 ok( msg.wParam == wch, "bad wparam %lx/%x\n", msg.wParam, wch );
14427 ret = PeekMessageW( &msg, hwnd, 0, 0, PM_REMOVE );
14428 ok( !ret, "got message %x\n", msg.message );
14429
14430 /* sent message */
14432 SendMessageA( hwnd, WM_CHAR, dbch[0], 0 );
14433 ok_sequence( WmEmptySeq, "no messages", FALSE );
14434 SendMessageA( hwnd, WM_CHAR, dbch[1], 0 );
14435 ok_sequence( wmCharSeq, "Unicode WM_CHAR", FALSE );
14436 ret = PeekMessageW( &msg, hwnd, 0, 0, PM_REMOVE );
14437 ok( !ret, "got message %x\n", msg.message );
14438
14439 /* sent message with timeout */
14441 SendMessageTimeoutA( hwnd, WM_CHAR, dbch[0], 0, SMTO_NORMAL, 0, &res );
14442 ok_sequence( WmEmptySeq, "no messages", FALSE );
14443 SendMessageTimeoutA( hwnd, WM_CHAR, dbch[1], 0, SMTO_NORMAL, 0, &res );
14444 ok_sequence( wmCharSeq, "Unicode WM_CHAR", FALSE );
14445 ret = PeekMessageW( &msg, hwnd, 0, 0, PM_REMOVE );
14446 ok( !ret, "got message %x\n", msg.message );
14447
14448 /* sent message with timeout and callback */
14450 SendMessageTimeoutA( hwnd, WM_CHAR, dbch[0], 0, SMTO_NORMAL, 0, &res );
14451 ok_sequence( WmEmptySeq, "no messages", FALSE );
14452 SendMessageCallbackA( hwnd, WM_CHAR, dbch[1], 0, NULL, 0 );
14453 ok_sequence( wmCharSeq, "Unicode WM_CHAR", FALSE );
14454 ret = PeekMessageW( &msg, hwnd, 0, 0, PM_REMOVE );
14455 ok( !ret, "got message %x\n", msg.message );
14456
14457 /* sent message with callback */
14459 SendNotifyMessageA( hwnd, WM_CHAR, dbch[0], 0 );
14460 ok_sequence( WmEmptySeq, "no messages", FALSE );
14461 SendMessageCallbackA( hwnd, WM_CHAR, dbch[1], 0, NULL, 0 );
14462 ok_sequence( wmCharSeq, "Unicode WM_CHAR", FALSE );
14463 ret = PeekMessageW( &msg, hwnd, 0, 0, PM_REMOVE );
14464 ok( !ret, "got message %x\n", msg.message );
14465
14466 /* direct window proc call */
14469 ok_sequence( WmEmptySeq, "no messages", FALSE );
14471 ok_sequence( wmCharSeq, "Unicode WM_CHAR", FALSE );
14472
14473 /* dispatch message */
14474 msg.hwnd = hwnd;
14475 msg.message = WM_CHAR;
14476 msg.wParam = dbch[0];
14477 msg.lParam = 0;
14479 ok_sequence( WmEmptySeq, "no messages", FALSE );
14480 msg.wParam = dbch[1];
14482 ok_sequence( wmCharSeq, "Unicode WM_CHAR", FALSE );
14483
14484 /* window handle is irrelevant */
14486 SendMessageA( hwnd2, WM_CHAR, dbch[0], 0 );
14487 ok_sequence( WmEmptySeq, "no messages", FALSE );
14488 SendMessageA( hwnd, WM_CHAR, dbch[1], 0 );
14489 ok_sequence( wmCharSeq, "Unicode WM_CHAR", FALSE );
14490 ret = PeekMessageW( &msg, hwnd, 0, 0, PM_REMOVE );
14491 ok( !ret, "got message %x\n", msg.message );
14492
14493 /* interleaved post and send */
14495 PostMessageA( hwnd2, WM_CHAR, dbch[0], 0 );
14496 SendMessageA( hwnd2, WM_CHAR, dbch[0], 0 );
14497 ok_sequence( WmEmptySeq, "no messages", FALSE );
14498 ret = PeekMessageW( &msg, hwnd, 0, 0, PM_REMOVE );
14499 ok( !ret, "got message %x\n", msg.message );
14500 PostMessageA( hwnd, WM_CHAR, dbch[1], 0 );
14501 ok_sequence( WmEmptySeq, "no messages", FALSE );
14502 ret = PeekMessageW( &msg, hwnd, 0, 0, PM_REMOVE );
14503 ok( ret, "no message\n" );
14504 ok( msg.message == WM_CHAR, "unexpected message %x\n", msg.message );
14505 ok( msg.wParam == wch, "bad wparam %lx/%x\n", msg.wParam, wch );
14506 ret = PeekMessageW( &msg, hwnd, 0, 0, PM_REMOVE );
14507 ok( !ret, "got message %x\n", msg.message );
14508 SendMessageA( hwnd, WM_CHAR, dbch[1], 0 );
14509 ok_sequence( wmCharSeq, "Unicode WM_CHAR", FALSE );
14510 ret = PeekMessageW( &msg, hwnd, 0, 0, PM_REMOVE );
14511 ok( !ret, "got message %x\n", msg.message );
14512
14513 /* interleaved sent message and winproc */
14515 SendMessageA( hwnd, WM_CHAR, dbch[0], 0 );
14517 ok_sequence( WmEmptySeq, "no messages", FALSE );
14518 SendMessageA( hwnd, WM_CHAR, dbch[1], 0 );
14519 ok_sequence( wmCharSeq, "Unicode WM_CHAR", FALSE );
14521 ok_sequence( wmCharSeq, "Unicode WM_CHAR", FALSE );
14522
14523 /* interleaved winproc and dispatch */
14524 msg.hwnd = hwnd;
14525 msg.message = WM_CHAR;
14526 msg.wParam = dbch[0];
14527 msg.lParam = 0;
14530 ok_sequence( WmEmptySeq, "no messages", FALSE );
14531 msg.wParam = dbch[1];
14533 ok_sequence( wmCharSeq, "Unicode WM_CHAR", FALSE );
14535 ok_sequence( wmCharSeq, "Unicode WM_CHAR", FALSE );
14536
14537 /* interleaved sends */
14539 SendMessageA( hwnd, WM_CHAR, dbch[0], 0 );
14540 SendMessageCallbackA( hwnd, WM_CHAR, dbch[0], 0, NULL, 0 );
14541 ok_sequence( WmEmptySeq, "no messages", FALSE );
14542 SendMessageTimeoutA( hwnd, WM_CHAR, dbch[1], 0, SMTO_NORMAL, 0, &res );
14543 ok_sequence( wmCharSeq, "Unicode WM_CHAR", FALSE );
14544 SendMessageA( hwnd, WM_CHAR, dbch[1], 0 );
14545 ok_sequence( wmCharSeq, "Unicode WM_CHAR", FALSE );
14546
14547 /* dbcs WM_CHAR */
14549 SendMessageA( hwnd2, WM_CHAR, (dbch[1] << 8) | dbch[0], 0 );
14550 ok_sequence( wmCharSeq, "Unicode WM_CHAR", FALSE );
14551 ret = PeekMessageW( &msg, hwnd, 0, 0, PM_REMOVE );
14552 ok( !ret, "got message %x\n", msg.message );
14553
14554 /* other char messages are not magic */
14555 PostMessageA( hwnd, WM_SYSCHAR, dbch[0], 0 );
14556 ret = PeekMessageW( &msg, hwnd, 0, 0, PM_REMOVE );
14557 ok( ret, "no message\n" );
14558 ok( msg.message == WM_SYSCHAR, "unexpected message %x\n", msg.message );
14559 ok( msg.wParam == bad_wch, "bad wparam %lx/%x\n", msg.wParam, bad_wch );
14560 ret = PeekMessageW( &msg, hwnd, 0, 0, PM_REMOVE );
14561 ok( !ret, "got message %x\n", msg.message );
14562 PostMessageA( hwnd, WM_DEADCHAR, dbch[0], 0 );
14563 ret = PeekMessageW( &msg, hwnd, 0, 0, PM_REMOVE );
14564 ok( ret, "no message\n" );
14565 ok( msg.message == WM_DEADCHAR, "unexpected message %x\n", msg.message );
14566 ok( msg.wParam == bad_wch, "bad wparam %lx/%x\n", msg.wParam, bad_wch );
14567 ret = PeekMessageW( &msg, hwnd, 0, 0, PM_REMOVE );
14568 ok( !ret, "got message %x\n", msg.message );
14569
14570 /* test retrieving messages */
14571
14572 PostMessageW( hwnd, WM_CHAR, wch, 0 );
14573 ret = PeekMessageA( &msg, hwnd, 0, 0, PM_REMOVE );
14574 ok( ret, "no message\n" );
14575 ok( msg.hwnd == hwnd, "unexpected hwnd %p\n", msg.hwnd );
14576 ok( msg.message == WM_CHAR, "unexpected message %x\n", msg.message );
14577 ok( msg.wParam == dbch[0], "bad wparam %lx/%x\n", msg.wParam, dbch[0] );
14578 ret = PeekMessageA( &msg, hwnd, 0, 0, PM_REMOVE );
14579 ok( ret, "no message\n" );
14580 ok( msg.hwnd == hwnd, "unexpected hwnd %p\n", msg.hwnd );
14581 ok( msg.message == WM_CHAR, "unexpected message %x\n", msg.message );
14582 ok( msg.wParam == dbch[1], "bad wparam %lx/%x\n", msg.wParam, dbch[0] );
14583 ret = PeekMessageA( &msg, hwnd, 0, 0, PM_REMOVE );
14584 ok( !ret, "got message %x\n", msg.message );
14585
14586 /* message filters */
14587 PostMessageW( hwnd, WM_CHAR, wch, 0 );
14588 ret = PeekMessageA( &msg, hwnd, 0, 0, PM_REMOVE );
14589 ok( ret, "no message\n" );
14590 ok( msg.hwnd == hwnd, "unexpected hwnd %p\n", msg.hwnd );
14591 ok( msg.message == WM_CHAR, "unexpected message %x\n", msg.message );
14592 ok( msg.wParam == dbch[0], "bad wparam %lx/%x\n", msg.wParam, dbch[0] );
14593 /* message id is filtered, hwnd is not */
14595 ok( !ret, "no message\n" );
14596 ret = PeekMessageA( &msg, hwnd2, 0, 0, PM_REMOVE );
14597 ok( ret, "no message\n" );
14598 ok( msg.hwnd == hwnd, "unexpected hwnd %p\n", msg.hwnd );
14599 ok( msg.message == WM_CHAR, "unexpected message %x\n", msg.message );
14600 ok( msg.wParam == dbch[1], "bad wparam %lx/%x\n", msg.wParam, dbch[0] );
14601 ret = PeekMessageA( &msg, hwnd, 0, 0, PM_REMOVE );
14602 ok( !ret, "got message %x\n", msg.message );
14603
14604 /* mixing GetMessage and PostMessage */
14605 PostMessageW( hwnd, WM_CHAR, wch, 0xbeef );
14606 ok( GetMessageA( &msg, hwnd, 0, 0 ), "no message\n" );
14607 ok( msg.hwnd == hwnd, "unexpected hwnd %p\n", msg.hwnd );
14608 ok( msg.message == WM_CHAR, "unexpected message %x\n", msg.message );
14609 ok( msg.wParam == dbch[0], "bad wparam %lx/%x\n", msg.wParam, dbch[0] );
14610 ok( msg.lParam == 0xbeef, "bad lparam %lx\n", msg.lParam );
14611 time = msg.time;
14612 pt = msg.pt;
14613 ok( time - GetTickCount() <= 100, "bad time %x\n", msg.time );
14614 ret = PeekMessageA( &msg, 0, 0, 0, PM_REMOVE );
14615 ok( ret, "no message\n" );
14616 ok( msg.hwnd == hwnd, "unexpected hwnd %p\n", msg.hwnd );
14617 ok( msg.message == WM_CHAR, "unexpected message %x\n", msg.message );
14618 ok( msg.wParam == dbch[1], "bad wparam %lx/%x\n", msg.wParam, dbch[0] );
14619 ok( msg.lParam == 0xbeef, "bad lparam %lx\n", msg.lParam );
14620 ok( msg.time == time, "bad time %x/%x\n", msg.time, time );
14621 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 );
14622 ret = PeekMessageA( &msg, hwnd, 0, 0, PM_REMOVE );
14623 ok( !ret, "got message %x\n", msg.message );
14624
14625 /* without PM_REMOVE */
14626 PostMessageW( hwnd, WM_CHAR, wch, 0 );
14627 ret = PeekMessageA( &msg, 0, 0, 0, PM_NOREMOVE );
14628 ok( ret, "no message\n" );
14629 ok( msg.hwnd == hwnd, "unexpected hwnd %p\n", msg.hwnd );
14630 ok( msg.message == WM_CHAR, "unexpected message %x\n", msg.message );
14631 ok( msg.wParam == dbch[0], "bad wparam %lx/%x\n", msg.wParam, dbch[0] );
14632 ret = PeekMessageA( &msg, 0, 0, 0, PM_REMOVE );
14633 ok( ret, "no message\n" );
14634 ok( msg.hwnd == hwnd, "unexpected hwnd %p\n", msg.hwnd );
14635 ok( msg.message == WM_CHAR, "unexpected message %x\n", msg.message );
14636 ok( msg.wParam == dbch[0], "bad wparam %lx/%x\n", msg.wParam, dbch[0] );
14637 ret = PeekMessageA( &msg, 0, 0, 0, PM_NOREMOVE );
14638 ok( ret, "no message\n" );
14639 ok( msg.hwnd == hwnd, "unexpected hwnd %p\n", msg.hwnd );
14640 ok( msg.message == WM_CHAR, "unexpected message %x\n", msg.message );
14641 ok( msg.wParam == dbch[1], "bad wparam %lx/%x\n", msg.wParam, dbch[0] );
14642 ret = PeekMessageA( &msg, 0, 0, 0, PM_REMOVE );
14643 ok( ret, "no message\n" );
14644 ok( msg.hwnd == hwnd, "unexpected hwnd %p\n", msg.hwnd );
14645 ok( msg.message == WM_CHAR, "unexpected message %x\n", msg.message );
14646 ok( msg.wParam == dbch[1], "bad wparam %lx/%x\n", msg.wParam, dbch[0] );
14647 ret = PeekMessageA( &msg, hwnd, 0, 0, PM_REMOVE );
14648 ok( !ret, "got message %x\n", msg.message );
14649
14651 DestroyWindow(hwnd2);
14652}
14653
14654static void test_unicode_wm_char(void)
14655{
14656 HWND hwnd;
14657 MSG msg;
14658 struct message seq[2];
14659 HKL hkl_orig, hkl_greek;
14660 DWORD cp;
14661 LCID thread_locale;
14662
14663 hkl_orig = GetKeyboardLayout( 0 );
14664 GetLocaleInfoW( LOWORD( hkl_orig ), LOCALE_IDEFAULTANSICODEPAGE | LOCALE_RETURN_NUMBER, (WCHAR*)&cp, sizeof(cp) / sizeof(WCHAR) );
14665 if (cp != 1252)
14666 {
14667 skip( "Default codepage %d\n", cp );
14668 return;
14669 }
14670
14671 hkl_greek = LoadKeyboardLayoutA( "00000408", 0 );
14672 if (!hkl_greek || hkl_greek == hkl_orig /* win2k */)
14673 {
14674 skip( "Unable to load Greek keyboard layout\n" );
14675 return;
14676 }
14677
14679 100, 100, 200, 200, 0, 0, 0, NULL );
14681
14682 PostMessageW( hwnd, WM_CHAR, 0x3b1, 0 );
14683
14684 while (GetMessageW( &msg, hwnd, 0, 0 ))
14685 {
14686 if (!ignore_message( msg.message )) break;
14687 }
14688
14689 ok( msg.hwnd == hwnd, "unexpected hwnd %p\n", msg.hwnd );
14690 ok( msg.message == WM_CHAR, "unexpected message %x\n", msg.message );
14691 ok( msg.wParam == 0x3b1, "bad wparam %lx\n", msg.wParam );
14692 ok( msg.lParam == 0, "bad lparam %lx\n", msg.lParam );
14693
14695
14696 memset( seq, 0, sizeof(seq) );
14697 seq[0].message = WM_CHAR;
14698 seq[0].flags = sent|wparam;
14699 seq[0].wParam = 0x3b1;
14700
14701 ok_sequence( seq, "unicode WM_CHAR", FALSE );
14702
14704
14705 /* greek alpha -> 'a' in cp1252 */
14706 PostMessageW( hwnd, WM_CHAR, 0x3b1, 0 );
14707
14708 ok( GetMessageA( &msg, hwnd, 0, 0 ), "no message\n" );
14709 ok( msg.hwnd == hwnd, "unexpected hwnd %p\n", msg.hwnd );
14710 ok( msg.message == WM_CHAR, "unexpected message %x\n", msg.message );
14711 ok( msg.wParam == 0x61, "bad wparam %lx\n", msg.wParam );
14712 ok( msg.lParam == 0, "bad lparam %lx\n", msg.lParam );
14713
14715
14716 seq[0].wParam = 0x61;
14717 ok_sequence( seq, "unicode WM_CHAR", FALSE );
14718
14719 thread_locale = GetThreadLocale();
14720 ActivateKeyboardLayout( hkl_greek, 0 );
14721 ok( GetThreadLocale() == thread_locale, "locale changed from %08x to %08x\n",
14722 thread_locale, GetThreadLocale() );
14723
14725
14726 /* greek alpha -> 0xe1 in cp1253 */
14727 PostMessageW( hwnd, WM_CHAR, 0x3b1, 0 );
14728
14729 ok( GetMessageA( &msg, hwnd, 0, 0 ), "no message\n" );
14730 ok( msg.hwnd == hwnd, "unexpected hwnd %p\n", msg.hwnd );
14731 ok( msg.message == WM_CHAR, "unexpected message %x\n", msg.message );
14732 ok( msg.wParam == 0xe1, "bad wparam %lx\n", msg.wParam );
14733 ok( msg.lParam == 0, "bad lparam %lx\n", msg.lParam );
14734
14736
14737 seq[0].wParam = 0x3b1;
14738 ok_sequence( seq, "unicode WM_CHAR", FALSE );
14739
14741 ActivateKeyboardLayout( hkl_orig, 0 );
14742 UnloadKeyboardLayout( hkl_greek );
14743}
14744
14745#define ID_LISTBOX 0x000f
14746
14747static const struct message wm_lb_setcursel_0[] =
14748{
14749 { LB_SETCURSEL, sent|wparam|lparam, 0, 0 },
14751 { WM_DRAWITEM, sent|wparam|lparam|parent, ID_LISTBOX, 0x000120f2 },
14752 { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 1 },
14753 { EVENT_OBJECT_SELECTION, winevent_hook|wparam|lparam, OBJID_CLIENT, 1 },
14754 { 0 }
14755};
14756static const struct message wm_lb_setcursel_1[] =
14757{
14758 { LB_SETCURSEL, sent|wparam|lparam, 1, 0 },
14760 { WM_DRAWITEM, sent|wparam|lparam|parent, ID_LISTBOX, 0x000020f2 },
14762 { WM_DRAWITEM, sent|wparam|lparam|parent, ID_LISTBOX, 0x000121f2 },
14763 { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 2 },
14764 { EVENT_OBJECT_SELECTION, winevent_hook|wparam|lparam, OBJID_CLIENT, 2 },
14765 { 0 }
14766};
14767static const struct message wm_lb_setcursel_2[] =
14768{
14769 { LB_SETCURSEL, sent|wparam|lparam, 2, 0 },
14771 { WM_DRAWITEM, sent|wparam|lparam|parent, ID_LISTBOX, 0x000021f2 },
14773 { WM_DRAWITEM, sent|wparam|lparam|parent, ID_LISTBOX, 0x000122f2 },
14774 { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 3 },
14775 { EVENT_OBJECT_SELECTION, winevent_hook|wparam|lparam, OBJID_CLIENT, 3 },
14776 { 0 }
14777};
14778static const struct message wm_lb_click_0[] =
14779{
14781 { HCBT_SETFOCUS, hook },
14785 { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
14787
14788 { WM_DRAWITEM, sent|wparam|lparam|parent, ID_LISTBOX, 0x001142f2 },
14790 { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 3 },
14792 { EVENT_SYSTEM_CAPTURESTART, winevent_hook|wparam|lparam, 0, 0 },
14793
14794 { WM_DRAWITEM, sent|wparam|lparam|parent, ID_LISTBOX, 0x000142f2 },
14796 { WM_DRAWITEM, sent|wparam|lparam|parent, ID_LISTBOX, 0x000022f2 },
14798 { WM_DRAWITEM, sent|wparam|lparam|parent, ID_LISTBOX, 0x000120f2 },
14799 { WM_DRAWITEM, sent|wparam|lparam|parent, ID_LISTBOX, 0x001140f2 },
14800
14801 { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 1 },
14802 { EVENT_OBJECT_SELECTION, winevent_hook|wparam|lparam, OBJID_CLIENT, 1 },
14803
14804 { WM_LBUTTONUP, sent|wparam|lparam, 0, 0 },
14805 { EVENT_SYSTEM_CAPTUREEND, winevent_hook|wparam|lparam, 0, 0 },
14808 { 0 }
14809};
14810static const struct message wm_lb_deletestring[] =
14811{
14812 { LB_DELETESTRING, sent|wparam|lparam, 0, 0 },
14816 { 0 }
14817};
14818static const struct message wm_lb_deletestring_reset[] =
14819{
14820 { LB_DELETESTRING, sent|wparam|lparam, 0, 0 },
14825 { 0 }
14826};
14827static const struct message wm_lb_addstring[] =
14828{
14829 { LB_ADDSTRING, sent|wparam|lparam, 0, 0xf30604ef },
14830 { LB_ADDSTRING, sent|wparam|lparam, 0, 0xf30604ed },
14831 { LB_ADDSTRING, sent|wparam|lparam, 0, 0xf30604ee },
14832 { 0 }
14833};
14834static const struct message wm_lb_addstring_ownerdraw[] =
14835{
14836 { LB_ADDSTRING, sent|wparam|lparam, 0, 0xf30604ed },
14837 { WM_MEASUREITEM, sent|wparam|lparam|parent, 0xf0f2, 0xf30604ed },
14838 { LB_ADDSTRING, sent|wparam|lparam, 0, 0xf30604ee },
14839 { WM_MEASUREITEM, sent|wparam|lparam|parent, 0xf1f2, 0xf30604ee },
14840 { LB_ADDSTRING, sent|wparam|lparam, 0, 0xf30604ef },
14841 { WM_MEASUREITEM, sent|wparam|lparam|parent, 0xf2f2, 0xf30604ef },
14842 { 0 }
14843};
14845{
14846 { LB_ADDSTRING, sent|wparam|lparam, 0, 0xf30604ed },
14847 { WM_MEASUREITEM, sent|wparam|lparam|parent, 0xf0f2, 0xf30604ed },
14848 { LB_ADDSTRING, sent|wparam|lparam, 0, 0xf30604ee },
14849 { WM_COMPAREITEM, sent|wparam|lparam|parent, 0xf30604ed, 0xf30604ee },
14850 { WM_MEASUREITEM, sent|wparam|lparam|parent, 0xf1f2, 0xf30604ee },
14851 { LB_ADDSTRING, sent|wparam|lparam, 0, 0xf30604ef },
14852 { WM_COMPAREITEM, sent|wparam|lparam|parent, 0xf30604ed, 0xf30604ef },
14853 { WM_COMPAREITEM, sent|wparam|lparam|parent, 0xf30604ee, 0xf30604ef },
14854 { WM_MEASUREITEM, sent|wparam|lparam|parent, 0xf2f2, 0xf30604ef },
14855 { 0 }
14856};
14857
14858#define check_lb_state(a1, a2, a3, a4, a5) check_lb_state_dbg(a1, a2, a3, a4, a5, __LINE__)
14859
14860static LRESULT (WINAPI *listbox_orig_proc)(HWND, UINT, WPARAM, LPARAM);
14861
14863{
14864 static LONG defwndproc_counter = 0;
14865 LRESULT ret;
14866 struct recvd_message msg;
14867
14868 /* do not log painting messages */
14869 if (message != WM_PAINT &&
14870 message != WM_NCPAINT &&
14871 message != WM_SYNCPAINT &&
14873 message != WM_NCHITTEST &&
14874 message != WM_GETTEXT &&
14876 {
14877 msg.hwnd = hwnd;
14878 msg.message = message;
14879 msg.flags = sent|wparam|lparam;
14880 if (defwndproc_counter) msg.flags |= defwinproc;
14881 msg.wParam = wp;
14882 if (message == LB_ADDSTRING)
14883 msg.lParam = lp ? hash_Ly((const char *)lp) : 0;
14884 else
14885 msg.lParam = lp;
14886 msg.descr = "listbox";
14887 add_message(&msg);
14888 }
14889
14890 defwndproc_counter++;
14891 ret = CallWindowProcA(listbox_orig_proc, hwnd, message, wp, lp);
14892 defwndproc_counter--;
14893
14894 return ret;
14895}
14896
14897static void check_lb_state_dbg(HWND listbox, int count, int cur_sel,
14898 int caret_index, int top_index, int line)
14899{
14900 LRESULT ret;
14901
14902 /* calling an orig proc helps to avoid unnecessary message logging */
14903 ret = CallWindowProcA(listbox_orig_proc, listbox, LB_GETCOUNT, 0, 0);
14904 ok_(__FILE__, line)(ret == count, "expected count %d, got %ld\n", count, ret);
14905 ret = CallWindowProcA(listbox_orig_proc, listbox, LB_GETCURSEL, 0, 0);
14906 ok_(__FILE__, line)(ret == cur_sel, "expected cur sel %d, got %ld\n", cur_sel, ret);
14907 ret = CallWindowProcA(listbox_orig_proc, listbox, LB_GETCARETINDEX, 0, 0);
14908 ok_(__FILE__, line)(ret == caret_index ||
14909 broken(cur_sel == -1 && caret_index == 0 && ret == -1), /* nt4 */
14910 "expected caret index %d, got %ld\n", caret_index, ret);
14911 ret = CallWindowProcA(listbox_orig_proc, listbox, LB_GETTOPINDEX, 0, 0);
14912 ok_(__FILE__, line)(ret == top_index, "expected top index %d, got %ld\n", top_index, ret);
14913}
14914
14915static void test_listbox_messages(void)
14916{
14917 HWND parent, listbox;
14918 LRESULT ret;
14919
14920 parent = CreateWindowExA(0, "TestParentClass", NULL, WS_OVERLAPPEDWINDOW | WS_VISIBLE,
14921 100, 100, 200, 200, 0, 0, 0, NULL);
14922 /* with LBS_HASSTRINGS */
14923 listbox = CreateWindowExA(WS_EX_NOPARENTNOTIFY, "ListBox", NULL,
14925 10, 10, 80, 80, parent, (HMENU)ID_LISTBOX, 0, NULL);
14926 listbox_orig_proc = (WNDPROC)SetWindowLongPtrA(listbox, GWLP_WNDPROC, (ULONG_PTR)listbox_hook_proc);
14927
14928 check_lb_state(listbox, 0, LB_ERR, 0, 0);
14929
14931
14933
14934 ret = SendMessageA(listbox, LB_ADDSTRING, 0, (LPARAM)"item 0");
14935 ok(ret == 0, "expected 0, got %ld\n", ret);
14936 ret = SendMessageA(listbox, LB_ADDSTRING, 0, (LPARAM)"item 1");
14937 ok(ret == 1, "expected 1, got %ld\n", ret);
14938 ret = SendMessageA(listbox, LB_ADDSTRING, 0, (LPARAM)"item 2");
14939 ok(ret == 2, "expected 2, got %ld\n", ret);
14940
14942 check_lb_state(listbox, 3, LB_ERR, 0, 0);
14943
14945
14946 trace("selecting item 0\n");
14947 ret = SendMessageA(listbox, LB_SETCURSEL, 0, 0);
14948 ok(ret == 0, "expected 0, got %ld\n", ret);
14949 ok_sequence(wm_lb_setcursel_0, "LB_SETCURSEL 0", FALSE );
14950 check_lb_state(listbox, 3, 0, 0, 0);
14952
14953 trace("selecting item 1\n");
14954 ret = SendMessageA(listbox, LB_SETCURSEL, 1, 0);
14955 ok(ret == 1, "expected 1, got %ld\n", ret);
14956 ok_sequence(wm_lb_setcursel_1, "LB_SETCURSEL 1", FALSE );
14957 check_lb_state(listbox, 3, 1, 1, 0);
14958
14959 trace("selecting item 2\n");
14960 ret = SendMessageA(listbox, LB_SETCURSEL, 2, 0);
14961 ok(ret == 2, "expected 2, got %ld\n", ret);
14962 ok_sequence(wm_lb_setcursel_2, "LB_SETCURSEL 2", FALSE );
14963 check_lb_state(listbox, 3, 2, 2, 0);
14964
14965 trace("clicking on item 0\n");
14966 ret = SendMessageA(listbox, WM_LBUTTONDOWN, 0, MAKELPARAM(1, 1));
14967 ok(ret == LB_OKAY, "expected LB_OKAY, got %ld\n", ret);
14968 ret = SendMessageA(listbox, WM_LBUTTONUP, 0, 0);
14969 ok(ret == LB_OKAY, "expected LB_OKAY, got %ld\n", ret);
14970 ok_sequence(wm_lb_click_0, "WM_LBUTTONDOWN 0", FALSE );
14971 check_lb_state(listbox, 3, 0, 0, 0);
14973
14974 trace("deleting item 0\n");
14975 ret = SendMessageA(listbox, LB_DELETESTRING, 0, 0);
14976 ok(ret == 2, "expected 2, got %ld\n", ret);
14977 ok_sequence(wm_lb_deletestring, "LB_DELETESTRING 0", FALSE );
14978 check_lb_state(listbox, 2, -1, 0, 0);
14980
14981 trace("deleting item 0\n");
14982 ret = SendMessageA(listbox, LB_DELETESTRING, 0, 0);
14983 ok(ret == 1, "expected 1, got %ld\n", ret);
14984 ok_sequence(wm_lb_deletestring, "LB_DELETESTRING 0", FALSE );
14985 check_lb_state(listbox, 1, -1, 0, 0);
14987
14988 trace("deleting item 0\n");
14989 ret = SendMessageA(listbox, LB_DELETESTRING, 0, 0);
14990 ok(ret == 0, "expected 0, got %ld\n", ret);
14991 ok_sequence(wm_lb_deletestring_reset, "LB_DELETESTRING 0", FALSE );
14992 check_lb_state(listbox, 0, -1, 0, 0);
14994
14995 trace("deleting item 0\n");
14996 ret = SendMessageA(listbox, LB_DELETESTRING, 0, 0);
14997 ok(ret == LB_ERR, "expected LB_ERR, got %ld\n", ret);
14998 check_lb_state(listbox, 0, -1, 0, 0);
15000
15002
15003 DestroyWindow(listbox);
15004
15005 /* with LBS_SORT and without LBS_HASSTRINGS */
15006 listbox = CreateWindowExA(WS_EX_NOPARENTNOTIFY, "ListBox", NULL,
15008 10, 10, 80, 80, parent, (HMENU)ID_LISTBOX, 0, NULL);
15009 listbox_orig_proc = (WNDPROC)SetWindowLongPtrA(listbox, GWLP_WNDPROC, (ULONG_PTR)listbox_hook_proc);
15010
15011 check_lb_state(listbox, 0, LB_ERR, 0, 0);
15012
15014
15016
15017 ret = SendMessageA(listbox, LB_ADDSTRING, 0, (LPARAM)"item 0");
15018 ok(ret == 0, "expected 0, got %ld\n", ret);
15019 ret = SendMessageA(listbox, LB_ADDSTRING, 0, (LPARAM)"item 1");
15020 ok(ret == 1, "expected 1, got %ld\n", ret);
15021 ret = SendMessageA(listbox, LB_ADDSTRING, 0, (LPARAM)"item 2");
15022 ok(ret == 2, "expected 2, got %ld\n", ret);
15023
15025 check_lb_state(listbox, 3, LB_ERR, 0, 0);
15026
15028
15029 DestroyWindow(listbox);
15030
15031 /* with LBS_HASSTRINGS */
15032 listbox = CreateWindowExA(WS_EX_NOPARENTNOTIFY, "ListBox", NULL,
15034 10, 10, 80, 80, parent, (HMENU)ID_LISTBOX, 0, NULL);
15035 listbox_orig_proc = (WNDPROC)SetWindowLongPtrA(listbox, GWLP_WNDPROC, (ULONG_PTR)listbox_hook_proc);
15036
15037 check_lb_state(listbox, 0, LB_ERR, 0, 0);
15038
15040
15042
15043 ret = SendMessageA(listbox, LB_ADDSTRING, 0, (LPARAM)"item 2");
15044 ok(ret == 0, "expected 0, got %ld\n", ret);
15045 ret = SendMessageA(listbox, LB_ADDSTRING, 0, (LPARAM)"item 0");
15046 ok(ret == 1, "expected 1, got %ld\n", ret);
15047 ret = SendMessageA(listbox, LB_ADDSTRING, 0, (LPARAM)"item 1");
15048 ok(ret == 2, "expected 2, got %ld\n", ret);
15049
15050 ok_sequence(wm_lb_addstring, "LB_ADDSTRING", FALSE);
15051 check_lb_state(listbox, 3, LB_ERR, 0, 0);
15052
15054
15055 DestroyWindow(listbox);
15056
15057 /* with LBS_HASSTRINGS and LBS_SORT */
15058 listbox = CreateWindowExA(WS_EX_NOPARENTNOTIFY, "ListBox", NULL,
15060 10, 10, 80, 80, parent, (HMENU)ID_LISTBOX, 0, NULL);
15061 listbox_orig_proc = (WNDPROC)SetWindowLongPtrA(listbox, GWLP_WNDPROC, (ULONG_PTR)listbox_hook_proc);
15062
15063 check_lb_state(listbox, 0, LB_ERR, 0, 0);
15064
15066
15068
15069 ret = SendMessageA(listbox, LB_ADDSTRING, 0, (LPARAM)"item 2");
15070 ok(ret == 0, "expected 0, got %ld\n", ret);
15071 ret = SendMessageA(listbox, LB_ADDSTRING, 0, (LPARAM)"item 0");
15072 ok(ret == 0, "expected 0, got %ld\n", ret);
15073 ret = SendMessageA(listbox, LB_ADDSTRING, 0, (LPARAM)"item 1");
15074 ok(ret == 1, "expected 1, got %ld\n", ret);
15075
15076 ok_sequence(wm_lb_addstring, "LB_ADDSTRING", FALSE);
15077 check_lb_state(listbox, 3, LB_ERR, 0, 0);
15078
15080
15081 DestroyWindow(listbox);
15083}
15084
15085/*************************** Menu test ******************************/
15086static const struct message wm_popup_menu_1[] =
15087{
15089 { WM_SYSKEYDOWN, sent|wparam|lparam, VK_MENU, 0x20000001 },
15090 { HCBT_KEYSKIPPED, hook|wparam|lparam|optional, 'E', 0x20000001 },
15091 { WM_SYSKEYDOWN, sent|wparam|lparam, 'E', 0x20000001 },
15092 { WM_SYSCHAR, sent|wparam|lparam, 'e', 0x20000001 },
15095 { WM_INITMENU, sent|lparam, 0, 0 },
15097 { WM_INITMENUPOPUP, sent|lparam, 0, 1 },
15098 { HCBT_CREATEWND, hook|optional }, /* Win9x doesn't create a window */
15100 { HCBT_KEYSKIPPED, hook|wparam|lparam|optional, 'E', 0xf0000001 },
15102 { HCBT_KEYSKIPPED, hook|wparam|lparam|optional, VK_RETURN, 0x10000001, 0, 0x40000000 },
15103 { HCBT_DESTROYWND, hook|optional }, /* Win9x doesn't create a window */
15104 { WM_UNINITMENUPOPUP, sent|lparam, 0, 0 },
15105 { WM_MENUSELECT, sent|wparam|lparam, MAKEWPARAM(0,0xffff), 0 },
15106 { WM_EXITMENULOOP, sent|wparam|lparam, 0, 0 },
15107 { WM_MENUCOMMAND, sent }, /* |wparam, 200 - Win9x */
15109 { WM_KEYUP, sent|wparam|lparam, VK_RETURN, 0xc0000001 },
15110 { 0 }
15111};
15112static const struct message wm_popup_menu_2[] =
15113{
15115 { WM_SYSKEYDOWN, sent|wparam|lparam, VK_MENU, 0x20000001 },
15116 { HCBT_KEYSKIPPED, hook|wparam|lparam|optional, 'F', 0x20000001 },
15117 { WM_SYSKEYDOWN, sent|wparam|lparam, 'F', 0x20000001 },
15118 { WM_SYSCHAR, sent|wparam|lparam, 'f', 0x20000001 },
15121 { WM_INITMENU, sent|lparam, 0, 0 },
15123 { WM_INITMENUPOPUP, sent|lparam, 0, 0 },
15125 { WM_INITMENUPOPUP, sent|lparam|optional, 0, 0 }, /* Win9x */
15126 { HCBT_CREATEWND, hook },
15127 { WM_MENUSELECT, sent }, /*|wparam, MAKEWPARAM(0,MF_HILITE|MF_POPUP) - XP
15128 |wparam, MAKEWPARAM(100,MF_HILITE) - Win9x */
15129 { HCBT_KEYSKIPPED, hook|wparam|lparam|optional, 'F', 0xf0000001 },
15132 { WM_INITMENUPOPUP, sent|lparam|optional, 0, 0 }, /* Win9x doesn't send it */
15133 { HCBT_CREATEWND, hook|optional }, /* Win9x doesn't send it */
15137 { HCBT_DESTROYWND, hook },
15138 { WM_UNINITMENUPOPUP, sent|lparam, 0, 0 },
15139 { HCBT_DESTROYWND, hook|optional }, /* Win9x doesn't send it */
15140 { WM_UNINITMENUPOPUP, sent|lparam, 0, 0 },
15141 { WM_MENUSELECT, sent|wparam|lparam, MAKEWPARAM(0,0xffff), 0 },
15142 { WM_EXITMENULOOP, sent|wparam|lparam, 0, 0 },
15143 { WM_MENUCOMMAND, sent }, /* |wparam, 100 - Win9x */
15145 { WM_KEYUP, sent|wparam|lparam, VK_RETURN, 0xc0000001 },
15146 { 0 }
15147};
15148static const struct message wm_popup_menu_3[] =
15149{
15151 { WM_SYSKEYDOWN, sent|wparam|lparam, VK_MENU, 0x20000001 },
15152 { HCBT_KEYSKIPPED, hook|wparam|lparam|optional, 'F', 0x20000001 },
15153 { WM_SYSKEYDOWN, sent|wparam|lparam, 'F', 0x20000001 },
15154 { WM_SYSCHAR, sent|wparam|lparam, 'f', 0x20000001 },
15157 { WM_INITMENU, sent|lparam, 0, 0 },
15159 { WM_INITMENUPOPUP, sent|lparam, 0, 0 },
15161 { WM_INITMENUPOPUP, sent|lparam|optional, 0, 0 }, /* Win9x */
15162 { HCBT_CREATEWND, hook },
15163 { WM_MENUSELECT, sent }, /*|wparam, MAKEWPARAM(0,MF_HILITE|MF_POPUP) - XP
15164 |wparam, MAKEWPARAM(100,MF_HILITE) - Win9x */
15165 { HCBT_KEYSKIPPED, hook|wparam|lparam|optional, 'F', 0xf0000001 },
15168 { WM_INITMENUPOPUP, sent|lparam|optional, 0, 0 }, /* Win9x doesn't send it */
15169 { HCBT_CREATEWND, hook|optional }, /* Win9x doesn't send it */
15173 { HCBT_DESTROYWND, hook },
15174 { WM_UNINITMENUPOPUP, sent|lparam, 0, 0 },
15175 { HCBT_DESTROYWND, hook|optional }, /* Win9x doesn't send it */
15176 { WM_UNINITMENUPOPUP, sent|lparam, 0, 0 },
15177 { WM_MENUSELECT, sent|wparam|lparam, MAKEWPARAM(0,0xffff), 0 },
15178 { WM_EXITMENULOOP, sent|wparam|lparam, 0, 0 },
15179 { WM_COMMAND, sent|wparam|lparam, 100, 0 },
15181 { WM_KEYUP, sent|wparam|lparam, VK_RETURN, 0xc0000001 },
15182 { 0 }
15183};
15184
15185static const struct message wm_single_menu_item[] =
15186{
15188 { WM_SYSKEYDOWN, sent|wparam|lparam, VK_MENU, 0x20000001 },
15189 { HCBT_KEYSKIPPED, hook|wparam|lparam|optional, 'Q', 0x20000001 },
15190 { WM_SYSKEYDOWN, sent|wparam|lparam, 'Q', 0x20000001 },
15191 { WM_SYSCHAR, sent|wparam|lparam, 'q', 0x20000001 },
15194 { WM_INITMENU, sent|lparam, 0, 0 },
15196 { WM_MENUSELECT, sent|wparam|lparam, MAKEWPARAM(0,0xffff), 0 },
15197 { WM_EXITMENULOOP, sent|wparam|lparam, 0, 0 },
15198 { WM_MENUCOMMAND, sent },
15199 { HCBT_KEYSKIPPED, hook|wparam|lparam|optional, 'Q', 0xe0000001 },
15200 { WM_SYSKEYUP, sent|wparam|lparam, 'Q', 0xe0000001 },
15202 { WM_KEYUP, sent|wparam|lparam, VK_MENU, 0xc0000001 },
15203
15206 { WM_CHAR, sent|wparam|lparam, VK_ESCAPE, 0x00000001 },
15208 { WM_KEYUP, sent|wparam|lparam, VK_ESCAPE, 0xc0000001 },
15209 { 0 }
15210};
15211
15213{
15214 if (message == WM_ENTERIDLE ||
15215 message == WM_INITMENU ||
15221 message == WM_UNINITMENUPOPUP ||
15222 message == WM_KEYDOWN ||
15223 message == WM_KEYUP ||
15224 message == WM_CHAR ||
15226 message == WM_SYSKEYUP ||
15227 message == WM_SYSCHAR ||
15228 message == WM_COMMAND ||
15229 message == WM_MENUCOMMAND)
15230 {
15231 struct recvd_message msg;
15232
15233 msg.hwnd = hwnd;
15234 msg.message = message;
15235 msg.flags = sent|wparam|lparam;
15236 msg.wParam = wp;
15237 msg.lParam = lp;
15238 msg.descr = "parent_menu_proc";
15239 add_message(&msg);
15240 }
15241
15242 return DefWindowProcA(hwnd, message, wp, lp);
15243}
15244
15246{
15247 MENUINFO mi;
15248 BOOL ret;
15249
15250 mi.cbSize = sizeof(mi);
15251 mi.fMask = MIM_STYLE;
15252 mi.dwStyle = style;
15253 SetLastError(0xdeadbeef);
15254 ret = pSetMenuInfo(hmenu, &mi);
15255 ok(ret, "SetMenuInfo error %u\n", GetLastError());
15256}
15257
15259{
15260 MENUINFO mi;
15261 BOOL ret;
15262
15263 mi.cbSize = sizeof(mi);
15264 mi.fMask = MIM_STYLE;
15265 mi.dwStyle = 0;
15266 SetLastError(0xdeadbeef);
15267 ret = pGetMenuInfo(hmenu, &mi);
15268 ok(ret, "GetMenuInfo error %u\n", GetLastError());
15269
15270 return mi.dwStyle;
15271}
15272
15273static void test_menu_messages(void)
15274{
15275 MSG msg;
15276 WNDCLASSA cls;
15277 HMENU hmenu, hmenu_popup;
15278 HWND hwnd;
15279 DWORD style;
15280
15281 if (!pGetMenuInfo || !pSetMenuInfo)
15282 {
15283 win_skip("GetMenuInfo and/or SetMenuInfo are not available\n");
15284 return;
15285 }
15286 cls.style = 0;
15288 cls.cbClsExtra = 0;
15289 cls.cbWndExtra = 0;
15290 cls.hInstance = GetModuleHandleA(0);
15291 cls.hIcon = 0;
15294 cls.lpszMenuName = NULL;
15295 cls.lpszClassName = "TestMenuClass";
15297 if (!RegisterClassA(&cls)) assert(0);
15298
15299 SetLastError(0xdeadbeef);
15300 hwnd = CreateWindowExA(0, "TestMenuClass", NULL, WS_OVERLAPPEDWINDOW | WS_VISIBLE,
15301 100, 100, 200, 200, 0, 0, 0, NULL);
15302 ok(hwnd != 0, "LoadMenuA error %u\n", GetLastError());
15303
15304 SetLastError(0xdeadbeef);
15306 ok(hmenu != 0, "LoadMenuA error %u\n", GetLastError());
15307
15308 SetMenu(hwnd, hmenu);
15310 flush_events();
15311
15314 ok(style == MNS_NOTIFYBYPOS, "expected MNS_NOTIFYBYPOS, got %u\n", style);
15315
15316 hmenu_popup = GetSubMenu(hmenu, 0);
15317 ok(hmenu_popup != 0, "GetSubMenu returned 0 for submenu 0\n");
15318 style = get_menu_style(hmenu_popup);
15319 ok(style == 0, "expected 0, got %u\n", style);
15320
15321 hmenu_popup = GetSubMenu(hmenu_popup, 0);
15322 ok(hmenu_popup != 0, "GetSubMenu returned 0 for submenu 0\n");
15323 style = get_menu_style(hmenu_popup);
15324 ok(style == 0, "expected 0, got %u\n", style);
15325
15326 /* Alt+E, Enter */
15327 trace("testing a popup menu command\n");
15329 keybd_event(VK_MENU, 0, 0, 0);
15330 keybd_event('E', 0, 0, 0);
15331 keybd_event('E', 0, KEYEVENTF_KEYUP, 0);
15333 keybd_event(VK_RETURN, 0, 0, 0);
15335 while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE))
15336 {
15339 }
15340 if (!sequence_cnt) /* we didn't get any message */
15341 {
15342 skip( "queuing key events not supported\n" );
15343 goto done;
15344 }
15345 /* win98 queues only a WM_KEYUP and doesn't start menu tracking */
15346 if (sequence[0].message == WM_KEYUP && sequence[0].wParam == VK_MENU)
15347 {
15348 win_skip( "menu tracking through VK_MENU not supported\n" );
15349 goto done;
15350 }
15351 ok_sequence(wm_popup_menu_1, "popup menu command", FALSE);
15352
15353 /* Alt+F, Right, Enter */
15354 trace("testing submenu of a popup menu command\n");
15356 keybd_event(VK_MENU, 0, 0, 0);
15357 keybd_event('F', 0, 0, 0);
15358 keybd_event('F', 0, KEYEVENTF_KEYUP, 0);
15360 keybd_event(VK_RIGHT, 0, 0, 0);
15362 keybd_event(VK_RETURN, 0, 0, 0);
15364 while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE))
15365 {
15368 }
15369 ok_sequence(wm_popup_menu_2, "submenu of a popup menu command", FALSE);
15370
15371 trace("testing single menu item command\n");
15373 keybd_event(VK_MENU, 0, 0, 0);
15374 keybd_event('Q', 0, 0, 0);
15375 keybd_event('Q', 0, KEYEVENTF_KEYUP, 0);
15377 keybd_event(VK_ESCAPE, 0, 0, 0);
15379 while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE))
15380 {
15383 }
15384 ok_sequence(wm_single_menu_item, "single menu item command", FALSE);
15385
15388 ok(style == 0, "expected 0, got %u\n", style);
15389
15390 hmenu_popup = GetSubMenu(hmenu, 0);
15391 ok(hmenu_popup != 0, "GetSubMenu returned 0 for submenu 0\n");
15392 set_menu_style(hmenu_popup, MNS_NOTIFYBYPOS);
15393 style = get_menu_style(hmenu_popup);
15394 ok(style == MNS_NOTIFYBYPOS, "expected MNS_NOTIFYBYPOS, got %u\n", style);
15395
15396 hmenu_popup = GetSubMenu(hmenu_popup, 0);
15397 ok(hmenu_popup != 0, "GetSubMenu returned 0 for submenu 0\n");
15398 style = get_menu_style(hmenu_popup);
15399 ok(style == 0, "expected 0, got %u\n", style);
15400
15401 /* Alt+F, Right, Enter */
15402 trace("testing submenu of a popup menu command\n");
15404 keybd_event(VK_MENU, 0, 0, 0);
15405 keybd_event('F', 0, 0, 0);
15406 keybd_event('F', 0, KEYEVENTF_KEYUP, 0);
15408 keybd_event(VK_RIGHT, 0, 0, 0);
15410 keybd_event(VK_RETURN, 0, 0, 0);
15412 while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE))
15413 {
15416 }
15417 ok_sequence(wm_popup_menu_3, "submenu of a popup menu command", FALSE);
15418
15419done:
15422}
15423
15424
15425static void test_paintingloop(void)
15426{
15427 HWND hwnd;
15428
15430 hwnd = CreateWindowExA(0x0,"PaintLoopWindowClass",
15431 "PaintLoopWindowClass",WS_OVERLAPPEDWINDOW,
15432 100, 100, 100, 100, 0, 0, 0, NULL );
15433 ok(hwnd != 0, "PaintLoop window error %u\n", GetLastError());
15435 SetFocus(hwnd);
15436
15437 while (!paint_loop_done)
15438 {
15439 MSG msg;
15440 if (PeekMessageA(&msg, 0, 0, 0, 1))
15441 {
15444 }
15445 }
15447}
15448
15449static const struct message NCRBUTTONDOWNSeq[] =
15450{
15451 { EVENT_SYSTEM_CAPTURESTART, winevent_hook|wparam|lparam, 0, 0 },
15452 { EVENT_SYSTEM_CAPTUREEND, winevent_hook|wparam|lparam, 0, 0 },
15454 { WM_CONTEXTMENU, sent, /*hwnd*/0, -1 },
15455 { 0 }
15456};
15457
15458static const struct message NCXBUTTONUPSeq1[] =
15459{
15460 { WM_APPCOMMAND, sent|lparam, /*hwnd*/0, MAKELPARAM(0, FAPPCOMMAND_MOUSE | APPCOMMAND_BROWSER_BACKWARD) },
15461 { 0 }
15462};
15463
15464static const struct message NCXBUTTONUPSeq2[] =
15465{
15466 { WM_APPCOMMAND, sent|lparam, /*hwnd*/0, MAKELPARAM(0, FAPPCOMMAND_MOUSE | APPCOMMAND_BROWSER_FORWARD) },
15467 { 0 }
15468};
15469
15470/* DefWindowProcA(hwnd, WM_SYSCOMMAND, SC_RESTORE, 0) to minimized visible window */
15472{
15474 { HCBT_MINMAX, hook },
15475 { WM_QUERYOPEN, sent },
15487 { HCBT_ACTIVATE, hook },
15493 { HCBT_SETFOCUS, hook },
15495 { WM_NCPAINT, sent },
15497 { WM_ERASEBKGND, sent },
15499 { WM_MOVE, sent|defwinproc },
15500 { WM_SIZE, sent|defwinproc },
15506 { WM_PAINT, sent },
15507 { 0 }
15508};
15509
15510static struct message WmContextMenuSeq[] = {
15511 { WM_CONTEXTMENU, sent|wparam, 0 }, /* wparams set in the code */
15514 { 0 }
15515};
15516
15518{
15521};
15522
15524{
15525 struct rbuttonup_thread_data *data = arg;
15526 DWORD ret;
15527
15528 ret = WaitForSingleObject( data->wndproc_finished, 500 );
15529 todo_wine ok( ret == WAIT_OBJECT_0, "WaitForSingleObject returned %x\n", ret );
15530 if( ret == WAIT_OBJECT_0 ) return 0;
15531
15532 PostMessageA( data->hwnd, WM_RBUTTONUP, 0, 0 );
15533 return 0;
15534}
15535
15536static void test_defwinproc(void)
15537{
15538 HWND hwnd, child[3];
15539 MSG msg;
15540 BOOL gotwmquit = FALSE;
15541 POINT pos;
15542 RECT rect;
15543 INT x, y;
15544 LRESULT res;
15546 char buffA[64];
15547 HANDLE thread;
15548
15549 hwnd = CreateWindowExA(0, "TestWindowClass", "test_defwndproc",
15550 WS_VISIBLE | WS_CAPTION | WS_OVERLAPPEDWINDOW, 0,0,500,100,0,0,0, NULL);
15551 assert(hwnd);
15552 flush_events();
15553
15554 buffA[0] = 0;
15555 GetWindowTextA(hwnd, buffA, ARRAY_SIZE(buffA));
15556 ok(!strcmp(buffA, "test_defwndproc"), "unexpected window text, %s\n", buffA);
15557
15558 /* Zero high word of the lParam */
15559 res = DefWindowProcA(hwnd, WM_SETTEXT, 0, 0x1234);
15560 ok(res == 0, "WM_SETTEXT was expected to fail, %ld\n", res);
15561
15562 GetWindowTextA(hwnd, buffA, ARRAY_SIZE(buffA));
15563 ok(!strcmp(buffA, "test_defwndproc"), "unexpected window text, %s\n", buffA);
15564
15565 res = DefWindowProcW(hwnd, WM_SETTEXT, 0, 0x1234);
15566 ok(res == 0, "WM_SETTEXT was expected to fail, %ld\n", res);
15567
15568 GetWindowTextA(hwnd, buffA, ARRAY_SIZE(buffA));
15569 ok(!strcmp(buffA, "test_defwndproc"), "unexpected window text, %s\n", buffA);
15570
15572 flush_events();
15574
15576 flush_events();
15577 ok_sequence(WmRestoreMinimizedOverlappedSeq, "DefWindowProcA(SC_RESTORE):overlapped", TRUE);
15579
15580 child[0] = CreateWindowExA(0, "TestWindowClass", "1st child",
15581 WS_VISIBLE | WS_CHILD, 0,0,500,100, hwnd, 0, 0, NULL);
15582 child[1] = CreateWindowExA(0, "TestWindowClass", "2nd child",
15583 WS_VISIBLE | WS_CHILD, 0,0,500,100, child[0], 0, 0, NULL);
15584 child[2] = CreateWindowExA(0, "TestWindowClass", "3rd child",
15585 WS_VISIBLE | WS_CHILD, 0,0,500,100, child[1], 0, 0, NULL);
15586 flush_events();
15589 DefWindowProcA(child[2], WM_CONTEXTMENU, 0xcafe, 0);
15591 WmContextMenuSeq[0].wParam = (WPARAM)child[2];
15592 WmContextMenuSeq[1].wParam = (WPARAM)child[1];
15593 WmContextMenuSeq[2].wParam = (WPARAM)child[0];
15594 ok_sequence(WmContextMenuSeq, "DefWindowProcA(WM_CONTEXTMENU)", FALSE);
15595 DestroyWindow(child[0]);
15596
15597 GetCursorPos(&pos);
15599 x = (rect.left+rect.right) / 2;
15600 y = rect.top + GetSystemMetrics(SM_CYFRAME) + 1;
15601 SetCursorPos(x, y);
15602 flush_events();
15604 ok(res == HTCAPTION, "WM_NCHITTEST returned %ld\n", res);
15605
15606 mouse_event( MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0 );
15607 mouse_event( MOUSEEVENTF_LEFTUP, 0, 0, 0, 0 );
15608 flush_events();
15609
15611 mouse_event( MOUSEEVENTF_RIGHTUP, 0, 0, 0, 0 );
15612 /* workaround for missing support for clicking on window frame */
15613 data.hwnd = hwnd;
15614 data.wndproc_finished = CreateEventA( NULL, FALSE, FALSE, NULL );
15615 thread = CreateThread( NULL, 0, post_rbuttonup_msg, (void*)&data, 0, NULL );
15616
15618 ok_sequence(NCRBUTTONDOWNSeq, "WM_NCRBUTTONDOWN on caption", FALSE);
15619
15620 res = DefWindowProcA(hwnd, WM_NCXBUTTONUP, 0, MAKELPARAM(x, y));
15621 ok(!res, "WM_NCXBUTTONUP returned %ld\n", res);
15622 ok_sequence(WmEmptySeq, "WM_NCXBUTTONUP without button", FALSE);
15623
15624 res = DefWindowProcA(hwnd, WM_NCXBUTTONUP, MAKEWPARAM(0, XBUTTON1), MAKELPARAM(x, y));
15625 ok(!res, "WM_NCXBUTTONUP returned %ld\n", res);
15626 ok_sequence(NCXBUTTONUPSeq1, "WM_NCXBUTTONUP with XBUTTON1", FALSE);
15627
15628 res = DefWindowProcA(hwnd, WM_NCXBUTTONUP, MAKEWPARAM(0, XBUTTON2), MAKELPARAM(x, y));
15629 ok(!res, "WM_NCXBUTTONUP returned %ld\n", res);
15630 ok_sequence(NCXBUTTONUPSeq2, "WM_NCXBUTTONUP with XBUTTON2", FALSE);
15631
15632 res = DefWindowProcA(hwnd, WM_NCXBUTTONUP, MAKEWPARAM(0, 3), MAKELPARAM(x, y));
15633 ok(!res, "WM_NCXBUTTONUP returned %ld\n", res);
15634 ok_sequence(WmEmptySeq, "WM_NCXBUTTONUP with invalid button", FALSE);
15635
15636 SetEvent( data.wndproc_finished );
15637 WaitForSingleObject( thread, 1000 );
15638 CloseHandle( data.wndproc_finished );
15640
15641 SetCursorPos(pos.x, pos.y);
15642
15644 while (PeekMessageA( &msg, 0, 0, 0, PM_REMOVE )) {
15645 if( msg.message == WM_QUIT) gotwmquit = TRUE;
15647 }
15648 ok(!gotwmquit, "Unexpected WM_QUIT message!\n");
15650}
15651
15652static void test_desktop_winproc(void)
15653{
15655 RECT rect, default_rect;
15656 WNDPROC desktop_proc;
15657 char buffer[256];
15658 WNDCLASSA cls;
15659 LRESULT res;
15660 HWND hwnd;
15661 BOOL ret;
15662
15663 ret = GetClassInfoA(instance, (const CHAR *)MAKEINTATOM(32769), &cls);
15664 ok(ret, "Failed to get desktop class.\n");
15665 desktop_proc = cls.lpfnWndProc;
15666
15667 memset(&cls, 0, sizeof(cls));
15668 cls.lpfnWndProc = desktop_proc;
15669 cls.hInstance = instance;
15672 cls.lpszClassName = "TestDesktopClass";
15673 ret = !!RegisterClassA(&cls);
15674 ok(ret, "Failed to register class.\n");
15675
15676 hwnd = CreateWindowExA(0, cls.lpszClassName, "test_desktop_wndproc",
15677 WS_VISIBLE | WS_CAPTION | WS_OVERLAPPEDWINDOW, 0, 0, 500, 100, 0, 0, 0, NULL);
15678 if (!hwnd) /* win2003 */
15679 {
15680 skip("Failed to create window with desktop window procedure.\n");
15681 goto out_unregister;
15682 }
15683
15684 memset(&cls, 0, sizeof(cls));
15685 ret = GetClassInfoA(instance, "TestDesktopClass", &cls);
15686 ok(ret, "Failed to get class info.\n");
15687 ok(cls.lpfnWndProc == desktop_proc, "Got %p, expected %p.\n", cls.lpfnWndProc, desktop_proc);
15688
15690 todo_wine ok(!strcmp(buffer, "test_desktop_wndproc"), "Got unexpected window text: %s.\n", buffer);
15691
15692 res = CallWindowProcA(desktop_proc, hwnd, WM_SETTEXT, 0, (LPARAM)"test");
15693 ok(res == TRUE, "Failed to set text, %ld.\n", res);
15695 ok(!strcmp(buffer, "test"), "Got unexpected window text: %s.\n", buffer);
15696
15697 SetRect(&default_rect, 0, 0, 100, 100);
15698 res = DefWindowProcW(hwnd, WM_NCCALCSIZE, FALSE, (LPARAM)&default_rect);
15699 ok(!res, "Got unexpected result %ld.\n", res);
15700
15701 SetRect(&rect, 0, 0, 100, 100);
15702 res = CallWindowProcA(desktop_proc, hwnd, WM_NCCALCSIZE, FALSE, (LPARAM)&rect);
15703 ok(!res, "Got unexpected result %ld.\n", res);
15704 todo_wine ok(EqualRect(&rect, &default_rect), "rect Got %s, expected %s.\n",
15705 wine_dbgstr_rect(&rect), wine_dbgstr_rect(&default_rect));
15706
15708
15709out_unregister:
15710 UnregisterClassA("TestDesktopClass", instance);
15711}
15712
15713#define clear_clipboard(hwnd) clear_clipboard_(__LINE__, (hwnd))
15715{
15716 BOOL succ;
15717 succ = OpenClipboard(hWnd);
15718 ok_(__FILE__, line)(succ, "OpenClipboard failed, err=%u\n", GetLastError());
15719 succ = EmptyClipboard();
15720 ok_(__FILE__, line)(succ, "EmptyClipboard failed, err=%u\n", GetLastError());
15721 succ = CloseClipboard();
15722 ok_(__FILE__, line)(succ, "CloseClipboard failed, err=%u\n", GetLastError());
15723}
15724
15725#define expect_HWND(expected, got) expect_HWND_(__LINE__, (expected), (got))
15726static void expect_HWND_(int line, HWND expected, HWND got)
15727{
15728 ok_(__FILE__, line)(got==expected, "Expected %p, got %p\n", expected, got);
15729}
15730
15732
15734{
15735 static BOOL recursion_guard;
15736
15737 if (message == WM_DRAWCLIPBOARD && !recursion_guard)
15738 {
15739 recursion_guard = TRUE;
15741 recursion_guard = FALSE;
15742 }
15744}
15745
15746static void test_clipboard_viewers(void)
15747{
15748 static struct message wm_change_cb_chain[] =
15749 {
15751 { 0 }
15752 };
15753 static const struct message wm_clipboard_destroyed[] =
15754 {
15756 { 0 }
15757 };
15758 static struct message wm_clipboard_changed[] =
15759 {
15761 { 0 }
15762 };
15763 static struct message wm_clipboard_changed_and_owned[] =
15764 {
15767 { 0 }
15768 };
15769
15772 HWND hOrigViewer;
15773 HWND hRet;
15774
15775 hWnd1 = CreateWindowExA(0, "TestWindowClass", "Clipboard viewer test wnd 1",
15779 hWnd2 = CreateWindowExA(0, "SimpleWindowClass", "Clipboard viewer test wnd 2",
15783 hWnd3 = CreateWindowExA(0, "SimpleWindowClass", "Clipboard viewer test wnd 3",
15787 trace("clipbd viewers: hWnd1=%p, hWnd2=%p, hWnd3=%p\n", hWnd1, hWnd2, hWnd3);
15788 assert(hWnd1 && hWnd2 && hWnd3);
15789
15790 CountClipboardFormats(); /* Ensure that we do not have an X11 update to the clipboard */
15792
15793 /* Test getting the clipboard viewer and setting the viewer to NULL. */
15794 hOrigViewer = GetClipboardViewer();
15795 hRet = SetClipboardViewer(NULL);
15796 ok_sequence(WmEmptySeq, "set viewer to NULL", FALSE);
15797 expect_HWND(hOrigViewer, hRet);
15799
15800 /* Test registering hWnd1 as a viewer. */
15801 hRet = SetClipboardViewer(hWnd1);
15802 wm_clipboard_changed[0].wParam = (WPARAM) GetClipboardOwner();
15803 ok_sequence(wm_clipboard_changed, "set viewer NULL->1", FALSE);
15804 expect_HWND(NULL, hRet);
15806
15807 /* Test that changing the clipboard actually refreshes the registered viewer. */
15809 wm_clipboard_changed[0].wParam = (WPARAM) GetClipboardOwner();
15810 ok_sequence(wm_clipboard_changed, "clear clipbd (viewer=owner=1)", FALSE);
15811
15812 /* Again, but with different owner. */
15814 wm_clipboard_changed_and_owned[1].wParam = (WPARAM) GetClipboardOwner();
15815 ok_sequence(wm_clipboard_changed_and_owned, "clear clipbd (viewer=1, owner=2)", FALSE);
15816
15817 /* Test re-registering same window. */
15818 hRet = SetClipboardViewer(hWnd1);
15819 wm_clipboard_changed[0].wParam = (WPARAM) GetClipboardOwner();
15820 ok_sequence(wm_clipboard_changed, "set viewer 1->1", FALSE);
15821 expect_HWND(hWnd1, hRet);
15823
15824 /* Test ChangeClipboardChain. */
15826 wm_change_cb_chain[0].wParam = (WPARAM) hWnd2;
15827 wm_change_cb_chain[0].lParam = (LPARAM) hWnd3;
15828 ok_sequence(wm_change_cb_chain, "change chain (viewer=1, remove=2, next=3)", FALSE);
15830
15832 wm_change_cb_chain[0].wParam = (WPARAM) hWnd2;
15833 wm_change_cb_chain[0].lParam = 0;
15834 ok_sequence(wm_change_cb_chain, "change chain (viewer=1, remove=2, next=NULL)", FALSE);
15836
15838 ok_sequence(WmEmptySeq, "change chain (viewer=1, remove=NULL, next=2)", FALSE);
15840
15841 /* Actually change clipboard viewer with ChangeClipboardChain. */
15843 ok_sequence(WmEmptySeq, "change chain (viewer=remove=1, next=2)", FALSE);
15845
15846 /* Test that no refresh messages are sent when viewer has unregistered. */
15848 ok_sequence(WmEmptySeq, "clear clipd (viewer=2, owner=1)", FALSE);
15849
15850 /* Register hWnd1 again. */
15852 ok_sequence(WmEmptySeq, "change chain (viewer=remove=2, next=1)", FALSE);
15854
15855 /* Subclass hWnd1 so that when it receives a WM_DRAWCLIPBOARD message, it
15856 * changes the clipboard. When this happens, the system shouldn't send
15857 * another WM_DRAWCLIPBOARD (as this could cause an infinite loop).
15858 */
15861 /* The clipboard owner is changed in recursive_viewer_proc: */
15862 wm_clipboard_changed[0].wParam = (WPARAM) hWnd2;
15863 ok_sequence(wm_clipboard_changed, "recursive clear clipbd (viewer=1, owner=2)", TRUE);
15864
15865 /* Test unregistering. */
15867 ok_sequence(WmEmptySeq, "change chain (viewer=remove=1, next=NULL)", FALSE);
15869
15871 ok_sequence(wm_clipboard_destroyed, "clear clipbd (no viewer, owner=1)", FALSE);
15872
15876 SetClipboardViewer(hOrigViewer);
15877}
15878
15879static void test_PostMessage(void)
15880{
15881 static const struct
15882 {
15883 HWND hwnd;
15884 BOOL ret;
15885 } data[] =
15886 {
15887 { HWND_TOP /* 0 */, TRUE },
15888 { HWND_BROADCAST, TRUE },
15889 { HWND_BOTTOM, TRUE },
15890 { HWND_TOPMOST, TRUE },
15891 { HWND_NOTOPMOST, FALSE },
15892 { HWND_MESSAGE, FALSE },
15893 { (HWND)0xdeadbeef, FALSE }
15894 };
15895 int i;
15896 HWND hwnd;
15897 BOOL ret;
15898 MSG msg;
15899 static const WCHAR staticW[] = {'s','t','a','t','i','c',0};
15900
15901 SetLastError(0xdeadbeef);
15902 hwnd = CreateWindowExW(0, staticW, NULL, WS_POPUP, 0,0,0,0,0,0,0, NULL);
15904 {
15905 win_skip("Skipping some PostMessage tests on Win9x/WinMe\n");
15906 return;
15907 }
15908 assert(hwnd);
15909
15910 flush_events();
15911
15912 PostMessageA(hwnd, WM_USER+1, 0x1234, 0x5678);
15913 PostMessageA(0, WM_USER+2, 0x5678, 0x1234);
15914
15915 for (i = 0; i < ARRAY_SIZE(data); i++)
15916 {
15917 memset(&msg, 0xab, sizeof(msg));
15918 ret = PeekMessageA(&msg, data[i].hwnd, 0, 0, PM_NOREMOVE);
15919 ok(ret == data[i].ret, "%d: hwnd %p expected %d, got %d\n", i, data[i].hwnd, data[i].ret, ret);
15920 if (data[i].ret)
15921 {
15922 if (data[i].hwnd)
15923 ok(ret && msg.hwnd == 0 && msg.message == WM_USER+2 &&
15924 msg.wParam == 0x5678 && msg.lParam == 0x1234,
15925 "%d: got ret %d hwnd %p msg %04x wParam %08lx lParam %08lx instead of TRUE/0/WM_USER+2/0x5678/0x1234\n",
15926 i, ret, msg.hwnd, msg.message, msg.wParam, msg.lParam);
15927 else
15928 ok(ret && msg.hwnd == hwnd && msg.message == WM_USER+1 &&
15929 msg.wParam == 0x1234 && msg.lParam == 0x5678,
15930 "%d: got ret %d hwnd %p msg %04x wParam %08lx lParam %08lx instead of TRUE/%p/WM_USER+1/0x1234/0x5678\n",
15931 i, ret, msg.hwnd, msg.message, msg.wParam, msg.lParam, msg.hwnd);
15932 }
15933 }
15934
15936 flush_events();
15937}
15938
15941{
15943
15944 if (wParam == 0xbaadbeef)
15946 else
15948
15949 return CallWindowProcA(oldproc, hwnd, message, wParam, lParam);
15950}
15951
15952static void test_broadcast(void)
15953{
15954 static const UINT messages[] =
15955 {
15956 WM_USER-1,
15957 WM_USER,
15958 WM_USER+1,
15959 0xc000-1,
15960 0xc000, /* lowest possible atom returned by RegisterWindowMessage */
15961 0xffff,
15962 };
15963 WNDPROC oldproc;
15964 unsigned int i;
15965 HWND hwnd;
15966
15967 hwnd = CreateWindowExA(0, "static", NULL, WS_POPUP, 0, 0, 0, 0, 0, 0, 0, NULL);
15968 ok(hwnd != NULL, "got %p\n", hwnd);
15969
15972
15973 for (i = 0; i < ARRAY_SIZE(messages); i++)
15974 {
15975 BOOL ret;
15976 MSG msg;
15977
15978 flush_events();
15979 while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE))
15980 ;
15981
15982 /* post, broadcast */
15984 ok(ret, "%d: got %d, error %d\n", i, ret, GetLastError());
15985
15986 memset(&msg, 0xab, sizeof(msg));
15987 ret = PeekMessageA(&msg, 0, 0, 0, PM_REMOVE);
15988 if (messages[i] < WM_USER || messages[i] >= 0xc000)
15989 {
15990 ok(ret, "%d: message %04x, got %d, error %d\n", i, messages[i], ret, GetLastError());
15991 ok(msg.hwnd == hwnd, "%d: got %p\n", i, msg.hwnd);
15992 }
15993 else
15994 {
15995 ok(!ret, "%d: message %04x, got %d, error %d\n", i, messages[i], ret, GetLastError());
15996 }
15997
15998 /* post, topmost */
16000 ok(ret, "%d: got %d, error %d\n", i, ret, GetLastError());
16001
16002 memset(&msg, 0xab, sizeof(msg));
16003 ret = PeekMessageA(&msg, 0, 0, 0, PM_REMOVE);
16004 if (messages[i] < WM_USER || messages[i] >= 0xc000)
16005 {
16006 ok(ret, "%d: message %04x, got %d, error %d\n", i, messages[i], ret, GetLastError());
16007 ok(msg.hwnd == hwnd, "%d: got %p\n", i, msg.hwnd);
16008 }
16009 else
16010 {
16011 ok(!ret, "%d: got %d, error %d\n", i, ret, GetLastError());
16012 }
16013
16014 /* send, broadcast */
16015 g_broadcast_lparam = 0xdead;
16016 ret = SendMessageTimeoutA(HWND_BROADCAST, messages[i], 0xbaadbeef, 0, SMTO_NORMAL, 2000, NULL);
16017 if (!ret && GetLastError() == ERROR_TIMEOUT)
16018 win_skip("broadcasting test %d, timeout\n", i);
16019 else
16020 {
16021 if (messages[i] < WM_USER || messages[i] >= 0xc000)
16022 {
16023 ok(g_broadcast_lparam == 0xbaadbeef, "%d: message %04x, got %#lx, error %d\n", i, messages[i],
16025 }
16026 else
16027 {
16028 ok(g_broadcast_lparam == 0xdead, "%d: message %04x, got %#lx, error %d\n", i, messages[i],
16030 }
16031 }
16032
16033 /* send, topmost */
16034 g_broadcast_lparam = 0xdead;
16035 ret = SendMessageTimeoutA(HWND_TOPMOST, messages[i], 0xbaadbeef, 0, SMTO_NORMAL, 2000, NULL);
16036 if (!ret && GetLastError() == ERROR_TIMEOUT)
16037 win_skip("broadcasting test %d, timeout\n", i);
16038 else
16039 {
16040 if (messages[i] < WM_USER || messages[i] >= 0xc000)
16041 {
16042 ok(g_broadcast_lparam == 0xbaadbeef, "%d: message %04x, got %#lx, error %d\n", i, messages[i],
16044 }
16045 else
16046 {
16047 ok(g_broadcast_lparam == 0xdead, "%d: message %04x, got %#lx, error %d\n", i, messages[i],
16049 }
16050 }
16051 }
16052
16054}
16055
16056static const struct
16057{
16060} wait_idle_expect[] =
16061{
16062/* 0 */ { WAIT_TIMEOUT, WAIT_TIMEOUT, FALSE },
16063 { WAIT_TIMEOUT, 0, FALSE },
16064 { WAIT_TIMEOUT, 0, FALSE },
16067/* 5 */ { WAIT_TIMEOUT, 0, FALSE },
16068 { WAIT_TIMEOUT, 0, FALSE },
16070 { 0, 0, FALSE },
16071 { 0, 0, FALSE },
16072/* 10 */ { 0, 0, FALSE },
16073 { 0, 0, FALSE },
16074 { 0, WAIT_TIMEOUT, FALSE },
16075 { 0, 0, FALSE },
16076 { 0, 0, FALSE },
16077/* 15 */ { 0, 0, FALSE },
16078 { WAIT_TIMEOUT, 0, FALSE },
16079 { WAIT_TIMEOUT, 0, FALSE },
16080 { WAIT_TIMEOUT, 0, FALSE },
16081 { WAIT_TIMEOUT, 0, FALSE },
16082/* 20 */ { WAIT_TIMEOUT, 0, FALSE },
16084
16086{
16087 MSG msg;
16088
16089 PeekMessageA( &msg, 0, 0, 0, PM_NOREMOVE );
16090 Sleep( 200 );
16092 return 0;
16093}
16094
16095static void do_wait_idle_child( int arg )
16096{
16097 WNDCLASSA cls;
16098 MSG msg;
16099 HWND hwnd = 0;
16100 HANDLE thread;
16101 DWORD id;
16102 HANDLE start_event = OpenEventA( EVENT_ALL_ACCESS, FALSE, "test_WaitForInputIdle_start" );
16103 HANDLE end_event = OpenEventA( EVENT_ALL_ACCESS, FALSE, "test_WaitForInputIdle_end" );
16104
16105 memset( &cls, 0, sizeof(cls) );
16107 cls.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
16109 cls.lpszClassName = "TestClass";
16110 RegisterClassA( &cls );
16111
16112 PeekMessageA( &msg, 0, 0, 0, PM_NOREMOVE ); /* create the msg queue */
16113
16114 ok( start_event != 0, "failed to create start event, error %u\n", GetLastError() );
16115 ok( end_event != 0, "failed to create end event, error %u\n", GetLastError() );
16116
16117 switch (arg)
16118 {
16119 case 0:
16121 break;
16122 case 1:
16124 Sleep( 200 );
16125 PeekMessageA( &msg, 0, 0, 0, PM_REMOVE );
16126 break;
16127 case 2:
16129 Sleep( 200 );
16130 PeekMessageA( &msg, 0, 0, 0, PM_NOREMOVE );
16131 PostThreadMessageA( GetCurrentThreadId(), WM_COMMAND, 0x1234, 0xabcd );
16132 PeekMessageA( &msg, 0, 0, 0, PM_REMOVE );
16133 break;
16134 case 3:
16136 Sleep( 200 );
16138 break;
16139 case 4:
16141 Sleep( 200 );
16142 hwnd = CreateWindowExA(0, "TestClass", NULL, WS_POPUP|WS_VISIBLE, 0, 0, 10, 10, 0, 0, 0, NULL);
16143 while (PeekMessageA( &msg, 0, 0, 0, PM_REMOVE|PM_NOYIELD )) DispatchMessageA( &msg );
16144 break;
16145 case 5:
16147 Sleep( 200 );
16148 hwnd = CreateWindowExA(0, "TestClass", NULL, WS_POPUP|WS_VISIBLE, 0, 0, 10, 10, 0, 0, 0, NULL);
16149 while (PeekMessageA( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessageA( &msg );
16150 break;
16151 case 6:
16153 Sleep( 200 );
16154 hwnd = CreateWindowExA(0, "TestClass", NULL, WS_POPUP|WS_VISIBLE, 0, 0, 10, 10, 0, 0, 0, NULL);
16155 while (PeekMessageA( &msg, 0, 0, 0, PM_NOREMOVE ))
16156 {
16157 GetMessageA( &msg, 0, 0, 0 );
16159 }
16160 break;
16161 case 7:
16163 Sleep( 200 );
16164 hwnd = CreateWindowExA(0, "TestClass", NULL, WS_POPUP|WS_VISIBLE, 0, 0, 10, 10, 0, 0, 0, NULL);
16165 SetTimer( hwnd, 3, 1, NULL );
16166 Sleep( 200 );
16167 while (PeekMessageA( &msg, 0, 0, 0, PM_REMOVE|PM_NOYIELD )) DispatchMessageA( &msg );
16168 break;
16169 case 8:
16171 Sleep( 200 );
16172 PeekMessageA( &msg, 0, 0, 0, PM_NOREMOVE );
16174 break;
16175 case 9:
16177 Sleep( 200 );
16178 hwnd = CreateWindowExA(0, "TestClass", NULL, WS_POPUP|WS_VISIBLE, 0, 0, 10, 10, 0, 0, 0, NULL);
16179 while (PeekMessageA( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessageA( &msg );
16180 for (;;) GetMessageA( &msg, 0, 0, 0 );
16181 break;
16182 case 10:
16184 Sleep( 200 );
16185 hwnd = CreateWindowExA(0, "TestClass", NULL, WS_POPUP|WS_VISIBLE, 0, 0, 10, 10, 0, 0, 0, NULL);
16186 SetTimer( hwnd, 3, 1, NULL );
16187 Sleep( 200 );
16188 while (PeekMessageA( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessageA( &msg );
16189 break;
16190 case 11:
16192 Sleep( 200 );
16193 return; /* exiting the process makes WaitForInputIdle return success too */
16194 case 12:
16195 PeekMessageA( &msg, 0, 0, 0, PM_NOREMOVE );
16196 Sleep( 200 );
16199 break;
16200 case 13:
16202 PeekMessageA( &msg, 0, 0, 0, PM_NOREMOVE );
16203 Sleep( 200 );
16205 WaitForSingleObject( thread, 10000 );
16207 break;
16208 case 14:
16210 Sleep( 200 );
16212 break;
16213 case 15:
16215 Sleep( 200 );
16217 break;
16218 case 16:
16220 Sleep( 200 );
16222 break;
16223 case 17:
16225 Sleep( 200 );
16226 PeekMessageA( &msg, (HWND)0xdeadbeef, 0, 0, PM_NOREMOVE );
16227 break;
16228 case 18:
16230 Sleep( 200 );
16232 break;
16233 case 19:
16235 Sleep( 200 );
16237 break;
16238 case 20:
16240 Sleep( 200 );
16242 break;
16243 }
16244 WaitForSingleObject( end_event, 2000 );
16246 CloseHandle( end_event );
16247 if (hwnd) DestroyWindow( hwnd );
16248}
16249
16251{
16252 if (msg == WM_WININICHANGE) Sleep( 200 ); /* make sure the child waits */
16253 return DefWindowProcA( hwnd, msg, wp, lp );
16254}
16255
16257{
16258 WNDCLASSA cls;
16259 MSG msg;
16260 HWND hwnd;
16261
16262 memset( &cls, 0, sizeof(cls) );
16264 cls.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
16266 cls.lpszClassName = "TestClass";
16267 RegisterClassA( &cls );
16268
16269 hwnd = CreateWindowExA(0, "TestClass", NULL, WS_POPUP, 0, 0, 10, 10, 0, 0, 0, NULL);
16270 while (GetMessageA( &msg, 0, 0, 0 )) DispatchMessageA( &msg );
16272 return 0;
16273}
16274
16275static void test_WaitForInputIdle( char *argv0 )
16276{
16277 char path[MAX_PATH];
16280 BOOL ret;
16281 HANDLE start_event, end_event, thread;
16282 unsigned int i;
16283 DWORD id;
16285 const IMAGE_NT_HEADERS *nt = (const IMAGE_NT_HEADERS *)((const char *)dos + dos->e_lfanew);
16287
16288 if (console_app) /* build the test with -mwindows for better coverage */
16289 trace( "not built as a GUI app, WaitForInputIdle may not be fully tested\n" );
16290
16291 start_event = CreateEventA(NULL, 0, 0, "test_WaitForInputIdle_start");
16292 end_event = CreateEventA(NULL, 0, 0, "test_WaitForInputIdle_end");
16293 ok(start_event != 0, "failed to create start event, error %u\n", GetLastError());
16294 ok(end_event != 0, "failed to create end event, error %u\n", GetLastError());
16295
16296 memset( &startup, 0, sizeof(startup) );
16297 startup.cb = sizeof(startup);
16298 startup.dwFlags = STARTF_USESHOWWINDOW;
16299 startup.wShowWindow = SW_SHOWNORMAL;
16300
16301 thread = CreateThread( NULL, 0, wait_idle_thread, NULL, 0, &id );
16302
16303 for (i = 0; i < ARRAY_SIZE(wait_idle_expect); i++)
16304 {
16306 ResetEvent( end_event );
16307#ifdef __REACTOS__
16308 sprintf( path, "%s msg_queue %u", argv0, i );
16309#else
16310 sprintf( path, "%s msg %u", argv0, i );
16311#endif
16313 ok( ret, "CreateProcess '%s' failed err %u.\n", path, GetLastError() );
16314 if (ret)
16315 {
16317 ok( ret == WAIT_OBJECT_0, "%u: WaitForSingleObject failed\n", i );
16318 if (ret == WAIT_OBJECT_0)
16319 {
16320 ret = WaitForInputIdle( pi.hProcess, 1000 );
16321 if (ret == WAIT_FAILED)
16322 ok( console_app ||
16323 ret == wait_idle_expect[i].exp ||
16325 "%u: WaitForInputIdle error %08x expected %08x\n",
16326 i, ret, wait_idle_expect[i].exp );
16329 "%u: WaitForInputIdle error %08x expected %08x\n",
16330 i, ret, wait_idle_expect[i].exp );
16331 SetEvent( end_event );
16332 WaitForSingleObject( pi.hProcess, 1000 ); /* give it a chance to exit on its own */
16333 }
16334 TerminateProcess( pi.hProcess, 0 ); /* just in case */
16335 winetest_wait_child_process( pi.hProcess );
16336 ret = WaitForInputIdle( pi.hProcess, 100 );
16337 ok( ret == WAIT_FAILED, "%u: WaitForInputIdle after exit error %08x\n", i, ret );
16338 CloseHandle( pi.hProcess );
16339 CloseHandle( pi.hThread );
16340 }
16341 }
16343 PostThreadMessageA( id, WM_QUIT, 0, 0 );
16344 WaitForSingleObject( thread, 10000 );
16346}
16347
16348static const struct message WmSetParentSeq_1[] = {
16349 { WM_SHOWWINDOW, sent|wparam, 0 },
16350 { EVENT_OBJECT_PARENTCHANGE, winevent_hook|wparam|lparam, 0, 0 },
16354 { WM_MOVE, sent|defwinproc|wparam, 0 },
16355 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 },
16356 { WM_SHOWWINDOW, sent|wparam, 1 },
16357 { 0 }
16358};
16359
16360static const struct message WmSetParentSeq_2[] = {
16361 { WM_SHOWWINDOW, sent|wparam, 0 },
16363 { EVENT_OBJECT_HIDE, winevent_hook|wparam|lparam, 0, 0 },
16369 { WM_KILLFOCUS, sent|wparam, 0 },
16370 { EVENT_OBJECT_PARENTCHANGE, winevent_hook|wparam|lparam, 0, 0 },
16373 { EVENT_SYSTEM_FOREGROUND, winevent_hook|wparam|lparam, 0, 0 },
16378 { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
16381 { WM_MOVE, sent|defwinproc|wparam, 0 },
16382 { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 },
16383 { WM_SHOWWINDOW, sent|wparam, 1 },
16385 { EVENT_OBJECT_SHOW, winevent_hook|wparam|lparam, 0, 0 },
16387 { 0 }
16388};
16389
16390
16391static void test_SetParent(void)
16392{
16393 HWND parent1, parent2, child, popup;
16394 RECT rc, rc_old;
16395
16396 parent1 = CreateWindowExA(0, "TestParentClass", NULL, WS_OVERLAPPEDWINDOW,
16397 100, 100, 200, 200, 0, 0, 0, NULL);
16398 ok(parent1 != 0, "Failed to create parent1 window\n");
16399
16400 parent2 = CreateWindowExA(0, "TestParentClass", NULL, WS_OVERLAPPEDWINDOW,
16401 400, 100, 200, 200, 0, 0, 0, NULL);
16402 ok(parent2 != 0, "Failed to create parent2 window\n");
16403
16404 /* WS_CHILD window */
16405 child = CreateWindowExA(0, "TestWindowClass", NULL, WS_CHILD | WS_VISIBLE,
16406 10, 10, 150, 150, parent1, 0, 0, NULL);
16407 ok(child != 0, "Failed to create child window\n");
16408
16409 GetWindowRect(parent1, &rc);
16410 trace("parent1 %s\n", wine_dbgstr_rect(&rc));
16411 GetWindowRect(child, &rc_old);
16412 MapWindowPoints(0, parent1, (POINT *)&rc_old, 2);
16413 trace("child %s\n", wine_dbgstr_rect(&rc_old));
16414
16416
16417 SetParent(child, parent2);
16418 flush_events();
16419 ok_sequence(WmSetParentSeq_1, "SetParent() visible WS_CHILD", FALSE);
16420
16421 ok(GetWindowLongA(child, GWL_STYLE) & WS_VISIBLE, "WS_VISIBLE should be set\n");
16422 ok(!IsWindowVisible(child), "IsWindowVisible() should return FALSE\n");
16423
16424 GetWindowRect(parent2, &rc);
16425 trace("parent2 %s\n", wine_dbgstr_rect(&rc));
16426 GetWindowRect(child, &rc);
16427 MapWindowPoints(0, parent2, (POINT *)&rc, 2);
16428 trace("child %s\n", wine_dbgstr_rect(&rc));
16429
16430 ok(EqualRect(&rc_old, &rc), "rects do not match %s / %s\n", wine_dbgstr_rect(&rc_old),
16431 wine_dbgstr_rect(&rc));
16432
16433 /* WS_POPUP window */
16434 popup = CreateWindowExA(0, "TestWindowClass", NULL, WS_POPUP | WS_VISIBLE,
16435 20, 20, 100, 100, 0, 0, 0, NULL);
16436 ok(popup != 0, "Failed to create popup window\n");
16437
16438 GetWindowRect(popup, &rc_old);
16439 trace("popup %s\n", wine_dbgstr_rect(&rc_old));
16440
16442
16443 SetParent(popup, child);
16444 flush_events();
16445 ok_sequence(WmSetParentSeq_2, "SetParent() visible WS_POPUP", TRUE);
16446
16447 ok(GetWindowLongA(popup, GWL_STYLE) & WS_VISIBLE, "WS_VISIBLE should be set\n");
16448 ok(!IsWindowVisible(popup), "IsWindowVisible() should return FALSE\n");
16449
16450 GetWindowRect(child, &rc);
16451 trace("parent2 %s\n", wine_dbgstr_rect(&rc));
16452 GetWindowRect(popup, &rc);
16453 MapWindowPoints(0, child, (POINT *)&rc, 2);
16454 trace("popup %s\n", wine_dbgstr_rect(&rc));
16455
16456 ok(EqualRect(&rc_old, &rc), "rects do not match %s / %s\n", wine_dbgstr_rect(&rc_old),
16457 wine_dbgstr_rect(&rc));
16458
16459 DestroyWindow(popup);
16461 DestroyWindow(parent1);
16462 DestroyWindow(parent2);
16463
16465}
16466
16467static const struct message WmKeyReleaseOnly[] = {
16468 { HCBT_KEYSKIPPED, hook|wparam|lparam|optional, 0x41, 0x80000001 },
16469 { WM_KEYUP, sent|wparam|lparam, 0x41, 0x80000001 },
16470 { 0 }
16471};
16472static const struct message WmKeyPressNormal[] = {
16473 { HCBT_KEYSKIPPED, hook|wparam|lparam|optional, 0x41, 0x1 },
16474 { WM_KEYDOWN, sent|wparam|lparam, 0x41, 0x1 },
16475 { 0 }
16476};
16477static const struct message WmKeyPressRepeat[] = {
16478 { HCBT_KEYSKIPPED, hook|wparam|lparam|optional, 0x41, 0x40000001 },
16479 { WM_KEYDOWN, sent|wparam|lparam, 0x41, 0x40000001 },
16480 { 0 }
16481};
16482static const struct message WmKeyReleaseNormal[] = {
16483 { HCBT_KEYSKIPPED, hook|wparam|lparam|optional, 0x41, 0xc0000001 },
16484 { WM_KEYUP, sent|wparam|lparam, 0x41, 0xc0000001 },
16485 { 0 }
16486};
16487
16488static void test_keyflags(void)
16489{
16491 SHORT key_state;
16492 BYTE keyboard_state[256];
16493 MSG msg;
16494
16496 100, 100, 200, 200, 0, 0, 0, NULL);
16497
16498 flush_events();
16500
16501 /* keyup without a keydown */
16502 keybd_event(0x41, 0, KEYEVENTF_KEYUP, 0);
16505 ok_sequence(WmKeyReleaseOnly, "key release only", TRUE);
16506
16507 key_state = GetAsyncKeyState(0x41);
16508 ok((key_state & 0x8000) == 0, "unexpected key state %x\n", key_state);
16509
16510 key_state = GetKeyState(0x41);
16511 ok((key_state & 0x8000) == 0, "unexpected key state %x\n", key_state);
16512
16513 /* keydown */
16514 keybd_event(0x41, 0, 0, 0);
16517 ok_sequence(WmKeyPressNormal, "key press only", FALSE);
16518
16519 key_state = GetAsyncKeyState(0x41);
16520 ok((key_state & 0x8000) == 0x8000, "unexpected key state %x\n", key_state);
16521
16522 key_state = GetKeyState(0x41);
16523 ok((key_state & 0x8000) == 0x8000, "unexpected key state %x\n", key_state);
16524
16525 /* keydown repeat */
16526 keybd_event(0x41, 0, 0, 0);
16529 ok_sequence(WmKeyPressRepeat, "key press repeat", FALSE);
16530
16531 key_state = GetAsyncKeyState(0x41);
16532 ok((key_state & 0x8000) == 0x8000, "unexpected key state %x\n", key_state);
16533
16534 key_state = GetKeyState(0x41);
16535 ok((key_state & 0x8000) == 0x8000, "unexpected key state %x\n", key_state);
16536
16537 /* keyup */
16538 keybd_event(0x41, 0, KEYEVENTF_KEYUP, 0);
16541 ok_sequence(WmKeyReleaseNormal, "key release repeat", FALSE);
16542
16543 key_state = GetAsyncKeyState(0x41);
16544 ok((key_state & 0x8000) == 0, "unexpected key state %x\n", key_state);
16545
16546 key_state = GetKeyState(0x41);
16547 ok((key_state & 0x8000) == 0, "unexpected key state %x\n", key_state);
16548
16549 /* set the key state in this thread */
16550 GetKeyboardState(keyboard_state);
16551 keyboard_state[0x41] = 0x80;
16552 SetKeyboardState(keyboard_state);
16553
16554 key_state = GetAsyncKeyState(0x41);
16555 ok((key_state & 0x8000) == 0, "unexpected key state %x\n", key_state);
16556
16557 /* keydown */
16558 keybd_event(0x41, 0, 0, 0);
16561 ok_sequence(WmKeyPressRepeat, "key press after setkeyboardstate", TRUE);
16562
16563 key_state = GetAsyncKeyState(0x41);
16564 ok((key_state & 0x8000) == 0x8000, "unexpected key state %x\n", key_state);
16565
16566 key_state = GetKeyState(0x41);
16567 ok((key_state & 0x8000) == 0x8000, "unexpected key state %x\n", key_state);
16568
16569 /* clear the key state in this thread */
16570 GetKeyboardState(keyboard_state);
16571 keyboard_state[0x41] = 0;
16572 SetKeyboardState(keyboard_state);
16573
16574 key_state = GetAsyncKeyState(0x41);
16575 ok((key_state & 0x8000) == 0x8000, "unexpected key state %x\n", key_state);
16576
16577 /* keyup */
16578 keybd_event(0x41, 0, KEYEVENTF_KEYUP, 0);
16581 ok_sequence(WmKeyReleaseOnly, "key release after setkeyboardstate", TRUE);
16582
16583 key_state = GetAsyncKeyState(0x41);
16584 ok((key_state & 0x8000) == 0, "unexpected key state %x\n", key_state);
16585
16586 key_state = GetKeyState(0x41);
16587 ok((key_state & 0x8000) == 0, "unexpected key state %x\n", key_state);
16588
16591}
16592
16593static const struct message WmHotkeyPressLWIN[] = {
16597 { 0 }
16598};
16599static const struct message WmHotkeyPress[] = {
16601 { WM_HOTKEY, sent|wparam, 5 },
16602 { 0 }
16603};
16604static const struct message WmHotkeyRelease[] = {
16606 { HCBT_KEYSKIPPED, hook|lparam|optional, 0, 0x80000001 },
16607 { WM_KEYUP, sent|lparam, 0, 0x80000001 },
16608 { 0 }
16609};
16610static const struct message WmHotkeyReleaseLWIN[] = {
16613 { WM_KEYUP, sent|wparam|lparam, VK_LWIN, 0xc0000001 },
16614 { 0 }
16615};
16616static const struct message WmHotkeyCombined[] = {
16621 { WM_APP, sent, 0, 0 },
16622 { WM_HOTKEY, sent|wparam, 5 },
16623 { WM_APP+1, sent, 0, 0 },
16626 { HCBT_KEYSKIPPED, hook|optional, 0, 0x80000001 },
16627 { WM_KEYUP, sent, 0, 0x80000001 }, /* lparam not checked so the sequence isn't a todo */
16629 { WM_KEYUP, sent|wparam|lparam, VK_LWIN, 0xc0000001 },
16630 { 0 }
16631};
16632static const struct message WmHotkeyPrevious[] = {
16640 { WM_KEYDOWN, sent|lparam, 0, 1 },
16641 { HCBT_KEYSKIPPED, hook|optional|lparam, 0, 0xc0000001 },
16642 { WM_KEYUP, sent|lparam, 0, 0xc0000001 },
16644 { WM_KEYUP, sent|wparam|lparam, VK_LWIN, 0xc0000001 },
16645 { 0 }
16646};
16647static const struct message WmHotkeyNew[] = {
16650 { WM_HOTKEY, sent|wparam, 5 },
16651 { HCBT_KEYSKIPPED, hook|optional, 0, 0x80000001 },
16652 { WM_KEYUP, sent, 0, 0x80000001 }, /* lparam not checked so the sequence isn't a todo */
16653 { 0 }
16654};
16655
16656static int hotkey_letter;
16657
16659{
16660 struct recvd_message msg;
16661
16662 if (nCode == HC_ACTION)
16663 {
16664 KBDLLHOOKSTRUCT *kdbhookstruct = (KBDLLHOOKSTRUCT*)lParam;
16665
16666 msg.hwnd = 0;
16667 msg.message = wParam;
16668 msg.flags = kbd_hook|wparam|lparam;
16669 msg.wParam = kdbhookstruct->vkCode;
16670 msg.lParam = kdbhookstruct->flags;
16671 msg.descr = "KeyboardHookProc";
16672 add_message(&msg);
16673
16674 if (wParam == WM_KEYUP || wParam == WM_KEYDOWN)
16675 {
16676 ok(kdbhookstruct->vkCode == VK_LWIN || kdbhookstruct->vkCode == hotkey_letter,
16677 "unexpected keycode %x\n", kdbhookstruct->vkCode);
16678 }
16679 }
16680
16681 return CallNextHookEx(hKBD_hook, nCode, wParam, lParam);
16682}
16683
16684static void test_hotkey(void)
16685{
16686 HWND test_window, taskbar_window;
16687 BOOL ret;
16688 MSG msg;
16689 DWORD queue_status;
16690 SHORT key_state;
16691
16692 SetLastError(0xdeadbeef);
16694 if (ret == TRUE)
16695 {
16696 skip("hotkeys not supported\n");
16697 return;
16698 }
16699
16700 ok(ret == FALSE, "expected FALSE, got %i\n", ret);
16702 "unexpected error %d\n", GetLastError());
16703
16704 test_window = CreateWindowExA(0, "HotkeyWindowClass", NULL, WS_OVERLAPPEDWINDOW | WS_VISIBLE,
16705 100, 100, 200, 200, 0, 0, 0, NULL);
16706
16708
16709 SetLastError(0xdeadbeef);
16711 ok(ret == FALSE, "expected FALSE, got %i\n", ret);
16713 "unexpected error %d\n", GetLastError());
16714
16715 /* Search for a Windows Key + letter combination that hasn't been registered */
16716 for (hotkey_letter = 0x41; hotkey_letter <= 0x51; hotkey_letter ++)
16717 {
16718 SetLastError(0xdeadbeef);
16720
16721 if (ret == TRUE)
16722 {
16723 break;
16724 }
16725 else
16726 {
16728 "unexpected error %d\n", GetLastError());
16729 }
16730 }
16731
16732 if (hotkey_letter == 0x52)
16733 {
16734 ok(0, "Couldn't find any free Windows Key + letter combination\n");
16735 goto end;
16736 }
16737
16739 if (!hKBD_hook) win_skip("WH_KEYBOARD_LL is not supported\n");
16740
16741 /* Same key combination, different id */
16742 SetLastError(0xdeadbeef);
16744 ok(ret == FALSE, "expected FALSE, got %i\n", ret);
16746 "unexpected error %d\n", GetLastError());
16747
16748 /* Same key combination, different window */
16749 SetLastError(0xdeadbeef);
16751 ok(ret == FALSE, "expected FALSE, got %i\n", ret);
16753 "unexpected error %d\n", GetLastError());
16754
16755 /* Register the same hotkey twice */
16756 SetLastError(0xdeadbeef);
16758 ok(ret == FALSE, "expected FALSE, got %i\n", ret);
16760 "unexpected error %d\n", GetLastError());
16761
16762 /* Window on another thread */
16763 taskbar_window = FindWindowA("Shell_TrayWnd", NULL);
16764 if (!taskbar_window)
16765 {
16766 skip("no taskbar?\n");
16767 }
16768 else
16769 {
16770 SetLastError(0xdeadbeef);
16771 ret = RegisterHotKey(taskbar_window, 5, 0, hotkey_letter);
16772 ok(ret == FALSE, "expected FALSE, got %i\n", ret);
16774 "unexpected error %d\n", GetLastError());
16775 }
16776
16777 /* Inject the appropriate key sequence */
16778 keybd_event(VK_LWIN, 0, 0, 0);
16779 while (PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE))
16781 ok_sequence(WmHotkeyPressLWIN, "window hotkey press LWIN", FALSE);
16782
16783 keybd_event(hotkey_letter, 0, 0, 0);
16784 queue_status = GetQueueStatus(QS_HOTKEY);
16785 ok((queue_status & (QS_HOTKEY << 16)) == QS_HOTKEY << 16, "expected QS_HOTKEY << 16 set, got %x\n", queue_status);
16786 while (PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE))
16787 {
16788 if (msg.message == WM_HOTKEY)
16789 {
16790 ok(msg.hwnd == test_window, "unexpected hwnd %p\n", msg.hwnd);
16791 ok(msg.lParam == MAKELPARAM(MOD_WIN, hotkey_letter), "unexpected WM_HOTKEY lparam %lx\n", msg.lParam);
16792 }
16794 }
16795 ok_sequence(WmHotkeyPress, "window hotkey press", FALSE);
16796
16797 queue_status = GetQueueStatus(QS_HOTKEY);
16798 ok((queue_status & (QS_HOTKEY << 16)) == 0, "expected QS_HOTKEY << 16 cleared, got %x\n", queue_status);
16799
16800 key_state = GetAsyncKeyState(hotkey_letter);
16801 ok((key_state & 0x8000) == 0x8000, "unexpected key state %x\n", key_state);
16802
16804 while (PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE))
16806 ok_sequence(WmHotkeyRelease, "window hotkey release", TRUE);
16807
16809 while (PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE))
16811 ok_sequence(WmHotkeyReleaseLWIN, "window hotkey release LWIN", FALSE);
16812
16813 /* normal posted WM_HOTKEY messages set QS_HOTKEY */
16815 queue_status = GetQueueStatus(QS_HOTKEY);
16816 ok((queue_status & (QS_HOTKEY << 16)) == QS_HOTKEY << 16, "expected QS_HOTKEY << 16 set, got %x\n", queue_status);
16817 queue_status = GetQueueStatus(QS_POSTMESSAGE);
16818 ok((queue_status & (QS_POSTMESSAGE << 16)) == QS_POSTMESSAGE << 16, "expected QS_POSTMESSAGE << 16 set, got %x\n", queue_status);
16819 while (PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE))
16822
16823 /* Send and process all messages at once */
16825 keybd_event(VK_LWIN, 0, 0, 0);
16826 keybd_event(hotkey_letter, 0, 0, 0);
16829
16830 while (PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE))
16831 {
16832 if (msg.message == WM_HOTKEY)
16833 {
16834 ok(msg.hwnd == test_window, "unexpected hwnd %p\n", msg.hwnd);
16835 ok(msg.lParam == MAKELPARAM(MOD_WIN, hotkey_letter), "unexpected WM_HOTKEY lparam %lx\n", msg.lParam);
16836 }
16838 }
16839 ok_sequence(WmHotkeyCombined, "window hotkey combined", FALSE);
16840
16841 /* Register same hwnd/id with different key combination */
16843 ok(ret == TRUE, "expected TRUE, got %i, err=%d\n", ret, GetLastError());
16844
16845 /* Previous key combination does not work */
16846 keybd_event(VK_LWIN, 0, 0, 0);
16847 keybd_event(hotkey_letter, 0, 0, 0);
16850
16851 while (PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE))
16853 ok_sequence(WmHotkeyPrevious, "window hotkey previous", FALSE);
16854
16855 /* New key combination works */
16856 keybd_event(hotkey_letter, 0, 0, 0);
16858
16859 while (PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE))
16860 {
16861 if (msg.message == WM_HOTKEY)
16862 {
16863 ok(msg.hwnd == test_window, "unexpected hwnd %p\n", msg.hwnd);
16864 ok(msg.lParam == MAKELPARAM(0, hotkey_letter), "unexpected WM_HOTKEY lparam %lx\n", msg.lParam);
16865 }
16867 }
16868 ok_sequence(WmHotkeyNew, "window hotkey new", FALSE);
16869
16870 /* Unregister hotkey properly */
16872 ok(ret == TRUE, "expected TRUE, got %i, err=%d\n", ret, GetLastError());
16873
16874 /* Unregister hotkey again */
16875 SetLastError(0xdeadbeef);
16877 ok(ret == FALSE, "expected FALSE, got %i\n", ret);
16879 "unexpected error %d\n", GetLastError());
16880
16881 /* Register thread hotkey */
16883 ok(ret == TRUE, "expected TRUE, got %i, err=%d\n", ret, GetLastError());
16884
16885 /* Inject the appropriate key sequence */
16886 keybd_event(VK_LWIN, 0, 0, 0);
16887 while (PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE))
16888 {
16889 ok(msg.hwnd != NULL, "unexpected thread message %x\n", msg.message);
16891 }
16892 ok_sequence(WmHotkeyPressLWIN, "thread hotkey press LWIN", FALSE);
16893
16894 keybd_event(hotkey_letter, 0, 0, 0);
16895 while (PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE))
16896 {
16897 if (msg.message == WM_HOTKEY)
16898 {
16899 struct recvd_message message;
16900 ok(msg.hwnd == NULL, "unexpected hwnd %p\n", msg.hwnd);
16901 ok(msg.lParam == MAKELPARAM(MOD_WIN, hotkey_letter), "unexpected WM_HOTKEY lparam %lx\n", msg.lParam);
16902 message.message = msg.message;
16904 message.wParam = msg.wParam;
16905 message.lParam = msg.lParam;
16906 message.descr = "test_hotkey thread message";
16908 }
16909 else
16910 ok(msg.hwnd != NULL, "unexpected thread message %x\n", msg.message);
16912 }
16913 ok_sequence(WmHotkeyPress, "thread hotkey press", FALSE);
16914
16916 while (PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE))
16917 {
16918 ok(msg.hwnd != NULL, "unexpected thread message %x\n", msg.message);
16920 }
16921 ok_sequence(WmHotkeyRelease, "thread hotkey release", TRUE);
16922
16924 while (PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE))
16925 {
16927 ok(msg.hwnd != NULL, "unexpected thread message %x\n", msg.message);
16929 }
16930 ok_sequence(WmHotkeyReleaseLWIN, "thread hotkey release LWIN", FALSE);
16931
16932 /* Unregister thread hotkey */
16934 ok(ret == TRUE, "expected TRUE, got %i, err=%d\n", ret, GetLastError());
16935
16937 hKBD_hook = NULL;
16938
16939end:
16944}
16945
16946
16947static const struct message WmSetFocus_1[] = {
16948 { HCBT_SETFOCUS, hook }, /* child */
16949 { HCBT_ACTIVATE, hook }, /* parent */
16956 { WM_ACTIVATE, sent|wparam|parent, 1 },
16957 { HCBT_SETFOCUS, hook }, /* parent */
16960 { WM_SETFOCUS, sent },
16961 { 0 }
16962};
16963static const struct message WmSetFocus_2[] = {
16964 { HCBT_SETFOCUS, hook }, /* parent */
16965 { WM_KILLFOCUS, sent },
16966 { WM_SETFOCUS, sent|parent },
16967 { 0 }
16968};
16969static const struct message WmSetFocus_3[] = {
16970 { HCBT_SETFOCUS, hook }, /* child */
16971 { 0 }
16972};
16973
16974static void test_SetFocus(void)
16975{
16976 HWND parent, old_parent, child, old_focus, old_active;
16977 MSG msg;
16978 struct wnd_event wnd_event;
16979 HANDLE hthread;
16980 DWORD ret, tid;
16981
16983 ok(wnd_event.start_event != 0, "CreateEvent error %d\n", GetLastError());
16984 hthread = CreateThread(NULL, 0, thread_proc, &wnd_event, 0, &tid);
16985 ok(hthread != 0, "CreateThread error %d\n", GetLastError());
16987 ok(ret == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
16989
16990 parent = CreateWindowExA(0, "TestParentClass", NULL, WS_OVERLAPPEDWINDOW,
16991 0, 0, 0, 0, 0, 0, 0, NULL);
16992 ok(parent != 0, "failed to create parent window\n");
16993 child = CreateWindowExA(0, "TestWindowClass", NULL, WS_CHILD,
16994 0, 0, 0, 0, parent, 0, 0, NULL);
16995 ok(child != 0, "failed to create child window\n");
16996
16997 trace("parent %p, child %p, thread window %p\n", parent, child, wnd_event.hwnd);
16998
16999 SetFocus(0);
17000 SetActiveWindow(0);
17001
17002 flush_events();
17004
17005 ok(GetActiveWindow() == 0, "expected active 0, got %p\n", GetActiveWindow());
17006 ok(GetFocus() == 0, "expected focus 0, got %p\n", GetFocus());
17007
17009
17010 old_focus = SetFocus(child);
17011 while (PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
17012 ok_sequence(WmSetFocus_1, "SetFocus on a child window", TRUE);
17013 ok(old_focus == parent, "expected old focus %p, got %p\n", parent, old_focus);
17014 ok(GetActiveWindow() == parent, "expected active %p, got %p\n", parent, GetActiveWindow());
17015 ok(GetFocus() == child, "expected focus %p, got %p\n", child, GetFocus());
17016
17017 old_focus = SetFocus(parent);
17018 while (PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
17019 ok_sequence(WmSetFocus_2, "SetFocus on a parent window", FALSE);
17020 ok(old_focus == child, "expected old focus %p, got %p\n", child, old_focus);
17021 ok(GetActiveWindow() == parent, "expected active %p, got %p\n", parent, GetActiveWindow());
17022 ok(GetFocus() == parent, "expected focus %p, got %p\n", parent, GetFocus());
17023
17024 SetLastError(0xdeadbeef);
17025 old_focus = SetFocus((HWND)0xdeadbeef);
17027 "expected ERROR_INVALID_WINDOW_HANDLE, got %d\n", GetLastError());
17028 while (PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
17029 ok_sequence(WmEmptySeq, "SetFocus on an invalid window", FALSE);
17030 ok(old_focus == 0, "expected old focus 0, got %p\n", old_focus);
17031 ok(GetActiveWindow() == parent, "expected active %p, got %p\n", parent, GetActiveWindow());
17032 ok(GetFocus() == parent, "expected focus %p, got %p\n", parent, GetFocus());
17033
17034 SetLastError(0xdeadbeef);
17035 old_focus = SetFocus(GetDesktopWindow());
17036 ok(GetLastError() == ERROR_ACCESS_DENIED /* Vista+ */ ||
17037 broken(GetLastError() == 0xdeadbeef), "expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
17038 while (PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
17039 ok_sequence(WmEmptySeq, "SetFocus on a desktop window", TRUE);
17040 ok(old_focus == 0, "expected old focus 0, got %p\n", old_focus);
17041 ok(GetActiveWindow() == parent, "expected active %p, got %p\n", parent, GetActiveWindow());
17042 ok(GetFocus() == parent, "expected focus %p, got %p\n", parent, GetFocus());
17043
17044 SetLastError(0xdeadbeef);
17045 old_focus = SetFocus(wnd_event.hwnd);
17046 ok(GetLastError() == ERROR_ACCESS_DENIED /* Vista+ */ ||
17047 broken(GetLastError() == 0xdeadbeef), "expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
17048 while (PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
17049 ok_sequence(WmEmptySeq, "SetFocus on another thread window", TRUE);
17050 ok(old_focus == 0, "expected old focus 0, got %p\n", old_focus);
17051 ok(GetActiveWindow() == parent, "expected active %p, got %p\n", parent, GetActiveWindow());
17052 ok(GetFocus() == parent, "expected focus %p, got %p\n", parent, GetFocus());
17053
17054 SetLastError(0xdeadbeef);
17055 old_active = SetActiveWindow((HWND)0xdeadbeef);
17057 "expected ERROR_INVALID_WINDOW_HANDLE, got %d\n", GetLastError());
17058 while (PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
17059 ok_sequence(WmEmptySeq, "SetActiveWindow on an invalid window", FALSE);
17060 ok(old_active == 0, "expected old focus 0, got %p\n", old_active);
17061 ok(GetActiveWindow() == parent, "expected active %p, got %p\n", parent, GetActiveWindow());
17062 ok(GetFocus() == parent, "expected focus %p, got %p\n", parent, GetFocus());
17063
17064 SetLastError(0xdeadbeef);
17065 old_active = SetActiveWindow(GetDesktopWindow());
17067 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
17068 while (PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
17069 ok_sequence(WmEmptySeq, "SetActiveWindow on a desktop window", TRUE);
17070 ok(old_active == 0, "expected old focus 0, got %p\n", old_focus);
17071 ok(GetActiveWindow() == parent, "expected active %p, got %p\n", parent, GetActiveWindow());
17072 ok(GetFocus() == parent, "expected focus %p, got %p\n", parent, GetFocus());
17073
17074 SetLastError(0xdeadbeef);
17075 old_active = SetActiveWindow(wnd_event.hwnd);
17077 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
17078 while (PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
17079 ok_sequence(WmEmptySeq, "SetActiveWindow on another thread window", TRUE);
17080 ok(old_active == 0, "expected old focus 0, got %p\n", old_active);
17081 ok(GetActiveWindow() == parent, "expected active %p, got %p\n", parent, GetActiveWindow());
17082 ok(GetFocus() == parent, "expected focus %p, got %p\n", parent, GetFocus());
17083
17084 SetLastError(0xdeadbeef);
17086 ok(ret, "AttachThreadInput error %d\n", GetLastError());
17087
17088 ok(GetActiveWindow() == parent, "expected active %p, got %p\n", parent, GetActiveWindow());
17089 ok(GetFocus() == parent, "expected focus %p, got %p\n", parent, GetFocus());
17090
17091 flush_events();
17093
17094 old_focus = SetFocus(wnd_event.hwnd);
17095 while (PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
17096 ok(old_focus == wnd_event.hwnd, "expected old focus %p, got %p\n", wnd_event.hwnd, old_focus);
17097 ok(GetActiveWindow() == wnd_event.hwnd, "expected active %p, got %p\n", wnd_event.hwnd, GetActiveWindow());
17098 ok(GetFocus() == wnd_event.hwnd, "expected focus %p, got %p\n", wnd_event.hwnd, GetFocus());
17099
17100 old_focus = SetFocus(parent);
17101 while (PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
17102 ok(old_focus == parent, "expected old focus %p, got %p\n", parent, old_focus);
17103 ok(GetActiveWindow() == parent, "expected active %p, got %p\n", parent, GetActiveWindow());
17104 ok(GetFocus() == parent, "expected focus %p, got %p\n", parent, GetFocus());
17105
17106 flush_events();
17108
17109 old_active = SetActiveWindow(wnd_event.hwnd);
17110 while (PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
17111 ok(old_active == parent, "expected old focus %p, got %p\n", parent, old_active);
17112 ok(GetActiveWindow() == wnd_event.hwnd, "expected active %p, got %p\n", wnd_event.hwnd, GetActiveWindow());
17113 ok(GetFocus() == wnd_event.hwnd, "expected focus %p, got %p\n", wnd_event.hwnd, GetFocus());
17114
17115 SetLastError(0xdeadbeef);
17117 ok(ret, "AttachThreadInput error %d\n", GetLastError());
17118
17119 ok(GetActiveWindow() == 0, "expected active 0, got %p\n", GetActiveWindow());
17120 ok(GetFocus() == 0, "expected focus 0, got %p\n", GetFocus());
17121
17122 old_parent = SetParent(child, GetDesktopWindow());
17123 ok(old_parent == parent, "expected old parent %p, got %p\n", parent, old_parent);
17124
17125 ok(GetActiveWindow() == 0, "expected active 0, got %p\n", GetActiveWindow());
17126 ok(GetFocus() == 0, "expected focus 0, got %p\n", GetFocus());
17127
17128 old_focus = SetFocus(parent);
17129 while (PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
17130 ok(old_focus == parent, "expected old focus %p, got %p\n", parent, old_focus);
17131 ok(GetActiveWindow() == parent, "expected active %p, got %p\n", parent, GetActiveWindow());
17132 ok(GetFocus() == parent, "expected focus %p, got %p\n", parent, GetFocus());
17133
17134 flush_events();
17136
17137 SetLastError(0xdeadbeef);
17138 old_focus = SetFocus(child);
17140 ok(GetLastError() == ERROR_INVALID_PARAMETER /* Vista+ */ ||
17141 broken(GetLastError() == 0) /* XP */ ||
17142 broken(GetLastError() == 0xdeadbeef), "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
17143 while (PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
17144 ok_sequence(WmSetFocus_3, "SetFocus on a child window", TRUE);
17145 ok(old_focus == 0, "expected old focus 0, got %p\n", old_focus);
17146 ok(GetActiveWindow() == parent, "expected active %p, got %p\n", parent, GetActiveWindow());
17147 ok(GetFocus() == parent, "expected focus %p, got %p\n", parent, GetFocus());
17148
17149 SetLastError(0xdeadbeef);
17150 old_active = SetActiveWindow(child);
17151 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
17152 while (PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
17153 ok_sequence(WmEmptySeq, "SetActiveWindow on a child window", FALSE);
17154 ok(old_active == parent, "expected old active %p, got %p\n", parent, old_active);
17155 ok(GetActiveWindow() == parent, "expected active %p, got %p\n", parent, GetActiveWindow());
17156 ok(GetFocus() == parent, "expected focus %p, got %p\n", parent, GetFocus());
17157
17159
17162
17164 ok(ret, "PostMessage(WM_QUIT) error %d\n", GetLastError());
17165 ret = WaitForSingleObject(hthread, INFINITE);
17166 ok(ret == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
17167 CloseHandle(hthread);
17168}
17169
17170static const struct message WmSetLayeredStyle[] = {
17171 { WM_STYLECHANGING, sent },
17172 { WM_STYLECHANGED, sent },
17174 { 0 }
17175};
17176
17177static const struct message WmSetLayeredStyle2[] = {
17178 { WM_STYLECHANGING, sent },
17179 { WM_STYLECHANGED, sent },
17185 { 0 }
17186};
17187
17189{
17195};
17196
17198{
17199 struct layered_window_info *info = param;
17200 POINT src = { 0, 0 };
17201
17202 info->ret = pUpdateLayeredWindow( info->hwnd, 0, NULL, &info->size,
17203 info->hdc, &src, 0, NULL, ULW_OPAQUE );
17204 ok( info->ret, "failed\n");
17205 SetEvent( info->event );
17206 return 0;
17207}
17208
17209static void test_layered_window(void)
17210{
17211 HWND hwnd;
17212 HDC hdc;
17213 HBITMAP bmp;
17214 BOOL ret;
17215 SIZE size;
17216 POINT pos, src;
17217 RECT rect, client;
17218 HANDLE thread;
17219 DWORD tid;
17221
17222 if (!pUpdateLayeredWindow)
17223 {
17224 win_skip( "UpdateLayeredWindow not supported\n" );
17225 return;
17226 }
17227
17228 hdc = CreateCompatibleDC( 0 );
17229 bmp = CreateCompatibleBitmap( hdc, 300, 300 );
17230 SelectObject( hdc, bmp );
17231
17232 hwnd = CreateWindowExA(0, "TestWindowClass", NULL, WS_CAPTION | WS_THICKFRAME | WS_SYSMENU,
17233 100, 100, 300, 300, 0, 0, 0, NULL);
17234 ok( hwnd != 0, "failed to create window\n" );
17236 UpdateWindow( hwnd );
17237 flush_events();
17239
17240 GetWindowRect( hwnd, &rect );
17242 ok( client.right < rect.right - rect.left, "wrong client area\n" );
17243 ok( client.bottom < rect.bottom - rect.top, "wrong client area\n" );
17244
17245 src.x = src.y = 0;
17246 pos.x = pos.y = 300;
17247 size.cx = size.cy = 250;
17248 ret = pUpdateLayeredWindow( hwnd, 0, &pos, &size, hdc, &src, 0, NULL, ULW_OPAQUE );
17249 ok( !ret, "UpdateLayeredWindow should fail on non-layered window\n" );
17250 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
17252 ok_sequence( WmSetLayeredStyle, "WmSetLayeredStyle", FALSE );
17253
17254 ret = pUpdateLayeredWindow( hwnd, 0, &pos, &size, hdc, &src, 0, NULL, ULW_OPAQUE );
17255 ok( ret, "UpdateLayeredWindow failed err %u\n", GetLastError() );
17256 ok_sequence( WmEmptySeq, "UpdateLayeredWindow", FALSE );
17257 GetWindowRect( hwnd, &rect );
17258 ok( rect.left == 300 && rect.top == 300 && rect.right == 550 && rect.bottom == 550,
17259 "wrong window rect %s\n", wine_dbgstr_rect( &rect ));
17260 GetClientRect( hwnd, &rect );
17261 ok( rect.right == client.right - 50 && rect.bottom == client.bottom - 50,
17262 "wrong client rect %s\n", wine_dbgstr_rect( &rect ));
17263
17264 size.cx = 150;
17265 pos.y = 200;
17266 ret = pUpdateLayeredWindow( hwnd, 0, &pos, &size, hdc, &src, 0, NULL, ULW_OPAQUE );
17267 ok( ret, "UpdateLayeredWindow failed err %u\n", GetLastError() );
17268 ok_sequence( WmEmptySeq, "UpdateLayeredWindow", FALSE );
17269 GetWindowRect( hwnd, &rect );
17270 ok( rect.left == 300 && rect.top == 200 && rect.right == 450 && rect.bottom == 450,
17271 "wrong window rect %s\n", wine_dbgstr_rect( &rect ));
17272 GetClientRect( hwnd, &rect );
17273 ok( rect.right == client.right - 150 && rect.bottom == client.bottom - 50,
17274 "wrong client rect %s\n", wine_dbgstr_rect( &rect ));
17275
17278 ok_sequence( WmSetLayeredStyle2, "WmSetLayeredStyle2", FALSE );
17279
17280 size.cx = 200;
17281 pos.x = 200;
17282 ret = pUpdateLayeredWindow( hwnd, 0, &pos, &size, hdc, &src, 0, NULL, ULW_OPAQUE );
17283 ok( ret, "UpdateLayeredWindow failed err %u\n", GetLastError() );
17284 ok_sequence( WmEmptySeq, "UpdateLayeredWindow", FALSE );
17285 GetWindowRect( hwnd, &rect );
17286 ok( rect.left == 200 && rect.top == 200 && rect.right == 400 && rect.bottom == 450,
17287 "wrong window rect %s\n", wine_dbgstr_rect( &rect ));
17288 GetClientRect( hwnd, &rect );
17289 ok( (rect.right == 200 && rect.bottom == 250) ||
17290 broken(rect.right == client.right - 100 && rect.bottom == client.bottom - 50),
17291 "wrong client rect %s\n", wine_dbgstr_rect( &rect ));
17292
17293 size.cx = 0;
17294 ret = pUpdateLayeredWindow( hwnd, 0, &pos, &size, hdc, &src, 0, NULL, ULW_OPAQUE );
17295 ok( !ret, "UpdateLayeredWindow should fail on non-layered window\n" );
17297 broken(GetLastError() == ERROR_GEN_FAILURE) /* win7 */, "wrong error %u\n", GetLastError() );
17298 size.cx = 1;
17299 size.cy = -1;
17300 ret = pUpdateLayeredWindow( hwnd, 0, &pos, &size, hdc, &src, 0, NULL, ULW_OPAQUE );
17301 ok( !ret, "UpdateLayeredWindow should fail on non-layered window\n" );
17302 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
17303
17305 ok_sequence( WmSetLayeredStyle, "WmSetLayeredStyle", FALSE );
17306 GetWindowRect( hwnd, &rect );
17307 ok( rect.left == 200 && rect.top == 200 && rect.right == 400 && rect.bottom == 450,
17308 "wrong window rect %s\n", wine_dbgstr_rect( &rect ));
17309 GetClientRect( hwnd, &rect );
17310 ok( (rect.right == 200 && rect.bottom == 250) ||
17311 broken(rect.right == client.right - 100 && rect.bottom == client.bottom - 50),
17312 "wrong client rect %s\n", wine_dbgstr_rect( &rect ));
17313
17315 info.hwnd = hwnd;
17316 info.hdc = hdc;
17317 info.size.cx = 250;
17318 info.size.cy = 300;
17319 info.event = CreateEventA( NULL, TRUE, FALSE, NULL );
17320 info.ret = FALSE;
17322 ok( WaitForSingleObject( info.event, 1000 ) == 0, "wait failed\n" );
17323 ok( info.ret, "UpdateLayeredWindow failed in other thread\n" );
17324 WaitForSingleObject( thread, 1000 );
17326 GetWindowRect( hwnd, &rect );
17327 ok( rect.left == 200 && rect.top == 200 && rect.right == 450 && rect.bottom == 500,
17328 "wrong window rect %s\n", wine_dbgstr_rect( &rect ));
17329 GetClientRect( hwnd, &rect );
17330 ok( (rect.right == 250 && rect.bottom == 300) ||
17331 broken(rect.right == client.right - 50 && rect.bottom == client.bottom),
17332 "wrong client rect %s\n", wine_dbgstr_rect( &rect ));
17333
17335 DeleteDC( hdc );
17336 DeleteObject( bmp );
17337}
17338
17340
17342{
17343 if (ignore_message( message )) return 0;
17344
17345 switch (message) {
17346 case WM_ENTERIDLE:
17347 todo_wine ok(GetCapture() == hwnd, "expected %p, got %p\n", hwnd, GetCapture());
17348 EndMenu();
17349 break;
17350 case WM_INITMENU:
17351 case WM_INITMENUPOPUP:
17352 case WM_UNINITMENUPOPUP:
17353 ok((HMENU)wParam == hpopupmenu, "expected %p, got %lx\n", hpopupmenu, wParam);
17354 break;
17355 case WM_CAPTURECHANGED:
17356 todo_wine ok(!lParam || (HWND)lParam == hwnd, "lost capture to %lx\n", lParam);
17357 break;
17358 }
17359
17361}
17362
17364{
17365 if (ignore_message( message )) return 0;
17366
17367 switch (message) {
17368 case WM_ENTERMENULOOP:
17369 ok(EndMenu() == TRUE, "EndMenu() failed\n");
17370 break;
17371 }
17372
17374}
17375
17376static void test_TrackPopupMenu(void)
17377{
17378 MSG msg;
17379 HWND hwnd;
17380 BOOL ret;
17381
17382 hwnd = CreateWindowExA(0, "TestWindowClass", NULL, 0,
17383 0, 0, 1, 1, 0,
17384 NULL, NULL, 0);
17385 ok(hwnd != NULL, "CreateWindowEx failed with error %d\n", GetLastError());
17386
17388
17390 ok(hpopupmenu != NULL, "CreateMenu failed with error %d\n", GetLastError());
17391
17392 AppendMenuA(hpopupmenu, MF_STRING, 100, "item 1");
17393 AppendMenuA(hpopupmenu, MF_STRING, 100, "item 2");
17394
17395 flush_events();
17397 ret = TrackPopupMenu(hpopupmenu, 0, 100,100, 0, hwnd, NULL);
17398 ok_sequence(WmTrackPopupMenu, "TrackPopupMenu", TRUE);
17399 ok(ret == 1, "TrackPopupMenu failed with error %i\n", GetLastError());
17400
17401 /* Test popup closing with an ESC-press */
17402 flush_events();
17404 ret = TrackPopupMenu(hpopupmenu, 0, 100,100, 0, hwnd, NULL);
17405 ok(ret == 1, "TrackPopupMenu failed with error %i\n", GetLastError());
17406 PostQuitMessage(0);
17408 while ( PeekMessageA(&msg, 0, 0, 0, PM_REMOVE) )
17409 {
17412 }
17413 ok_sequence(WmTrackPopupMenuEsc, "TrackPopupMenuEsc", FALSE); /* Shouldn't get any message */
17414
17416
17417 flush_events();
17419 ret = TrackPopupMenu(hpopupmenu, 0, 100,100, 0, hwnd, NULL);
17420 ok_sequence(WmTrackPopupMenuAbort, "WmTrackPopupMenuAbort", TRUE);
17421 ok(ret == TRUE, "TrackPopupMenu failed\n");
17422
17424
17426
17427 flush_events();
17429 ret = TrackPopupMenu(hpopupmenu, 0, 100,100, 0, hwnd, NULL);
17430 ok_sequence(WmTrackPopupMenuCapture, "TrackPopupMenuCapture", TRUE);
17431 ok(ret == 1, "TrackPopupMenuCapture failed with error %i\n", GetLastError());
17432
17435}
17436
17438{
17439 HWND hwnd;
17440 BOOL ret;
17441
17442 hwnd = CreateWindowExA(0, "TestWindowClass", NULL, 0,
17443 0, 0, 1, 1, 0,
17444 NULL, NULL, 0);
17445 ok(hwnd != NULL, "CreateWindowEx failed with error %d\n", GetLastError());
17446
17448
17450 ok(hpopupmenu != NULL, "CreateMenu failed with error %d\n", GetLastError());
17451
17452 flush_events();
17454 ret = TrackPopupMenu(hpopupmenu, 0, 100,100, 0, hwnd, NULL);
17455 ok_sequence(WmTrackPopupMenuEmpty, "TrackPopupMenuEmpty", TRUE);
17456 ok(ret == 0, "TrackPopupMenu succeeded\n");
17457
17460}
17461
17462static const struct message send_message_1[] = {
17463 { WM_USER+2, sent|wparam|lparam, 0, 0 },
17464 { WM_USER, sent|wparam|lparam, 0, 0 },
17465 { 0 }
17466};
17467static const struct message send_message_2[] = {
17468 { WM_USER+4, sent|wparam|lparam, 0, 0 },
17469 { 0 }
17470};
17471static const struct message send_message_3[] = {
17472 { WM_USER+3, sent|wparam|lparam, 0, 0 },
17473 { WM_USER+1, sent|wparam|lparam, 0, 0 },
17474 { 0 }
17475};
17476
17478{
17479 struct wnd_event *wnd_event = param;
17480
17481 trace("thread: starting\n");
17483
17484 trace("thread: call PostMessage\n");
17486
17487 trace("thread: call PostMessage\n");
17489
17490 trace("thread: call SendMessage\n");
17492
17493 trace("thread: call SendMessage\n");
17495
17496 return 0;
17497}
17498
17500{
17501 struct wnd_event *wnd_event = param;
17502
17503 trace("thread: starting\n");
17505
17506 trace("thread: call PostMessage\n");
17508
17509 trace("thread: call PostMessage\n");
17511
17512 /* this leads to sending an internal message under Wine */
17513 trace("thread: call SetParent\n");
17515
17516 trace("thread: call SendMessage\n");
17518
17519 trace("thread: call SendMessage\n");
17521
17522 return 0;
17523}
17524
17525static void test_SendMessage_other_thread(int thread_n)
17526{
17527 DWORD qs_all_input = QS_ALLINPUT & ~QS_RAWINPUT;
17528 HANDLE hthread;
17529 struct wnd_event wnd_event;
17530 DWORD tid, ret;
17531 MSG msg;
17532
17534
17535 wnd_event.hwnd = CreateWindowExA(0, "TestWindowClass", NULL, WS_OVERLAPPEDWINDOW,
17536 100, 100, 200, 200, 0, 0, 0, NULL);
17537 ok(wnd_event.hwnd != 0, "CreateWindowEx failed\n");
17538
17539 hthread = CreateThread(NULL, 0, thread_n == 1 ? SendMessage_thread_1 : SendMessage_thread_2, &wnd_event, 0, &tid);
17540 ok(hthread != NULL, "CreateThread failed, error %d\n", GetLastError());
17541 CloseHandle(hthread);
17542
17543 flush_events();
17545
17547 ok(ret == 0, "wrong status %08x\n", ret);
17548
17550
17551 /* wait for other thread's SendMessage */
17552 for (;;)
17553 {
17555 if (ret == MAKELONG(QS_SENDMESSAGE, QS_SENDMESSAGE)) break;
17556 Sleep(50);
17557 }
17558
17560 ok(ret == MAKELONG(QS_POSTMESSAGE, QS_SENDMESSAGE|QS_POSTMESSAGE), "wrong status %08x\n", ret);
17561
17562 trace("main: call GetMessage\n");
17563 GetMessageA(&msg, 0, 0, 0);
17564 ok(msg.message == WM_USER, "expected WM_USER, got %04x\n", msg.message);
17566 ok_sequence(send_message_1, "SendMessage from other thread 1", thread_n == 2);
17567
17568 /* intentionally yield */
17569 MsgWaitForMultipleObjects(0, NULL, FALSE, 100, qs_all_input);
17570
17571 trace("main: call SendMessage\n");
17573 ok_sequence(send_message_2, "SendMessage from other thread 2", FALSE);
17574
17576 ok(ret == MAKELONG(QS_SENDMESSAGE, QS_SENDMESSAGE|QS_POSTMESSAGE), "wrong status %08x\n", ret);
17577
17578 trace("main: call PeekMessage\n");
17579 ok(PeekMessageA(&msg, 0, 0, 0, PM_REMOVE), "PeekMessage should not fail\n");
17580 ok(msg.message == WM_USER+1, "expected WM_USER+1, got %04x\n", msg.message);
17582 ok_sequence(send_message_3, "SendMessage from other thread 3", thread_n == 2);
17583
17584 /* intentionally yield */
17585 MsgWaitForMultipleObjects(0, NULL, FALSE, 100, qs_all_input);
17586
17588 /* FIXME: remove once Wine is fixed */
17589todo_wine_if (thread_n == 2)
17590 ok(ret == 0, "wrong status %08x\n", ret);
17591
17592 trace("main: call PeekMessage\n");
17593 ok(!PeekMessageA(&msg, 0, 0, 0, PM_REMOVE), "PeekMessage should fail\n");
17594 ok_sequence(WmEmptySeq, "SendMessage from other thread 5", thread_n == 2);
17595
17597 ok(ret == 0, "wrong status %08x\n", ret);
17598
17599 trace("main: call DestroyWindow\n");
17600 DestroyWindow(msg.hwnd);
17601
17602 flush_events();
17604}
17605
17607{
17609 BOOL ret;
17610
17611 switch (msg)
17612 {
17613 case WM_USER:
17614 ok( flags == ISMEX_SEND, "wrong flags %x\n", flags );
17615 ok( InSendMessage(), "InSendMessage returned false\n" );
17616 ret = ReplyMessage( msg );
17617 ok( ret, "ReplyMessage failed err %u\n", GetLastError() );
17619 ok( flags == (ISMEX_SEND | ISMEX_REPLIED), "wrong flags %x\n", flags );
17620 ok( InSendMessage(), "InSendMessage returned false\n" );
17621 break;
17622 case WM_USER + 1:
17623 ok( flags == ISMEX_NOTIFY, "wrong flags %x\n", flags );
17624 ok( InSendMessage(), "InSendMessage returned false\n" );
17625 ret = ReplyMessage( msg );
17626 ok( ret, "ReplyMessage failed err %u\n", GetLastError() );
17628 ok( flags == ISMEX_NOTIFY, "wrong flags %x\n", flags );
17629 ok( InSendMessage(), "InSendMessage returned false\n" );
17630 break;
17631 case WM_USER + 2:
17632 ok( flags == ISMEX_CALLBACK, "wrong flags %x\n", flags );
17633 ok( InSendMessage(), "InSendMessage returned false\n" );
17634 ret = ReplyMessage( msg );
17635 ok( ret, "ReplyMessage failed err %u\n", GetLastError() );
17637 ok( flags == (ISMEX_CALLBACK | ISMEX_REPLIED) || flags == ISMEX_SEND, "wrong flags %x\n", flags );
17638 ok( InSendMessage(), "InSendMessage returned false\n" );
17639 break;
17640 case WM_USER + 3:
17641 ok( flags == ISMEX_NOSEND, "wrong flags %x\n", flags );
17642 ok( !InSendMessage(), "InSendMessage returned true\n" );
17643 ret = ReplyMessage( msg );
17644 ok( !ret, "ReplyMessage succeeded\n" );
17645 break;
17646 }
17647
17648 return DefWindowProcA( hwnd, msg, wp, lp );
17649}
17650
17652{
17653 ok( msg == WM_USER + 2, "wrong msg %x\n", msg );
17654 ok( result == WM_USER + 2, "wrong result %lx\n", result );
17655}
17656
17658{
17659 HWND win = arg;
17660
17661 SendMessageA( win, WM_USER, 0, 0 );
17662 SendNotifyMessageA( win, WM_USER + 1, 0, 0 );
17663 SendMessageCallbackA( win, WM_USER + 2, 0, 0, msg_callback, 0 );
17664 PostMessageA( win, WM_USER + 3, 0, 0 );
17665 PostMessageA( win, WM_QUIT, 0, 0 );
17666 return 0;
17667}
17668
17669static void test_InSendMessage(void)
17670{
17671 WNDCLASSA cls;
17672 HWND win;
17673 MSG msg;
17674 HANDLE thread;
17675 DWORD tid;
17676
17677 memset(&cls, 0, sizeof(cls));
17680 cls.lpszClassName = "InSendMessage_test";
17681 RegisterClassA(&cls);
17682
17683 win = CreateWindowA( "InSendMessage_test", NULL, 0, 0, 0, 0, 0, NULL, 0, NULL, 0 );
17684 ok( win != NULL, "CreateWindow failed: %d\n", GetLastError() );
17685
17687 ok( thread != NULL, "CreateThread failed: %d\n", GetLastError() );
17688
17689 while (GetMessageA(&msg, NULL, 0, 0)) DispatchMessageA( &msg );
17690
17691 ok( WaitForSingleObject( thread, 30000 ) == WAIT_OBJECT_0, "WaitForSingleObject failed\n" );
17693
17694 DestroyWindow( win );
17695 UnregisterClassA( "InSendMessage_test", GetModuleHandleA(NULL) );
17696}
17697
17698static const struct message DoubleSetCaptureSeq[] =
17699{
17701 { 0 }
17702};
17703
17704static void test_DoubleSetCapture(void)
17705{
17706 HWND hwnd;
17707
17708 hwnd = CreateWindowExA(0, "TestWindowClass", "Test DoubleSetCapture",
17710 100, 100, 200, 200, 0, 0, 0, NULL);
17711 ok (hwnd != 0, "Failed to create overlapped window\n");
17712
17714 UpdateWindow( hwnd );
17715 flush_events();
17717
17718 SetCapture( hwnd );
17719 SetCapture( hwnd );
17720 ok_sequence(DoubleSetCaptureSeq, "SetCapture( hwnd ) twice", FALSE);
17721
17723}
17724
17725static const struct message WmRestoreMinimizedSeq[] =
17726{
17727 { HCBT_ACTIVATE, hook },
17730 { WM_ACTIVATEAPP, sent|wparam, 1 },
17731 { WM_NCACTIVATE, sent|wparam, 0x200001 },
17733 { WM_ACTIVATE, sent|wparam, 0x200001 }, /* Note that activate messages are after WM_WINDOWPOSCHANGED and before WM_SYSCOMMAND */
17739 { HCBT_MINMAX, hook },
17751 { WM_MOVE, sent|defwinproc },
17752 { WM_SIZE, sent|defwinproc },
17756 { HCBT_SETFOCUS, hook },
17759 { WM_PAINT, sent| optional },
17762 { WM_KEYUP, sent|optional },
17766 { WM_KEYUP, sent|optional },
17767 { WM_PAINT, sent| optional },
17768 { 0 }
17769};
17770
17771static void test_restore_messages(void)
17772{
17773 INPUT ip = {0};
17774 HWND hwnd;
17775 INT i;
17776
17777 hwnd = CreateWindowExA(0, "TestWindowClass", "Test overlapped", WS_OVERLAPPEDWINDOW | WS_VISIBLE, 100,
17778 100, 200, 200, 0, 0, 0, NULL);
17779 ok (hwnd != 0, "Failed to create overlapped window\n");
17782 flush_events();
17784
17785 for (i = 0; i < 5; i++)
17786 {
17787 /* Send Alt+Tab to restore test window from minimized state */
17788 ip.type = INPUT_KEYBOARD;
17789 ip.ki.wVk = VK_MENU;
17790 SendInput(1, &ip, sizeof(INPUT));
17791 ip.ki.wVk = VK_TAB;
17792 SendInput(1, &ip, sizeof(INPUT));
17793 ip.ki.wVk = VK_MENU;
17794 ip.ki.dwFlags = KEYEVENTF_KEYUP;
17795 SendInput(1, &ip, sizeof(INPUT));
17796 ip.ki.wVk = VK_TAB;
17797 ip.ki.dwFlags = KEYEVENTF_KEYUP;
17798 SendInput(1, &ip, sizeof(INPUT));
17799 flush_events();
17800 if (!IsIconic(hwnd))
17801 break;
17802 }
17803
17804 if (IsIconic(hwnd))
17805 {
17806 skip("Alt+Tab failed to bring up test window.\n");
17807 goto done;
17808 }
17809 ok_sequence(WmRestoreMinimizedSeq, "Restore minimized window", TRUE);
17810
17811done:
17813}
17814
17815static void test_invalid_window(void)
17816{
17817 MSG msg;
17818 BOOL ret;
17819
17820 SetLastError(0xdeadbeef);
17821 ret = GetMessageA(&msg, (HWND)0xdeadbeef, 0, 0);
17822 ok(ret == -1, "wrong ret %d\n", ret);
17823 ok(GetLastError() == ERROR_INVALID_WINDOW_HANDLE, "wrong error %u\n", GetLastError());
17824
17825 SetLastError(0xdeadbeef);
17826 ret = PeekMessageA(&msg, (HWND)0xdeadbeef, 0, 0, PM_REMOVE);
17827 ok(!ret, "wrong ret %d\n", ret);
17828 ok(GetLastError() == ERROR_INVALID_WINDOW_HANDLE, "wrong error %u\n", GetLastError());
17829}
17830
17831static void init_funcs(void)
17832{
17833 HMODULE hKernel32 = GetModuleHandleA("kernel32.dll");
17834
17835#define X(f) p##f = (void*)GetProcAddress(hKernel32, #f)
17840 X(QueryActCtxW);
17842#undef X
17843}
17844
17845#ifndef __REACTOS__
17847{
17848 char **test_argv;
17849 BOOL ret;
17850 BOOL (WINAPI *pIsWinEventHookInstalled)(DWORD)= 0;/*GetProcAddress(user32, "IsWinEventHookInstalled");*/
17851 HMODULE hModuleImm32;
17852 BOOL (WINAPI *pImmDisableIME)(DWORD);
17853 int argc;
17854
17855 init_funcs();
17856
17858 if (argc >= 3)
17859 {
17860 unsigned int arg;
17861 /* Child process. */
17862 sscanf (test_argv[2], "%d", (unsigned int *) &arg);
17864 return;
17865 }
17866
17868 init_procs();
17869
17870 hModuleImm32 = LoadLibraryA("imm32.dll");
17871 if (hModuleImm32) {
17872 pImmDisableIME = (void *)GetProcAddress(hModuleImm32, "ImmDisableIME");
17873 if (pImmDisableIME)
17874 pImmDisableIME(0);
17875 }
17876 pImmDisableIME = NULL;
17877 FreeLibrary(hModuleImm32);
17878
17879 if (!RegisterWindowClasses()) assert(0);
17880
17881 if (pSetWinEventHook)
17882 {
17883 hEvent_hook = pSetWinEventHook(EVENT_MIN, EVENT_MAX,
17885 0, GetCurrentThreadId(),
17887 if (pIsWinEventHookInstalled && hEvent_hook)
17888 {
17889 UINT event;
17890 for (event = EVENT_MIN; event <= EVENT_MAX; event++)
17891 ok(pIsWinEventHookInstalled(event), "IsWinEventHookInstalled(%u) failed\n", event);
17892 }
17893 }
17894 if (!hEvent_hook) win_skip( "no win event hook support\n" );
17895
17898 if (!hCBT_hook) win_skip( "cannot set global hook, will skip hook tests\n" );
17899
17901
17902 /* Fix message sequences before removing 4 lines below */
17903 if (pUnhookWinEvent && hEvent_hook)
17904 {
17905 ret = pUnhookWinEvent(hEvent_hook);
17906 ok( ret, "UnhookWinEvent error %d\n", GetLastError());
17907 pUnhookWinEvent = 0;
17908 }
17909 hEvent_hook = 0;
17910
17914 test_SetFocus();
17924 test_messages();
17942 test_timers();
17945 if (hCBT_hook)
17946 {
17947 test_set_hook();
17949 }
17959
17960 if (!pTrackMouseEvent)
17961 win_skip("TrackMouseEvent is not available\n");
17962 else
17964
17966 test_sys_menu();
17977 test_keyflags();
17978 test_hotkey();
17983 /* keep it the last test, under Windows it tends to break the tests
17984 * which rely on active/foreground windows being correct.
17985 */
17987
17989 if (pUnhookWinEvent && hEvent_hook)
17990 {
17991 ret = pUnhookWinEvent(hEvent_hook);
17992 ok( ret, "UnhookWinEvent error %d\n", GetLastError());
17993 SetLastError(0xdeadbeef);
17994 ok(!pUnhookWinEvent(hEvent_hook), "UnhookWinEvent succeeded\n");
17995 ok(GetLastError() == ERROR_INVALID_HANDLE || /* Win2k */
17996 GetLastError() == 0xdeadbeef, /* Win9x */
17997 "unexpected error %d\n", GetLastError());
17998 }
18000}
18001#endif /* __REACTOS__ */
18002
18003static void init_tests()
18004{
18005 HMODULE hModuleImm32;
18006 BOOL (WINAPI *pImmDisableIME)(DWORD);
18007
18008 init_funcs();
18009
18011 init_procs();
18012
18013 hModuleImm32 = LoadLibraryA("imm32.dll");
18014 if (hModuleImm32) {
18015 pImmDisableIME = (void *)GetProcAddress(hModuleImm32, "ImmDisableIME");
18016 if (pImmDisableIME)
18017 pImmDisableIME(0);
18018 }
18019 pImmDisableIME = NULL;
18020 FreeLibrary(hModuleImm32);
18021
18022 if (!RegisterWindowClasses()) assert(0);
18023
18026 if (!hCBT_hook) win_skip( "cannot set global hook, will skip hook tests\n" );
18027}
18028
18029static void cleanup_tests()
18030{
18031 BOOL ret;
18033 if (pUnhookWinEvent && hEvent_hook)
18034 {
18035 ret = pUnhookWinEvent(hEvent_hook);
18036 ok( ret, "UnhookWinEvent error %d\n", GetLastError());
18037 SetLastError(0xdeadbeef);
18038 ok(!pUnhookWinEvent(hEvent_hook), "UnhookWinEvent succeeded\n");
18039 ok(GetLastError() == ERROR_INVALID_HANDLE || /* Win2k */
18040 GetLastError() == 0xdeadbeef, /* Win9x */
18041 "unexpected error %d\n", GetLastError());
18042 }
18044
18045}
18046
18047START_TEST(msg_queue)
18048{
18049 int argc;
18050 char **test_argv;
18052 if (argc >= 3)
18053 {
18054 unsigned int arg;
18055 /* Child process. */
18056 sscanf (test_argv[2], "%d", (unsigned int *) &arg);
18058 return;
18059 }
18060
18061 init_tests();
18077 cleanup_tests();
18078}
18079
18080START_TEST(msg_messages)
18081{
18082 init_tests();
18084 test_messages();
18091 cleanup_tests();
18092}
18093
18094START_TEST(msg_focus)
18095{
18096 init_tests();
18097
18098 test_SetFocus();
18099
18100 /* HACK: For some reason the tests fail on Windows if run consecutively.
18101 * Putting these in between helps, and is essentially what happens in the
18102 * "normal" msg test. */
18104 flush_events();
18105
18107
18108 /* HACK */
18110 flush_events();
18111
18114
18116
18117 /* keep it the last test, under Windows it tends to break the tests
18118 * which rely on active/foreground windows being correct.
18119 */
18121 cleanup_tests();
18122}
18123
18124START_TEST(msg_winpos)
18125{
18126 init_tests();
18134 cleanup_tests();
18135}
18136
18137START_TEST(msg_paint)
18138{
18139 init_tests();
18142#ifdef __REACTOS__
18143 if (!winetest_interactive &&
18144 !strcmp(winetest_platform, "windows"))
18145 {
18146 skip("ROSTESTS-185: Skipping user32_winetest:msg_paint test_paintingloop because it hangs on WHS-Testbot. Set winetest_interactive to run it anyway.\n");
18147 }
18148 else
18149#endif
18151 cleanup_tests();
18152}
18153
18154START_TEST(msg_input)
18155{
18156 init_tests();
18158 if (!pTrackMouseEvent)
18159 win_skip("TrackMouseEvent is not available\n");
18160 else
18162
18163 test_keyflags();
18164 test_hotkey();
18165 cleanup_tests();
18166}
18167
18168START_TEST(msg_timer)
18169{
18170 init_tests();
18171 test_timers();
18174 cleanup_tests();
18175}
18176
18178
18179START_TEST(msg_hook)
18180{
18181// HMODULE user32 = GetModuleHandleA("user32.dll");
18182// IS_WINEVENT_HOOK_INSTALLED pIsWinEventHookInstalled = (IS_WINEVENT_HOOK_INSTALLED)GetProcAddress(user32, "IsWinEventHookInstalled");
18183 BOOL (WINAPI *pIsWinEventHookInstalled)(DWORD)= 0;/*GetProcAddress(user32, "IsWinEventHookInstalled");*/
18184
18185 init_tests();
18186
18187 if (pSetWinEventHook)
18188 {
18189 hEvent_hook = pSetWinEventHook(EVENT_MIN, EVENT_MAX,
18191 0, GetCurrentThreadId(),
18193 if (pIsWinEventHookInstalled && hEvent_hook)
18194 {
18195 UINT event;
18196 for (event = EVENT_MIN; event <= EVENT_MAX; event++)
18197 ok(pIsWinEventHookInstalled(event), "IsWinEventHookInstalled(%u) failed\n", event);
18198 }
18199 }
18200 if (!hEvent_hook) win_skip( "no win event hook support\n" );
18201
18203
18204 /* Fix message sequences before removing 4 lines below */
18205 if (pUnhookWinEvent && hEvent_hook)
18206 {
18207 BOOL ret;
18208 ret = pUnhookWinEvent(hEvent_hook);
18209 ok( ret, "UnhookWinEvent error %d\n", GetLastError());
18210 pUnhookWinEvent = 0;
18211 }
18212 hEvent_hook = 0;
18213 if (hCBT_hook)
18214 {
18215 test_set_hook();
18217 }
18218 cleanup_tests();
18219}
18220
18221START_TEST(msg_menu)
18222{
18223 init_tests();
18224 test_sys_menu();
18228 cleanup_tests();
18229}
18230
18232{
18233 init_tests();
18235 cleanup_tests();
18236}
18237
18238START_TEST(msg_controls)
18239{
18240 init_tests();
18249 cleanup_tests();
18250}
18251
18252START_TEST(msg_layered_window)
18253{
18254 init_tests();
18256 cleanup_tests();
18257}
18258
18259START_TEST(msg_dialog)
18260{
18261 init_tests();
18264 cleanup_tests();
18265}
18266
18267START_TEST(msg_clipboard)
18268{
18269 init_tests();
18271 cleanup_tests();
18272}
static HWND hWnd3
static HRGN hrgn2
static HRGN hrgn
static int argc
Definition: ServiceArgs.c:12
msg_flags_t
Definition: SystemMenu.c:26
#define broken(x)
Definition: _sntprintf.h:21
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
static void startup(void)
Arabic default style
Definition: afstyles.h:94
static int state
Definition: maze.c:121
#define trace
Definition: atltest.h:70
#define ok(value,...)
Definition: atltest.h:57
#define skip(...)
Definition: atltest.h:64
#define START_TEST(x)
Definition: atltest.h:75
#define ok_(x1, x2)
Definition: atltest.h:61
static const char * wine_dbgstr_rect(const RECT *prc)
Definition: atltest.h:160
#define msg(x)
Definition: auth_time.c:54
HANDLE HMONITOR
Definition: axextend.idl:431
HWND hWnd
Definition: settings.c:17
#define ARRAY_SIZE(A)
Definition: main.h:33
static HANDLE thread
Definition: service.c:33
static HANDLE hevent
Definition: broadcast.c:34
HBITMAP hbmp
r l[0]
Definition: byte_order.h:168
Definition: _set.h:50
WPARAM wParam
Definition: combotst.c:138
LPARAM lParam
Definition: combotst.c:139
#define DBT_DEVICEREMOVEPENDING
Definition: dbt.h:15
#define DBT_DEVICETYPESPECIFIC
Definition: dbt.h:17
#define DBT_DEVNODES_CHANGED
Definition: dbt.h:28
#define DBT_CONFIGCHANGECANCELED
Definition: dbt.h:31
#define DBT_QUERYCHANGECONFIG
Definition: dbt.h:29
#define DBT_DEVICEQUERYREMOVE
Definition: dbt.h:13
#define DBT_DEVICEARRIVAL
Definition: dbt.h:12
#define DBT_DEVICEREMOVECOMPLETE
Definition: dbt.h:16
#define DBT_DEVICEQUERYREMOVEFAILED
Definition: dbt.h:14
#define DBT_NO_DISK_SPACE
Definition: dbt.h:9
#define DBT_LOW_DISK_SPACE
Definition: dbt.h:10
#define DBT_CONFIGMGPRIVATE
Definition: dbt.h:11
#define DBT_CUSTOMEVENT
Definition: dbt.h:18
#define DBT_CONFIGCHANGED
Definition: dbt.h:30
#define WAIT_TIMEOUT
Definition: dderror.h:14
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
static HINSTANCE instance
Definition: main.c:40
unsigned int idx
Definition: utils.c:41
#define CloseHandle
Definition: compat.h:739
#define GetProcessHeap()
Definition: compat.h:736
#define ERROR_CALL_NOT_IMPLEMENTED
Definition: compat.h:102
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define CP_ACP
Definition: compat.h:109
#define SetLastError(x)
Definition: compat.h:752
#define GetProcAddress(x, y)
Definition: compat.h:753
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define HeapAlloc
Definition: compat.h:733
#define HeapReAlloc
Definition: compat.h:734
#define FreeLibrary(x)
Definition: compat.h:748
#define MAX_PATH
Definition: compat.h:34
#define HeapFree(x, y, z)
Definition: compat.h:735
#define ERROR_INVALID_HANDLE
Definition: compat.h:98
#define CreateFileW
Definition: compat.h:741
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:137
#define CALLBACK
Definition: compat.h:35
#define WideCharToMultiByte
Definition: compat.h:111
#define MultiByteToWideChar
Definition: compat.h:110
#define ERROR_ACCESS_DENIED
Definition: compat.h:97
#define lstrcpynW
Definition: compat.h:738
#define lstrlenW
Definition: compat.h:750
VOID WINAPI ReleaseActCtx(IN HANDLE hActCtx)
Definition: actctx.c:208
BOOL WINAPI DeactivateActCtx(IN DWORD dwFlags, IN ULONG_PTR ulCookie)
Definition: actctx.c:268
BOOL WINAPI QueryActCtxW(IN DWORD dwFlags, IN HANDLE hActCtx, IN PVOID pvSubInstance, IN ULONG ulInfoClass, IN PVOID pvBuffer, IN SIZE_T cbBuffer, IN OUT SIZE_T *pcbWrittenOrRequired OPTIONAL)
Definition: actctx.c:328
BOOL WINAPI GetCurrentActCtx(OUT PHANDLE phActCtx)
Definition: actctx.c:298
BOOL WINAPI ActivateActCtx(IN HANDLE hActCtx, OUT PULONG_PTR ulCookie)
Definition: actctx.c:237
VOID WINAPI RaiseException(_In_ DWORD dwExceptionCode, _In_ DWORD dwExceptionFlags, _In_ DWORD nNumberOfArguments, _In_opt_ const ULONG_PTR *lpArguments)
Definition: except.c:700
BOOL WINAPI DeleteFileA(IN LPCSTR lpFileName)
Definition: delete.c:24
BOOL WINAPI WriteFile(IN HANDLE hFile, IN LPCVOID lpBuffer, IN DWORD nNumberOfBytesToWrite OPTIONAL, OUT LPDWORD lpNumberOfBytesWritten, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:24
HMODULE WINAPI GetModuleHandleW(LPCWSTR lpModuleName)
Definition: loader.c:838
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:812
HINSTANCE WINAPI DECLSPEC_HOTPATCH LoadLibraryA(LPCSTR lpLibFileName)
Definition: loader.c:111
BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessA(LPCSTR lpApplicationName, LPSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCSTR lpCurrentDirectory, LPSTARTUPINFOA lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation)
Definition: proc.c:4741
BOOL WINAPI TerminateProcess(IN HANDLE hProcess, IN UINT uExitCode)
Definition: proc.c:1532
DWORD WINAPI QueueUserAPC(IN PAPCFUNC pfnAPC, IN HANDLE hThread, IN ULONG_PTR dwData)
Definition: thread.c:959
HANDLE WINAPI DECLSPEC_HOTPATCH CreateThread(IN LPSECURITY_ATTRIBUTES lpThreadAttributes, IN DWORD dwStackSize, IN LPTHREAD_START_ROUTINE lpStartAddress, IN LPVOID lpParameter, IN DWORD dwCreationFlags, OUT LPDWORD lpThreadId)
Definition: thread.c:137
DWORD WINAPI GetTickCount(VOID)
Definition: time.c:455
HANDLE WINAPI CreateActCtxW(PCACTCTXW pActCtx)
Definition: actctx.c:104
BOOL WINAPI GetCPInfoExA(UINT CodePage, DWORD dwFlags, LPCPINFOEXA lpCPInfoEx)
Definition: nls.c:2152
#define assert(x)
Definition: debug.h:53
static void test_window(IHTMLDocument2 *doc)
Definition: dom.c:6306
#define pt(x, y)
Definition: drawing.c:79
#define INFINITE
Definition: serial.h:102
HINSTANCE hInst
Definition: dxdiag.c:13
RECT rect2
Definition: edittest.c:51
#define ERROR(name)
Definition: error_private.h:53
#define WM_APP
Definition: eventvwr.h:73
#define abs(i)
Definition: fconv.c:206
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
#define printf
Definition: freeldr.h:93
pKey DeleteObject()
GLuint start
Definition: gl.h:1545
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
GLuint GLuint end
Definition: gl.h:1545
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLsizeiptr size
Definition: glext.h:5919
struct _cl_event * event
Definition: glext.h:7739
GLuint res
Definition: glext.h:9613
GLenum src
Definition: glext.h:6340
GLuint * ids
Definition: glext.h:5907
GLuint buffer
Definition: glext.h:5915
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLbitfield flags
Definition: glext.h:7161
GLuint GLfloat * val
Definition: glext.h:7180
GLfloat param
Definition: glext.h:5796
GLenum GLsizei len
Definition: glext.h:6722
GLubyte GLubyte GLubyte GLubyte w
Definition: glext.h:6102
GLuint64EXT * result
Definition: glext.h:11304
GLuint id
Definition: glext.h:5910
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble * u
Definition: glfuncs.h:240
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
#define INT_MAX
Definition: limits.h:40
_Check_return_ _CRTIMP int __cdecl sscanf(_In_z_ const char *_Src, _In_z_ _Scanf_format_string_ const char *_Format,...)
const char * filename
Definition: ioapi.h:137
#define EVENT_ALL_ACCESS
Definition: isotest.c:82
#define HIBYTE(W)
Definition: jmemdos.c:486
#define b
Definition: ke_i.h:79
#define actctx
Definition: kernel32.h:8
#define trace_(file, line,...)
Definition: kmt_test.h:223
static real win[4][36]
LCID WINAPI GetThreadLocale(void)
Definition: lang.c:1459
INT WINAPI GetLocaleInfoW(LCID lcid, LCTYPE lctype, LPWSTR buffer, INT len)
Definition: lang.c:1108
static HANDLE hmon
Definition: localmon.c:41
int WINAPI lstrcmpiA(LPCSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:42
int WINAPI lstrcmpW(LPCWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:170
int WINAPI lstrcmpA(LPCSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:18
int WINAPI lstrlenA(LPCSTR lpString)
Definition: lstring.c:145
POINT cp
Definition: magnifier.c:59
__u16 time
Definition: mkdosfs.c:8
#define CREATE_ALWAYS
Definition: disk.h:72
HACCEL hAccel
Definition: main.c:47
HWND hWnd1
Definition: button.c:416
HWND hWnd2
Definition: button.c:416
HANDLE hKernel32
Definition: locale.c:13
#define sprintf(buf, format,...)
Definition: sprintf.c:55
BITMAP bmp
Definition: alphablend.c:62
HDC hdc
Definition: main.c:9
HANDLE events[2]
Definition: event.c:4
static HBITMAP
Definition: button.c:44
DWORD button
Definition: button.c:166
static HICON
Definition: imagelist.c:84
static void test_create(void)
Definition: monthcal.c:1595
#define comment(fmt, arg1)
Definition: rebar.c:820
#define GET_PROC(dll, func)
static const WCHAR desc[]
Definition: protectdata.c:36
BOOL expected
Definition: store.c:2063
static DNS_RECORDW r1
Definition: record.c:37
static DNS_RECORDW r2
Definition: record.c:38
static DWORD *static HFONT(WINAPI *pCreateFontIndirectExA)(const ENUMLOGFONTEXDVA *)
IMAGE_NT_HEADERS nt
Definition: module.c:50
IMAGE_DOS_HEADER dos
Definition: module.c:49
static HANDLE start_event
Definition: thread.c:135
static TfClientId tid
#define todo_wine_if(is_todo)
Definition: custom.c:76
#define todo_wine
Definition: custom.c:79
static refpint_t pi[]
Definition: server.c:96
static BOOL is_win9x
Definition: diskspace.c:33
static const CLSID *static CLSID *static const GUID VARIANT VARIANT *static IServiceProvider DWORD *static HMENU
Definition: ordinal.c:63
static DWORD thread_id
Definition: protocol.c:159
static char ** test_argv
Definition: cursoricon.c:296
static HWND child
Definition: cursoricon.c:298
static ATOM item
Definition: dde.c:856
#define ctrl
Definition: input.c:1756
static const struct message WmMinimize_1[]
Definition: msg.c:13194
static INT_PTR CALLBACK StopQuitMsgCheckProcA(HWND hwnd, UINT message, WPARAM wp, LPARAM lp)
Definition: msg.c:9644
static const struct message sl_edit_lbutton_up[]
Definition: msg.c:11581
static void subclass_static(void)
Definition: msg.c:7193
static const WCHAR wszAnsi[]
Definition: msg.c:10042
#define WND_CHILD_ID
Definition: msg.c:56
msg_flags_t
Definition: msg.c:136
@ sent
Definition: msg.c:137
@ beginpaint
Definition: msg.c:143
@ defwinproc
Definition: msg.c:142
@ kbd_hook
Definition: msg.c:147
@ parent
Definition: msg.c:139
@ posted
Definition: msg.c:138
@ lparam
Definition: msg.c:141
@ hook
Definition: msg.c:145
@ winevent_hook
Definition: msg.c:146
@ wparam
Definition: msg.c:140
@ optional
Definition: msg.c:144
static const struct message sl_edit_lbutton_down[]
Definition: msg.c:11542
static DWORD CALLBACK do_wait_idle_child_thread(void *arg)
Definition: msg.c:16085
static LRESULT CALLBACK static_hook_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
Definition: msg.c:7169
static LRESULT WINAPI wmime_keydown_procA(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
Definition: msg.c:7639
static void test_nullCallback(void)
Definition: msg.c:14112
static WNDPROC old_edit_proc
Definition: msg.c:11598
static const struct message WmCreateDialogParamSeq_4[]
Definition: msg.c:13749
static void test_WaitForInputIdle(char *argv0)
Definition: msg.c:16275
static const struct message WmVkN[]
Definition: msg.c:8814
static void test_DispatchMessage(void)
Definition: msg.c:11285
static const struct message WmCreateMDIchildInvisibleParentSeq[]
Definition: msg.c:2749
static const struct message WmDestroyOverlappedSeq[]
Definition: msg.c:696
static void cleanup_tests()
Definition: msg.c:18029
static HMODULE
Definition: msg.c:2009
static const struct message WmCreateInvisibleMaxPopupSeq[]
Definition: msg.c:759
static const struct message WmHotkeyPressLWIN[]
Definition: msg.c:16593
static const struct message WmSetMenuNonVisibleNoSizeChangeSeq[]
Definition: msg.c:1694
static const struct message auto_radio_button_VK_UP_parent[]
Definition: msg.c:6770
static const struct message WmSetStyleButtonSeq[]
Definition: msg.c:6090
static const struct message WmCreateMDIframeSeq[]
Definition: msg.c:2580
static const struct message WmSWP_MoveSeq[]
Definition: msg.c:290
#define SWP_NOCLIENTSIZE
Definition: msg.c:40
static const struct message WmChildPaintNc[]
Definition: msg.c:7857
static const struct message WmFirstDrawSetWindowPosSeq4[]
Definition: msg.c:1123
static const struct message WmSetFocus_3[]
Definition: msg.c:16969
static const struct message WmFirstDrawChildSeq2[]
Definition: msg.c:1176
static const struct message WmMinMax_3[]
Definition: msg.c:13248
static const struct message wm_lb_addstring_sort_ownerdraw[]
Definition: msg.c:14844
static void do_wait_idle_child(int arg)
Definition: msg.c:16095
static const struct message WmAltVkN[]
Definition: msg.c:8874
static const struct message WmCreateMDIchildInvisibleMaxSeq4[]
Definition: msg.c:3127
static const struct message WmShowNoActivate_1[]
Definition: msg.c:13073
static const struct message WmDispatchPaint[]
Definition: msg.c:11271
#define set_selection(hctl, start, end)
static void test_notify_message(void)
Definition: msg.c:12681
static const struct message WmRestore_2[]
Definition: msg.c:13121
#define add_message(msg)
Definition: msg.c:2109
#define ID_RADIO1
Definition: msg.c:6726
static const struct message WmSetFocus_1[]
Definition: msg.c:16947
static void test_edit_messages(void)
Definition: msg.c:11639
static HHOOK recursive_hook
Definition: msg.c:10999
static const struct message WmDestroyMDIframeSeq[]
Definition: msg.c:2620
static const struct message WmTrackPopupMenuEmpty[]
Definition: msg.c:1967
static void test_dialog_messages(void)
Definition: msg.c:13784
static const struct message SetFocusComboBoxSeq[]
Definition: msg.c:7340
static const struct message WmCreateMDIchildVisibleSeq[]
Definition: msg.c:2686
static const struct message WmSHOWNAChildInvisParVis[]
Definition: msg.c:1888
static LRESULT MsgCheckProc(BOOL unicode, HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
Definition: msg.c:9380
static void test_SetFocus(void)
Definition: msg.c:16974
static const struct message WmWinEventAlertSeq_2[]
Definition: msg.c:10475
static INT_PTR CALLBACK wm_quit_dlg_proc(HWND hwnd, UINT message, WPARAM wp, LPARAM lp)
Definition: msg.c:12534
static const struct message wm_lb_setcursel_1[]
Definition: msg.c:14756
static void pump_msg_loop_timeout(DWORD timeout, BOOL inject_mouse_move)
Definition: msg.c:12749
static DWORD WINAPI send_message_thread(void *arg)
Definition: msg.c:17657
static DWORD CALLBACK send_msg_thread_2(void *param)
Definition: msg.c:11770
static LRESULT WINAPI MsgCheckProcW(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
Definition: msg.c:9537
static const struct message WmShowChildInvisibleParentSeq_3[]
Definition: msg.c:1332
static const struct message WmDestroyMDIchildInvisibleSeq[]
Definition: msg.c:2870
static void test_PeekMessage3(void)
Definition: msg.c:12405
static void subclass_edit(void)
Definition: msg.c:11624
#define WS_BASE
static BOOL test_context_menu
Definition: msg.c:115
static HWINEVENTHOOK hEvent_hook
Definition: msg.c:116
static const struct message WmMinMax_2[]
Definition: msg.c:13235
static void test_InSendMessage(void)
Definition: msg.c:17669
static const struct message WmShowVisiblePopupSeq_2[]
Definition: msg.c:922
static void init_procs(void)
Definition: msg.c:2021
static const struct message WmLButtonUpAutoSeq[]
Definition: msg.c:6027
static const struct message WmCreateChildPopupSeq[]
Definition: msg.c:894
#define ID_BUTTON
Definition: msg.c:5893
static const struct message WmShowChildInvisibleParentSeq_1r[]
Definition: msg.c:1309
static const struct message WmInvalidateParentChild[]
Definition: msg.c:7824
static const struct message WmLButtonUpBrokenSeq[]
Definition: msg.c:6039
static BOOL mdi_RegisterWindowClasses(void)
Definition: msg.c:3748
DWORD exp
Definition: msg.c:16058
static void CALLBACK win_event_proc(HWINEVENTHOOK hevent, DWORD event, HWND hwnd, LONG object_id, LONG child_id, DWORD thread_id, DWORD event_time)
Definition: msg.c:10014
static LRESULT CALLBACK combobox_hook_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
Definition: msg.c:7436
static void test_restore_messages(void)
Definition: msg.c:17771
static const struct message WmShowMaxPopupResizedSeq[]
Definition: msg.c:778
static DWORD CALLBACK post_rbuttonup_msg(void *arg)
Definition: msg.c:15523
static const struct message WmInitEndSession_4[]
Definition: msg.c:4913
static void test_layered_window(void)
Definition: msg.c:17209
static const struct message WmMinimizeMDIchildVisibleSeq[]
Definition: msg.c:3607
static const struct message WmCreateMDIchildVisibleMaxSeq3[]
Definition: msg.c:3026
static const struct message WmAltVkN_2[]
Definition: msg.c:8907
static WNDPROC orig_edit_proc
Definition: msg.c:13571
static DWORD WINAPI SendMessage_thread_2(void *param)
Definition: msg.c:17499
static void test_button_messages(void)
Definition: msg.c:6278
static const char manifest_dep[]
Definition: msg.c:8599
static const struct message destroy_window_with_children[]
Definition: msg.c:11132
static const struct message WmSetRedrawFalseSeq[]
Definition: msg.c:1762
static const struct message WmSetFontStaticSeq[]
Definition: msg.c:6053
static INT_PTR WINAPI radio_test_dlg_proc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
Definition: msg.c:6889
#define WM_KEYF1
Definition: msg.c:47
static void test_invalid_window(void)
Definition: msg.c:17815
static const struct message WmInitEndSession[]
Definition: msg.c:4892
static WNDPROC old_combobox_proc
Definition: msg.c:7369
static const struct message WmVkAppsSeq[]
Definition: msg.c:9049
static void test_DestroyWindow(void)
Definition: msg.c:11154
static const struct message WmShowChildInvisibleParentSeq_2[]
Definition: msg.c:1314
static const struct message WmCreateMDIchildVisibleMaxSeq2[]
Definition: msg.c:2945
static void test_clipboard_viewers(void)
Definition: msg.c:15746
static const struct message WmSetStyleUserSeq[]
Definition: msg.c:6110
static const struct message WMSetFocusComboBoxSeq[]
Definition: msg.c:7312
static void test_paint_messages(void)
Definition: msg.c:7890
static const struct message WmHideChildSeq[]
Definition: msg.c:1247
static void test_static_messages(void)
Definition: msg.c:7208
static const struct message WmDestroyMDIchildVisibleMaxSeq1[]
Definition: msg.c:3256
static const struct message WmShowMaximized_2[]
Definition: msg.c:13274
BOOL(WINAPI * IS_WINEVENT_HOOK_INSTALLED)(DWORD)
Definition: msg.c:18177
#define track_query(expected_track_flags, expected_track_hwnd, expected_hover_time)
static const struct message SetCurSelComboSeq[]
Definition: msg.c:7251
static const struct message WmParentOnlyNcPaint[]
Definition: msg.c:7877
static const struct message SetForegroundWindowSeq[]
Definition: msg.c:14287
static void test_sys_menu(void)
Definition: msg.c:4809
static void test_desktop_winproc(void)
Definition: msg.c:15652
static int hotkey_letter
Definition: msg.c:16656
static void test_messages(void)
Definition: msg.c:5106
static const struct message WmDrawMenuBarSeq[]
Definition: msg.c:1744
static void test_recursive_activation(void)
Definition: msg.c:4776
static const struct message WmSetFontStaticSeq2[]
Definition: msg.c:7158
static const struct message WmCtrlVkN[]
Definition: msg.c:8842
static const struct message WmInvalidateErasePaint[]
Definition: msg.c:7786
static void test_autoradio_BM_CLICK(void)
Definition: msg.c:6895
static void test_WM_SETREDRAW(HWND hwnd)
Definition: msg.c:4363
static DWORD get_menu_style(HMENU hmenu)
Definition: msg.c:15258
static const struct message WmImeKeydownMsgSeq_0[]
Definition: msg.c:7625
static const struct message WmShiftF10Seq[]
Definition: msg.c:9090
static const struct message send_message_2[]
Definition: msg.c:17467
static const struct message ScrollWindowPaint1[]
Definition: msg.c:11046
static const struct message WmShowRestoreMaxOverlappedSeq[]
Definition: msg.c:549
static const struct message WmMinMax_1[]
Definition: msg.c:13231
static const struct message WmShiftMouseButton[]
Definition: msg.c:9022
#define X(f)
static const struct message WmTrackPopupMenuAbort[]
Definition: msg.c:1982
static const struct message WmCtrlAltVkN[]
Definition: msg.c:8922
static const struct message WmSetStateStaticSeq[]
Definition: msg.c:6140
static const struct message WmKeyDownSkippedSeq[]
Definition: msg.c:11738
static const struct message WmSetMenuNonVisibleSizeChangeSeq[]
Definition: msg.c:1679
static LPCPINFOEXA
Definition: msg.c:2019
static LRESULT WINAPI ShowWindowProcA(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
Definition: msg.c:9693
static void test_PostMessage(void)
Definition: msg.c:15879
static const struct message ScrollWindowPaint2[]
Definition: msg.c:11060
static DWORD CALLBACK wait_idle_thread(void *arg)
Definition: msg.c:16256
static void test_MsgWaitForMultipleObjects(HWND hwnd)
Definition: msg.c:4963
static const struct message WmSetParentStyle[]
Definition: msg.c:7884
static const struct message send_message_3[]
Definition: msg.c:17471
static void test_SetParent(void)
Definition: msg.c:16391
static const struct message WmHideChildInvisibleParentSeq[]
Definition: msg.c:1380
static DWORD exception
Definition: msg.c:10227
static const struct message WmWinEventAlertSeq[]
Definition: msg.c:10471
static const struct message WmSHOWNAChildInvisParInvis[]
Definition: msg.c:1875
static TIMERPROC
Definition: msg.c:2015
static const struct message WmShowChildSeq_2[]
Definition: msg.c:1267
static void register_wmime_keydown_class(void)
Definition: msg.c:7654
static HANDLE
Definition: msg.c:78
static const struct message WmSWP_ResizePopupSeq[]
Definition: msg.c:270
static const struct message WmKeyPressRepeat[]
Definition: msg.c:16477
static void CALLBACK apc_test_proc(ULONG_PTR param)
Definition: msg.c:4958
static const struct message WmKeyPressNormal[]
Definition: msg.c:16472
#define EV_ACK
Definition: msg.c:11762
static INT_PTR CALLBACK TestModalDlgProcA(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
Definition: msg.c:4390
static const struct message WmShowChildInvisibleParentSeq_5[]
Definition: msg.c:1375
static void test_unicode_wm_char(void)
Definition: msg.c:14654
static DWORD WINAPI thread_proc(void *param)
Definition: msg.c:8529
static void test_SetWindowRgn(void)
Definition: msg.c:13023
static DWORD CALLBACK show_window_thread(LPVOID arg)
Definition: msg.c:5078
static BOOL test_def_id
Definition: msg.c:1998
static LRESULT WINAPI test_dlg_proc4(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
Definition: msg.c:13618
static void test_wmime_keydown_message(void)
Definition: msg.c:7665
static const struct message WmShowRestoreMinOverlappedSeq[]
Definition: msg.c:572
static HWINEVENTHOOK(WINAPI *pSetWinEventHook)(DWORD
static const struct message SetFocusButtonSeq2[]
Definition: msg.c:7354
static const struct message WmSetScrollRangeSeq[]
Definition: msg.c:1814
static void test_timers_exception(DWORD code)
Definition: msg.c:10395
static void test_timers_no_wnd(void)
Definition: msg.c:10325
static const struct message NCXBUTTONUPSeq2[]
Definition: msg.c:15464
static const struct message WmWinEventCaretSeq_2[]
Definition: msg.c:10465
static const struct message WmSetScrollRangeVSeq_empty[]
Definition: msg.c:1828
static void check_update_rgn_(int line, HWND hwnd, HRGN hrgn)
Definition: msg.c:7717
static BOOL ignore_message(UINT message)
Definition: msg.c:2077
static const struct message WmShowChildInvisibleParentSeq_3r[]
Definition: msg.c:1349
static const struct message SetActiveWindowSeq3[]
Definition: msg.c:14188
#define TIMER_COUNT_EXPECTED
Definition: msg.c:10218
static LPARAM
Definition: msg.c:14860
static void test_keyflags(void)
Definition: msg.c:16488
static void test_autoradio_kbd_move(void)
Definition: msg.c:6995
static const struct message WmShowChildInvisibleParentSeq_4r[]
Definition: msg.c:1370
static CRITICAL_SECTION sequence_cs
Definition: msg.c:2002
static const struct message WmMaximizeMDIchildInvisibleSeq2[]
Definition: msg.c:3456
static void test_TrackMouseEvent(void)
Definition: msg.c:12793
static const struct message WmCreateMDIclientSeq[]
Definition: msg.c:2637
static const struct message WmWinEventsSeq[]
Definition: msg.c:10431
static const struct message WmShowChildSeq_4[]
Definition: msg.c:1286
#define test_msg_setpos(expected_list, flags, todo)
Definition: msg.c:5089
static const struct message WmShowMinNoActivate[]
Definition: msg.c:13223
static LRESULT WINAPI DispatchMessageCheckProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
Definition: msg.c:11279
static const WCHAR testWindowClassW[]
Definition: msg.c:121
static const struct message WmInvalidateRgn[]
Definition: msg.c:7753
static void test_SendMessage_other_thread(int thread_n)
Definition: msg.c:17525
static void test_hv_scroll_1(HWND hwnd, INT ctl, DWORD clear, DWORD set, INT min, INT max)
Definition: msg.c:4451
static const struct message WmHide_1[]
Definition: msg.c:13161
#define expect_HWND(expected, got)
Definition: msg.c:15725
static const struct message SetActiveWindowSeq2[]
Definition: msg.c:14160
static LRESULT WINAPI PopupMsgCheckProcA(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
Definition: msg.c:9542
static const struct message auto_radio_button_BM_CLICK[]
Definition: msg.c:6731
static const struct message WmInvalidateParentChild2[]
Definition: msg.c:7834
static const struct message WmSWP_ShowOverlappedSeq[]
Definition: msg.c:191
static const struct message WmCreateChildSeq[]
Definition: msg.c:1185
#define EV_SENDMSG
Definition: msg.c:11761
static HHOOK hKBD_hook
Definition: msg.c:117
static void test_SetForegroundWindow(void)
Definition: msg.c:14299
static INT_PTR WINAPI test_dlg_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
Definition: msg.c:13544
static const struct message WmEnableWindowSeq_3[]
Definition: msg.c:1791
static const struct message WmInitEndSession_2[]
Definition: msg.c:4899
#define check_lb_state(a1, a2, a3, a4, a5)
Definition: msg.c:14858
static const struct message DoubleSetCaptureSeq[]
Definition: msg.c:17698
static void test_quit_message(void)
Definition: msg.c:12585
static const struct message WmCreateDialogParamSeq_0[]
Definition: msg.c:13673
static const struct message WmSHOWNATopInvisible[]
Definition: msg.c:1905
static const struct message WmInitEndSession_3[]
Definition: msg.c:4906
static WNDPROC old_button_proc
Definition: msg.c:6210
static LRESULT WINAPI mdi_client_hook_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
Definition: msg.c:3642
#define SWP_NOCLIENTMOVE
Definition: msg.c:41
static const struct message WmRestoreMinimizedSeq[]
Definition: msg.c:17725
static void test_defwinproc(void)
Definition: msg.c:15536
static const struct message WmTrackPopupMenu[]
Definition: msg.c:1928
static const struct message auto_radio_button_VK_DOWN_radio3[]
Definition: msg.c:6868
void dump_region(HRGN hrgn)
Definition: msg.c:7695
static const struct message WmSetFontButtonSeq[]
Definition: msg.c:6044
static const struct message WmSwitchChild[]
Definition: msg.c:325
#define ARCH
Definition: msg.c:71
static LRESULT CALLBACK combobox_lbox_subclass_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
Definition: msg.c:7404
static DWORD WINAPI cbt_global_hook_thread_proc(void *param)
Definition: msg.c:10625
static const struct message WmUserKeyUpSkippedSeq[]
Definition: msg.c:11753
static void test_menu_messages(void)
Definition: msg.c:15273
static const struct message WmSetIcon_2[]
Definition: msg.c:4886
static const struct message WmSWP_ResizeNoZOrder[]
Definition: msg.c:304
static const struct message WmCreateInvisiblePopupSeq[]
Definition: msg.c:907
static const struct message WmInvalidatePaint[]
Definition: msg.c:7779
static DWORD get_input_codepage(void)
Definition: msg.c:14322
static const struct message WmFirstDrawChildSeq1[]
Definition: msg.c:1173
static LRESULT WINAPI mdi_frame_wnd_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
Definition: msg.c:3716
static void CALLBACK callback_count(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
Definition: msg.c:10222
#define ok_sequence(exp, contx, todo)
Definition: msg.c:2389
static void ULONG
Definition: msg.c:78
static LRESULT WINAPI send_msg_delay_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
Definition: msg.c:11393
#define DUMP(flag)
static void create_manifest_file(const char *filename, const char *manifest)
Definition: msg.c:8615
static const struct message WmParentErasePaint[]
Definition: msg.c:7865
static const struct message WmSetCheckStaticSeq[]
Definition: msg.c:6202
static const struct message WmSetScrollRangeHSeq_empty[]
Definition: msg.c:1823
static const struct message WmKeyReleaseOnly[]
Definition: msg.c:16467
static const struct message WmCtrlShiftVkN[]
Definition: msg.c:8945
static const WCHAR dummy_window_text[]
Definition: msg.c:10065
static const struct message WmHotkeyReleaseLWIN[]
Definition: msg.c:16610
static LRESULT WINAPI TestDlgProcA(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
Definition: msg.c:9659
static const struct message WmFirstDrawSetWindowPosSeq1[]
Definition: msg.c:1053
static const struct message WmLButtonUpStaticSeq[]
Definition: msg.c:6017
#define WM_SYSTIMER
Definition: msg.c:51
static const struct message WmShowChildSeq[]
Definition: msg.c:1238
static const struct message WmGetTextLengthAfromW[]
Definition: msg.c:10059
static const struct message WmRestoreMDIchildInvisibleSeq[]
Definition: msg.c:3622
static const struct message auto_radio_button_VK_DOWN_dialog[]
Definition: msg.c:6816
static const struct message WmShowNormal[]
Definition: msg.c:13055
#define STEP
Definition: msg.c:12311
static const struct message WmFirstDrawSetWindowPosSeq3[]
Definition: msg.c:1105
static void test_msg_setpos_(const struct message *expected_list, UINT flags, BOOL todo, const char *file, int line)
Definition: msg.c:5091
static HWND mdi_client
Definition: msg.c:3639
static const struct message WmKeyDownWasDownSkippedSeq[]
Definition: msg.c:11743
static const struct message WmShowChildSeq_3[]
Definition: msg.c:1277
static void test_enddialog_seq(HWND dialog, HWND owner)
Definition: msg.c:13952
static LPCMENUINFO
Definition: msg.c:2006
static HWND
Definition: msg.c:2007
static const struct message WmSetStateUserSeq[]
Definition: msg.c:6147
static const struct message WmHide_3[]
Definition: msg.c:13176
static const struct message WmSetFocusStaticSeq[]
Definition: msg.c:5921
static const struct message wm_lb_click_0[]
Definition: msg.c:14778
static const struct message send_message_1[]
Definition: msg.c:17462
static void invisible_parent_tests(void)
Definition: msg.c:5727
static void test_scroll_messages(HWND hwnd)
Definition: msg.c:4548
static void test_TrackPopupMenuEmpty(void)
Definition: msg.c:17437
static const struct message WmMouseHoverSeq[]
Definition: msg.c:12740
static const struct message WmShowVisMaxPopupSeq[]
Definition: msg.c:877
static void test_SetActiveWindow(void)
Definition: msg.c:14232
static const struct message WmGlobalHookSeq_1[]
Definition: msg.c:10482
static LRESULT WINAPI cancel_init_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
Definition: msg.c:17363
static void test_PeekMessage2(void)
Definition: msg.c:12312
static const struct message WmSetStateOwnerdrawSeq[]
Definition: msg.c:6155
static const struct message WmMinimize_2[]
Definition: msg.c:13204
static const struct message WmFirstDrawSetWindowPosSeq5[]
Definition: msg.c:1149
static LRESULT WINAPI MsgCheckProcA(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
Definition: msg.c:9532
static const struct message WmShowMaxOverlappedSeq[]
Definition: msg.c:507
static DWORD CALLBACK create_child_thread(void *param)
Definition: msg.c:8573
static const struct message WmSetRedrawTrueSeq[]
Definition: msg.c:1768
static int sequence_size
Definition: msg.c:1999
static const struct message WmCreateMaximizedChildSeq[]
Definition: msg.c:1198
static const struct message WmSetTextStaticSeq[]
Definition: msg.c:6070
static void test_WM_DEVICECHANGE(HWND hwnd)
Definition: msg.c:5037
#define ID_TEXT
Definition: msg.c:6729
static void flush_sequence(void)
Definition: msg.c:2300
static const struct message WmSetPosComboSeq[]
Definition: msg.c:7297
static WPARAM
Definition: msg.c:14860
static void CALLBACK win_event_global_hook_proc(HWINEVENTHOOK hevent, DWORD event, HWND hwnd, LONG object_id, LONG child_id, DWORD thread_id, DWORD event_time)
Definition: msg.c:10505
static const struct message WmSetWindowRgn_no_redraw[]
Definition: msg.c:12989
static void test_enddialog_seq2(HWND dialog, HWND owner)
Definition: msg.c:13977
static const struct message WmPaint[]
Definition: msg.c:7807
static const struct message WmResizingChildWithMoveWindowSeq[]
Definition: msg.c:1440
#define SWP_STATECHANGED
Definition: msg.c:42
static void test_message_conversion(void)
Definition: msg.c:10082
static void subclass_button(void)
Definition: msg.c:6263
static LPARAM g_broadcast_lparam
Definition: msg.c:15939
static void CALLBACK msg_callback(HWND hwnd, UINT msg, ULONG_PTR arg, LRESULT result)
Definition: msg.c:17651
static LRESULT CALLBACK get_text_len_proc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
Definition: msg.c:10068
static const struct message WmShowNA_2[]
Definition: msg.c:13103
static const struct message WmRestore_3[]
Definition: msg.c:13130
static LRESULT WINAPI HotkeyMsgCheckProcA(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
Definition: msg.c:9807
static void test_mdi_messages(void)
Definition: msg.c:3778
static const struct message WmShowCustomDialogSeq[]
Definition: msg.c:1536
static int hook_depth
Definition: msg.c:11000
#define test_radio(r1, s1, r2, s2, r3, s3)
Definition: msg.c:6975
static const struct message WmGetScrollRangeSeq[]
Definition: msg.c:1804
#define EV_STOP
Definition: msg.c:11760
#define WM_LBTRACKPOINT
Definition: msg.c:59
static const struct message WmModalDialogSeq_2[]
Definition: msg.c:1651
static void test_winevents(void)
Definition: msg.c:10692
static const struct message wm_popup_menu_3[]
Definition: msg.c:15148
static void test_radio_dbg(HWND radio1, int state1, HWND radio2, int state2, HWND radio3, int state3, int line)
Definition: msg.c:6976
static const struct message WmKillFocusOwnerdrawSeq[]
Definition: msg.c:5961
static LRESULT CALLBACK cbt_hook_proc(int nCode, WPARAM wParam, LPARAM lParam)
Definition: msg.c:9955
static const struct message WmErase[]
Definition: msg.c:7802
static const struct message WmWinEventCaretSeq[]
Definition: msg.c:10458
static LPMONITORINFO
Definition: msg.c:2012
static void test_paintingloop(void)
Definition: msg.c:15425
#define WND_PARENT_ID
Definition: msg.c:54
static const struct message SetCurSelComboSeq2[]
Definition: msg.c:7266
static void test_recursive_hook(void)
Definition: msg.c:11021
static const struct message WmDestroyMDIclientSeq[]
Definition: msg.c:2672
static const struct message WmHotkeyPress[]
Definition: msg.c:16599
static void test_broadcast(void)
Definition: msg.c:15952
static const struct message WmHotkeyPrevious[]
Definition: msg.c:16632
static const struct message WmOptionalPaint[]
Definition: msg.c:4926
static const struct message WmHotkeyNew[]
Definition: msg.c:16647
static const struct message WmLButtonUpSeq[]
Definition: msg.c:6007
static const struct message WmShowPopupExtremeLocationSeq[]
Definition: msg.c:950
static HHOOK hCBT_hook
Definition: msg.c:118
static const struct message sl_edit_killfocus[]
Definition: msg.c:11524
static HHOOK hCBT_global_hook
Definition: msg.c:10533
static const struct message WmSWP_FrameChanged_clip[]
Definition: msg.c:412
static void init_tests()
Definition: msg.c:18003
static const struct message WmParentPaint[]
Definition: msg.c:7842
static BOOL paint_loop_done
Definition: msg.c:1998
static DWORD cbt_global_hook_thread_id
Definition: msg.c:10534
static LRESULT WINAPI rec_get_message_hook(int code, WPARAM w, LPARAM l)
Definition: msg.c:11002
static const struct message WmKeyUpSkippedSeq[]
Definition: msg.c:11748
static void flush_events(void)
Definition: msg.c:2285
static const struct message wm_lb_addstring_ownerdraw[]
Definition: msg.c:14834
static const struct message WmSetParentSeq_1[]
Definition: msg.c:16348
static LRESULT CALLBACK cbt_global_hook_proc(int nCode, WPARAM wParam, LPARAM lParam)
Definition: msg.c:10536
static const struct message WmNotifySeq[]
Definition: msg.c:12676
static void wait_for_thread(HANDLE thread)
Definition: msg.c:11384
static const struct message WmUser[]
Definition: msg.c:11361
static const struct message WmShowMaxPopupSeq[]
Definition: msg.c:810
static const struct message WmCreateDialogParamSeq_2[]
Definition: msg.c:13711
static const struct message WmSetWindowRgn[]
Definition: msg.c:12978
static const struct message WmShowMaximized_3[]
Definition: msg.c:13290
static const struct message WmClearStateOwnerdrawSeq[]
Definition: msg.c:6188
static const struct message WmMaximizeMDIchildInvisibleParentSeq[]
Definition: msg.c:3484
static BOOL after_end_dialog
Definition: msg.c:1998
static const struct message WmEnableWindowSeq_1[]
Definition: msg.c:1774
#define MDI_FIRST_CHILD_ID
Definition: msg.c:37
static INT_PTR CALLBACK TestModalDlgProc2(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
Definition: msg.c:4421
static const struct message WmExitThreadSeq[]
Definition: msg.c:1422
static void test_PeekMessage(void)
Definition: msg.c:11804
static const struct message NCXBUTTONUPSeq1[]
Definition: msg.c:15458
static const struct message WmImeKeydownMsgSeq_1[]
Definition: msg.c:7632
static void test_EndDialog(void)
Definition: msg.c:13998
static const struct message WmParentOnlyPaint[]
Definition: msg.c:7812
#define WND_POPUP_ID
Definition: msg.c:55
static const struct message WmShowChildInvisibleParentSeq_1[]
Definition: msg.c:1292
static WNDPROC lbox_window_proc
Definition: msg.c:7369
static const struct message WmSetCheckIgnoredSeq[]
Definition: msg.c:6196
static const struct message WmCreateCustomDialogSeq[]
Definition: msg.c:1452
static void set_radio(HWND radio1, int state1, HWND radio2, int state2, HWND radio3, int state3)
Definition: msg.c:6988
static const struct message WmShowPopupFirstDrawSeq_2[]
Definition: msg.c:1015
static LRESULT WINAPI mdi_child_wnd_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
Definition: msg.c:3668
static const struct message WmShowChildInvisibleParentSeq_2r[]
Definition: msg.c:1327
static const struct message WmHide_2[]
Definition: msg.c:13169
static const struct message WmSetFocusOwnerdrawSeq[]
Definition: msg.c:5948
static const struct message WmShowMinOverlappedSeq[]
Definition: msg.c:620
static const struct message WmQuitDialogSeq[]
Definition: msg.c:12566
#define TIMER_COUNT_TOLERANCE
Definition: msg.c:10219
static const struct message WmMaximizeMDIchildInvisibleSeq[]
Definition: msg.c:3424
static const struct message WmKillFocusStaticSeq[]
Definition: msg.c:5934
static void test_listbox_messages(void)
Definition: msg.c:14915
static DWORD WINAPI timer_thread_proc(LPVOID x)
Definition: msg.c:10234
static DWORD cbt_hook_thread_id
Definition: msg.c:119
static const WCHAR wszUnicode[]
Definition: msg.c:10041
static const struct message WmSetIcon_1[]
Definition: msg.c:4877
static const struct message wm_lb_deletestring[]
Definition: msg.c:14810
static const struct message WmCreateMaxPopupSeq[]
Definition: msg.c:715
static const struct message WmModalDialogSeq[]
Definition: msg.c:1565
static const struct message WmHideChildInvisibleParentSeq_2[]
Definition: msg.c:1392
static const struct message WmHideOverlappedSeq[]
Definition: msg.c:679
static const struct @1722 wait_idle_expect[]
static LRESULT CALLBACK insendmessage_wnd_proc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
Definition: msg.c:17606
static struct recvd_message * sequence
Definition: msg.c:2000
static const struct message WmClearStateButtonSeq[]
Definition: msg.c:6163
static LRESULT WINAPI ParentMsgCheckProcA(HWND, UINT, WPARAM, LPARAM)
Definition: msg.c:9580
static void test_scrollwindowex(void)
Definition: msg.c:11065
static void pump_msg_loop(HWND hwnd, HACCEL hAccel)
Definition: msg.c:9117
static LRESULT CALLBACK combobox_edit_subclass_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
Definition: msg.c:7371
static int sequence_cnt
Definition: msg.c:1999
static LRESULT WINAPI parent_menu_proc(HWND hwnd, UINT message, WPARAM wp, LPARAM lp)
Definition: msg.c:15212
BOOL todo
Definition: msg.c:16059
static const struct message WmRestoreMDIchildVisibleSeq_2[]
Definition: msg.c:3588
static const struct message WmGlobalHookSeq_2[]
Definition: msg.c:10490
static void test_DoubleSetCapture(void)
Definition: msg.c:17704
static const struct message WmInvalidateErasePaint2[]
Definition: msg.c:7794
static const struct message WmFirstDrawSetWindowPosSeq2[]
Definition: msg.c:1080
static const struct message WmKeyDownComboSeq[]
Definition: msg.c:7286
#define expect(EXPECTED, GOT)
Definition: msg.c:2575
static const struct message WmEmptySeq[]
Definition: msg.c:171
static LRESULT CALLBACK edit_hook_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
Definition: msg.c:11600
static const struct message WmSetScrollRangeHVSeq[]
Definition: msg.c:1833
static const struct message WmDisableButtonSeq[]
Definition: msg.c:6171
static const struct message wm_single_menu_item[]
Definition: msg.c:15185
static const struct message WmDefDlgSetFocus_1[]
Definition: msg.c:13641
static const struct message WmShowMaximized_1[]
Definition: msg.c:13261
static void test_showwindow(void)
Definition: msg.c:4635
static const struct message ml_edit_lbutton_up[]
Definition: msg.c:11590
static const struct message WmSetMenuVisibleSizeChangeSeq[]
Definition: msg.c:1702
static LRESULT CALLBACK recursive_viewer_proc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
Definition: msg.c:15733
static const struct message wm_popup_menu_2[]
Definition: msg.c:15112
static void CALLBACK callback_exception(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
Definition: msg.c:10228
static const struct message WmCtrlVkN_2[]
Definition: msg.c:8859
static ULONG_PTR
Definition: msg.c:76
static void test_ShowWindow(void)
Definition: msg.c:13303
static const struct message wm_popup_menu_1[]
Definition: msg.c:15086
static UINT_PTR
Definition: msg.c:2015
static BOOL is_our_logged_class(HWND hwnd)
Definition: msg.c:9926
static const struct message WmSetStyleStaticSeq[]
Definition: msg.c:6100
static const struct message WmInvalidateFull[]
Definition: msg.c:7766
static WINEVENTPROC
Definition: msg.c:2009
static const struct message SetActiveWindowSeq0[]
Definition: msg.c:14126
static LRESULT CALLBACK KeyboardHookProc(int nCode, WPARAM wParam, LPARAM lParam)
Definition: msg.c:16658
static struct message WmContextMenuSeq[]
Definition: msg.c:15510
static const struct message WmGetUpdateRect[]
Definition: msg.c:7759
static void add_message_(int line, const struct recvd_message *msg)
Definition: msg.c:2110
static const struct message WmSetTextGroupSeq[]
Definition: msg.c:6077
static const struct message WmMinMax_4[]
Definition: msg.c:13257
static void test_TrackPopupMenu(void)
Definition: msg.c:17376
static LRESULT WINAPI recursive_activation_wndprocA(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
Definition: msg.c:9736
static const struct message NCRBUTTONDOWNSeq[]
Definition: msg.c:15449
static const struct message WmZOrder[]
Definition: msg.c:4934
static const struct message WmSWP_FrameChangedDeferErase[]
Definition: msg.c:429
static const struct message WmInitEndSession_5[]
Definition: msg.c:4920
static LRESULT WINAPI broadcast_test_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
Definition: msg.c:15940
static const struct message WmTrackPopupMenuEsc[]
Definition: msg.c:1945
static LRESULT CALLBACK wait_idle_proc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
Definition: msg.c:16250
static const struct message sl_edit_invisible[]
Definition: msg.c:11499
static const struct message WmShowVisiblePopupSeq_3[]
Definition: msg.c:929
static const struct message SetCurSelComboSeq_edit[]
Definition: msg.c:7278
static const struct message WmMouseLLHookSeq[]
Definition: msg.c:10498
static void test_combobox_messages(void)
Definition: msg.c:7483
static const struct message WmEnableWindowSeq_4[]
Definition: msg.c:1798
static const struct message WmRestoreMinimizedOverlappedSeq[]
Definition: msg.c:15471
static const struct message WmEndCustomDialogSeq[]
Definition: msg.c:1511
static const struct message WmParentPaintNc[]
Definition: msg.c:7848
static int max_hook_depth
Definition: msg.c:11000
static const struct message WmVkF10Seq[]
Definition: msg.c:9060
static POINT SIZE POINT COLORREF
Definition: msg.c:2014
static WNDPROC pOldViewerProc
Definition: msg.c:15731
static const struct message WmSetTextButtonSeq[]
Definition: msg.c:6061
static BOOL test_DestroyWindow_flag
Definition: msg.c:114
static const struct message WmCreateOverlappedSeq[]
Definition: msg.c:176
static LRESULT WINAPI dlg_creation_edit_proc(HWND hwnd, UINT message, WPARAM wp, LPARAM lp)
Definition: msg.c:13572
static unsigned hash_Ly(const char *str)
Definition: msg.c:2099
static LRESULT WINAPI cancel_popup_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
Definition: msg.c:17341
static void init_funcs(void)
Definition: msg.c:17831
static DWORD CALLBACK send_msg_thread(LPVOID arg)
Definition: msg.c:11373
static const struct message WmDefDlgSetFocus_2[]
Definition: msg.c:13661
static const struct message WmCtrlAltShiftVkN[]
Definition: msg.c:8966
static const struct message WmSWP_FrameChanged_noclip[]
Definition: msg.c:447
static INT_PTR WINAPI test_dlg_proc2(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
Definition: msg.c:13589
static int log_all_parent_messages
Definition: msg.c:2001
static WNDPROC edit_window_proc
Definition: msg.c:7369
static DWORD WINAPI mouse_ll_global_thread_proc(void *param)
Definition: msg.c:10661
static const struct message WmShowChildInvisibleParentSeq_6[]
Definition: msg.c:1385
#define ID_LISTBOX
Definition: msg.c:14745
static const struct message WmLButtonDownStaticSeq[]
Definition: msg.c:5992
static const struct message WmShowNoActivate_2[]
Definition: msg.c:13081
static const struct message WmDestroyMDIchildVisibleSeq[]
Definition: msg.c:2784
static const struct message WmTrackPopupMenuCapture[]
Definition: msg.c:1949
static const struct message WmGetScrollInfoSeq[]
Definition: msg.c:1809
static const struct message SetActiveWindowSeq4[]
Definition: msg.c:14207
static const struct message WmShowMinimized_1[]
Definition: msg.c:13184
static const struct message WmLButtonDownSeq[]
Definition: msg.c:5977
static const struct message WmSHOWNATopVisible[]
Definition: msg.c:1896
static const struct message WmShowOverlappedSeq[]
Definition: msg.c:462
#define check_update_rgn(hwnd, hrgn)
Definition: msg.c:7716
static const struct message WmF1Seq[]
Definition: msg.c:9037
static const struct message auto_radio_button_VK_UP_child[]
Definition: msg.c:6763
static const struct message WmDestroyChildSeq[]
Definition: msg.c:1399
static unsigned hash_Ly_W(const WCHAR *str)
Definition: msg.c:2089
static const struct message WmSHOWNAChildVisParInvis[]
Definition: msg.c:1879
static const struct message WmAltPressRelease[]
Definition: msg.c:8993
static const struct message WmSHOWNAChildVisParVis[]
Definition: msg.c:1883
static const struct message WmCreateDialogParamSeq_3[]
Definition: msg.c:13723
static const struct message WmCreateMDIchildInvisibleSeq[]
Definition: msg.c:2853
static void test_hotkey(void)
Definition: msg.c:16684
static const struct message WmSetLayeredStyle2[]
Definition: msg.c:17177
static BOOL RegisterWindowClasses(void)
Definition: msg.c:9850
#define check_selection(hctl, start, end)
static WNDPROC old_mdi_client_proc
Definition: msg.c:3640
static void test_timers_exceptions(void)
Definition: msg.c:10416
static HMENU hpopupmenu
Definition: msg.c:17339
static void expect_HWND_(int line, HWND expected, HWND got)
Definition: msg.c:15726
#define SW_NORMALNA
Definition: msg.c:44
static const struct message WmStopQuitSeq[]
Definition: msg.c:12578
static void test_button_bm_get_set_image(void)
Definition: msg.c:6611
static INT_PTR WINAPI test_dlg_proc3(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
Definition: msg.c:13612
static const struct message WmSetStyleOwnerdrawSeq[]
Definition: msg.c:6121
static const struct message SetFocusButtonSeq[]
Definition: msg.c:7325
static void test_dbcs_wm_char(void)
Definition: msg.c:14334
static void test_interthread_messages(void)
Definition: msg.c:8655
static LRESULT WINAPI listbox_hook_proc(HWND hwnd, UINT message, WPARAM wp, LPARAM lp)
Definition: msg.c:14862
static const struct message wm_lb_deletestring_reset[]
Definition: msg.c:14818
static void check_lb_state_dbg(HWND listbox, int count, int cur_sel, int caret_index, int top_index, int line)
Definition: msg.c:14897
static DWORD CALLBACK create_grand_child_thread(void *param)
Definition: msg.c:8551
#define clear_clipboard(hwnd)
Definition: msg.c:15713
static const struct message WmHotkeyCombined[]
Definition: msg.c:16616
static const struct message WmDestroyMDIchildVisibleMaxSeq2[]
Definition: msg.c:3165
static LRESULT CALLBACK MsgConversionProcW(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
Definition: msg.c:10044
static VOID CALLBACK tfunc(HWND hwnd, UINT uMsg, UINT_PTR id, DWORD dwTime)
Definition: msg.c:10213
static void test_set_hook(void)
Definition: msg.c:10897
static void wait_move_event(HWND hwnd, int x, int y)
Definition: msg.c:12296
static LONG
Definition: msg.c:2007
static const struct message sl_edit_lbutton_dblclk[]
Definition: msg.c:11536
static const struct message ml_edit_setfocus[]
Definition: msg.c:11510
#define TIMER_ID
Definition: msg.c:10217
static const struct message SetActiveWindowSeq1[]
Definition: msg.c:14154
static const struct message WmEnableWindowSeq_2[]
Definition: msg.c:1784
static const struct message wm_lb_addstring[]
Definition: msg.c:14827
static void set_menu_style(HMENU hmenu, DWORD style)
Definition: msg.c:15245
static const struct message auto_radio_button_VK_UP_radio1[]
Definition: msg.c:6883
static const struct message WmShowNA_1[]
Definition: msg.c:13097
static const char * get_winpos_flags(UINT flags)
Definition: msg.c:2051
static const struct message WmSetScrollRangeHV_NC_Seq[]
Definition: msg.c:1845
static const struct message WmHideMDIclientSeq[]
Definition: msg.c:2663
static const struct message WmShowMDIclientSeq[]
Definition: msg.c:2655
static DWORD CALLBACK update_layered_proc(void *param)
Definition: msg.c:17197
static HWND hook_hwnd
Definition: msg.c:10998
static const struct message WmCreateMDIchildVisibleMaxSeq1[]
Definition: msg.c:2887
static void test_setwindowpos(void)
Definition: msg.c:5698
static WNDPROC old_static_proc
Definition: msg.c:7167
static const struct message WmSetMenuVisibleNoSizeChangeSeq[]
Definition: msg.c:1732
static const struct message WmKeyReleaseNormal[]
Definition: msg.c:16482
static const struct message wm_lb_setcursel_0[]
Definition: msg.c:14747
static const struct message WmRestore_5[]
Definition: msg.c:13151
static void test_accelerators(void)
Definition: msg.c:9147
static const struct message wm_lb_setcursel_2[]
Definition: msg.c:14767
static DWORD WINAPI SendMessage_thread_1(void *param)
Definition: msg.c:17477
static const struct message WmCreatePopupSeq[]
Definition: msg.c:843
static void dump_sequence(const struct message *expected, const char *context, const char *file, int line)
Definition: msg.c:2309
static void test_SendMessageTimeout(void)
Definition: msg.c:11399
static const struct message WmInvalidateParent[]
Definition: msg.c:7817
static const struct message WmSetWindowRgn_clear[]
Definition: msg.c:12997
static HDC
Definition: msg.c:2014
static const struct message WmCreateVisibleChildSeq[]
Definition: msg.c:1217
static const struct message WmShowPopupFirstDrawSeq_1[]
Definition: msg.c:982
static const struct message WmSWP_HideOverlappedSeq[]
Definition: msg.c:234
#define ID_RADIO3
Definition: msg.c:6728
static const struct message ml_edit_lbutton_down[]
Definition: msg.c:11565
static const struct message WmRestore_1[]
Definition: msg.c:13109
static const struct message WmSetStateButtonSeq[]
Definition: msg.c:6133
static const struct message WmSwitchNotMaximizedChild[]
Definition: msg.c:380
static const struct message WmShiftVkN[]
Definition: msg.c:8825
static const struct message WmSetLayeredStyle[]
Definition: msg.c:17170
#define track_hover_cancel(track_hwnd)
static const struct message WmMaximizeMDIchildVisibleSeq[]
Definition: msg.c:3555
#define ID_EDIT
Definition: msg.c:11482
static const struct message WmSWP_ResizeSeq[]
Definition: msg.c:249
static const struct message WmRestore_4[]
Definition: msg.c:13143
static void clear_clipboard_(int line, HWND hWnd)
Definition: msg.c:15714
static const struct message sl_edit_setfocus[]
Definition: msg.c:11483
static const struct message WmHideChildSeq2[]
Definition: msg.c:1256
#define ID_COMBOBOX
Definition: msg.c:7249
static void test_hv_scroll_2(HWND hwnd, INT ctl, DWORD clear, DWORD set, INT min, INT max)
Definition: msg.c:4490
static const struct message WmMinimize_3[]
Definition: msg.c:13213
static const struct message WmHotkeyRelease[]
Definition: msg.c:16604
#define ID_RADIO2
Definition: msg.c:6727
static const struct message auto_radio_button_VK_UP_dialog[]
Definition: msg.c:6777
static const struct message WmShowChildInvisibleParentSeq_4[]
Definition: msg.c:1354
static const struct message WmInvalidateErase[]
Definition: msg.c:7772
static const struct message WmKillFocusButtonSeq[]
Definition: msg.c:5907
static const struct message WmSetParentSeq_2[]
Definition: msg.c:16360
static void test_timers(void)
Definition: msg.c:10249
static LRESULT CALLBACK button_hook_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
Definition: msg.c:6212
static const struct message WmSetTextInvisibleSeq[]
Definition: msg.c:6085
static LRESULT WINAPI PaintLoopProcA(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
Definition: msg.c:9778
static const struct message WmShow[]
Definition: msg.c:13064
static const struct message WmSetFocusButtonSeq[]
Definition: msg.c:5895
static const struct message WmSetFocus_2[]
Definition: msg.c:16963
static void subclass_combobox(void)
Definition: msg.c:7468
static const struct message WmDestroyInvisibleChildSeq[]
Definition: msg.c:1429
static DWORD WINAPI win_event_global_thread_proc(void *param)
Definition: msg.c:10596
static const struct message WmRestoreMDIchildVisibleSeq[]
Definition: msg.c:3572
static const struct message WmChildActivateWindowSeq[]
Definition: msg.c:2732
static const struct message WmCreateDialogParamSeq_1[]
Definition: msg.c:13687
static void ok_sequence_(const struct message *expected_list, const char *context, BOOL todo, const char *file, int line)
Definition: msg.c:2393
static void void SIZE_T
Definition: msg.c:78
#define track_hover(track_hwnd, track_hover_time)
static const char manifest_main[]
Definition: msg.c:8605
static UINT
Definition: msg.c:2005
static const struct message WmChildActivateDisabledWindowSeq[]
Definition: msg.c:2727
static HWND dialog
Definition: gui.c:33
#define min(a, b)
Definition: monoChain.cc:55
int k
Definition: mpi.c:3369
static void dump(const void *ptr, unsigned len)
Definition: msc.c:95
HKL hkl
Definition: msctf.idl:650
UINT_PTR HKL
Definition: msctf.idl:143
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
unsigned __int3264 UINT_PTR
Definition: mstsclib_h.h:274
HMONITOR WINAPI MonitorFromPoint(POINT, DWORD)
unsigned int UINT
Definition: ndis.h:50
HANDLE hThread
Definition: wizard.c:28
#define BOOL
Definition: nt_native.h:43
#define DWORD
Definition: nt_native.h:44
#define GENERIC_WRITE
Definition: nt_native.h:90
#define IMAGE_SUBSYSTEM_WINDOWS_GUI
Definition: ntimage.h:437
#define OBJ_FONT
Definition: objidl.idl:1414
#define LRESULT
Definition: ole.h:14
static HANDLE proc()
Definition: pdb.c:34
#define LOWORD(l)
Definition: pedump.c:82
#define BS_AUTORADIOBUTTON
Definition: pedump.c:660
#define WS_CHILD
Definition: pedump.c:617
#define WS_CAPTION
Definition: pedump.c:624
#define WS_OVERLAPPEDWINDOW
Definition: pedump.c:637
#define BS_USERBUTTON
Definition: pedump.c:659
#define LBS_SORT
Definition: pedump.c:679
#define WS_EX_NOPARENTNOTIFY
Definition: pedump.c:646
#define WS_MAXIMIZEBOX
Definition: pedump.c:632
#define WS_OVERLAPPED
Definition: pedump.c:615
#define WS_EX_DLGMODALFRAME
Definition: pedump.c:645
#define WS_MAXIMIZE
Definition: pedump.c:623
#define WS_TABSTOP
Definition: pedump.c:634
#define WS_SYSMENU
Definition: pedump.c:629
#define WS_BORDER
Definition: pedump.c:625
#define WS_POPUP
Definition: pedump.c:616
#define LBS_HASSTRINGS
Definition: pedump.c:684
#define WS_VSCROLL
Definition: pedump.c:627
#define LBS_OWNERDRAWVARIABLE
Definition: pedump.c:683
#define WS_MINIMIZE
Definition: pedump.c:622
#define WS_VISIBLE
Definition: pedump.c:620
short SHORT
Definition: pedump.c:59
#define BS_AUTOCHECKBOX
Definition: pedump.c:654
long LONG
Definition: pedump.c:60
#define BS_GROUPBOX
Definition: pedump.c:658
#define BS_OWNERDRAW
Definition: pedump.c:661
#define BS_3STATE
Definition: pedump.c:656
#define BS_CHECKBOX
Definition: pedump.c:653
#define WS_DISABLED
Definition: pedump.c:621
#define WS_DLGFRAME
Definition: pedump.c:626
#define SS_LEFT
Definition: pedump.c:692
#define WS_HSCROLL
Definition: pedump.c:628
#define BS_AUTO3STATE
Definition: pedump.c:657
#define LBS_NOTIFY
Definition: pedump.c:678
#define BS_RADIOBUTTON
Definition: pedump.c:655
#define WS_CLIPCHILDREN
Definition: pedump.c:619
#define BS_PUSHBUTTON
Definition: pedump.c:651
#define ES_MULTILINE
Definition: pedump.c:667
#define WS_MINIMIZEBOX
Definition: pedump.c:631
#define WS_THICKFRAME
Definition: pedump.c:630
#define BS_DEFPUSHBUTTON
Definition: pedump.c:652
#define TME_CANCEL
Definition: commctrl.h:4984
#define HOVER_DEFAULT
Definition: commctrl.h:4986
#define WM_MOUSEHOVER
Definition: commctrl.h:4974
#define TME_QUERY
Definition: commctrl.h:4983
#define TME_HOVER
Definition: commctrl.h:4980
#define WM_CONTEXTMENU
Definition: richedit.h:64
#define WM_PRINTCLIENT
Definition: richedit.h:70
#define WM_NOTIFY
Definition: richedit.h:61
#define test
Definition: rosglue.h:37
const WCHAR * str
DWORD LCID
Definition: nls.h:13
const char * winetest_platform
int winetest_debug
#define ros_skip_flaky
Definition: test.h:177
#define win_skip
Definition: test.h:160
int winetest_interactive
int winetest_get_mainargs(char ***pargv)
void winetest_wait_child_process(HANDLE process)
#define memset(x, y, z)
Definition: compat.h:39
static const WCHAR staticW[]
Definition: actctx.c:693
static FILE * client
Definition: client.c:41
static char argv0[MAX_PATH]
Definition: shlexec.c:49
DWORD dwTime
Definition: solitaire.cpp:27
& rect
Definition: startmenu.cpp:1413
UINT action
Definition: msg.c:91
UINT item_id
Definition: msg.c:90
UINT ctl_id
Definition: msg.c:89
UINT type
Definition: msg.c:88
LPARAM lp
Definition: msg.c:94
struct DRAW_ITEM_STRUCT::@1723::@1724 item
union DRAW_ITEM_STRUCT::@1723 u
UINT state
Definition: msg.c:92
LONG lfHeight
Definition: dimm.idl:42
LONG lfWeight
Definition: dimm.idl:46
CHAR lfFaceName[LF_FACESIZE]
Definition: dimm.idl:55
Definition: bl.h:1331
BOOL fIcon
Definition: winuser.h:3123
HBITMAP hbmColor
Definition: winuser.h:3127
HBITMAP hbmMask
Definition: winuser.h:3126
IMAGE_OPTIONAL_HEADER32 OptionalHeader
Definition: ntddk_ex.h:184
POINT ptMaxPosition
Definition: winuser.h:3294
RECT rcNormalPosition
Definition: winuser.h:3295
POINT ptMinPosition
Definition: winuser.h:3293
UINT flags
Definition: winuser.h:3594
HWND hwndInsertAfter
Definition: winuser.h:3589
HBRUSH hbrBackground
Definition: winuser.h:3170
HICON hIcon
Definition: winuser.h:3168
HINSTANCE hInstance
Definition: winuser.h:3167
HCURSOR hCursor
Definition: winuser.h:3169
int cbWndExtra
Definition: winuser.h:3166
UINT style
Definition: winuser.h:3163
LPCSTR lpszMenuName
Definition: winuser.h:3171
LPCSTR lpszClassName
Definition: winuser.h:3172
WNDPROC lpfnWndProc
Definition: winuser.h:3164
int cbClsExtra
Definition: winuser.h:3165
LPCWSTR lpszClassName
Definition: winuser.h:3185
LPCWSTR lpszMenuName
Definition: winuser.h:3184
HBRUSH hbrBackground
Definition: winuser.h:3183
HICON hIcon
Definition: winuser.h:3181
HINSTANCE hInstance
Definition: winuser.h:3180
int cbClsExtra
Definition: winuser.h:3178
UINT style
Definition: winuser.h:3176
WNDPROC lpfnWndProc
Definition: winuser.h:3177
int cbWndExtra
Definition: winuser.h:3179
HCURSOR hCursor
Definition: winuser.h:3182
UINT MaxCharSize
Definition: winnls.h:586
WCHAR UnicodeDefaultChar
Definition: winnls.h:589
BYTE LeadByte[MAX_LEADBYTES]
Definition: winnls.h:588
CHAR CodePageName[MAX_PATH]
Definition: winnls.h:591
Definition: ftp_var.h:139
Definition: inflate.c:139
Definition: http.c:7252
Definition: cookie.c:34
Definition: fci.c:127
Definition: _hash_fun.h:40
Definition: dhcpd.h:62
Definition: parser.c:49
Definition: tftpd.h:60
UINT message
Definition: SystemMenu.c:42
WPARAM wp_mask
Definition: SystemMenu.c:46
LPARAM lp_mask
Definition: SystemMenu.c:47
msg_flags_t flags
Definition: SystemMenu.c:43
HANDLE hevent[3]
Definition: msg.c:11767
HWND hwnd
Definition: msg.c:11766
HANDLE wndproc_finished
Definition: msg.c:15520
WPARAM wParam
Definition: SystemMenu.c:55
const char * descr
Definition: SystemMenu.c:58
char output[512]
Definition: SystemMenu.c:59
msg_flags_t flags
Definition: SystemMenu.c:53
LPARAM lParam
Definition: SystemMenu.c:56
HWND hwnd
Definition: msg.c:11368
DWORD timeout
Definition: msg.c:11369
DWORD ret
Definition: msg.c:11370
ULONG_PTR itemData1
Definition: winuser.h:2994
ULONG_PTR itemData2
Definition: winuser.h:2996
ULONG_PTR itemData
Definition: winuser.h:3646
POINT ptMaxPosition
Definition: winuser.h:3629
POINT ptMaxSize
Definition: winuser.h:3628
POINT ptMinTrackSize
Definition: winuser.h:3630
POINT ptReserved
Definition: winuser.h:3627
POINT ptMaxTrackSize
Definition: winuser.h:3631
RECT rcMonitor
Definition: winuser.h:3785
DWORD cbSize
Definition: winuser.h:3784
long y
Definition: polytest.cpp:48
long x
Definition: polytest.cpp:48
LONG right
Definition: windef.h:308
LONG bottom
Definition: windef.h:309
LONG top
Definition: windef.h:307
LONG left
Definition: windef.h:306
Definition: dhcpd.h:245
HANDLE handles[2]
Definition: msg.c:10209
DWORD id
Definition: msg.c:10210
HWND hWnd
Definition: msg.c:10208
HANDLE grand_child
Definition: msg.c:8524
HWND hwnd
Definition: input.c:2591
HANDLE stop_event
Definition: msg.c:8526
HANDLE start_event
Definition: input.c:2593
#define max(a, b)
Definition: svc.c:63
DWORD WINAPI WaitForMultipleObjects(IN DWORD nCount, IN CONST HANDLE *lpHandles, IN BOOL bWaitAll, IN DWORD dwMilliseconds)
Definition: synch.c:151
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:790
VOID WINAPI InitializeCriticalSection(OUT LPCRITICAL_SECTION lpCriticalSection)
Definition: synch.c:751
HANDLE WINAPI DECLSPEC_HOTPATCH CreateEventA(IN LPSECURITY_ATTRIBUTES lpEventAttributes OPTIONAL, IN BOOL bManualReset, IN BOOL bInitialState, IN LPCSTR lpName OPTIONAL)
Definition: synch.c:637
HANDLE WINAPI DECLSPEC_HOTPATCH CreateEventW(IN LPSECURITY_ATTRIBUTES lpEventAttributes OPTIONAL, IN BOOL bManualReset, IN BOOL bInitialState, IN LPCWSTR lpName OPTIONAL)
Definition: synch.c:651
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:733
HANDLE WINAPI DECLSPEC_HOTPATCH OpenEventA(IN DWORD dwDesiredAccess, IN BOOL bInheritHandle, IN LPCSTR lpName)
Definition: synch.c:669
BOOL WINAPI DECLSPEC_HOTPATCH ResetEvent(IN HANDLE hEvent)
Definition: synch.c:714
#define ICON_SMALL
Definition: tnclass.cpp:48
#define LONG_PTR
Definition: treelist.c:79
#define GWLP_WNDPROC
Definition: treelist.c:66
#define GWLP_USERDATA
Definition: treelist.c:63
TW_UINT32 TW_UINT16 TW_UINT16 MSG
Definition: twain.h:1829
int32_t INT_PTR
Definition: typedefs.h:64
uint32_t DWORD_PTR
Definition: typedefs.h:65
ULONG_PTR SIZE_T
Definition: typedefs.h:80
int32_t INT
Definition: typedefs.h:58
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define MAKELONG(a, b)
Definition: typedefs.h:249
#define HIWORD(l)
Definition: typedefs.h:247
static const CHAR manifest[]
Definition: v6util.h:39
int ret
#define POINT
Definition: precomp.h:30
DWORD WINAPI InSendMessageEx(LPVOID lpReserved)
Definition: message.c:1391
BOOL WINAPI UpdateLayeredWindow(HWND hwnd, HDC hdcDst, POINT *pptDst, SIZE *psize, HDC hdcSrc, POINT *pptSrc, COLORREF crKey, BLENDFUNCTION *pbl, DWORD dwFlags)
Definition: window.c:1789
int WINAPI GetWindowTextA(HWND hWnd, LPSTR lpString, int nMaxCount)
Definition: window.c:1330
static MONITORINFO mi
Definition: win.c:7338
static HMENU hmenu
Definition: win.c:66
#define OBJID_TITLEBAR
Definition: winable.h:17
#define OBJID_ALERT
Definition: winable.h:25
#define OBJID_CARET
Definition: winable.h:23
#define OBJID_MENU
Definition: winable.h:18
#define OBJID_SYSMENU
Definition: winable.h:16
#define OBJID_SOUND
Definition: winable.h:26
UINT WINAPI SendInput(UINT, LPINPUT, int)
Definition: ntwrapper.h:344
#define OBJID_CURSOR
Definition: winable.h:24
void WINAPI NotifyWinEvent(DWORD, HWND, LONG, LONG)
Definition: hook.c:325
#define WINEVENT_INCONTEXT
Definition: winable.h:35
#define OBJID_SIZEGRIP
Definition: winable.h:22
HWINEVENTHOOK WINAPI SetWinEventHook(UINT, UINT, HMODULE, WINEVENTPROC, DWORD, DWORD, UINT)
Definition: hook.c:344
#define INPUT_KEYBOARD
Definition: winable.h:10
#define OBJID_VSCROLL
Definition: winable.h:20
BOOL WINAPI UnhookWinEvent(HWINEVENTHOOK)
#define OBJID_HSCROLL
Definition: winable.h:21
#define OBJID_CLIENT
Definition: winable.h:19
#define OBJID_WINDOW
Definition: winable.h:15
#define WINEVENT_OUTOFCONTEXT
Definition: winable.h:32
#define EXCEPTION_SINGLE_STEP
Definition: winbase.h:314
#define ZeroMemory
Definition: winbase.h:1712
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define STARTF_USESHOWWINDOW
Definition: winbase.h:491
HANDLE WINAPI GetCurrentThread(void)
Definition: proc.c:1148
DWORD WINAPI GetCurrentThreadId(void)
Definition: thread.c:459
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
#define WAIT_IO_COMPLETION
Definition: winbase.h:411
DWORD WINAPI GetCurrentProcessId(void)
Definition: proc.c:1158
#define EXCEPTION_ARRAY_BOUNDS_EXCEEDED
Definition: winbase.h:315
#define MAKEINTATOM(i)
Definition: winbase.h:1463
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
#define EXCEPTION_DATATYPE_MISALIGNMENT
Definition: winbase.h:312
void WINAPI DeleteCriticalSection(PCRITICAL_SECTION)
#define EXCEPTION_FLT_DENORMAL_OPERAND
Definition: winbase.h:316
#define WAIT_OBJECT_0
Definition: winbase.h:406
#define EXCEPTION_FLT_INEXACT_RESULT
Definition: winbase.h:318
#define EXCEPTION_ILLEGAL_INSTRUCTION
Definition: winbase.h:327
#define WAIT_FAILED
Definition: winbase.h:413
#define EXCEPTION_ACCESS_VIOLATION
Definition: winbase.h:311
#define EXCEPTION_BREAKPOINT
Definition: winbase.h:313
#define EXCEPTION_FLT_DIVIDE_BY_ZERO
Definition: winbase.h:317
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG _In_ LONG _In_ LONG x2
Definition: winddi.h:3710
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG _In_ LONG y1
Definition: winddi.h:3709
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG x1
Definition: winddi.h:3708
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG _In_ LONG _In_ LONG _In_ LONG y2
Definition: winddi.h:3711
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4023
LONG_PTR LPARAM
Definition: windef.h:208
LONG_PTR LRESULT
Definition: windef.h:209
UINT_PTR WPARAM
Definition: windef.h:207
void * arg
Definition: msvc.h:10
#define WINAPI
Definition: msvc.h:6
#define ERROR_INVALID_FILTER_PROC
Definition: winerror.h:908
#define ERROR_HOTKEY_NOT_REGISTERED
Definition: winerror.h:900
#define ERROR_INVALID_THREAD_ID
Definition: winerror.h:925
#define ERROR_HOOK_NEEDS_HMOD
Definition: winerror.h:909
#define ERROR_GEN_FAILURE
Definition: winerror.h:134
#define ERROR_WINDOW_OF_OTHER_THREAD
Definition: winerror.h:889
#define ERROR_NO_MORE_USER_HANDLES
Definition: winerror.h:680
#define ERROR_INVALID_HOOK_FILTER
Definition: winerror.h:907
#define ERROR_MESSAGE_SYNC_ONLY
Definition: winerror.h:681
#define ERROR_INVALID_WINDOW_HANDLE
Definition: winerror.h:881
#define ERROR_HOTKEY_ALREADY_REGISTERED
Definition: winerror.h:890
#define ERROR_MR_MID_NOT_FOUND
Definition: winerror.h:321
#define ERROR_INVALID_HOOK_HANDLE
Definition: winerror.h:885
#define ERROR_INVALID_FLAGS
Definition: winerror.h:583
#define ERROR_TIMEOUT
Definition: winerror.h:941
#define ERROR_NOACCESS
Definition: winerror.h:578
HGDIOBJ WINAPI GetStockObject(_In_ int)
int WINAPI GetObjectW(_In_ HANDLE h, _In_ int c, _Out_writes_bytes_opt_(c) LPVOID pv)
int WINAPI GetClipBox(_In_ HDC, _Out_ LPRECT)
HRGN WINAPI CreateRectRgn(_In_ int, _In_ int, _In_ int, _In_ int)
HFONT WINAPI CreateFontIndirectA(_In_ const LOGFONTA *)
#define RGN_DIFF
Definition: wingdi.h:358
#define NULLREGION
Definition: wingdi.h:361
HGDIOBJ WINAPI GetCurrentObject(_In_ HDC, _In_ UINT)
Definition: dc.c:428
#define DEFAULT_GUI_FONT
Definition: wingdi.h:909
HGDIOBJ WINAPI SelectObject(_In_ HDC, _In_ HGDIOBJ)
Definition: dc.c:1539
HDC WINAPI CreateCompatibleDC(_In_opt_ HDC hdc)
int WINAPI CombineRgn(_In_opt_ HRGN hrgnDest, _In_opt_ HRGN hrgnSrc1, _In_opt_ HRGN hrgnSrc2, _In_ int fnCombineMode)
#define WHITE_BRUSH
Definition: wingdi.h:902
#define SIMPLEREGION
Definition: wingdi.h:362
#define RGN_XOR
Definition: wingdi.h:360
#define RGN_OR
Definition: wingdi.h:359
HBITMAP WINAPI CreateCompatibleBitmap(_In_ HDC hdc, _In_ INT cx, _In_ INT cy)
#define FW_NORMAL
Definition: wingdi.h:373
#define SYSTEM_FONT
Definition: wingdi.h:911
DWORD WINAPI GetRegionData(_In_ HRGN hrgn, _In_ DWORD nCount, _Out_writes_bytes_to_opt_(nCount, return) LPRGNDATA lpRgnData)
BOOL WINAPI DeleteDC(_In_ HDC)
BOOL WINAPI SetRectRgn(_In_ HRGN, _In_ int, _In_ int, _In_ int, _In_ int)
int WINAPI GetRgnBox(_In_ HRGN, _Out_ LPRECT)
#define LOCALE_IDEFAULTANSICODEPAGE
Definition: winnls.h:38
#define MAX_LEADBYTES
Definition: winnls.h:14
#define SW_SHOWNORMAL
Definition: winuser.h:770
#define WM_PAINT
Definition: winuser.h:1620
HWND WINAPI GetFocus(void)
Definition: window.c:1893
#define HWND_MESSAGE
Definition: winuser.h:1210
#define LB_ERR
Definition: winuser.h:2432
#define CBS_OWNERDRAWFIXED
Definition: winuser.h:289
HWND WINAPI SetCapture(_In_ HWND hWnd)
#define GW_OWNER
Definition: winuser.h:766
int WINAPI ReleaseDC(_In_opt_ HWND, _In_ HDC)
#define WM_ERASEBKGND
Definition: winuser.h:1625
LRESULT WINAPI DispatchMessageA(_In_ const MSG *)
LRESULT WINAPI DefFrameProcA(_In_ HWND, _In_opt_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define HCBT_MINMAX
Definition: winuser.h:56
#define ODT_COMBOBOX
Definition: winuser.h:2539
#define SW_SHOWMAXIMIZED
Definition: winuser.h:773
#define WM_QUERYNEWPALETTE
Definition: winuser.h:1878
BOOL WINAPI EndMenu(void)
#define BS_BITMAP
Definition: winuser.h:258
#define MAKEWPARAM(l, h)
Definition: winuser.h:4009
#define QS_KEY
Definition: winuser.h:874
#define SetWindowLongPtrA
Definition: winuser.h:5345
BOOL WINAPI IsWindow(_In_opt_ HWND)
HWND WINAPI GetActiveWindow(void)
Definition: winpos.c:138
BOOL WINAPI ReplyMessage(_In_ LRESULT)
#define WM_CTLCOLORSTATIC
Definition: winuser.h:1772
HMENU WINAPI CreatePopupMenu(void)
Definition: menu.c:838
#define MK_SHIFT
Definition: winuser.h:2369
#define LB_GETCOUNT
Definition: winuser.h:2038
#define WM_GETTEXTLENGTH
Definition: winuser.h:1619
#define SW_HIDE
Definition: winuser.h:768
HKL WINAPI GetKeyboardLayout(_In_ DWORD)
#define BM_GETSTATE
Definition: winuser.h:1920
#define WM_CLOSE
Definition: winuser.h:1621
LRESULT WINAPI DefMDIChildProcA(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define SWP_NOACTIVATE
Definition: winuser.h:1242
#define DM_SETDEFID
Definition: winuser.h:2099
#define LB_GETITEMDATA
Definition: winuser.h:2041
BOOL WINAPI SetMenu(_In_ HWND, _In_opt_ HMENU)
BOOL WINAPI SendNotifyMessageW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define SWP_NOREDRAW
Definition: winuser.h:1246
#define MNS_NOTIFYBYPOS
Definition: winuser.h:759
#define MF_BYCOMMAND
Definition: winuser.h:202
#define WM_SYSCOMMAND
Definition: winuser.h:1741
BOOL WINAPI RedrawWindow(_In_opt_ HWND, _In_opt_ LPCRECT, _In_opt_ HRGN, _In_ UINT)
void WINAPI mouse_event(_In_ DWORD, _In_ DWORD, _In_ DWORD, _In_ DWORD, _In_ ULONG_PTR)
#define IMAGE_BITMAP
Definition: winuser.h:211
BOOL WINAPI UnloadKeyboardLayout(_In_ HKL)
#define QS_SENDMESSAGE
Definition: winuser.h:880
#define GetWindowLongPtrW
Definition: winuser.h:4829
#define SC_KEYMENU
Definition: winuser.h:2596
#define VK_TAB
Definition: winuser.h:2199
#define WM_ENABLE
Definition: winuser.h:1615
HICON WINAPI CreateIconIndirect(_In_ PICONINFO)
Definition: cursoricon.c:2581
#define WM_MOUSEFIRST
Definition: winuser.h:1774
DWORD WINAPI GetQueueStatus(_In_ UINT)
#define SWP_FRAMECHANGED
Definition: winuser.h:1240
#define WM_QUIT
Definition: winuser.h:1623
BOOL WINAPI SetKeyboardState(_In_reads_(256) LPBYTE)
#define VK_APPS
Definition: winuser.h:2237
BOOL WINAPI TranslateMessage(_In_ const MSG *)
#define MAKELPARAM(l, h)
Definition: winuser.h:4008
#define WM_KEYUP
Definition: winuser.h:1716
#define EN_KILLFOCUS
Definition: winuser.h:2025
HWND WINAPI CreateWindowExA(_In_ DWORD dwExStyle, _In_opt_ LPCSTR lpClassName, _In_opt_ LPCSTR lpWindowName, _In_ DWORD dwStyle, _In_ int X, _In_ int Y, _In_ int nWidth, _In_ int nHeight, _In_opt_ HWND hWndParent, _In_opt_ HMENU hMenu, _In_opt_ HINSTANCE hInstance, _In_opt_ LPVOID lpParam)
#define MF_RIGHTJUSTIFY
Definition: winuser.h:144
#define COLOR_WINDOW
Definition: winuser.h:918
BOOL WINAPI ShowWindow(_In_ HWND, _In_ int)
#define WM_MOUSELAST
Definition: winuser.h:1801
BOOL WINAPI ReleaseCapture(void)
Definition: message.c:2890
BOOL WINAPI UnregisterClassA(_In_ LPCSTR, HINSTANCE)
#define SM_CYSCREEN
Definition: winuser.h:960
#define HTCAPTION
Definition: winuser.h:2476
HWND WINAPI GetForegroundWindow(void)
Definition: ntwrapper.h:392
#define WM_MDICREATE
Definition: winuser.h:1812
#define MWMO_ALERTABLE
Definition: winuser.h:909
UINT WINAPI GetMenuState(_In_ HMENU, _In_ UINT, _In_ UINT)
LRESULT WINAPI DefWindowProcW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
int WINAPI GetMenuItemCount(_In_opt_ HMENU)
#define MOUSEEVENTF_LEFTUP
Definition: winuser.h:1185
LONG WINAPI GetWindowLongA(_In_ HWND, _In_ int)
#define HWND_TOPMOST
Definition: winuser.h:1208
#define DLGC_BUTTON
Definition: winuser.h:2620
BOOL WINAPI AttachThreadInput(_In_ DWORD, _In_ DWORD, _In_ BOOL)
HWND WINAPI CreateDialogParamA(_In_opt_ HINSTANCE, _In_ LPCSTR, _In_opt_ HWND, _In_opt_ DLGPROC, _In_ LPARAM)
#define CBS_DROPDOWNLIST
Definition: winuser.h:284
#define WM_IME_NOTIFY
Definition: winuser.h:1830
LRESULT WINAPI DefWindowProcA(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define WM_DESTROYCLIPBOARD
Definition: winuser.h:1868
#define LB_OKAY
Definition: winuser.h:2431
#define LB_GETTEXT
Definition: winuser.h:2049
#define LB_SETTOPINDEX
Definition: winuser.h:2070
#define VK_F10
Definition: winuser.h:2264
BOOL WINAPI GetMessageW(_Out_ LPMSG, _In_opt_ HWND, _In_ UINT, _In_ UINT)
#define BST_UNCHECKED
Definition: winuser.h:199
#define WM_QUERYOPEN
Definition: winuser.h:1624
BOOL WINAPI PostMessageW(_In_opt_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define IMAGE_ICON
Definition: winuser.h:212
#define BN_SETFOCUS
Definition: winuser.h:1933
BOOL WINAPI GetIconInfo(_In_ HICON, _Out_ PICONINFO)
Definition: cursoricon.c:2045
#define WM_CAPTURECHANGED
Definition: winuser.h:1808
#define MOD_WIN
Definition: winuser.h:2644
#define WM_WINDOWPOSCHANGING
Definition: winuser.h:1661
BOOL WINAPI GetWindowPlacement(_In_ HWND, _Inout_ WINDOWPLACEMENT *)
#define SW_SCROLLCHILDREN
Definition: winuser.h:2578
#define WM_IME_KEYDOWN
Definition: winuser.h:1838
#define CreateWindowA(a, b, c, d, e, f, g, h, i, j, k)
Definition: winuser.h:4315
BOOL WINAPI GetWindowRect(_In_ HWND, _Out_ LPRECT)
#define WM_CHILDACTIVATE
Definition: winuser.h:1638
#define WM_SYNCPAINT
Definition: winuser.h:1690
LONG WINAPI SetWindowLongA(_In_ HWND, _In_ int, _In_ LONG)
#define SIF_RANGE
Definition: winuser.h:1235
#define WM_CREATE
Definition: winuser.h:1608
#define DLGC_WANTCHARS
Definition: winuser.h:2618
#define SM_CXMINTRACK
Definition: winuser.h:997
#define SW_MINIMIZE
Definition: winuser.h:776
HHOOK WINAPI SetWindowsHookExW(_In_ int, _In_ HOOKPROC, _In_opt_ HINSTANCE, _In_ DWORD)
#define EN_SETFOCUS
Definition: winuser.h:2027
BOOL WINAPI SetWindowPos(_In_ HWND, _In_opt_ HWND, _In_ int, _In_ int, _In_ int, _In_ int, _In_ UINT)
BOOL WINAPI UnregisterHotKey(_In_opt_ HWND, _In_ int)
__analysis_noreturn void WINAPI PostQuitMessage(_In_ int)
#define BS_ICON
Definition: winuser.h:264
#define SC_PREVWINDOW
Definition: winuser.h:2591
#define VK_SPACE
Definition: winuser.h:2219
#define HCBT_ACTIVATE
Definition: winuser.h:60
#define WM_DRAWCLIPBOARD
Definition: winuser.h:1869
HWND WINAPI SetParent(_In_ HWND, _In_opt_ HWND)
#define WM_SIZE
Definition: winuser.h:1611
int WINAPI SetWindowRgn(_In_ HWND, _In_opt_ HRGN, _In_ BOOL)
#define SB_VERT
Definition: winuser.h:553
#define BM_SETSTATE
Definition: winuser.h:1923
int WINAPI GetClassNameA(_In_ HWND hWnd, _Out_writes_to_(nMaxCount, return) LPSTR lpClassName, _In_ int nMaxCount)
#define HWND_BROADCAST
Definition: winuser.h:1204
LONG WINAPI SetWindowLongW(_In_ HWND, _In_ int, _In_ LONG)
LONG WINAPI GetWindowLongW(_In_ HWND, _In_ int)
#define VK_CAPITAL
Definition: winuser.h:2206
HMENU WINAPI CreateMenu(void)
Definition: menu.c:829
#define WM_CANCELMODE
Definition: winuser.h:1635
#define CBN_SETFOCUS
Definition: winuser.h:1982
#define DLGC_WANTALLKEYS
Definition: winuser.h:2612
#define WM_LBUTTONDBLCLK
Definition: winuser.h:1778
#define SWP_NOMOVE
Definition: winuser.h:1244
#define WM_DWMNCRENDERINGCHANGED
Definition: winuser.h:1885
BOOL WINAPI ValidateRect(_In_opt_ HWND, _In_opt_ LPCRECT)
#define WM_COMMAND
Definition: winuser.h:1740
#define WM_WININICHANGE
Definition: winuser.h:1630
#define SW_INVALIDATE
Definition: winuser.h:2579
#define MF_STRING
Definition: winuser.h:138
#define DLGC_UNDEFPUSHBUTTON
Definition: winuser.h:2616
ATOM WINAPI RegisterClassW(_In_ CONST WNDCLASSW *)
BOOL WINAPI SetForegroundWindow(_In_ HWND)
#define IDC_ARROW
Definition: winuser.h:687
BOOL WINAPI CloseClipboard(void)
Definition: ntwrapper.h:178
#define WM_GETTITLEBARINFOEX
Definition: winuser.h:1897
#define WM_APPCOMMAND
Definition: winuser.h:1882
#define CB_SETCURSEL
Definition: winuser.h:1961
#define WM_KEYFIRST
Definition: winuser.h:1714
#define LBN_SETFOCUS
Definition: winuser.h:2076
#define LB_GETTOPINDEX
Definition: winuser.h:2051
HWND WINAPI GetClipboardOwner(void)
Definition: ntwrapper.h:196
#define VK_CONTROL
Definition: winuser.h:2203
BOOL WINAPI GetCursorPos(_Out_ LPPOINT)
Definition: cursoricon.c:2670
#define HC_ACTION
Definition: winuser.h:48
#define WM_NCHITTEST
Definition: winuser.h:1686
#define HCBT_DESTROYWND
Definition: winuser.h:59
#define WM_RBUTTONUP
Definition: winuser.h:1780
#define BS_BOTTOM
Definition: winuser.h:259
#define BN_KILLFOCUS
Definition: winuser.h:1930
#define LLMHF_INJECTED
Definition: winuser.h:2649
#define DC_HASDEFID
Definition: winuser.h:2609
#define VK_UP
Definition: winuser.h:2225
LRESULT WINAPI SendMessageA(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define SW_SHOWNOACTIVATE
Definition: winuser.h:774
#define WM_SETFOCUS
Definition: winuser.h:1613
#define GA_PARENT
Definition: winuser.h:2788
#define QS_ALLINPUT
Definition: winuser.h:903
#define SIF_PAGE
Definition: winuser.h:1233
#define BN_HILITE
Definition: winuser.h:1929
#define SWP_NOSIZE
Definition: winuser.h:1245
#define WM_MOUSEMOVE
Definition: winuser.h:1775
#define WM_GETTEXT
Definition: winuser.h:1618
#define RDW_UPDATENOW
Definition: winuser.h:1220
#define MOUSEEVENTF_RIGHTUP
Definition: winuser.h:1187
HWND WINAPI GetCapture(void)
Definition: message.c:2881
#define RDW_ERASE
Definition: winuser.h:1211
#define SIZE_MINIMIZED
Definition: winuser.h:2506
#define WM_INITMENU
Definition: winuser.h:1745
#define MF_SYSMENU
Definition: winuser.h:141
#define GetWindowLongPtrA
Definition: winuser.h:4828
_Check_return_ BOOL WINAPI GetKeyboardState(_Out_writes_(256) PBYTE lpKeyState)
#define BS_NOTIFY
Definition: winuser.h:268
BOOL WINAPI OpenClipboard(_In_opt_ HWND)
BOOL WINAPI TrackMouseEvent(_Inout_ LPTRACKMOUSEEVENT)
#define RDW_NOCHILDREN
Definition: winuser.h:1222
#define WA_INACTIVE
Definition: winuser.h:2622
UINT WINAPI GetMenuItemID(_In_ HMENU, _In_ int)
#define CB_FINDSTRINGEXACT
Definition: winuser.h:1940
#define WM_INITDIALOG
Definition: winuser.h:1739
HMENU WINAPI GetSystemMenu(_In_ HWND, _In_ BOOL)
#define WM_LBUTTONDOWN
Definition: winuser.h:1776
#define WM_DEVICECHANGE
Definition: winuser.h:1811
#define WH_CBT
Definition: winuser.h:35
#define LB_ADDSTRING
Definition: winuser.h:2031
#define SWP_ASYNCWINDOWPOS
Definition: winuser.h:1253
#define SBM_GETRANGE
Definition: winuser.h:2079
BOOL WINAPI SetCursorPos(_In_ int, _In_ int)
Definition: cursoricon.c:2662
HCURSOR WINAPI LoadCursorW(_In_opt_ HINSTANCE, _In_ LPCWSTR)
Definition: cursoricon.c:2105
#define WM_CHANGECBCHAIN
Definition: winuser.h:1874
#define WM_MDIACTIVATE
Definition: winuser.h:1814
BOOL WINAPI InsertMenuA(_In_ HMENU, _In_ UINT, _In_ UINT, _In_ UINT_PTR, _In_opt_ LPCSTR)
LRESULT WINAPI DefDlgProcA(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define DLGC_DEFPUSHBUTTON
Definition: winuser.h:2615
#define ULW_OPAQUE
Definition: winuser.h:2786
DWORD WINAPI MsgWaitForMultipleObjects(_In_ DWORD nCount, _In_reads_opt_(nCount) CONST HANDLE *pHandles, _In_ BOOL fWaitAll, _In_ DWORD dwMilliseconds, _In_ DWORD dwWakeMask)
int WINAPI MapWindowPoints(_In_opt_ HWND hWndFrom, _In_opt_ HWND hWndTo, _Inout_updates_(cPoints) LPPOINT lpPoints, _In_ UINT cPoints)
#define VK_F1
Definition: winuser.h:2255
#define GWLP_HINSTANCE
Definition: winuser.h:856
#define SWP_DEFERERASE
Definition: winuser.h:1252
BOOL WINAPI SendMessageCallbackW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM, _In_ SENDASYNCPROC, _In_ ULONG_PTR)
#define WM_DELETEITEM
Definition: winuser.h:1647
#define MF_POPUP
Definition: winuser.h:136
#define HCBT_CREATEWND
Definition: winuser.h:58
HACCEL WINAPI LoadAcceleratorsA(_In_opt_ HINSTANCE, _In_ LPCSTR)
#define CB_GETCOMBOBOXINFO
Definition: winuser.h:1941
#define SM_CYFRAME
Definition: winuser.h:996
HWND WINAPI GetDlgItem(_In_opt_ HWND, _In_ int)
BOOL WINAPI IsIconic(_In_ HWND)
#define WM_DRAWITEM
Definition: winuser.h:1645
#define MDIS_ALLCHILDSTYLES
Definition: winuser.h:253
BOOL WINAPI GetScrollRange(_In_ HWND, _In_ int, _Out_ LPINT, _Out_ LPINT)
UINT_PTR WINAPI SetTimer(_In_opt_ HWND, _In_ UINT_PTR, _In_ UINT, _In_opt_ TIMERPROC)
#define CBN_SELCHANGE
Definition: winuser.h:1979
#define WM_NCCREATE
Definition: winuser.h:1683
#define DialogBoxA(i, t, p, f)
Definition: winuser.h:4398
#define IDI_APPLICATION
Definition: winuser.h:704
#define BM_SETCHECK
Definition: winuser.h:1921
HWND WINAPI SetClipboardViewer(_In_ HWND)
HHOOK WINAPI SetWindowsHookExA(_In_ int, _In_ HOOKPROC, _In_opt_ HINSTANCE, _In_ DWORD)
#define WM_ACTIVATE
Definition: winuser.h:1612
#define WM_MDIREFRESHMENU
Definition: winuser.h:1826
#define WM_SHOWWINDOW
Definition: winuser.h:1628
HWND WINAPI GetDesktopWindow(void)
Definition: window.c:656
#define BM_SETIMAGE
Definition: winuser.h:1922
#define WM_TIMECHANGE
Definition: winuser.h:1634
#define WM_IME_SETCONTEXT
Definition: winuser.h:1829
#define MWMO_INPUTAVAILABLE
Definition: winuser.h:910
BOOL WINAPI IsZoomed(_In_ HWND)
#define QS_HOTKEY
Definition: winuser.h:881
#define BN_UNHILITE
Definition: winuser.h:1934
#define WM_CTLCOLORBTN
Definition: winuser.h:1769
#define WM_SETTEXT
Definition: winuser.h:1617
#define MOUSEEVENTF_MOVE
Definition: winuser.h:1183
#define SC_NEXTWINDOW
Definition: winuser.h:2590
DWORD WINAPI MsgWaitForMultipleObjectsEx(_In_ DWORD nCount, _In_reads_opt_(nCount) CONST HANDLE *pHandles, _In_ DWORD dwMilliseconds, _In_ DWORD dwWakeMask, _In_ DWORD dwFlags)
#define SW_SHOWMINIMIZED
Definition: winuser.h:771
#define WM_NCMOUSEMOVE
Definition: winuser.h:1691
#define WH_MOUSE_LL
Definition: winuser.h:44
UINT_PTR WINAPI SetSystemTimer(HWND, UINT_PTR, UINT, TIMERPROC)
Definition: ntwrapper.h:106
#define MOUSEEVENTF_LEFTDOWN
Definition: winuser.h:1184
BOOL WINAPI GetClientRect(_In_ HWND, _Out_ LPRECT)
#define WM_NCACTIVATE
Definition: winuser.h:1688
#define WM_SYSCHAR
Definition: winuser.h:1721
ATOM WINAPI RegisterClassA(_In_ CONST WNDCLASSA *)
#define WM_ENTERMENULOOP
Definition: winuser.h:1804
#define SW_FORCEMINIMIZE
Definition: winuser.h:781
#define LB_RESETCONTENT
Definition: winuser.h:2055
#define LB_DELETESTRING
Definition: winuser.h:2032
#define VK_RETURN
Definition: winuser.h:2201
#define HWND_TOP
Definition: winuser.h:1207
BOOL WINAPI RegisterHotKey(_In_opt_ HWND, _In_ int, _In_ UINT, _In_ UINT)
#define WS_EX_MDICHILD
Definition: winuser.h:394
#define SW_SHOWNA
Definition: winuser.h:778
HMENU WINAPI GetSubMenu(_In_ HMENU, _In_ int)
BOOL WINAPI InSendMessage(void)
Definition: message.c:1372
BOOL WINAPI SendNotifyMessageA(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define WM_GETMINMAXINFO
Definition: winuser.h:1640
BOOL WINAPI KillSystemTimer(HWND, UINT_PTR)
Definition: timer.c:35
#define WM_MENUCHAR
Definition: winuser.h:1748
HWND WINAPI SetFocus(_In_opt_ HWND)
#define WM_INITMENUPOPUP
Definition: winuser.h:1746
#define SIZE_MAXIMIZED
Definition: winuser.h:2507
BOOL WINAPI SetScrollRange(_In_ HWND, _In_ int, _In_ int, _In_ int, _In_ BOOL)
BOOL WINAPI DrawMenuBar(_In_ HWND)
BOOL WINAPI UnhookWindowsHookEx(_In_ HHOOK)
BOOL WINAPI IsChild(_In_ HWND, _In_ HWND)
HWND WINAPI SetActiveWindow(_In_ HWND)
#define DLGC_RADIOBUTTON
Definition: winuser.h:2617
#define USER_TIMER_MAXIMUM
Definition: winuser.h:905
#define PM_NOYIELD
Definition: winuser.h:1197
BOOL WINAPI IsDialogMessageA(_In_ HWND, _In_ LPMSG)
LRESULT WINAPI SendMessageTimeoutA(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM, _In_ UINT, _In_ UINT, _Out_opt_ PDWORD_PTR)
#define SWP_NOCOPYBITS
Definition: winuser.h:1243
#define WM_MDIDESTROY
Definition: winuser.h:1813
#define HCBT_SETFOCUS
Definition: winuser.h:64
BOOL WINAPI PeekMessageW(_Out_ LPMSG, _In_opt_ HWND, _In_ UINT, _In_ UINT, _In_ UINT)
BOOL WINAPI GetComboBoxInfo(_In_ HWND, _Inout_ PCOMBOBOXINFO)
BOOL WINAPI PostThreadMessageW(_In_ DWORD, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define WM_MDIMAXIMIZE
Definition: winuser.h:1817
#define RDW_ALLCHILDREN
Definition: winuser.h:1221
#define WM_SETFONT
Definition: winuser.h:1650
#define WM_TIMER
Definition: winuser.h:1742
#define BM_CLICK
Definition: winuser.h:1917
HWND WINAPI CreateWindowExW(_In_ DWORD dwExStyle, _In_opt_ LPCWSTR lpClassName, _In_opt_ LPCWSTR lpWindowName, _In_ DWORD dwStyle, _In_ int X, _In_ int Y, _In_ int nWidth, _In_ int nHeight, _In_opt_ HWND hWndParent, _In_opt_ HMENU hMenu, _In_opt_ HINSTANCE hInstance, _In_opt_ LPVOID lpParam)
BOOL WINAPI EndPaint(_In_ HWND, _In_ const PAINTSTRUCT *)
HICON WINAPI LoadIconA(_In_opt_ HINSTANCE hInstance, _In_ LPCSTR lpIconName)
Definition: cursoricon.c:2060
#define WM_QUERYENDSESSION
Definition: winuser.h:1622
#define MF_BYPOSITION
Definition: winuser.h:203
#define DLGC_WANTARROWS
Definition: winuser.h:2610
#define BM_GETIMAGE
Definition: winuser.h:1919
BOOL WINAPI ChangeClipboardChain(_In_ HWND, _In_ HWND)
#define PM_REMOVE
Definition: winuser.h:1196
#define LLKHF_UP
Definition: winuser.h:2648
#define RDW_ERASENOW
Definition: winuser.h:1219
#define CB_ADDSTRING
Definition: winuser.h:1936
DWORD WINAPI WaitForInputIdle(_In_ HANDLE, _In_ DWORD)
struct tagCOMBOBOXINFO COMBOBOXINFO
#define HCBT_CLICKSKIPPED
Definition: winuser.h:61
#define RDW_FRAME
Definition: winuser.h:1212
BOOL WINAPI SetMenuInfo(_In_ HMENU, _In_ LPCMENUINFO)
int WINAPI GetUpdateRgn(_In_ HWND, _In_ HRGN, _In_ BOOL)
#define QS_INPUT
Definition: winuser.h:899
BOOL WINAPI EmptyClipboard(void)
Definition: ntwrapper.h:190
BOOL WINAPI UpdateWindow(_In_ HWND)
#define HTCLIENT
Definition: winuser.h:2475
#define SWP_SHOWWINDOW
Definition: winuser.h:1248
#define WM_NULL
Definition: winuser.h:1607
BOOL WINAPI GetMonitorInfoA(_In_ HMONITOR, _Inout_ LPMONITORINFO)
#define CBN_KILLFOCUS
Definition: winuser.h:1978
BOOL WINAPI ValidateRgn(_In_ HWND, _In_opt_ HRGN)
BOOL WINAPI EnableWindow(_In_ HWND, _In_ BOOL)
#define BM_SETSTYLE
Definition: winuser.h:1924
#define WM_SYSKEYUP
Definition: winuser.h:1720
HKL WINAPI LoadKeyboardLayoutA(_In_ LPCSTR, _In_ UINT)
BOOL WINAPI SendMessageCallbackA(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM, _In_ SENDASYNCPROC, _In_ ULONG_PTR)
#define WM_EXITMENULOOP
Definition: winuser.h:1805
HDC WINAPI GetDC(_In_opt_ HWND)
BOOL WINAPI InvalidateRgn(_In_ HWND, _In_opt_ HRGN, _In_ BOOL)
#define EM_SETSEL
Definition: winuser.h:2018
#define CBS_DROPDOWN
Definition: winuser.h:283
#define SC_CLOSE
Definition: winuser.h:2592
#define VK_LWIN
Definition: winuser.h:2235
#define DLGC_STATIC
Definition: winuser.h:2619
#define WM_MOUSEACTIVATE
Definition: winuser.h:1637
#define WH_KEYBOARD_LL
Definition: winuser.h:43
#define WS_EX_LAYERED
Definition: winuser.h:389
int WINAPI CountClipboardFormats(void)
Definition: ntwrapper.h:184
#define CBS_HASSTRINGS
Definition: winuser.h:285
BOOL WINAPI GetMenuInfo(_In_ HMENU, _Inout_ LPMENUINFO)
#define LLKHF_INJECTED
Definition: winuser.h:2646
#define CreateWindowW(a, b, c, d, e, f, g, h, i, j, k)
Definition: winuser.h:4316
#define WM_MEASUREITEM
Definition: winuser.h:1646
BOOL WINAPI AppendMenuA(_In_ HMENU, _In_ UINT, _In_ UINT_PTR, _In_opt_ LPCSTR)
VOID WINAPI keybd_event(_In_ BYTE, _In_ BYTE, _In_ DWORD, _In_ ULONG_PTR)
BOOL WINAPI GetClassInfoA(_In_opt_ HINSTANCE, _In_ LPCSTR, _Out_ LPWNDCLASSA)
#define WM_LBUTTONUP
Definition: winuser.h:1777
#define WM_CHAR
Definition: winuser.h:1717
BOOL WINAPI SetRectEmpty(_Out_ LPRECT)
BOOL WINAPI IsWindowEnabled(_In_ HWND)
#define LB_GETTEXTLEN
Definition: winuser.h:2050
#define CW_USEDEFAULT
Definition: winuser.h:225
#define WH_GETMESSAGE
Definition: winuser.h:33
#define MAKEINTRESOURCEA(i)
Definition: winuser.h:581
#define WA_ACTIVE
Definition: winuser.h:2623
HWND WINAPI GetParent(_In_ HWND)
#define QS_POSTMESSAGE
Definition: winuser.h:877
BOOL WINAPI DestroyMenu(_In_ HMENU)
LRESULT WINAPI CallNextHookEx(_In_opt_ HHOOK, _In_ int, _In_ WPARAM, _In_ LPARAM)
#define WM_MOVE
Definition: winuser.h:1610
#define LBN_SELCHANGE
Definition: winuser.h:2075
HWND WINAPI GetWindow(_In_ HWND, _In_ UINT)
#define SWP_HIDEWINDOW
Definition: winuser.h:1241
#define WM_NCDESTROY
Definition: winuser.h:1684
#define VK_RIGHT
Definition: winuser.h:2226
#define SIZE_RESTORED
Definition: winuser.h:2505
LRESULT WINAPI DispatchMessageW(_In_ const MSG *)
#define SIF_POS
Definition: winuser.h:1234
#define VK_DOWN
Definition: winuser.h:2227
#define WPF_RESTORETOMAXIMIZED
Definition: winuser.h:2532
#define LB_GETCARETINDEX
Definition: winuser.h:2037
#define GWLP_ID
Definition: winuser.h:860
#define SB_CTL
Definition: winuser.h:554
#define SWP_NOOWNERZORDER
Definition: winuser.h:1249
BOOL WINAPI SystemParametersInfoA(_In_ UINT uiAction, _In_ UINT uiParam, _Inout_opt_ PVOID pvParam, _In_ UINT fWinIni)
#define SW_RESTORE
Definition: winuser.h:779
#define WM_SETCURSOR
Definition: winuser.h:1636
#define WM_HOTKEY
Definition: winuser.h:1879
#define SW_ERASE
Definition: winuser.h:2580
BOOL WINAPI PeekMessageA(_Out_ LPMSG, _In_opt_ HWND, _In_ UINT, _In_ UINT, _In_ UINT)
#define WM_USER
Definition: winuser.h:1895
#define MK_LBUTTON
Definition: winuser.h:2367
#define QS_PAINT
Definition: winuser.h:879
#define WM_ACTIVATEAPP
Definition: winuser.h:1632
BOOL WINAPI OffsetRect(_Inout_ LPRECT, _In_ int, _In_ int)
#define WM_CTLCOLORLISTBOX
Definition: winuser.h:1768
#define VK_SHIFT
Definition: winuser.h:2202
#define MF_HILITE
Definition: winuser.h:205
#define BN_CLICKED
Definition: winuser.h:1925
#define CBN_SELENDOK
Definition: winuser.h:1981
#define SW_SHOW
Definition: winuser.h:775
BOOL WINAPI TrackPopupMenu(_In_ HMENU, _In_ UINT, _In_ int, _In_ int, _Reserved_ int, _In_ HWND, _Reserved_ LPCRECT)
int WINAPI SetScrollInfo(_In_ HWND, _In_ int, _In_ LPCSCROLLINFO, _In_ BOOL)
#define WM_IME_SELECT
Definition: winuser.h:1833
#define WM_DESTROY
Definition: winuser.h:1609
#define CBN_SELENDCANCEL
Definition: winuser.h:1980
#define LB_SETCURSEL
Definition: winuser.h:2063
SHORT WINAPI GetAsyncKeyState(_In_ int)
#define SM_CXSCREEN
Definition: winuser.h:959
#define RDW_NOFRAME
Definition: winuser.h:1216
#define WM_KEYDOWN
Definition: winuser.h:1715
#define WM_COMPAREITEM
Definition: winuser.h:1655
#define WM_MDIGETACTIVE
Definition: winuser.h:1821
#define WM_ENDSESSION
Definition: winuser.h:1627
#define GW_CHILD
Definition: winuser.h:763
BOOL WINAPI InvalidateRect(_In_opt_ HWND, _In_opt_ LPCRECT, _In_ BOOL)
LRESULT(CALLBACK * WNDPROC)(HWND, UINT, WPARAM, LPARAM)
Definition: winuser.h:2906
#define WM_PARENTNOTIFY
Definition: winuser.h:1803
#define DM_GETDEFID
Definition: winuser.h:2098
BOOL WINAPI PostThreadMessageA(_In_ DWORD, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
HKL WINAPI ActivateKeyboardLayout(_In_ HKL, _In_ UINT)
BOOL WINAPI DestroyAcceleratorTable(_In_ HACCEL)
#define WM_NCMOUSELEAVE
Definition: winuser.h:1842
#define SWP_NOZORDER
Definition: winuser.h:1247
#define SW_MAXIMIZE
Definition: winuser.h:772
HDC WINAPI BeginPaint(_In_ HWND, _Out_ LPPAINTSTRUCT)
BOOL WINAPI KillTimer(_In_opt_ HWND, _In_ UINT_PTR)
#define LB_GETCURSEL
Definition: winuser.h:2039
#define SetWindowLongPtrW
Definition: winuser.h:5346
LRESULT WINAPI CallWindowProcW(_In_ WNDPROC, _In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define RDW_INTERNALPAINT
Definition: winuser.h:1213
#define WM_NCCALCSIZE
Definition: winuser.h:1685
#define RDW_NOERASE
Definition: winuser.h:1215
#define GWL_STYLE
Definition: winuser.h:852
BOOL WINAPI GetMessageA(_Out_ LPMSG, _In_opt_ HWND, _In_ UINT, _In_ UINT)
BOOL WINAPI GetScrollInfo(_In_ HWND, _In_ int, _Inout_ LPSCROLLINFO)
#define BN_PAINT
Definition: winuser.h:1931
BOOL WINAPI GetUpdateRect(_In_ HWND, _Out_opt_ LPRECT, _In_ BOOL)
#define WM_KEYLAST
Definition: winuser.h:1728
HWND WINAPI FindWindowA(_In_opt_ LPCSTR, _In_opt_ LPCSTR)
#define RDW_VALIDATE
Definition: winuser.h:1218
#define WM_CTLCOLOREDIT
Definition: winuser.h:1767
#define WM_MENUSELECT
Definition: winuser.h:1747
#define VK_ESCAPE
Definition: winuser.h:2214
#define WM_WINDOWPOSCHANGED
Definition: winuser.h:1662
#define SWP_NOSENDCHANGING
Definition: winuser.h:1251
#define SC_RESTORE
Definition: winuser.h:2598
#define WM_ENTERIDLE
Definition: winuser.h:1749
#define HWND_NOTOPMOST
Definition: winuser.h:1206
#define DLGC_HASSETSEL
Definition: winuser.h:2614
BOOL WINAPI IsWindowVisible(_In_ HWND)
BOOL WINAPI DestroyWindow(_In_ HWND)
BOOL WINAPI EnableMenuItem(_In_ HMENU, _In_ UINT, _In_ UINT)
int WINAPI ScrollWindowEx(_In_ HWND, _In_ int, _In_ int, _In_opt_ LPCRECT, _In_opt_ LPCRECT, _In_opt_ HRGN, _Out_opt_ LPRECT, _In_ UINT)
#define ODT_MENU
Definition: winuser.h:2537
#define WM_DEADCHAR
Definition: winuser.h:1718
BOOL WINAPI PostMessageA(_In_opt_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
BOOL WINAPI ScrollWindow(_In_ HWND, _In_ int, _In_ int, _In_opt_ LPCRECT, _In_opt_ LPCRECT)
#define WM_CTLCOLORDLG
Definition: winuser.h:1770
#define ODT_LISTBOX
Definition: winuser.h:2538
#define WM_KILLFOCUS
Definition: winuser.h:1614
BOOL WINAPI EqualRect(_In_ LPCRECT, _In_ LPCRECT)
#define PM_NOREMOVE
Definition: winuser.h:1195
int WINAPI GetSystemMetrics(_In_ int)
#define CS_NOCLOSE
Definition: winuser.h:654
#define KEYEVENTF_KEYUP
Definition: winuser.h:1102
HWND WINAPI GetAncestor(_In_ HWND, _In_ UINT)
#define SW_NORMAL
Definition: winuser.h:769
#define WM_SYSKEYDOWN
Definition: winuser.h:1719
#define SW_SHOWMINNOACTIVE
Definition: winuser.h:777
BOOL WINAPI MoveWindow(_In_ HWND, _In_ int, _In_ int, _In_ int, _In_ int, _In_ BOOL)
LRESULT WINAPI CallWindowProcA(_In_ WNDPROC, _In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define HCBT_SYSCOMMAND
Definition: winuser.h:63
#define RDW_INVALIDATE
Definition: winuser.h:1214
#define HCBT_KEYSKIPPED
Definition: winuser.h:62
HWND WINAPI GetClipboardViewer(void)
Definition: ntwrapper.h:208
#define WM_GETDLGCODE
Definition: winuser.h:1689
#define HWND_BOTTOM
Definition: winuser.h:1205
#define WM_PALETTEISCHANGING
Definition: winuser.h:1876
int WINAPI TranslateAcceleratorA(_In_ HWND, _In_ HACCEL, _In_ LPMSG)
INT_PTR WINAPI DialogBoxParamA(_In_opt_ HINSTANCE, _In_ LPCSTR, _In_opt_ HWND, _In_opt_ DLGPROC, _In_ LPARAM)
LRESULT WINAPI SendMessageW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define BST_CHECKED
Definition: winuser.h:197
HMENU WINAPI GetMenu(_In_ HWND)
#define SMTO_NORMAL
Definition: winuser.h:1225
HCURSOR WINAPI LoadCursorA(_In_opt_ HINSTANCE, _In_ LPCSTR)
Definition: cursoricon.c:2090
#define SB_HORZ
Definition: winuser.h:552
SHORT WINAPI GetKeyState(_In_ int)
#define COLOR_BTNFACE
Definition: winuser.h:928
#define VK_MENU
Definition: winuser.h:2204
#define WM_NCPAINT
Definition: winuser.h:1687
BOOL WINAPI SetRect(_Out_ LPRECT, _In_ int, _In_ int, _In_ int, _In_ int)
#define BM_GETCHECK
Definition: winuser.h:1918
#define WM_NCRBUTTONDOWN
Definition: winuser.h:1695
BOOL WINAPI EndDialog(_In_ HWND, _In_ INT_PTR)
#define GWL_EXSTYLE
Definition: winuser.h:851
BOOL WINAPI DestroyIcon(_In_ HICON)
Definition: cursoricon.c:2053
#define MF_GRAYED
Definition: winuser.h:129
#define WM_SETREDRAW
Definition: winuser.h:1616
#define MF_DISABLED
Definition: winuser.h:130
HMENU WINAPI LoadMenuA(_In_opt_ HINSTANCE, _In_ LPCSTR)
const char * LPCSTR
Definition: xmlstorage.h:183
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
char CHAR
Definition: xmlstorage.h:175
unsigned char BYTE
Definition: xxhash.c:193