* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
-#define _WIN32_WINNT 0x0600 /* For WM_CHANGEUISTATE,QS_RAWINPUT,WM_DWMxxxx */
-#define WINVER 0x0600 /* for WM_GETTITLEBARINFOEX */
+//#define _WIN32_WINNT 0x0600 /* For WM_CHANGEUISTATE,QS_RAWINPUT,WM_DWMxxxx */
+//#define WINVER 0x0600 /* for WM_GETTITLEBARINFOEX */
#include <assert.h>
#include <stdarg.h>
#define WM_LBTRACKPOINT 0x0131
#endif
+#ifdef __i386__
+#define ARCH "x86"
+#elif defined __x86_64__
+#define ARCH "amd64"
+#else
+#define ARCH "none"
+#endif
+
+static BOOL (WINAPI *pActivateActCtx)(HANDLE,ULONG_PTR*);
+static HANDLE (WINAPI *pCreateActCtxW)(PCACTCTXW);
+static BOOL (WINAPI *pDeactivateActCtx)(DWORD,ULONG_PTR);
+static BOOL (WINAPI *pGetCurrentActCtx)(HANDLE *);
+static void (WINAPI *pReleaseActCtx)(HANDLE);
+
/* encoded DRAWITEMSTRUCT into an LPARAM */
typedef struct
{
static BOOL test_DestroyWindow_flag;
static HWINEVENTHOOK hEvent_hook;
+static HHOOK hKBD_hook;
static HHOOK hCBT_hook;
static DWORD cbt_hook_thread_id;
beginpaint=0x40,
optional=0x80,
hook=0x100,
- winevent_hook=0x200
+ winevent_hook=0x200,
+ kbd_hook=0x400
} msg_flags_t;
struct message {
{ WM_NCACTIVATE, sent|wparam|defwinproc, 0 }, /* in the 2nd MDI child */
{ WM_MDIACTIVATE, sent|defwinproc }, /* in the 2nd MDI child */
{ HCBT_MINMAX, hook|lparam, 0, SW_MAXIMIZE },
- /* Preparing for maximize and maximaze the 1st MDI child */
+ /* Preparing for maximize and maximize the 1st MDI child */
{ WM_GETMINMAXINFO, sent|defwinproc }, /* in the 1st MDI child */
{ WM_WINDOWPOSCHANGING, sent|wparam|defwinproc, SWP_FRAMECHANGED|SWP_STATECHANGED }, /* in the 1st MDI child */
{ WM_NCCALCSIZE, sent|wparam|defwinproc, 1 }, /* in the 1st MDI child */
{ WM_NCPAINT, sent|wparam|optional, 1 },
{ WM_GETTEXT, sent|defwinproc|optional },
{ WM_ERASEBKGND, sent|optional },
- { HCBT_ACTIVATE, hook },
+ { HCBT_ACTIVATE, hook|optional },
{ EVENT_SYSTEM_FOREGROUND, winevent_hook|wparam|lparam, 0, 0 },
{ WM_QUERYNEWPALETTE, sent|wparam|lparam|optional, 0, 0 },
{ WM_WINDOWPOSCHANGING, sent|wparam|optional, SWP_NOSIZE|SWP_NOMOVE },
{ WM_NCPAINT, sent|wparam|optional, 1 },
- { WM_ACTIVATEAPP, sent|wparam, 1 },
- { WM_NCACTIVATE, sent|wparam, 1 },
+ { WM_ACTIVATEAPP, sent|wparam|optional, 1 },
+ { WM_NCACTIVATE, sent|wparam|optional, 1 },
{ WM_GETTEXT, sent|defwinproc|optional },
- { WM_ACTIVATE, sent|wparam, 1 },
- { HCBT_SETFOCUS, hook },
+ { WM_ACTIVATE, sent|wparam|optional, 1 },
+ { HCBT_SETFOCUS, hook|optional },
{ WM_IME_SETCONTEXT, sent|wparam|defwinproc|optional, 1 },
{ WM_IME_NOTIFY, sent|wparam|defwinproc|optional, 2 },
{ EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
- { WM_SETFOCUS, sent|wparam|defwinproc, 0 },
+ { WM_SETFOCUS, sent|wparam|defwinproc|optional, 0 },
{ WM_GETTEXT, sent|optional },
{ WM_NCPAINT, sent|wparam|optional, 1 },
{ WM_GETTEXT, sent|defwinproc|optional },
{ WM_GETMINMAXINFO, sent|defwinproc },
{ WM_NCCALCSIZE, sent|wparam, TRUE },
{ EVENT_OBJECT_SHOW, winevent_hook|wparam|lparam, 0, 0 },
- { HCBT_ACTIVATE, hook },
+ { HCBT_ACTIVATE, hook|optional },
{ EVENT_SYSTEM_FOREGROUND, winevent_hook|wparam|lparam, 0, 0 },
{ WM_QUERYNEWPALETTE, sent|wparam|lparam|optional, 0, 0 },
{ WM_WINDOWPOSCHANGING, sent|wparam|optional, SWP_NOSIZE|SWP_NOMOVE },
- { WM_ACTIVATEAPP, sent|wparam, 1 },
- { WM_NCACTIVATE, sent|wparam, 1 },
+ { WM_ACTIVATEAPP, sent|wparam|optional, 1 },
+ { WM_NCACTIVATE, sent|wparam|optional, 1 },
{ WM_GETTEXT, sent|defwinproc|optional },
- { WM_ACTIVATE, sent|wparam, 1 },
- { HCBT_SETFOCUS, hook },
+ { WM_ACTIVATE, sent|wparam|optional, 1 },
+ { HCBT_SETFOCUS, hook|optional },
{ WM_IME_SETCONTEXT, sent|wparam|defwinproc|optional, 1 },
{ WM_IME_NOTIFY, sent|wparam|defwinproc|optional, 2 },
{ EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
- { WM_SETFOCUS, sent|wparam|defwinproc, 0 },
+ { WM_SETFOCUS, sent|wparam|defwinproc|optional, 0 },
{ WM_GETTEXT, sent|optional },
{ WM_NCPAINT, sent|wparam|optional, 1 },
{ WM_GETTEXT, sent|defwinproc|optional },
{ HCBT_MINMAX, hook|lparam, 0, SW_RESTORE },
{ WM_QUERYOPEN, sent|optional },
{ WM_GETTEXT, sent|optional },
- { WM_WINDOWPOSCHANGING, sent|wparam, SWP_FRAMECHANGED|SWP_STATECHANGED|SWP_NOCOPYBITS },
- { WM_GETMINMAXINFO, sent|defwinproc },
- { WM_NCCALCSIZE, sent|wparam, TRUE },
- { HCBT_ACTIVATE, hook },
+ { WM_NCACTIVATE, sent|wparam|optional, 1 },
+ { WM_WINDOWPOSCHANGING, sent|optional }, /* SWP_NOSIZE|SWP_NOMOVE */
+ { WM_WINDOWPOSCHANGED, sent|wparam|optional, SWP_NOSIZE|SWP_NOMOVE|SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE },
+ { WM_NCCALCSIZE, sent|wparam|optional, TRUE },
+ { WM_MOVE, sent|optional },
+ { WM_SIZE, sent|wparam|optional, SIZE_RESTORED },
+ { WM_GETTEXT, sent|optional },
+ { WM_WINDOWPOSCHANGING, sent|wparam|optional, SWP_FRAMECHANGED|SWP_STATECHANGED|SWP_NOCOPYBITS },
+ { WM_GETMINMAXINFO, sent|defwinproc|optional },
+ { WM_NCCALCSIZE, sent|wparam|optional, TRUE },
+ { HCBT_ACTIVATE, hook|optional },
{ WM_QUERYNEWPALETTE, sent|wparam|lparam|optional, 0, 0 },
{ WM_WINDOWPOSCHANGING, sent|wparam|optional, SWP_NOSIZE|SWP_NOMOVE },
- { WM_ACTIVATEAPP, sent|wparam, 1 },
- { WM_NCACTIVATE, sent|wparam, 1 },
+ { WM_ACTIVATEAPP, sent|wparam|optional, 1 },
+ { WM_NCACTIVATE, sent|wparam|optional, 1 },
{ WM_GETTEXT, sent|defwinproc|optional },
- { WM_ACTIVATE, sent|wparam, 1 },
- { HCBT_SETFOCUS, hook },
+ { WM_ACTIVATE, sent|wparam|optional, 1 },
+ { HCBT_SETFOCUS, hook|optional },
{ WM_IME_SETCONTEXT, sent|wparam|defwinproc|optional, 1 },
{ WM_IME_NOTIFY, sent|wparam|defwinproc|optional, 2 },
- { WM_SETFOCUS, sent|wparam|defwinproc, 0 },
+ { WM_SETFOCUS, sent|wparam|defwinproc|optional, 0 },
{ WM_GETTEXT, sent|optional },
{ WM_NCPAINT, sent|wparam|optional, 1 },
{ WM_GETTEXT, sent|defwinproc|optional },
{ WM_WINDOWPOSCHANGED, sent|wparam, SWP_STATECHANGED|SWP_FRAMECHANGED|SWP_NOCOPYBITS },
{ WM_MOVE, sent|defwinproc },
{ WM_SIZE, sent|defwinproc|wparam, SIZE_RESTORED },
+ { HCBT_SETFOCUS, hook|optional },
+ { WM_SETFOCUS, sent|wparam|optional, 0 },
{ WM_NCCALCSIZE, sent|wparam|optional, TRUE },
{ WM_NCPAINT, sent|wparam|optional, 1 },
{ WM_ERASEBKGND, sent|optional },
+ { HCBT_SETFOCUS, hook|optional },
+ { WM_SETFOCUS, sent|wparam|optional, 0 },
{ WM_ACTIVATE, sent|wparam, 1 },
{ WM_GETTEXT, sent|optional },
{ WM_PAINT, sent|optional },
/* ShowWindow(SW_SHOWMINIMIZED) for a not visible overlapped window */
static const struct message WmShowMinOverlappedSeq[] = {
{ HCBT_MINMAX, hook|lparam, 0, SW_MINIMIZE },
- { HCBT_SETFOCUS, hook },
+ { HCBT_SETFOCUS, hook|optional },
{ EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
- { WM_KILLFOCUS, sent },
+ { WM_KILLFOCUS, sent|optional },
{ WM_IME_SETCONTEXT, sent|wparam|optional, 0 },
{ WM_IME_NOTIFY, sent|wparam|optional|defwinproc, 1 },
{ WM_GETTEXT, sent|optional },
{ EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 },
{ EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 },
{ EVENT_SYSTEM_MINIMIZESTART, winevent_hook|wparam|lparam, 0, 0 },
- { WM_NCACTIVATE, sent|wparam, 0 },
+ { WM_NCACTIVATE, sent|wparam|optional, 0 },
{ WM_GETTEXT, sent|defwinproc|optional },
- { WM_ACTIVATE, sent },
- { WM_ACTIVATEAPP, sent|wparam, 0 },
+ { WM_ACTIVATE, sent|optional },
+ { WM_ACTIVATEAPP, sent|wparam|optional, 0 },
/* Vista sometimes restores the window right away... */
{ WM_SYSCOMMAND, sent|optional|wparam, SC_RESTORE },
{ WM_ACTIVATE, sent|wparam|optional, 0 },
{ WM_ACTIVATEAPP, sent|wparam|optional, 0 },
{ HCBT_SETFOCUS, hook|optional },
- { WM_KILLFOCUS, sent|wparam, 0 },
+ { WM_KILLFOCUS, sent|wparam|optional, 0 },
{ WM_IME_SETCONTEXT, sent|wparam|optional, 0 },
{ WM_IME_NOTIFY, sent|wparam|optional|defwinproc, 1 },
{ 0 }
{ 0 }
};
-static int after_end_dialog, test_def_id;
+static const struct message WmTrackPopupMenu[] = {
+ { HCBT_CREATEWND, hook },
+ { WM_ENTERMENULOOP, sent|wparam|lparam, TRUE, 0 },
+ { WM_INITMENU, sent|lparam, 0, 0 },
+ { WM_INITMENUPOPUP, sent|lparam, 0, 0 },
+ { 0x0093, sent|optional },
+ { 0x0094, sent|optional },
+ { 0x0094, sent|optional },
+ { WM_ENTERIDLE, sent|wparam, 2 },
+ { WM_CAPTURECHANGED, sent },
+ { HCBT_DESTROYWND, hook },
+ { WM_UNINITMENUPOPUP, sent|lparam, 0, 0 },
+ { WM_MENUSELECT, sent|wparam|lparam, 0xffff0000, 0 },
+ { WM_EXITMENULOOP, sent|wparam|lparam, 1, 0 },
+ { 0 }
+};
+
+static const struct message WmTrackPopupMenuCapture[] = {
+ { HCBT_CREATEWND, hook },
+ { WM_ENTERMENULOOP, sent|wparam|lparam, TRUE, 0 },
+ { WM_CAPTURECHANGED, sent },
+ { WM_INITMENU, sent|lparam, 0, 0 },
+ { WM_INITMENUPOPUP, sent|lparam, 0, 0 },
+ { 0x0093, sent|optional },
+ { 0x0094, sent|optional },
+ { 0x0094, sent|optional },
+ { WM_ENTERIDLE, sent|wparam, 2 },
+ { WM_CAPTURECHANGED, sent },
+ { HCBT_DESTROYWND, hook },
+ { WM_UNINITMENUPOPUP, sent|lparam, 0, 0 },
+ { WM_MENUSELECT, sent|wparam|lparam, 0xffff0000, 0 },
+ { WM_EXITMENULOOP, sent|wparam|lparam, 1, 0 },
+ { 0 }
+};
+
+static const struct message WmTrackPopupMenuEmpty[] = {
+ { HCBT_CREATEWND, hook },
+ { WM_ENTERMENULOOP, sent|wparam|lparam, TRUE, 0 },
+ { WM_INITMENU, sent|lparam, 0, 0 },
+ { WM_INITMENUPOPUP, sent|lparam, 0, 0 },
+ { 0x0093, sent|optional },
+ { 0x0094, sent|optional },
+ { 0x0094, sent|optional },
+ { WM_CAPTURECHANGED, sent },
+ { WM_EXITMENULOOP, sent|wparam|lparam, 1, 0 },
+ { HCBT_DESTROYWND, hook },
+ { WM_UNINITMENUPOPUP, sent|lparam, 0, 0 },
+ { 0 }
+};
+
+static const struct message WmTrackPopupMenuAbort[] = {
+ { HCBT_CREATEWND, hook },
+ { WM_ENTERMENULOOP, sent|wparam|lparam, TRUE, 0 },
+ { WM_INITMENU, sent|lparam, 0, 0 },
+ { WM_INITMENUPOPUP, sent|lparam, 0, 0 },
+ { 0x0093, sent|optional },
+ { 0x0094, sent|optional },
+ { 0x0094, sent|optional },
+ { WM_CAPTURECHANGED, sent },
+ { HCBT_DESTROYWND, hook },
+ { WM_UNINITMENUPOPUP, sent|lparam, 0, 0 },
+ { WM_MENUSELECT, sent|wparam|lparam, 0xffff0000, 0 },
+ { WM_EXITMENULOOP, sent|wparam|lparam, 1, 0 },
+ { 0 }
+};
+
+static BOOL after_end_dialog, test_def_id, paint_loop_done;
static int sequence_cnt, sequence_size;
static struct recvd_message* sequence;
static int log_all_parent_messages;
-static int paint_loop_done;
+static CRITICAL_SECTION sequence_cs;
/* user32 functions */
static HWND (WINAPI *pGetAncestor)(HWND,UINT);
static HWINEVENTHOOK (WINAPI *pSetWinEventHook)(DWORD, DWORD, HMODULE, WINEVENTPROC, DWORD, DWORD, DWORD);
static BOOL (WINAPI *pTrackMouseEvent)(TRACKMOUSEEVENT*);
static BOOL (WINAPI *pUnhookWinEvent)(HWINEVENTHOOK);
+static BOOL (WINAPI *pGetMonitorInfoA)(HMONITOR,LPMONITORINFO);
+static HMONITOR (WINAPI *pMonitorFromPoint)(POINT,DWORD);
+static BOOL (WINAPI *pUpdateLayeredWindow)(HWND,HDC,POINT*,SIZE*,HDC,POINT*,COLORREF,BLENDFUNCTION*,DWORD);
+static UINT_PTR (WINAPI *pSetSystemTimer)(HWND, UINT_PTR, UINT, TIMERPROC);
+static UINT_PTR (WINAPI *pKillSystemTimer)(HWND, UINT_PTR);
/* kernel32 functions */
static BOOL (WINAPI *pGetCPInfoExA)(UINT, DWORD, LPCPINFOEXA);
GET_PROC(user32, SetWinEventHook)
GET_PROC(user32, TrackMouseEvent)
GET_PROC(user32, UnhookWinEvent)
+ GET_PROC(user32, GetMonitorInfoA)
+ GET_PROC(user32, MonitorFromPoint)
+ GET_PROC(user32, UpdateLayeredWindow)
+ GET_PROC(user32, SetSystemTimer)
+ GET_PROC(user32, KillSystemTimer)
GET_PROC(kernel32, GetCPInfoExA)
{
struct recvd_message *seq;
- if (!sequence)
+ EnterCriticalSection( &sequence_cs );
+ if (!sequence)
{
sequence_size = 10;
sequence = HeapAlloc( GetProcessHeap(), 0, sequence_size * sizeof(*sequence) );
}
assert(sequence);
- seq = &sequence[sequence_cnt];
+ seq = &sequence[sequence_cnt++];
seq->hwnd = msg->hwnd;
seq->message = msg->message;
seq->flags = msg->flags;
seq->line = line;
seq->descr = msg->descr;
seq->output[0] = 0;
+ LeaveCriticalSection( &sequence_cs );
if (msg->descr)
{
sprintf( seq->output + strlen(seq->output), " (flags %x)", msg->flags );
}
}
-
- sequence_cnt++;
}
/* try to make sure pending X events have been processed before continuing */
while (diff > 0)
{
if (MsgWaitForMultipleObjects( 0, NULL, FALSE, min_timeout, QS_ALLINPUT ) == WAIT_TIMEOUT) break;
- while (PeekMessage( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessage( &msg );
+ while (PeekMessageA( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessageA( &msg );
diff = time - GetTickCount();
}
}
static void flush_sequence(void)
{
+ EnterCriticalSection( &sequence_cs );
HeapFree(GetProcessHeap(), 0, sequence);
sequence = 0;
sequence_cnt = sequence_size = 0;
+ LeaveCriticalSection( &sequence_cs );
}
static void dump_sequence(const struct message *expected, const char *context, const char *file, int line)
trace_(file, line)( " %u: expected: winevent %04x - actual: %s\n",
count, expected->message, actual->output );
}
+ else if (expected->flags & kbd_hook)
+ {
+ trace_(file, line)( " %u: expected: kbd %04x - actual: %s\n",
+ count, expected->message, actual->output );
+ }
else
{
trace_(file, line)( " %u: expected: msg %04x - actual: %s\n",
ok_sequence_( (exp), (contx), (todo), __FILE__, __LINE__)
-static void ok_sequence_(const struct message *expected_list, const char *context, int todo,
+static void ok_sequence_(const struct message *expected_list, const char *context, BOOL todo,
const char *file, int line)
{
static const struct recvd_message end_of_sequence;
while (expected->message && actual->message)
{
- if (expected->message == actual->message)
+ if (expected->message == actual->message &&
+ !((expected->flags ^ actual->flags) & (hook|winevent_hook|kbd_hook)))
{
if (expected->flags & wparam)
{
context, count, expected->message);
if ((expected->flags & winevent_hook) != (actual->flags & winevent_hook)) dump++;
+ ok_( file, line) ((expected->flags & kbd_hook) == (actual->flags & kbd_hook),
+ "%s: %u: the msg 0x%04x should have been sent by a keyboard hook\n",
+ context, count, expected->message);
+ if ((expected->flags & kbd_hook) != (actual->flags & kbd_hook)) dump++;
+
expected++;
actual++;
}
/* silently drop hook messages if there is no support for them */
else if ((expected->flags & optional) ||
((expected->flags & hook) && !hCBT_hook) ||
- ((expected->flags & winevent_hook) && !hEvent_hook))
+ ((expected->flags & winevent_hook) && !hEvent_hook) ||
+ ((expected->flags & kbd_hook) && !hKBD_hook))
expected++;
else if (todo)
{
cls.cbWndExtra = 0;
cls.hInstance = GetModuleHandleA(0);
cls.hIcon = 0;
- cls.hCursor = LoadCursorA(0, IDC_ARROW);
+ cls.hCursor = LoadCursorA(0, (LPCSTR)IDC_ARROW);
cls.hbrBackground = GetStockObject(WHITE_BRUSH);
cls.lpszMenuName = NULL;
cls.lpszClassName = "MDI_frame_class";
RECT rc;
HMENU hMenu = CreateMenu();
- assert(mdi_RegisterWindowClasses());
+ if (!mdi_RegisterWindowClasses()) assert(0);
flush_sequence();
/* test maximization of MDI child with invisible parent */
client_cs.hWindowMenu = 0;
- mdi_client = CreateWindow("MDI_client_class",
+ mdi_client = CreateWindowA("MDI_client_class",
NULL,
WS_CHILD | WS_CLIPCHILDREN | WS_VSCROLL | WS_HSCROLL | WS_VISIBLE,
0, 0, 660, 430,
mdi_client, 0, GetModuleHandleA(0), NULL);
ok_sequence(WmCreateMDIchildInvisibleParentSeq, "Create MDI child window with invisible parent", FALSE);
- SendMessage(mdi_client, WM_MDIMAXIMIZE, (WPARAM) mdi_child, 0);
+ SendMessageA(mdi_client, WM_MDIMAXIMIZE, (WPARAM) mdi_child, 0);
ok_sequence(WmMaximizeMDIchildInvisibleParentSeq, "Maximize MDI child window with invisible parent", TRUE);
zoomed = IsZoomed(mdi_child);
ok(zoomed, "wrong zoomed state %d\n", zoomed);
-
+
ShowWindow(mdi_client, SW_SHOW);
ok_sequence(WmShowMDIclientSeq, "Show MDI client window", FALSE);
HMENU hmenu;
MSG msg;
LRESULT res;
+ POINT pos;
flush_sequence();
flush_sequence();
- test_def_id = 1;
- SendMessage(hwnd, WM_NULL, 0, 0);
+ test_def_id = TRUE;
+ SendMessageA(hwnd, WM_NULL, 0, 0);
flush_sequence();
- after_end_dialog = 1;
+ after_end_dialog = TRUE;
EndDialog( hwnd, 0 );
ok_sequence(WmEndCustomDialogSeq, "EndCustomDialog", FALSE);
DestroyWindow(hwnd);
- after_end_dialog = 0;
- test_def_id = 0;
+ after_end_dialog = FALSE;
+ test_def_id = FALSE;
+
+ ok(GetCursorPos(&pos), "GetCursorPos failed\n");
+ ok(SetCursorPos(109, 109), "SetCursorPos failed\n");
- hwnd = CreateWindowExA(0, "TestDialogClass", NULL, WS_POPUP,
+ hwnd = CreateWindowExA(0, "TestDialogClass", NULL, WS_POPUP|WS_CHILD,
0, 0, 100, 100, 0, 0, GetModuleHandleA(0), NULL);
ok(hwnd != 0, "Failed to create custom dialog window\n");
flush_sequence();
trace("call ShowWindow(%p, SW_SHOW)\n", hwnd);
ShowWindow(hwnd, SW_SHOW);
ok_sequence(WmShowCustomDialogSeq, "ShowCustomDialog", TRUE);
+
+ flush_events();
+ flush_sequence();
+ ok(DrawMenuBar(hwnd), "DrawMenuBar failed: %d\n", GetLastError());
+ flush_events();
+ ok_sequence(WmDrawMenuBarSeq, "DrawMenuBar", FALSE);
+ ok(SetCursorPos(pos.x, pos.y), "SetCursorPos failed\n");
DestroyWindow(hwnd);
flush_sequence();
flush_sequence();
/* Message sequence for SetMenu */
- ok(!DrawMenuBar(hwnd), "DrawMenuBar should return FALSE for a window without a menu\n");
+ ok(!DrawMenuBar(hwnd), "DrawMenuBar should return FALSE for a destroyed window\n");
+ ok(GetLastError() == ERROR_INVALID_WINDOW_HANDLE, "last error is %d\n", GetLastError());
ok_sequence(WmEmptySeq, "DrawMenuBar for a window without a menu", FALSE);
hmenu = CreateMenu();
UpdateWindow(hwnd);
flush_events();
flush_sequence();
- SendMessage(hwnd, WM_SETICON, ICON_SMALL, (LPARAM)LoadIcon(0, IDI_APPLICATION));
+ SendMessageA(hwnd, WM_SETICON, ICON_SMALL, (LPARAM)LoadIconA(0, (LPCSTR)IDI_APPLICATION));
ok_sequence(WmSetIcon_1, "WM_SETICON for shown window with caption", FALSE);
ShowWindow(hwnd, SW_HIDE);
flush_events();
flush_sequence();
- SendMessage(hwnd, WM_SETICON, ICON_SMALL, (LPARAM)LoadIcon(0, IDI_APPLICATION));
+ SendMessageA(hwnd, WM_SETICON, ICON_SMALL, (LPARAM)LoadIconA(0, (LPCSTR)IDI_APPLICATION));
ok_sequence(WmSetIcon_2, "WM_SETICON for hidden window with caption", FALSE);
DestroyWindow(hwnd);
flush_sequence();
UpdateWindow(hwnd);
flush_events();
flush_sequence();
- SendMessage(hwnd, WM_SETICON, ICON_SMALL, (LPARAM)LoadIcon(0, IDI_APPLICATION));
+ SendMessageA(hwnd, WM_SETICON, ICON_SMALL, (LPARAM)LoadIconA(0, (LPCSTR)IDI_APPLICATION));
ok_sequence(WmSetIcon_2, "WM_SETICON for shown window without caption", FALSE);
ShowWindow(hwnd, SW_HIDE);
flush_events();
flush_sequence();
- SendMessage(hwnd, WM_SETICON, ICON_SMALL, (LPARAM)LoadIcon(0, IDI_APPLICATION));
+ SendMessageA(hwnd, WM_SETICON, ICON_SMALL, (LPARAM)LoadIconA(0, (LPCSTR)IDI_APPLICATION));
ok_sequence(WmSetIcon_2, "WM_SETICON for hidden window without caption", FALSE);
flush_sequence();
- res = SendMessage(hwnd, 0x3B, 0x8000000b, 0);
+ res = SendMessageA(hwnd, 0x3B, 0x8000000b, 0);
if (!res)
{
todo_wine win_skip( "Message 0x3b not supported\n" );
}
ok_sequence(WmInitEndSession, "Handling of undocumented 0x3B message by DefWindowProc wparam=0x8000000b", TRUE);
ok(res == 1, "SendMessage(hwnd, 0x3B, 0x8000000b, 0) should have returned 1 instead of %ld\n", res);
- res = SendMessage(hwnd, 0x3B, 0x0000000b, 0);
+ res = SendMessageA(hwnd, 0x3B, 0x0000000b, 0);
ok_sequence(WmInitEndSession_2, "Handling of undocumented 0x3B message by DefWindowProc wparam=0x0000000b", TRUE);
ok(res == 1, "SendMessage(hwnd, 0x3B, 0x0000000b, 0) should have returned 1 instead of %ld\n", res);
- res = SendMessage(hwnd, 0x3B, 0x0000000f, 0);
+ res = SendMessageA(hwnd, 0x3B, 0x0000000f, 0);
ok_sequence(WmInitEndSession_2, "Handling of undocumented 0x3B message by DefWindowProc wparam=0x0000000f", TRUE);
ok(res == 1, "SendMessage(hwnd, 0x3B, 0x0000000f, 0) should have returned 1 instead of %ld\n", res);
flush_sequence();
- res = SendMessage(hwnd, 0x3B, 0x80000008, 0);
+ res = SendMessageA(hwnd, 0x3B, 0x80000008, 0);
ok_sequence(WmInitEndSession_3, "Handling of undocumented 0x3B message by DefWindowProc wparam=0x80000008", TRUE);
ok(res == 2, "SendMessage(hwnd, 0x3B, 0x80000008, 0) should have returned 2 instead of %ld\n", res);
- res = SendMessage(hwnd, 0x3B, 0x00000008, 0);
+ res = SendMessageA(hwnd, 0x3B, 0x00000008, 0);
ok_sequence(WmInitEndSession_4, "Handling of undocumented 0x3B message by DefWindowProc wparam=0x00000008", TRUE);
ok(res == 2, "SendMessage(hwnd, 0x3B, 0x00000008, 0) should have returned 2 instead of %ld\n", res);
- res = SendMessage(hwnd, 0x3B, 0x80000004, 0);
+ res = SendMessageA(hwnd, 0x3B, 0x80000004, 0);
ok_sequence(WmInitEndSession_3, "Handling of undocumented 0x3B message by DefWindowProc wparam=0x80000004", TRUE);
ok(res == 2, "SendMessage(hwnd, 0x3B, 0x80000004, 0) should have returned 2 instead of %ld\n", res);
- res = SendMessage(hwnd, 0x3B, 0x80000001, 0);
+ res = SendMessageA(hwnd, 0x3B, 0x80000001, 0);
ok_sequence(WmInitEndSession_5, "Handling of undocumented 0x3B message by DefWindowProc wparam=0x80000001", TRUE);
ok(res == 2, "SendMessage(hwnd, 0x3B, 0x80000001, 0) should have returned 2 instead of %ld\n", res);
old_button_proc = cls.lpfnWndProc;
- cls.hInstance = GetModuleHandle(0);
+ cls.hInstance = GetModuleHandleA(NULL);
cls.lpfnWndProc = button_hook_proc;
cls.lpszClassName = "my_button_class";
- UnregisterClass(cls.lpszClassName, cls.hInstance);
+ UnregisterClassA(cls.lpszClassName, cls.hInstance);
if (!RegisterClassA(&cls)) assert(0);
}
ok(GetFocus() == 0, "expected focus 0, got %p\n", GetFocus());
SetFocus(hwnd);
- SendMessage(hwnd, WM_APP, 0, 0); /* place a separator mark here */
- while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessage(&msg);
+ SendMessageA(hwnd, WM_APP, 0, 0); /* place a separator mark here */
+ while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
ok_sequence(button[i].setfocus, "SetFocus(hwnd) on a button", FALSE);
SetFocus(0);
- SendMessage(hwnd, WM_APP, 0, 0); /* place a separator mark here */
- while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessage(&msg);
+ SendMessageA(hwnd, WM_APP, 0, 0); /* place a separator mark here */
+ while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
ok_sequence(button[i].killfocus, "SetFocus(0) on a button", FALSE);
ok(GetFocus() == 0, "expected focus 0, got %p\n", GetFocus());
- SendMessage(hwnd, BM_SETSTYLE, button[i].style | BS_BOTTOM, TRUE);
- SendMessage(hwnd, WM_APP, 0, 0); /* place a separator mark here */
- while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessage(&msg);
+ SendMessageA(hwnd, BM_SETSTYLE, button[i].style | BS_BOTTOM, TRUE);
+ SendMessageA(hwnd, WM_APP, 0, 0); /* place a separator mark here */
+ while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
ok_sequence(button[i].setstyle, "BM_SETSTYLE on a button", FALSE);
style = GetWindowLongA(hwnd, GWL_STYLE);
/* XP doesn't turn a BS_USERBUTTON into BS_PUSHBUTTON here! */
ok(style == button[i].style, "expected style %04x got %04x\n", button[i].style, style);
- state = SendMessage(hwnd, BM_GETSTATE, 0, 0);
+ state = SendMessageA(hwnd, BM_GETSTATE, 0, 0);
ok(state == 0, "expected state 0, got %04x\n", state);
flush_sequence();
- SendMessage(hwnd, BM_SETSTATE, TRUE, 0);
- SendMessage(hwnd, WM_APP, 0, 0); /* place a separator mark here */
- while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessage(&msg);
+ SendMessageA(hwnd, BM_SETSTATE, TRUE, 0);
+ SendMessageA(hwnd, WM_APP, 0, 0); /* place a separator mark here */
+ while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
ok_sequence(button[i].setstate, "BM_SETSTATE/TRUE on a button", FALSE);
- state = SendMessage(hwnd, BM_GETSTATE, 0, 0);
+ state = SendMessageA(hwnd, BM_GETSTATE, 0, 0);
ok(state == 0x0004, "expected state 0x0004, got %04x\n", state);
style = GetWindowLongA(hwnd, GWL_STYLE);
flush_sequence();
- SendMessage(hwnd, BM_SETSTATE, FALSE, 0);
- SendMessage(hwnd, WM_APP, 0, 0); /* place a separator mark here */
- while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessage(&msg);
+ SendMessageA(hwnd, BM_SETSTATE, FALSE, 0);
+ SendMessageA(hwnd, WM_APP, 0, 0); /* place a separator mark here */
+ while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
ok_sequence(button[i].clearstate, "BM_SETSTATE/FALSE on a button", FALSE);
- state = SendMessage(hwnd, BM_GETSTATE, 0, 0);
+ state = SendMessageA(hwnd, BM_GETSTATE, 0, 0);
ok(state == 0, "expected state 0, got %04x\n", state);
style = GetWindowLongA(hwnd, GWL_STYLE);
style &= ~(WS_CHILD | BS_NOTIFY | WS_VISIBLE);
ok(style == button[i].style, "expected style %04x got %04x\n", button[i].style, style);
- state = SendMessage(hwnd, BM_GETCHECK, 0, 0);
+ state = SendMessageA(hwnd, BM_GETCHECK, 0, 0);
ok(state == BST_UNCHECKED, "expected BST_UNCHECKED, got %04x\n", state);
flush_sequence();
- SendMessage(hwnd, BM_SETCHECK, BST_UNCHECKED, 0);
- SendMessage(hwnd, WM_APP, 0, 0); /* place a separator mark here */
- while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessage(&msg);
+ SendMessageA(hwnd, BM_SETCHECK, BST_UNCHECKED, 0);
+ SendMessageA(hwnd, WM_APP, 0, 0); /* place a separator mark here */
+ while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
ok_sequence(WmSetCheckIgnoredSeq, "BM_SETCHECK on a button", FALSE);
- state = SendMessage(hwnd, BM_GETCHECK, 0, 0);
+ state = SendMessageA(hwnd, BM_GETCHECK, 0, 0);
ok(state == BST_UNCHECKED, "expected BST_UNCHECKED, got %04x\n", state);
style = GetWindowLongA(hwnd, GWL_STYLE);
flush_sequence();
- SendMessage(hwnd, BM_SETCHECK, BST_CHECKED, 0);
- SendMessage(hwnd, WM_APP, 0, 0); /* place a separator mark here */
- while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessage(&msg);
+ SendMessageA(hwnd, BM_SETCHECK, BST_CHECKED, 0);
+ SendMessageA(hwnd, WM_APP, 0, 0); /* place a separator mark here */
+ while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
ok_sequence(button[i].setcheck, "BM_SETCHECK on a button", FALSE);
- state = SendMessage(hwnd, BM_GETCHECK, 0, 0);
+ state = SendMessageA(hwnd, BM_GETCHECK, 0, 0);
if (button[i].style == BS_PUSHBUTTON ||
button[i].style == BS_DEFPUSHBUTTON ||
button[i].style == BS_GROUPBOX ||
old_static_proc = cls.lpfnWndProc;
- cls.hInstance = GetModuleHandle(0);
+ cls.hInstance = GetModuleHandleA(NULL);
cls.lpfnWndProc = static_hook_proc;
cls.lpszClassName = "my_static_class";
- UnregisterClass(cls.lpszClassName, cls.hInstance);
+ UnregisterClassA(cls.lpszClassName, cls.hInstance);
if (!RegisterClassA(&cls)) assert(0);
}
flush_sequence();
trace("static style %08x\n", static_ctrl[i].style);
- SendMessage(hwnd, WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT), TRUE);
+ SendMessageA(hwnd, WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT), TRUE);
ok_sequence(static_ctrl[i].setfont, "WM_SETFONT on a static", FALSE);
DestroyWindow(hwnd);
{ 0 }
};
+static const struct message WmSetPosComboSeq[] =
+{
+ { WM_WINDOWPOSCHANGING, sent },
+ { WM_NCCALCSIZE, sent|wparam, TRUE },
+ { WM_CHILDACTIVATE, sent },
+ { WM_WINDOWPOSCHANGED, sent },
+ { WM_MOVE, sent|defwinproc },
+ { WM_SIZE, sent|defwinproc|wparam, SIZE_RESTORED },
+ { WM_WINDOWPOSCHANGING, sent|defwinproc },
+ { WM_NCCALCSIZE, sent|defwinproc|wparam, TRUE },
+ { WM_WINDOWPOSCHANGED, sent|defwinproc },
+ { WM_SIZE, sent|defwinproc|wparam, SIZE_RESTORED },
+ { 0 }
+};
+
static WNDPROC old_combobox_proc;
static LRESULT CALLBACK combobox_hook_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
old_combobox_proc = cls.lpfnWndProc;
- cls.hInstance = GetModuleHandle(0);
+ cls.hInstance = GetModuleHandleA(NULL);
cls.lpfnWndProc = combobox_hook_proc;
cls.lpszClassName = "my_combobox_class";
- UnregisterClass(cls.lpszClassName, cls.hInstance);
+ UnregisterClassA(cls.lpszClassName, cls.hInstance);
if (!RegisterClassA(&cls)) assert(0);
}
ok(parent != 0, "Failed to create parent window\n");
flush_sequence();
- combo = CreateWindowEx(0, "my_combobox_class", "test", WS_CHILD | WS_VISIBLE | CBS_DROPDOWNLIST | CBS_HASSTRINGS,
+ combo = CreateWindowExA(0, "my_combobox_class", "test", WS_CHILD | WS_VISIBLE | CBS_DROPDOWNLIST | CBS_HASSTRINGS,
0, 0, 100, 150, parent, (HMENU)ID_COMBOBOX, 0, NULL);
ok(combo != 0, "Failed to create combobox window\n");
UpdateWindow(combo);
- ret = SendMessage(combo, WM_GETDLGCODE, 0, 0);
+ ret = SendMessageA(combo, WM_GETDLGCODE, 0, 0);
ok(ret == (DLGC_WANTCHARS | DLGC_WANTARROWS), "wrong dlg_code %08lx\n", ret);
- ret = SendMessage(combo, CB_ADDSTRING, 0, (LPARAM)"item 0");
+ ret = SendMessageA(combo, CB_ADDSTRING, 0, (LPARAM)"item 0");
ok(ret == 0, "expected 0, got %ld\n", ret);
- ret = SendMessage(combo, CB_ADDSTRING, 0, (LPARAM)"item 1");
+ ret = SendMessageA(combo, CB_ADDSTRING, 0, (LPARAM)"item 1");
ok(ret == 1, "expected 1, got %ld\n", ret);
- ret = SendMessage(combo, CB_ADDSTRING, 0, (LPARAM)"item 2");
+ ret = SendMessageA(combo, CB_ADDSTRING, 0, (LPARAM)"item 2");
ok(ret == 2, "expected 2, got %ld\n", ret);
- SendMessage(combo, CB_SETCURSEL, 0, 0);
+ SendMessageA(combo, CB_SETCURSEL, 0, 0);
SetFocus(combo);
flush_sequence();
log_all_parent_messages++;
- SendMessage(combo, WM_KEYDOWN, VK_DOWN, 0);
- SendMessage(combo, WM_KEYUP, VK_DOWN, 0);
+ SendMessageA(combo, WM_KEYDOWN, VK_DOWN, 0);
+ SendMessageA(combo, WM_KEYUP, VK_DOWN, 0);
log_all_parent_messages--;
ok_sequence(WmKeyDownComboSeq, "WM_KEYDOWN/VK_DOWN on a ComboBox", FALSE);
+ flush_sequence();
+ SetWindowPos(combo, 0, 10, 10, 120, 130, SWP_NOZORDER);
+ ok_sequence(WmSetPosComboSeq, "repositioning messages on a ComboBox", FALSE);
+
DestroyWindow(combo);
DestroyWindow(parent);
}
flush_events();
flush_sequence();
- SendMessage(hwnd, WM_IME_KEYDOWN, VK_RETURN, 0x1c0001);
- SendMessage(hwnd, WM_CHAR, 'A', 1);
+ SendMessageA(hwnd, WM_IME_KEYDOWN, VK_RETURN, 0x1c0001);
+ SendMessageA(hwnd, WM_CHAR, 'A', 1);
ok_sequence(WmImeKeydownMsgSeq_0, "WM_IME_KEYDOWN 0", FALSE);
- while ( PeekMessage(&msg, 0, 0, 0, PM_REMOVE) )
+ while ( PeekMessageA(&msg, 0, 0, 0, PM_REMOVE) )
{
TranslateMessage(&msg);
- DispatchMessage(&msg);
+ DispatchMessageA(&msg);
}
ok_sequence(WmImeKeydownMsgSeq_1, "WM_IME_KEYDOWN 1", FALSE);
flush_events();
ok_sequence( WmEmptySeq, "WmEmptySeq", FALSE );
+ trace("testing UpdateWindow(NULL)\n");
+ SetLastError(0xdeadbeef);
+ ok(!UpdateWindow(NULL), "UpdateWindow(NULL) should fail\n");
+ ok(GetLastError() == ERROR_INVALID_WINDOW_HANDLE ||
+ broken( GetLastError() == 0xdeadbeef ) /* win9x */,
+ "wrong error code %d\n", GetLastError());
+ check_update_rgn( hwnd, 0 );
+ flush_events();
+ ok_sequence( WmEmptySeq, "WmEmptySeq", FALSE );
+
/* now with frame */
SetRectRgn( hrgn, -5, -5, 20, 20 );
flush_sequence();
SetRectRgn( hrgn, -4, -4, -1, -1 );
RedrawWindow( hwnd, NULL, hrgn, RDW_INVALIDATE | RDW_FRAME );
- while (PeekMessage( &msg, 0, 0, 0, PM_REMOVE ))
+ while (PeekMessageA( &msg, 0, 0, 0, PM_REMOVE ))
{
if (msg.hwnd == hwnd && msg.message == WM_PAINT)
{
ret = GetUpdateRect( hwnd, &rect, TRUE );
ok( !ret, "Invalid GetUpdateRect result %d\n", ret );
}
- DispatchMessage( &msg );
+ DispatchMessageA( &msg );
}
ok_sequence( WmGetUpdateRect, "GetUpdateRect", FALSE );
RedrawWindow( hparent, NULL, 0, RDW_ERASENOW | RDW_ALLCHILDREN );
ok_sequence( WmInvalidateParentChild2, "InvalidateParentChild2", FALSE );
- SetWindowLong( hparent, GWL_STYLE, GetWindowLong(hparent,GWL_STYLE) | WS_CLIPCHILDREN );
+ SetWindowLongA( hparent, GWL_STYLE, GetWindowLongA(hparent,GWL_STYLE) | WS_CLIPCHILDREN );
flush_sequence();
RedrawWindow( hparent, &rect, 0, RDW_INVALIDATE | RDW_ERASE | RDW_FRAME | RDW_ALLCHILDREN );
RedrawWindow( hparent, NULL, 0, RDW_ERASENOW );
/* flush all paint messages */
flush_events();
- SetWindowLong( hparent, GWL_STYLE, GetWindowLong(hparent,GWL_STYLE) & ~WS_CLIPCHILDREN );
+ SetWindowLongA( hparent, GWL_STYLE, GetWindowLongA(hparent,GWL_STYLE) & ~WS_CLIPCHILDREN );
flush_sequence();
/* RDW_UPDATENOW on child without WS_CLIPCHILDREN will validate corresponding parent area */
SetRectRgn( hrgn, 20, 20, 30, 30 );
check_update_rgn( hparent, hrgn );
/* no WM_PAINT in child while parent still pending */
- while (PeekMessage( &msg, hchild, 0, 0, PM_REMOVE )) DispatchMessage( &msg );
+ while (PeekMessageA( &msg, hchild, 0, 0, PM_REMOVE )) DispatchMessageA( &msg );
ok_sequence( WmEmptySeq, "No WM_PAINT", FALSE );
- while (PeekMessage( &msg, hparent, 0, 0, PM_REMOVE )) DispatchMessage( &msg );
+ while (PeekMessageA( &msg, hparent, 0, 0, PM_REMOVE )) DispatchMessageA( &msg );
ok_sequence( WmParentErasePaint, "WmParentErasePaint", FALSE );
flush_sequence();
RedrawWindow( hparent, &rect, 0, RDW_INVALIDATE | RDW_ERASE | RDW_FRAME );
/* no WM_PAINT in child while parent still pending */
- while (PeekMessage( &msg, hchild, 0, 0, PM_REMOVE )) DispatchMessage( &msg );
+ while (PeekMessageA( &msg, hchild, 0, 0, PM_REMOVE )) DispatchMessageA( &msg );
ok_sequence( WmEmptySeq, "No WM_PAINT", FALSE );
RedrawWindow( hparent, &rect, 0, RDW_VALIDATE | RDW_NOERASE | RDW_NOCHILDREN );
/* now that parent is valid child should get WM_PAINT */
- while (PeekMessage( &msg, hchild, 0, 0, PM_REMOVE )) DispatchMessage( &msg );
+ while (PeekMessageA( &msg, hchild, 0, 0, PM_REMOVE )) DispatchMessageA( &msg );
ok_sequence( WmInvalidateErasePaint2, "WmInvalidateErasePaint2", FALSE );
- while (PeekMessage( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessage( &msg );
+ while (PeekMessageA( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessageA( &msg );
ok_sequence( WmEmptySeq, "No other message", FALSE );
/* same thing with WS_CLIPCHILDREN in parent */
flush_sequence();
- SetWindowLong( hparent, GWL_STYLE, GetWindowLong(hparent,GWL_STYLE) | WS_CLIPCHILDREN );
+ SetWindowLongA( hparent, GWL_STYLE, GetWindowLongA(hparent,GWL_STYLE) | WS_CLIPCHILDREN );
ok_sequence( WmSetParentStyle, "WmSetParentStyle", FALSE );
/* changing style invalidates non client area, but we need to invalidate something else to see it */
RedrawWindow( hparent, &rect, 0, RDW_UPDATENOW );
SetRectRgn( hrgn, 20, 20, 30, 30 );
check_update_rgn( hparent, hrgn );
/* no WM_PAINT in child while parent still pending */
- while (PeekMessage( &msg, hchild, 0, 0, PM_REMOVE )) DispatchMessage( &msg );
+ while (PeekMessageA( &msg, hchild, 0, 0, PM_REMOVE )) DispatchMessageA( &msg );
ok_sequence( WmEmptySeq, "No WM_PAINT", FALSE );
/* WM_PAINT in parent first */
- while (PeekMessage( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessage( &msg );
+ while (PeekMessageA( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessageA( &msg );
ok_sequence( WmParentPaintNc, "WmParentPaintNc2", FALSE );
/* no RDW_ERASE in parent still causes RDW_ERASE and RDW_FRAME in child */
flush_events();
ok_sequence( WmParentOnlyPaint, "WmParentOnlyPaint", FALSE );
- assert( GetWindowLong(hparent, GWL_STYLE) & WS_CLIPCHILDREN );
+ assert( GetWindowLongA(hparent, GWL_STYLE) & WS_CLIPCHILDREN );
UpdateWindow( hparent );
flush_events();
flush_sequence();
flush_events();
ok_sequence(WmSWP_FrameChangedDeferErase, "SetWindowPos:FrameChangedDeferErase", FALSE );
- SetWindowLong( hparent, GWL_STYLE, GetWindowLong(hparent,GWL_STYLE) & ~WS_CLIPCHILDREN );
+ SetWindowLongA( hparent, GWL_STYLE, GetWindowLongA(hparent,GWL_STYLE) & ~WS_CLIPCHILDREN );
ok_sequence( WmSetParentStyle, "WmSetParentStyle", FALSE );
RedrawWindow( hparent, NULL, 0, RDW_INTERNALPAINT );
flush_events();
ok_sequence( WmParentPaint, "WmParentPaint", FALSE );
- assert( !(GetWindowLong(hparent, GWL_STYLE) & WS_CLIPCHILDREN) );
+ assert( !(GetWindowLongA(hparent, GWL_STYLE) & WS_CLIPCHILDREN) );
UpdateWindow( hparent );
flush_events();
flush_sequence();
flush_events();
ok_sequence(WmSWP_FrameChangedDeferErase, "SetWindowPos:FrameChangedDeferErase", FALSE );
- ok(GetWindowLong( hparent, GWL_STYLE ) & WS_VISIBLE, "parent should be visible\n");
- ok(GetWindowLong( hchild, GWL_STYLE ) & WS_VISIBLE, "child should be visible\n");
+ ok(GetWindowLongA( hparent, GWL_STYLE ) & WS_VISIBLE, "parent should be visible\n");
+ ok(GetWindowLongA( hchild, GWL_STYLE ) & WS_VISIBLE, "child should be visible\n");
UpdateWindow( hparent );
flush_events();
SetEvent(wnd_event->start_event);
- while (GetMessage(&msg, 0, 0, 0))
+ while (GetMessageA(&msg, 0, 0, 0))
{
TranslateMessage(&msg);
- DispatchMessage(&msg);
+ DispatchMessageA(&msg);
}
ok(IsWindow(wnd_event->hwnd), "window should still exist\n");
{
MsgWaitForMultipleObjects(0, NULL, FALSE, 1000, QS_ALLINPUT);
if (!IsWindow( hchild )) break; /* will be destroyed when parent thread exits */
- while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessage(&msg);
+ while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
}
return 0;
}
{
DWORD ret = MsgWaitForMultipleObjects(1, &child_event.start_event, FALSE, 1000, QS_SENDMESSAGE);
if (ret != 1) break;
- while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessage(&msg);
+ while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
}
ret = WaitForSingleObject( wnd_event->stop_event, 5000 );
ok( !ret, "WaitForSingleObject failed %x\n", ret );
return 0;
}
+static const char manifest_dep[] =
+"<assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\" manifestVersion=\"1.0\">"
+"<assemblyIdentity version=\"1.2.3.4\" name=\"testdep1\" type=\"win32\" processorArchitecture=\"" ARCH "\"/>"
+" <file name=\"testdep.dll\" />"
+"</assembly>";
+
+static const char manifest_main[] =
+"<assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\" manifestVersion=\"1.0\">"
+"<assemblyIdentity version=\"1.2.3.4\" name=\"Wine.Test\" type=\"win32\" />"
+"<dependency>"
+" <dependentAssembly>"
+" <assemblyIdentity type=\"win32\" name=\"testdep1\" version=\"1.2.3.4\" processorArchitecture=\"" ARCH "\" />"
+" </dependentAssembly>"
+"</dependency>"
+"</assembly>";
+
+static void create_manifest_file(const char *filename, const char *manifest)
+{
+ WCHAR path[MAX_PATH];
+ HANDLE file;
+ DWORD size;
+
+ MultiByteToWideChar( CP_ACP, 0, filename, -1, path, MAX_PATH );
+ file = CreateFileW(path, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
+ ok(file != INVALID_HANDLE_VALUE, "CreateFile failed: %u\n", GetLastError());
+ WriteFile(file, manifest, strlen(manifest), &size, NULL);
+ CloseHandle(file);
+}
+
+static HANDLE test_create(const char *file)
+{
+ WCHAR path[MAX_PATH];
+ ACTCTXW actctx;
+ HANDLE handle;
+
+ MultiByteToWideChar(CP_ACP, 0, file, -1, path, MAX_PATH);
+ memset(&actctx, 0, sizeof(ACTCTXW));
+ actctx.cbSize = sizeof(ACTCTXW);
+ actctx.lpSource = path;
+
+ handle = pCreateActCtxW(&actctx);
+ ok(handle != INVALID_HANDLE_VALUE, "failed to create context, error %u\n", GetLastError());
+
+ ok(actctx.cbSize == sizeof(actctx), "cbSize=%d\n", actctx.cbSize);
+ ok(actctx.dwFlags == 0, "dwFlags=%d\n", actctx.dwFlags);
+ ok(actctx.lpSource == path, "lpSource=%p\n", actctx.lpSource);
+ ok(actctx.wProcessorArchitecture == 0, "wProcessorArchitecture=%d\n", actctx.wProcessorArchitecture);
+ ok(actctx.wLangId == 0, "wLangId=%d\n", actctx.wLangId);
+ ok(actctx.lpAssemblyDirectory == NULL, "lpAssemblyDirectory=%p\n", actctx.lpAssemblyDirectory);
+ ok(actctx.lpResourceName == NULL, "lpResourceName=%p\n", actctx.lpResourceName);
+ ok(actctx.lpApplicationName == NULL, "lpApplicationName=%p\n", actctx.lpApplicationName);
+ ok(actctx.hModule == NULL, "hModule=%p\n", actctx.hModule);
+
+ return handle;
+}
+
static void test_interthread_messages(void)
{
- HANDLE hThread;
+ HANDLE hThread, context, handle, event;
+ ULONG_PTR cookie;
DWORD tid;
WNDPROC proc;
MSG msg;
CloseHandle(wnd_event.start_event);
SetLastError(0xdeadbeef);
- ok(!DestroyWindow(wnd_event.hwnd), "DestroyWindow succeded\n");
+ ok(!DestroyWindow(wnd_event.hwnd), "DestroyWindow succeeded\n");
ok(GetLastError() == ERROR_ACCESS_DENIED || GetLastError() == 0xdeadbeef,
"wrong error code %d\n", GetLastError());
SetLastError(0xdeadbeef);
len = DispatchMessageA(&msg);
ok((!len && GetLastError() == ERROR_MESSAGE_SYNC_ONLY) || broken(len), /* nt4 */
- "DispatchMessageA(WM_GETTEXT) succeded on another thread window: ret %d, error %d\n", len, GetLastError());
+ "DispatchMessageA(WM_GETTEXT) succeeded on another thread window: ret %d, error %d\n", len, GetLastError());
/* the following test causes an exception in user.exe under win9x */
msg.hwnd = wnd_event.hwnd;
wnd_event.hwnd = CreateWindowExA(0, "TestParentClass", "Test parent", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
100, 100, 200, 200, 0, 0, 0, NULL);
ok (wnd_event.hwnd != 0, "Failed to create parent window\n");
+ flush_events();
flush_sequence();
log_all_parent_messages++;
wnd_event.start_event = CreateEventA( NULL, TRUE, FALSE, NULL );
{
ret = MsgWaitForMultipleObjects(1, &wnd_event.start_event, FALSE, 1000, QS_SENDMESSAGE);
if (ret != 1) break;
- while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessage(&msg);
+ while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
}
ok( !ret, "MsgWaitForMultipleObjects failed %x\n", ret );
/* now wait for the thread without processing messages; this shouldn't deadlock */
ok_sequence(WmExitThreadSeq, "destroy child on thread exit", FALSE);
log_all_parent_messages--;
DestroyWindow( wnd_event.hwnd );
+
+ /* activation context tests */
+ if (!pActivateActCtx)
+ {
+ win_skip("Activation contexts are not supported, skipping\n");
+ return;
+ }
+
+ create_manifest_file("testdep1.manifest", manifest_dep);
+ create_manifest_file("main.manifest", manifest_main);
+
+ context = test_create("main.manifest");
+ DeleteFileA("testdep1.manifest");
+ DeleteFileA("main.manifest");
+
+ handle = (void*)0xdeadbeef;
+ ret = pGetCurrentActCtx(&handle);
+ ok(ret, "GetCurentActCtx failed: %u\n", GetLastError());
+ ok(handle == 0, "active context %p\n", handle);
+
+ wnd_event.start_event = CreateEventW(NULL, 0, 0, NULL);
+ hThread = CreateThread(NULL, 0, thread_proc, &wnd_event, 0, &tid);
+ ok(hThread != NULL, "CreateThread failed, error %d\n", GetLastError());
+ ok(WaitForSingleObject(wnd_event.start_event, INFINITE) == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
+ CloseHandle(wnd_event.start_event);
+
+ /* context is activated after thread creation, so it doesn't inherit it by default */
+ ret = pActivateActCtx(context, &cookie);
+ ok(ret, "activation failed: %u\n", GetLastError());
+
+ handle = 0;
+ ret = pGetCurrentActCtx(&handle);
+ ok(ret, "GetCurentActCtx failed: %u\n", GetLastError());
+ ok(handle != 0, "active context %p\n", handle);
+ pReleaseActCtx(handle);
+
+ /* destination window will test for active context */
+ ret = SendMessageA(wnd_event.hwnd, WM_USER+10, 0, 0);
+ ok(ret, "thread window returned %d\n", ret);
+
+ event = CreateEventW(NULL, 0, 0, NULL);
+ ret = PostMessageA(wnd_event.hwnd, WM_USER+10, 0, (LPARAM)event);
+ ok(ret, "thread window returned %d\n", ret);
+ ok(WaitForSingleObject(event, INFINITE) == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
+ CloseHandle(event);
+
+ ret = PostMessageA(wnd_event.hwnd, WM_QUIT, 0, 0);
+ ok(ret, "PostMessageA(WM_QUIT) error %d\n", GetLastError());
+
+ ok(WaitForSingleObject(hThread, INFINITE) == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
+ CloseHandle(hThread);
+
+ ret = pDeactivateActCtx(0, cookie);
+ ok(ret, "DeactivateActCtx failed: %u\n", GetLastError());
+ pReleaseActCtx(context);
}
log_msg.descr = "accel";
add_message(&log_msg);
- if (!hAccel || !TranslateAccelerator(hwnd, hAccel, &msg))
+ if (!hAccel || !TranslateAcceleratorA(hwnd, hAccel, &msg))
{
TranslateMessage(&msg);
- DispatchMessage(&msg);
+ DispatchMessageA(&msg);
}
}
}
state = GetKeyState(VK_CAPITAL);
ok(state == 0, "wrong CapsLock state %04x\n", state);
- hAccel = LoadAccelerators(GetModuleHandleA(0), MAKEINTRESOURCE(1));
+ hAccel = LoadAcceleratorsA(GetModuleHandleA(NULL), MAKEINTRESOURCEA(1));
assert(hAccel != 0);
flush_events();
ret = DestroyAcceleratorTable(hAccel);
ok( ret, "DestroyAcceleratorTable error %d\n", GetLastError());
- hAccel = LoadAccelerators(GetModuleHandleA(0), MAKEINTRESOURCE(2));
+ hAccel = LoadAcceleratorsA(GetModuleHandleA(NULL), MAKEINTRESOURCEA(2));
assert(hAccel != 0);
trace("testing VK_N press/release\n");
case WM_NCHITTEST:
return HTCLIENT;
+ case WM_USER+10:
+ {
+ HANDLE handle, event = (HANDLE)lParam;
+ BOOL ret;
+
+ handle = (void*)0xdeadbeef;
+ ret = pGetCurrentActCtx(&handle);
+ ok(ret, "failed to get current context, %u\n", GetLastError());
+ ok(handle == 0, "got active context %p\n", handle);
+ if (event) SetEvent(event);
+ return 1;
+ }
+
/* ignore */
case WM_MOUSEMOVE:
case WM_MOUSEACTIVATE:
return ret;
}
+static INT_PTR CALLBACK StopQuitMsgCheckProcA(HWND hwnd, UINT message, WPARAM wp, LPARAM lp)
+{
+ if (message == WM_CREATE)
+ PostMessageA(hwnd, WM_CLOSE, 0, 0);
+ else if (message == WM_CLOSE)
+ {
+ /* Only the first WM_QUIT will survive the window destruction */
+ PostMessageA(hwnd, WM_USER, 0x1234, 0x5678);
+ PostMessageA(hwnd, WM_QUIT, 0x1234, 0x5678);
+ PostMessageA(hwnd, WM_QUIT, 0x4321, 0x8765);
+ }
+
+ return DefWindowProcA(hwnd, message, wp, lp);
+}
+
static LRESULT WINAPI TestDlgProcA(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
static LONG defwndproc_counter = 0;
if (PeekMessageA(&msg2, 0, 0, 0, 1))
{
TranslateMessage(&msg2);
- DispatchMessage(&msg2);
+ DispatchMessageA(&msg2);
}
i--;
}
else ok(broken(1), "infinite loop\n");
if ( i == 0)
- paint_loop_done = 1;
+ paint_loop_done = TRUE;
return DefWindowProcA(hWnd,msg,wParam,lParam);
}
}
return DefWindowProcA(hWnd,msg,wParam,lParam);
}
+static LRESULT WINAPI HotkeyMsgCheckProcA(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ static LONG defwndproc_counter = 0;
+ LRESULT ret;
+ struct recvd_message msg;
+ DWORD queue_status;
+
+ if (ignore_message( message )) return 0;
+
+ if ((message >= WM_KEYFIRST && message <= WM_KEYLAST) ||
+ message == WM_HOTKEY || message >= WM_APP)
+ {
+ msg.hwnd = hwnd;
+ msg.message = message;
+ msg.flags = sent|wparam|lparam;
+ if (defwndproc_counter) msg.flags |= defwinproc;
+ msg.wParam = wParam;
+ msg.lParam = lParam;
+ msg.descr = "HotkeyMsgCheckProcA";
+ add_message(&msg);
+ }
+
+ defwndproc_counter++;
+ ret = DefWindowProcA(hwnd, message, wParam, lParam);
+ defwndproc_counter--;
+
+ if (message == WM_APP)
+ {
+ queue_status = GetQueueStatus(QS_HOTKEY);
+ ok((queue_status & (QS_HOTKEY << 16)) == QS_HOTKEY << 16, "expected QS_HOTKEY << 16 set, got %x\n", queue_status);
+ queue_status = GetQueueStatus(QS_POSTMESSAGE);
+ ok((queue_status & (QS_POSTMESSAGE << 16)) == QS_POSTMESSAGE << 16, "expected QS_POSTMESSAGE << 16 set, got %x\n", queue_status);
+ PostMessageA(hwnd, WM_APP+1, 0, 0);
+ }
+ else if (message == WM_APP+1)
+ {
+ queue_status = GetQueueStatus(QS_HOTKEY);
+ ok((queue_status & (QS_HOTKEY << 16)) == 0, "expected QS_HOTKEY << 16 cleared, got %x\n", queue_status);
+ }
+
+ return ret;
+}
+
static BOOL RegisterWindowClasses(void)
{
WNDCLASSA cls;
cls.cbWndExtra = 0;
cls.hInstance = GetModuleHandleA(0);
cls.hIcon = 0;
- cls.hCursor = LoadCursorA(0, IDC_ARROW);
+ cls.hCursor = LoadCursorA(0, (LPCSTR)IDC_ARROW);
cls.hbrBackground = GetStockObject(WHITE_BRUSH);
cls.lpszMenuName = NULL;
cls.lpszClassName = "TestWindowClass";
if(!RegisterClassA(&cls)) return FALSE;
+ cls.lpfnWndProc = HotkeyMsgCheckProcA;
+ cls.lpszClassName = "HotkeyWindowClass";
+ if(!RegisterClassA(&cls)) return FALSE;
+
cls.lpfnWndProc = ShowWindowProcA;
cls.lpszClassName = "ShowWindowClass";
if(!RegisterClassA(&cls)) return FALSE;
cls.lpszClassName = "TestParentClass";
if(!RegisterClassA(&cls)) return FALSE;
+ cls.lpfnWndProc = StopQuitMsgCheckProcA;
+ cls.lpszClassName = "StopQuitClass";
+ if(!RegisterClassA(&cls)) return FALSE;
+
cls.lpfnWndProc = DefWindowProcA;
cls.lpszClassName = "SimpleWindowClass";
if(!RegisterClassA(&cls)) return FALSE;
{
}
-static VOID CALLBACK tfunc_crash(HWND hwnd, UINT uMsg, UINT_PTR id, DWORD dwTime)
+#define TIMER_ID 0x19
+#define TIMER_COUNT_EXPECTED 100
+#define TIMER_COUNT_TOLERANCE 10
+
+static int count = 0;
+static void CALLBACK callback_count(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
{
- /* Crash on purpose */
- *(volatile int *)0 = 2;
+ count++;
}
-#define TIMER_ID 0x19
-
static DWORD WINAPI timer_thread_proc(LPVOID x)
{
struct timer_info *info = x;
static void test_timers(void)
{
struct timer_info info;
+ DWORD start;
DWORD id;
MSG msg;
- info.hWnd = CreateWindow ("TestWindowClass", NULL,
+ info.hWnd = CreateWindowA("TestWindowClass", NULL,
WS_OVERLAPPEDWINDOW ,
CW_USEDEFAULT, CW_USEDEFAULT, 300, 300, 0,
NULL, NULL, 0);
info.id = SetTimer(info.hWnd,TIMER_ID,10000,tfunc);
ok(info.id, "SetTimer failed\n");
ok(info.id==TIMER_ID, "SetTimer timer ID different\n");
- info.handles[0] = CreateEvent(NULL,0,0,NULL);
+ info.handles[0] = CreateEventW(NULL,0,0,NULL);
info.handles[1] = CreateThread(NULL,0,timer_thread_proc,&info,0,&id);
WaitForMultipleObjects(2, info.handles, FALSE, INFINITE);
ok( KillTimer(info.hWnd, TIMER_ID), "KillTimer failed\n");
- ok(DestroyWindow(info.hWnd), "failed to destroy window\n");
-
- /* Test timer callback with crash */
- SetLastError(0xdeadbeef);
- info.hWnd = CreateWindowW(testWindowClassW, NULL,
- WS_OVERLAPPEDWINDOW ,
- CW_USEDEFAULT, CW_USEDEFAULT, 300, 300, 0,
- NULL, NULL, 0);
- if ((!info.hWnd && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) || /* Win9x/Me */
- (!pGetMenuInfo)) /* Win95/NT4 */
- {
- win_skip("Test would crash on Win9x/WinMe/NT4\n");
- DestroyWindow(info.hWnd);
- return;
+ /* Check the minimum allowed timeout for a timer. MSDN indicates that it should be 10.0 ms,
+ * which occurs sometimes, but most testing on the VMs indicates a minimum timeout closer to
+ * 15.6 ms. Since there is some measurement error between test runs we are allowing for
+ * ±9 counts (~4 ms) around the expected value.
+ */
+ count = 0;
+ id = SetTimer(info.hWnd, TIMER_ID, 0, callback_count);
+ ok(id != 0, "did not get id from SetTimer.\n");
+ ok(id==TIMER_ID, "SetTimer timer ID different\n");
+ start = GetTickCount();
+ while (GetTickCount()-start < 1001 && GetMessageA(&msg, info.hWnd, 0, 0))
+ DispatchMessageA(&msg);
+ ok(abs(count-TIMER_COUNT_EXPECTED) < TIMER_COUNT_TOLERANCE /* xp */
+ || broken(abs(count-64) < TIMER_COUNT_TOLERANCE) /* most common */
+ || broken(abs(count-43) < TIMER_COUNT_TOLERANCE) /* w2k3, win8 */,
+ "did not get expected count for minimum timeout (%d != ~%d).\n",
+ count, TIMER_COUNT_EXPECTED);
+ ok(KillTimer(info.hWnd, id), "KillTimer failed\n");
+ /* Perform the same check on SetSystemTimer (only available on w2k3 and older) */
+ if (pSetSystemTimer)
+ {
+ int syscount = 0;
+
+ count = 0;
+ id = pSetSystemTimer(info.hWnd, TIMER_ID, 0, callback_count);
+ ok(id != 0, "did not get id from SetSystemTimer.\n");
+ ok(id==TIMER_ID, "SetTimer timer ID different\n");
+ start = GetTickCount();
+ while (GetTickCount()-start < 1001 && GetMessageA(&msg, info.hWnd, 0, 0))
+ {
+ if (msg.message == WM_SYSTIMER)
+ syscount++;
+ DispatchMessageA(&msg);
+ }
+ ok(abs(syscount-TIMER_COUNT_EXPECTED) < TIMER_COUNT_TOLERANCE
+ || broken(abs(syscount-64) < TIMER_COUNT_TOLERANCE) /* most common */
+ || broken(syscount > 4000 && syscount < 12000) /* win2k3sp0 */,
+ "did not get expected count for minimum timeout (%d != ~%d).\n",
+ syscount, TIMER_COUNT_EXPECTED);
+ todo_wine ok(count == 0, "did not get expected count for callback timeout (%d != 0).\n",
+ count);
+ ok(pKillSystemTimer(info.hWnd, id), "KillSystemTimer failed\n");
}
- info.id = SetTimer(info.hWnd, TIMER_ID, 0, tfunc_crash);
- ok(info.id, "SetTimer failed\n");
- Sleep(150);
- while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) DispatchMessage(&msg);
ok(DestroyWindow(info.hWnd), "failed to destroy window\n");
}
-static int count = 0;
-static VOID CALLBACK callback_count(
- HWND hwnd,
- UINT uMsg,
- UINT_PTR idEvent,
- DWORD dwTime
-)
-{
- count++;
-}
-
static void test_timers_no_wnd(void)
{
UINT_PTR id, id2;
+ DWORD start;
MSG msg;
count = 0;
id2 = SetTimer(NULL, id, 200, callback_count);
ok(id2 == id, "did not get same id from SetTimer when replacing (%li expected %li).\n", id2, id);
Sleep(150);
- while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) DispatchMessage(&msg);
+ while (PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
ok(count == 0, "did not get zero count as expected (%i).\n", count);
Sleep(150);
- while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) DispatchMessage(&msg);
+ while (PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
ok(count == 1, "did not get one count as expected (%i).\n", count);
KillTimer(NULL, id);
Sleep(250);
- while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) DispatchMessage(&msg);
+ while (PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
ok(count == 1, "killing replaced timer did not work (%i).\n", count);
+
+ /* Check the minimum allowed timeout for a timer. MSDN indicates that it should be 10.0 ms,
+ * which occurs sometimes, but most testing on the VMs indicates a minimum timeout closer to
+ * 15.6 ms. Since there is some measurement error between test runs we are allowing for
+ * ±9 counts (~4 ms) around the expected value.
+ */
+ count = 0;
+ id = SetTimer(NULL, 0, 0, callback_count);
+ ok(id != 0, "did not get id from SetTimer.\n");
+ start = GetTickCount();
+ while (GetTickCount()-start < 1001 && GetMessageA(&msg, NULL, 0, 0))
+ DispatchMessageA(&msg);
+ ok(abs(count-TIMER_COUNT_EXPECTED) < TIMER_COUNT_TOLERANCE /* xp */
+ || broken(abs(count-64) < TIMER_COUNT_TOLERANCE) /* most common */,
+ "did not get expected count for minimum timeout (%d != ~%d).\n",
+ count, TIMER_COUNT_EXPECTED);
+ KillTimer(NULL, id);
+ /* Note: SetSystemTimer doesn't support a NULL window, see test_timers */
}
/* Various win events with arbitrary parameters */
pNotifyWinEvent(EVENT_OBJECT_LOCATIONCHANGE, hwnd, OBJID_ALERT, 0);
SetEvent(hevent);
- while (GetMessage(&msg, 0, 0, 0))
+ while (GetMessageA(&msg, 0, 0, 0))
{
TranslateMessage(&msg);
- DispatchMessage(&msg);
+ DispatchMessageA(&msg);
}
return 0;
}
SetEvent(hevent);
- while (GetMessage(&msg, 0, 0, 0))
+ while (GetMessageA(&msg, 0, 0, 0))
{
TranslateMessage(&msg);
- DispatchMessage(&msg);
+ DispatchMessageA(&msg);
}
return 0;
}
mouse_event(MOUSEEVENTF_MOVE, 1, 0, 0, 0);
SetEvent(hevent);
- while (GetMessage(&msg, 0, 0, 0))
+ while (GetMessageA(&msg, 0, 0, 0))
{
TranslateMessage(&msg);
- DispatchMessage(&msg);
+ DispatchMessageA(&msg);
}
return 0;
}
ok(hthread != NULL, "CreateThread failed, error %d\n", GetLastError());
while (WaitForSingleObject(hevent, 100) == WAIT_TIMEOUT)
- while (PeekMessage( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessage( &msg );
+ while (PeekMessageA( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessageA( &msg );
ok_sequence(WmMouseLLHookSeq, "MOUSE_LL hook other thread", FALSE);
flush_sequence();
trace("start scroll\n");
ScrollWindowEx( hwnd, 10, 10, &rect, NULL, NULL, NULL,
SW_ERASE|SW_INVALIDATE);
- ok_sequence(WmEmptySeq, "ScrollWindowEx", 0);
+ ok_sequence(WmEmptySeq, "ScrollWindowEx", FALSE);
trace("end scroll\n");
flush_sequence();
flush_events();
- ok_sequence(ScrollWindowPaint1, "ScrollWindowEx", 0);
+ ok_sequence(ScrollWindowPaint1, "ScrollWindowEx", FALSE);
flush_events();
flush_sequence();
/* Now without the SW_ERASE flag */
trace("start scroll\n");
ScrollWindowEx( hwnd, 10, 10, &rect, NULL, NULL, NULL, SW_INVALIDATE);
- ok_sequence(WmEmptySeq, "ScrollWindowEx", 0);
+ ok_sequence(WmEmptySeq, "ScrollWindowEx", FALSE);
trace("end scroll\n");
flush_sequence();
flush_events();
- ok_sequence(ScrollWindowPaint2, "ScrollWindowEx", 0);
+ ok_sequence(ScrollWindowPaint2, "ScrollWindowEx", FALSE);
flush_events();
flush_sequence();
trace("end scroll\n");
flush_sequence();
flush_events();
- ok_sequence(ScrollWindowPaint1, "ScrollWindowEx", 0);
+ ok_sequence(ScrollWindowPaint1, "ScrollWindowEx", FALSE);
flush_events();
flush_sequence();
trace("end scroll\n");
flush_sequence();
flush_events();
- ok_sequence(ScrollWindowPaint1, "ScrollWindow", 0);
+ ok_sequence(ScrollWindowPaint1, "ScrollWindow", FALSE);
ok(DestroyWindow(hchild), "failed to destroy window\n");
ok(DestroyWindow(hwnd), "failed to destroy window\n");
ret = DestroyWindow(parent);
ok( ret, "DestroyWindow() error %d\n", GetLastError());
test_DestroyWindow_flag = FALSE;
- ok_sequence(destroy_window_with_children, "destroy window with children", 0);
+ ok_sequence(destroy_window_with_children, "destroy window with children", FALSE);
ok(!IsWindow(parent), "parent still exists\n");
ok(!IsWindow(child1), "child1 still exists\n");
SetRect( &rect, -5, -5, 5, 5 );
RedrawWindow( hwnd, &rect, 0, RDW_INVALIDATE|RDW_ERASE|RDW_FRAME );
count = 0;
- while (PeekMessage( &msg, 0, 0, 0, PM_REMOVE ))
+ while (PeekMessageA( &msg, 0, 0, 0, PM_REMOVE ))
{
- if (msg.message != WM_PAINT) DispatchMessage( &msg );
+ if (msg.message != WM_PAINT) DispatchMessageA( &msg );
else
{
flush_sequence();
- DispatchMessage( &msg );
+ DispatchMessageA( &msg );
/* DispatchMessage will send WM_NCPAINT if non client area is still invalid after WM_PAINT */
if (!count) ok_sequence( WmDispatchPaint, "WmDispatchPaint", FALSE );
else ok_sequence( WmEmptySeq, "WmEmpty", FALSE );
flush_sequence();
RedrawWindow( hwnd, &rect, 0, RDW_INVALIDATE|RDW_ERASE|RDW_FRAME );
count = 0;
- while (PeekMessage( &msg, 0, 0, 0, PM_REMOVE ))
+ while (PeekMessageA( &msg, 0, 0, 0, PM_REMOVE ))
{
- if (msg.message != WM_PAINT) DispatchMessage( &msg );
+ if (msg.message != WM_PAINT) DispatchMessageA( &msg );
else
{
HRGN hrgn = CreateRectRgn( 0, 0, 0, 0 );
if (++count > 10) break;
}
}
+
+ flush_sequence();
+ RedrawWindow( hwnd, &rect, 0, RDW_INVALIDATE|RDW_ERASE|RDW_FRAME );
+ count = 0;
+ while (PeekMessageA( &msg, 0, 0, 0, PM_REMOVE ))
+ {
+ if (msg.message != WM_PAINT) DispatchMessageA( &msg );
+ else
+ {
+ HDC hdc;
+
+ flush_sequence();
+ hdc = BeginPaint( hwnd, NULL );
+ ok( !hdc, "got valid hdc %p from BeginPaint\n", hdc );
+ ok( !EndPaint( hwnd, NULL ), "EndPaint succeeded\n" );
+ ok_sequence( WmDispatchPaint, "WmDispatchPaint", FALSE );
+ ok( !count, "Got multiple WM_PAINTs\n" );
+ if (++count > 10) break;
+ }
+ }
DestroyWindow(hwnd);
}
while (MsgWaitForMultipleObjects(1, &thread, FALSE, INFINITE, QS_SENDMESSAGE) != WAIT_OBJECT_0)
{
MSG msg;
- while (PeekMessageA( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessage(&msg);
+ while (PeekMessageA( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessageA(&msg);
}
}
{ WM_COMMAND, sent|parent|wparam, MAKEWPARAM(ID_EDIT, EN_SETFOCUS) },
{ 0 }
};
+static const struct message sl_edit_invisible[] =
+{
+ { HCBT_SETFOCUS, hook },
+ { WM_IME_SETCONTEXT, sent|wparam|optional, 1 },
+ { WM_IME_NOTIFY, sent|wparam|defwinproc|optional, 2 },
+ { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
+ { WM_KILLFOCUS, sent|parent },
+ { WM_SETFOCUS, sent },
+ { WM_COMMAND, sent|parent|wparam, MAKEWPARAM(ID_EDIT, EN_SETFOCUS) },
+ { 0 }
+};
static const struct message ml_edit_setfocus[] =
{
{ HCBT_SETFOCUS, hook },
old_edit_proc = cls.lpfnWndProc;
- cls.hInstance = GetModuleHandle(0);
+ cls.hInstance = GetModuleHandleA(NULL);
cls.lpfnWndProc = edit_hook_proc;
cls.lpszClassName = "my_edit_class";
- UnregisterClass(cls.lpszClassName, cls.hInstance);
+ UnregisterClassA(cls.lpszClassName, cls.hInstance);
if (!RegisterClassA(&cls)) assert(0);
}
dlg_code = SendMessageA(hwnd, WM_GETDLGCODE, 0, 0);
ok(dlg_code == (DLGC_WANTCHARS|DLGC_HASSETSEL|DLGC_WANTARROWS), "wrong dlg_code %08x\n", dlg_code);
+ flush_sequence();
+ SetFocus(hwnd);
+ ok_sequence(sl_edit_invisible, "SetFocus(hwnd) on an invisible edit", FALSE);
+
ShowWindow(hwnd, SW_SHOW);
UpdateWindow(hwnd);
SetFocus(0);
case WAIT_OBJECT_0 + EV_SENDMSG:
trace("thread: sending message\n");
- ok( SendNotifyMessageA(info->hwnd, WM_USER, 0, 0),
- "SendNotifyMessageA failed error %u\n", GetLastError());
+ ret = SendNotifyMessageA(info->hwnd, WM_USER, 0, 0);
+ ok(ret, "SendNotifyMessageA failed error %u\n", GetLastError());
SetEvent(info->hevent[EV_ACK]);
break;
}
if (qstatus & QS_POSTMESSAGE)
{
- while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) /* nothing */ ;
+ while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) /* nothing */ ;
qstatus = GetQueueStatus(qs_all_input);
}
ok(qstatus == 0, "wrong qstatus %08x\n", qstatus);
{
MSG msg;
DWORD time;
- BOOL ret;
- int go = 0;
+ BOOL ret, go = FALSE;
time = GetTickCount();
while (GetTickCount() - time < 200 && !go) {
x1 = y1 = x2 = y2 = x3 = y3 = 0;
/* Initialise window and make sure it is ready for events */
- hwnd = CreateWindow("TestWindowClass", "PeekMessage2", WS_OVERLAPPEDWINDOW,
+ hwnd = CreateWindowA("TestWindowClass", "PeekMessage2", WS_OVERLAPPEDWINDOW,
10, 10, 800, 800, NULL, NULL, NULL, NULL);
assert(hwnd);
trace("Window for test_PeekMessage2 %p\n", hwnd);
flush_events();
}
+static INT_PTR CALLBACK wm_quit_dlg_proc(HWND hwnd, UINT message, WPARAM wp, LPARAM lp)
+{
+ struct recvd_message msg;
+
+ if (ignore_message( message )) return 0;
+
+ msg.hwnd = hwnd;
+ msg.message = message;
+ msg.flags = sent|wparam|lparam;
+ msg.wParam = wp;
+ msg.lParam = lp;
+ msg.descr = "dialog";
+ add_message(&msg);
+
+ switch (message)
+ {
+ case WM_INITDIALOG:
+ PostMessageA(hwnd, WM_QUIT, 0x1234, 0x5678);
+ PostMessageA(hwnd, WM_USER, 0xdead, 0xbeef);
+ return 0;
+
+ case WM_GETDLGCODE:
+ return 0;
+
+ case WM_USER:
+ EndDialog(hwnd, 0);
+ break;
+ }
+
+ return 1;
+}
+
+static const struct message WmQuitDialogSeq[] = {
+ { HCBT_CREATEWND, hook },
+ { WM_SETFONT, sent },
+ { WM_INITDIALOG, sent },
+ { WM_CHANGEUISTATE, sent|optional },
+ { HCBT_DESTROYWND, hook },
+ { 0x0090, sent|optional }, /* Vista */
+ { WM_DESTROY, sent },
+ { WM_NCDESTROY, sent },
+ { 0 }
+};
+
+static const struct message WmStopQuitSeq[] = {
+ { WM_DWMNCRENDERINGCHANGED, posted|optional },
+ { WM_CLOSE, posted },
+ { WM_QUIT, posted|wparam|lparam, 0x1234, 0 },
+ { 0 }
+};
+
static void test_quit_message(void)
{
MSG msg;
flush_events();
PostQuitMessage(0xbeef);
- ret = PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE);
+ ret = PeekMessageA(&msg, NULL, 0, 0, PM_NOREMOVE);
ok(ret, "PeekMessage failed with error %d\n", GetLastError());
ok(msg.message == WM_QUIT, "Received message 0x%04x instead of WM_QUIT\n", msg.message);
ok(msg.wParam == 0xbeef, "wParam was 0x%lx instead of 0xbeef\n", msg.wParam);
- ret = PostThreadMessage(GetCurrentThreadId(), WM_USER, 0, 0);
+ ret = PostThreadMessageA(GetCurrentThreadId(), WM_USER, 0, 0);
ok(ret, "PostMessage failed with error %d\n", GetLastError());
- ret = GetMessage(&msg, NULL, 0, 0);
+ ret = GetMessageA(&msg, NULL, 0, 0);
ok(ret > 0, "GetMessage failed with error %d\n", GetLastError());
ok(msg.message == WM_USER, "Received message 0x%04x instead of WM_USER\n", msg.message);
/* note: WM_QUIT message received after WM_USER message */
- ret = GetMessage(&msg, NULL, 0, 0);
+ ret = GetMessageA(&msg, NULL, 0, 0);
ok(!ret, "GetMessage return %d with error %d instead of FALSE\n", ret, GetLastError());
ok(msg.message == WM_QUIT, "Received message 0x%04x instead of WM_QUIT\n", msg.message);
ok(msg.wParam == 0xbeef, "wParam was 0x%lx instead of 0xbeef\n", msg.wParam);
- ret = PeekMessage(&msg, NULL, 0, 0, PM_REMOVE);
+ ret = PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE);
ok( !ret || msg.message != WM_QUIT, "Received WM_QUIT again\n" );
/* now test with PostThreadMessage - different behaviour! */
- PostThreadMessage(GetCurrentThreadId(), WM_QUIT, 0xdead, 0);
+ PostThreadMessageA(GetCurrentThreadId(), WM_QUIT, 0xdead, 0);
- ret = PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE);
+ ret = PeekMessageA(&msg, NULL, 0, 0, PM_NOREMOVE);
ok(ret, "PeekMessage failed with error %d\n", GetLastError());
ok(msg.message == WM_QUIT, "Received message 0x%04x instead of WM_QUIT\n", msg.message);
ok(msg.wParam == 0xdead, "wParam was 0x%lx instead of 0xdead\n", msg.wParam);
- ret = PostThreadMessage(GetCurrentThreadId(), WM_USER, 0, 0);
+ ret = PostThreadMessageA(GetCurrentThreadId(), WM_USER, 0, 0);
ok(ret, "PostMessage failed with error %d\n", GetLastError());
/* note: we receive the WM_QUIT message first this time */
- ret = GetMessage(&msg, NULL, 0, 0);
+ ret = GetMessageA(&msg, NULL, 0, 0);
ok(!ret, "GetMessage return %d with error %d instead of FALSE\n", ret, GetLastError());
ok(msg.message == WM_QUIT, "Received message 0x%04x instead of WM_QUIT\n", msg.message);
ok(msg.wParam == 0xdead, "wParam was 0x%lx instead of 0xdead\n", msg.wParam);
- ret = GetMessage(&msg, NULL, 0, 0);
+ ret = GetMessageA(&msg, NULL, 0, 0);
ok(ret > 0, "GetMessage failed with error %d\n", GetLastError());
ok(msg.message == WM_USER, "Received message 0x%04x instead of WM_USER\n", msg.message);
+
+ flush_events();
+ flush_sequence();
+ ret = DialogBoxParamA(GetModuleHandleA(NULL), "TEST_EMPTY_DIALOG", 0, wm_quit_dlg_proc, 0);
+ ok(ret == 1, "expected 1, got %d\n", ret);
+ ok_sequence(WmQuitDialogSeq, "WmQuitDialogSeq", FALSE);
+ memset(&msg, 0xab, sizeof(msg));
+ ret = PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE);
+ ok(ret, "PeekMessage failed\n");
+ ok(msg.message == WM_QUIT, "Received message 0x%04x instead of WM_QUIT\n", msg.message);
+ ok(msg.wParam == 0x1234, "wParam was 0x%lx instead of 0x1234\n", msg.wParam);
+ ok(msg.lParam == 0, "lParam was 0x%lx instead of 0\n", msg.lParam);
+
+ /* Check what happens to a WM_QUIT message posted to a window that gets
+ * destroyed.
+ */
+ CreateWindowExA(0, "StopQuitClass", "Stop Quit Test", WS_OVERLAPPEDWINDOW,
+ 0, 0, 100, 100, NULL, NULL, NULL, NULL);
+ flush_sequence();
+ while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE))
+ {
+ struct recvd_message rmsg;
+ rmsg.hwnd = msg.hwnd;
+ rmsg.message = msg.message;
+ rmsg.flags = posted|wparam|lparam;
+ rmsg.wParam = msg.wParam;
+ rmsg.lParam = msg.lParam;
+ rmsg.descr = "stop/quit";
+ if (msg.message == WM_QUIT)
+ /* The hwnd can only be checked here */
+ ok(!msg.hwnd, "The WM_QUIT hwnd was %p instead of NULL\n", msg.hwnd);
+ add_message(&rmsg);
+ DispatchMessageA(&msg);
+ }
+ ok_sequence(WmStopQuitSeq, "WmStopQuitSeq", FALSE);
}
static const struct message WmMouseHoverSeq[] = {
do
{
- while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
+ while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE))
{
/* Timer proc messages are not dispatched to the window proc,
* and therefore not logged.
s_msg.descr = "msg_loop";
add_message(&s_msg);
}
- DispatchMessage(&msg);
+ DispatchMessageA(&msg);
}
end_ticks = GetTickCount();
default_hover_time = 0xdeadbeef;
SetLastError(0xdeadbeef);
- ret = SystemParametersInfo(SPI_GETMOUSEHOVERTIME, 0, &default_hover_time, 0);
+ ret = SystemParametersInfoA(SPI_GETMOUSEHOVERTIME, 0, &default_hover_time, 0);
ok(ret || broken(GetLastError() == 0xdeadbeef), /* win9x */
"SystemParametersInfo(SPI_GETMOUSEHOVERTIME) error %u\n", GetLastError());
if (!ret) default_hover_time = 400;
trace("SPI_GETMOUSEHOVERTIME returned %u ms\n", default_hover_time);
SetLastError(0xdeadbeef);
- ret = SystemParametersInfo(SPI_GETMOUSEHOVERWIDTH, 0, &hover_width, 0);
+ ret = SystemParametersInfoA(SPI_GETMOUSEHOVERWIDTH, 0, &hover_width, 0);
ok(ret || broken(GetLastError() == 0xdeadbeef), /* win9x */
"SystemParametersInfo(SPI_GETMOUSEHOVERWIDTH) error %u\n", GetLastError());
if (!ret) hover_width = 4;
SetLastError(0xdeadbeef);
- ret = SystemParametersInfo(SPI_GETMOUSEHOVERHEIGHT, 0, &hover_height, 0);
+ ret = SystemParametersInfoA(SPI_GETMOUSEHOVERHEIGHT, 0, &hover_height, 0);
ok(ret || broken(GetLastError() == 0xdeadbeef), /* win9x */
"SystemParametersInfo(SPI_GETMOUSEHOVERHEIGHT) error %u\n", GetLastError());
if (!ret) hover_height = 4;
trace("hover rect is %u x %d\n", hover_width, hover_height);
- hwnd = CreateWindowEx(0, "TestWindowClass", NULL,
+ hwnd = CreateWindowExA(0, "TestWindowClass", NULL,
WS_OVERLAPPEDWINDOW | WS_VISIBLE,
CW_USEDEFAULT, CW_USEDEFAULT, 300, 300, 0,
NULL, NULL, 0);
assert(hwnd);
- hchild = CreateWindowEx(0, "TestWindowClass", NULL,
+ hchild = CreateWindowExA(0, "TestWindowClass", NULL,
WS_CHILD | WS_BORDER | WS_VISIBLE,
50, 50, 200, 200, hwnd,
NULL, NULL, 0);
};
static const struct message WmShowNoActivate_2[] = {
{ HCBT_MINMAX, hook|lparam, 0, SW_SHOWNOACTIVATE },
- { WM_WINDOWPOSCHANGING, sent|wparam, SWP_SHOWWINDOW|SWP_NOACTIVATE|SWP_FRAMECHANGED|SWP_NOCOPYBITS|SWP_STATECHANGED },
- { WM_WINDOWPOSCHANGED, sent|wparam, SWP_SHOWWINDOW|SWP_NOACTIVATE|SWP_FRAMECHANGED|SWP_NOCOPYBITS|SWP_STATECHANGED },
+ { WM_WINDOWPOSCHANGING, sent|wparam, SWP_SHOWWINDOW|SWP_NOACTIVATE|SWP_FRAMECHANGED|SWP_NOCOPYBITS|SWP_STATECHANGED, 0, SWP_NOACTIVATE },
+ { HCBT_ACTIVATE, hook|optional },
+ { WM_WINDOWPOSCHANGING, sent|wparam|optional, SWP_NOSIZE|SWP_NOMOVE },
+ { HCBT_SETFOCUS, hook|optional },
+ { WM_WINDOWPOSCHANGED, sent|wparam, SWP_SHOWWINDOW|SWP_NOACTIVATE|SWP_FRAMECHANGED|SWP_NOCOPYBITS|SWP_STATECHANGED, 0, SWP_NOACTIVATE },
{ WM_MOVE, sent|defwinproc },
{ WM_SIZE, sent|wparam|defwinproc, SIZE_RESTORED },
{ HCBT_SETFOCUS, hook|optional },
static const struct message WmMinimize_2[] = {
{ HCBT_MINMAX, hook|lparam, 0, SW_MINIMIZE },
{ HCBT_SETFOCUS, hook|optional },
- { WM_WINDOWPOSCHANGING, sent|wparam, SWP_SHOWWINDOW|SWP_NOACTIVATE|SWP_FRAMECHANGED|SWP_NOCOPYBITS|SWP_STATECHANGED },
- { WM_WINDOWPOSCHANGED, sent|wparam, SWP_NOACTIVATE|SWP_FRAMECHANGED|SWP_NOCOPYBITS|SWP_STATECHANGED },
+ { WM_WINDOWPOSCHANGING, sent|wparam, SWP_SHOWWINDOW|SWP_NOACTIVATE|SWP_FRAMECHANGED|SWP_NOCOPYBITS|SWP_STATECHANGED, 0, SWP_NOACTIVATE },
+ { WM_WINDOWPOSCHANGED, sent|wparam, SWP_NOACTIVATE|SWP_FRAMECHANGED|SWP_NOCOPYBITS|SWP_STATECHANGED, 0, SWP_NOACTIVATE },
{ WM_MOVE, sent|defwinproc },
{ WM_SIZE, sent|wparam|lparam|defwinproc, SIZE_MINIMIZED, 0 },
{ 0 }
};
static const struct message WmMinimize_3[] = {
{ HCBT_MINMAX, hook|lparam, 0, SW_MINIMIZE },
- { WM_WINDOWPOSCHANGING, sent|wparam, SWP_SHOWWINDOW|SWP_NOACTIVATE|SWP_FRAMECHANGED|SWP_NOCOPYBITS|SWP_STATECHANGED },
- { WM_WINDOWPOSCHANGED, sent|wparam, SWP_SHOWWINDOW|SWP_NOACTIVATE|SWP_FRAMECHANGED|SWP_NOCOPYBITS|SWP_STATECHANGED },
+ { WM_WINDOWPOSCHANGING, sent|wparam, SWP_SHOWWINDOW|SWP_NOACTIVATE|SWP_FRAMECHANGED|SWP_NOCOPYBITS|SWP_STATECHANGED, 0, SWP_NOACTIVATE },
+ { HCBT_ACTIVATE, hook|optional },
+ { WM_WINDOWPOSCHANGING, sent|wparam|optional, SWP_NOSIZE|SWP_NOMOVE },
+ { WM_WINDOWPOSCHANGED, sent|wparam, SWP_SHOWWINDOW|SWP_NOACTIVATE|SWP_FRAMECHANGED|SWP_NOCOPYBITS|SWP_STATECHANGED, 0, SWP_NOACTIVATE },
{ WM_MOVE, sent|defwinproc },
{ WM_SIZE, sent|wparam|lparam|defwinproc, SIZE_MINIMIZED, 0 },
{ 0 }
LPARAM ret; /* ShowWindow return value */
DWORD style; /* window style after the command */
const struct message *msg; /* message sequence the command produces */
+ INT wp_cmd, wp_flags; /* window placement after the command */
+ POINT wp_min, wp_max; /* window placement after the command */
BOOL todo_msg; /* message sequence doesn't match what Wine does */
} sw[] =
{
-/* 1 */ { SW_SHOWNORMAL, FALSE, WS_VISIBLE, WmShowNormal, FALSE },
-/* 2 */ { SW_SHOWNORMAL, TRUE, WS_VISIBLE, WmEmptySeq, FALSE },
-/* 3 */ { SW_HIDE, TRUE, 0, WmHide_1, FALSE },
-/* 4 */ { SW_HIDE, FALSE, 0, WmEmptySeq, FALSE },
-/* 5 */ { SW_SHOWMINIMIZED, FALSE, WS_VISIBLE|WS_MINIMIZE, WmShowMinimized_1, FALSE },
-/* 6 */ { SW_SHOWMINIMIZED, TRUE, WS_VISIBLE|WS_MINIMIZE, WmMinMax_1, FALSE },
-/* 7 */ { SW_HIDE, TRUE, WS_MINIMIZE, WmHide_1, FALSE },
-/* 8 */ { SW_HIDE, FALSE, WS_MINIMIZE, WmEmptySeq, FALSE },
-/* 9 */ { SW_SHOWMAXIMIZED, FALSE, WS_VISIBLE|WS_MAXIMIZE, WmShowMaximized_1, FALSE },
-/* 10 */ { SW_SHOWMAXIMIZED, TRUE, WS_VISIBLE|WS_MAXIMIZE, WmMinMax_2, FALSE },
-/* 11 */ { SW_HIDE, TRUE, WS_MAXIMIZE, WmHide_1, FALSE },
-/* 12 */ { SW_HIDE, FALSE, WS_MAXIMIZE, WmEmptySeq, FALSE },
-/* 13 */ { SW_SHOWNOACTIVATE, FALSE, WS_VISIBLE, WmShowNoActivate_1, FALSE },
-/* 14 */ { SW_SHOWNOACTIVATE, TRUE, WS_VISIBLE, WmEmptySeq, FALSE },
-/* 15 */ { SW_HIDE, TRUE, 0, WmHide_2, FALSE },
-/* 16 */ { SW_HIDE, FALSE, 0, WmEmptySeq, FALSE },
-/* 17 */ { SW_SHOW, FALSE, WS_VISIBLE, WmShow, FALSE },
-/* 18 */ { SW_SHOW, TRUE, WS_VISIBLE, WmEmptySeq, FALSE },
-/* 19 */ { SW_MINIMIZE, TRUE, WS_VISIBLE|WS_MINIMIZE, WmMinimize_1, FALSE },
-/* 20 */ { SW_MINIMIZE, TRUE, WS_VISIBLE|WS_MINIMIZE, WmMinMax_3, FALSE },
-/* 21 */ { SW_HIDE, TRUE, WS_MINIMIZE, WmHide_2, FALSE },
-/* 22 */ { SW_SHOWMINNOACTIVE, FALSE, WS_VISIBLE|WS_MINIMIZE, WmShowMinNoActivate, TRUE },
-/* 23 */ { SW_SHOWMINNOACTIVE, TRUE, WS_VISIBLE|WS_MINIMIZE, WmMinMax_4, FALSE },
-/* 24 */ { SW_HIDE, TRUE, WS_MINIMIZE, WmHide_2, FALSE },
-/* 25 */ { SW_HIDE, FALSE, WS_MINIMIZE, WmEmptySeq, FALSE },
-/* 26 */ { SW_SHOWNA, FALSE, WS_VISIBLE|WS_MINIMIZE, WmShowNA_1, FALSE },
-/* 27 */ { SW_SHOWNA, TRUE, WS_VISIBLE|WS_MINIMIZE, WmShowNA_2, FALSE },
-/* 28 */ { SW_HIDE, TRUE, WS_MINIMIZE, WmHide_2, FALSE },
-/* 29 */ { SW_HIDE, FALSE, WS_MINIMIZE, WmEmptySeq, FALSE },
-/* 30 */ { SW_RESTORE, FALSE, WS_VISIBLE, WmRestore_1, FALSE },
-/* 31 */ { SW_RESTORE, TRUE, WS_VISIBLE, WmEmptySeq, FALSE },
-/* 32 */ { SW_HIDE, TRUE, 0, WmHide_3, FALSE },
-/* 33 */ { SW_HIDE, FALSE, 0, WmEmptySeq, FALSE },
-/* 34 */ { SW_NORMALNA, FALSE, 0, WmEmptySeq, FALSE }, /* what does this mean?! */
-/* 35 */ { SW_NORMALNA, FALSE, 0, WmEmptySeq, FALSE },
-/* 36 */ { SW_HIDE, FALSE, 0, WmEmptySeq, FALSE },
-/* 37 */ { SW_RESTORE, FALSE, WS_VISIBLE, WmRestore_2, FALSE },
-/* 38 */ { SW_RESTORE, TRUE, WS_VISIBLE, WmEmptySeq, FALSE },
-/* 39 */ { SW_SHOWNOACTIVATE, TRUE, WS_VISIBLE, WmEmptySeq, FALSE },
-/* 40 */ { SW_MINIMIZE, TRUE, WS_VISIBLE|WS_MINIMIZE, WmMinimize_2, FALSE },
-/* 41 */ { SW_MINIMIZE, TRUE, WS_VISIBLE|WS_MINIMIZE, WmMinMax_3, FALSE },
-/* 42 */ { SW_SHOWMAXIMIZED, TRUE, WS_VISIBLE|WS_MAXIMIZE, WmShowMaximized_2, FALSE },
-/* 43 */ { SW_SHOWMAXIMIZED, TRUE, WS_VISIBLE|WS_MAXIMIZE, WmMinMax_2, FALSE },
-/* 44 */ { SW_MINIMIZE, TRUE, WS_VISIBLE|WS_MINIMIZE, WmMinimize_1, FALSE },
-/* 45 */ { SW_MINIMIZE, TRUE, WS_VISIBLE|WS_MINIMIZE, WmMinMax_3, FALSE },
-/* 46 */ { SW_RESTORE, TRUE, WS_VISIBLE|WS_MAXIMIZE, WmRestore_3, FALSE },
-/* 47 */ { SW_RESTORE, TRUE, WS_VISIBLE, WmRestore_4, FALSE },
-/* 48 */ { SW_SHOWMAXIMIZED, TRUE, WS_VISIBLE|WS_MAXIMIZE, WmShowMaximized_3, FALSE },
-/* 49 */ { SW_SHOW, TRUE, WS_VISIBLE|WS_MAXIMIZE, WmEmptySeq, FALSE },
-/* 50 */ { SW_SHOWNORMAL, TRUE, WS_VISIBLE, WmRestore_5, FALSE },
-/* 51 */ { SW_SHOWNORMAL, TRUE, WS_VISIBLE, WmRestore_5, FALSE },
-/* 52 */ { SW_HIDE, TRUE, 0, WmHide_1, FALSE },
-/* 53 */ { SW_HIDE, FALSE, 0, WmEmptySeq, FALSE },
-/* 54 */ { SW_MINIMIZE, FALSE, WS_VISIBLE|WS_MINIMIZE, WmMinimize_3, FALSE },
-/* 55 */ { SW_HIDE, TRUE, WS_MINIMIZE, WmHide_2, FALSE },
-/* 56 */ { SW_SHOWNOACTIVATE, FALSE, WS_VISIBLE, WmShowNoActivate_2, FALSE },
-/* 57 */ { SW_SHOW, TRUE, WS_VISIBLE, WmEmptySeq, FALSE }
+/* 1 */ { SW_SHOWNORMAL, FALSE, WS_VISIBLE, WmShowNormal,
+ SW_SHOWNORMAL, 0, {-1,-1}, {-1,-1}, FALSE },
+/* 2 */ { SW_SHOWNORMAL, TRUE, WS_VISIBLE, WmEmptySeq,
+ SW_SHOWNORMAL, 0, {-1,-1}, {-1,-1}, FALSE },
+/* 3 */ { SW_HIDE, TRUE, 0, WmHide_1,
+ SW_SHOWNORMAL, 0, {-1,-1}, {-1,-1}, FALSE },
+/* 4 */ { SW_HIDE, FALSE, 0, WmEmptySeq,
+ SW_SHOWNORMAL, 0, {-1,-1}, {-1,-1}, FALSE },
+/* 5 */ { SW_SHOWMINIMIZED, FALSE, WS_VISIBLE|WS_MINIMIZE, WmShowMinimized_1,
+ SW_SHOWMINIMIZED, 0, {-32000,-32000}, {-1,-1}, FALSE },
+/* 6 */ { SW_SHOWMINIMIZED, TRUE, WS_VISIBLE|WS_MINIMIZE, WmMinMax_1,
+ SW_SHOWMINIMIZED, 0, {-32000,-32000}, {-1,-1}, FALSE },
+/* 7 */ { SW_HIDE, TRUE, WS_MINIMIZE, WmHide_1,
+ SW_SHOWMINIMIZED, 0, {-32000,-32000}, {-1,-1}, FALSE },
+/* 8 */ { SW_HIDE, FALSE, WS_MINIMIZE, WmEmptySeq,
+ SW_SHOWMINIMIZED, 0, {-32000,-32000}, {-1,-1}, FALSE },
+/* 9 */ { SW_SHOWMAXIMIZED, FALSE, WS_VISIBLE|WS_MAXIMIZE, WmShowMaximized_1,
+ SW_SHOWMAXIMIZED, WPF_RESTORETOMAXIMIZED, {-32000,-32000}, {-1,-1}, FALSE },
+/* 10 */ { SW_SHOWMAXIMIZED, TRUE, WS_VISIBLE|WS_MAXIMIZE, WmMinMax_2,
+ SW_SHOWMAXIMIZED, WPF_RESTORETOMAXIMIZED, {-32000,-32000}, {-1,-1}, FALSE },
+/* 11 */ { SW_HIDE, TRUE, WS_MAXIMIZE, WmHide_1,
+ SW_SHOWMAXIMIZED, WPF_RESTORETOMAXIMIZED, {-32000,-32000}, {-1,-1}, FALSE },
+/* 12 */ { SW_HIDE, FALSE, WS_MAXIMIZE, WmEmptySeq,
+ SW_SHOWMAXIMIZED, WPF_RESTORETOMAXIMIZED, {-32000,-32000}, {-1,-1}, FALSE },
+/* 13 */ { SW_SHOWNOACTIVATE, FALSE, WS_VISIBLE, WmShowNoActivate_1,
+ SW_SHOWNORMAL, 0, {-32000,-32000}, {-1,-1}, FALSE },
+/* 14 */ { SW_SHOWNOACTIVATE, TRUE, WS_VISIBLE, WmEmptySeq,
+ SW_SHOWNORMAL, 0, {-32000,-32000}, {-1,-1}, FALSE },
+/* 15 */ { SW_HIDE, TRUE, 0, WmHide_2,
+ SW_SHOWNORMAL, 0, {-32000,-32000}, {-1,-1}, FALSE },
+/* 16 */ { SW_HIDE, FALSE, 0, WmEmptySeq,
+ SW_SHOWNORMAL, 0, {-32000,-32000}, {-1,-1}, FALSE },
+/* 17 */ { SW_SHOW, FALSE, WS_VISIBLE, WmShow,
+ SW_SHOWNORMAL, 0, {-32000,-32000}, {-1,-1}, FALSE },
+/* 18 */ { SW_SHOW, TRUE, WS_VISIBLE, WmEmptySeq,
+ SW_SHOWNORMAL, 0, {-32000,-32000}, {-1,-1}, FALSE },
+/* 19 */ { SW_MINIMIZE, TRUE, WS_VISIBLE|WS_MINIMIZE, WmMinimize_1,
+ SW_SHOWMINIMIZED, 0, {-32000,-32000}, {-1,-1}, FALSE },
+/* 20 */ { SW_MINIMIZE, TRUE, WS_VISIBLE|WS_MINIMIZE, WmMinMax_3,
+ SW_SHOWMINIMIZED, 0, {-32000,-32000}, {-1,-1}, FALSE },
+/* 21 */ { SW_HIDE, TRUE, WS_MINIMIZE, WmHide_2,
+ SW_SHOWMINIMIZED, 0, {-32000,-32000}, {-1,-1}, FALSE },
+/* 22 */ { SW_SHOWMINNOACTIVE, FALSE, WS_VISIBLE|WS_MINIMIZE, WmShowMinNoActivate,
+ SW_SHOWMINIMIZED, 0, {-32000,-32000}, {-1,-1}, TRUE },
+/* 23 */ { SW_SHOWMINNOACTIVE, TRUE, WS_VISIBLE|WS_MINIMIZE, WmMinMax_4,
+ SW_SHOWMINIMIZED, 0, {-32000,-32000}, {-1,-1}, FALSE },
+/* 24 */ { SW_HIDE, TRUE, WS_MINIMIZE, WmHide_2,
+ SW_SHOWMINIMIZED, 0, {-32000,-32000}, {-1,-1}, FALSE },
+/* 25 */ { SW_HIDE, FALSE, WS_MINIMIZE, WmEmptySeq,
+ SW_SHOWMINIMIZED, 0, {-32000,-32000}, {-1,-1}, FALSE },
+/* 26 */ { SW_SHOWNA, FALSE, WS_VISIBLE|WS_MINIMIZE, WmShowNA_1,
+ SW_SHOWMINIMIZED, 0, {-32000,-32000}, {-1,-1}, FALSE },
+/* 27 */ { SW_SHOWNA, TRUE, WS_VISIBLE|WS_MINIMIZE, WmShowNA_2,
+ SW_SHOWMINIMIZED, 0, {-32000,-32000}, {-1,-1}, FALSE },
+/* 28 */ { SW_HIDE, TRUE, WS_MINIMIZE, WmHide_2,
+ SW_SHOWMINIMIZED, 0, {-32000,-32000}, {-1,-1}, FALSE },
+/* 29 */ { SW_HIDE, FALSE, WS_MINIMIZE, WmEmptySeq,
+ SW_SHOWMINIMIZED, 0, {-32000,-32000}, {-1,-1}, FALSE },
+/* 30 */ { SW_RESTORE, FALSE, WS_VISIBLE, WmRestore_1,
+ SW_SHOWNORMAL, 0, {-32000,-32000}, {-1,-1}, FALSE },
+/* 31 */ { SW_RESTORE, TRUE, WS_VISIBLE, WmEmptySeq,
+ SW_SHOWNORMAL, 0, {-32000,-32000}, {-1,-1}, FALSE },
+/* 32 */ { SW_HIDE, TRUE, 0, WmHide_3,
+ SW_SHOWNORMAL, 0, {-32000,-32000}, {-1,-1}, FALSE },
+/* 33 */ { SW_HIDE, FALSE, 0, WmEmptySeq,
+ SW_SHOWNORMAL, 0, {-32000,-32000}, {-1,-1}, FALSE },
+/* 34 */ { SW_NORMALNA, FALSE, 0, WmEmptySeq, /* what does this mean?! */
+ SW_SHOWNORMAL, 0, {-32000,-32000}, {-1,-1}, FALSE },
+/* 35 */ { SW_NORMALNA, FALSE, 0, WmEmptySeq,
+ SW_SHOWNORMAL, 0, {-32000,-32000}, {-1,-1}, FALSE },
+/* 36 */ { SW_HIDE, FALSE, 0, WmEmptySeq,
+ SW_SHOWNORMAL, 0, {-32000,-32000}, {-1,-1}, FALSE },
+/* 37 */ { SW_RESTORE, FALSE, WS_VISIBLE, WmRestore_2,
+ SW_SHOWNORMAL, 0, {-32000,-32000}, {-1,-1}, FALSE },
+/* 38 */ { SW_RESTORE, TRUE, WS_VISIBLE, WmEmptySeq,
+ SW_SHOWNORMAL, 0, {-32000,-32000}, {-1,-1}, FALSE },
+/* 39 */ { SW_SHOWNOACTIVATE, TRUE, WS_VISIBLE, WmEmptySeq,
+ SW_SHOWNORMAL, 0, {-32000,-32000}, {-1,-1}, FALSE },
+/* 40 */ { SW_MINIMIZE, TRUE, WS_VISIBLE|WS_MINIMIZE, WmMinimize_2,
+ SW_SHOWMINIMIZED, 0, {-32000,-32000}, {-1,-1}, FALSE },
+/* 41 */ { SW_MINIMIZE, TRUE, WS_VISIBLE|WS_MINIMIZE, WmMinMax_3,
+ SW_SHOWMINIMIZED, 0, {-32000,-32000}, {-1,-1}, FALSE },
+/* 42 */ { SW_SHOWMAXIMIZED, TRUE, WS_VISIBLE|WS_MAXIMIZE, WmShowMaximized_2,
+ SW_SHOWMAXIMIZED, WPF_RESTORETOMAXIMIZED, {-32000,-32000}, {-1,-1}, FALSE },
+/* 43 */ { SW_SHOWMAXIMIZED, TRUE, WS_VISIBLE|WS_MAXIMIZE, WmMinMax_2,
+ SW_SHOWMAXIMIZED, WPF_RESTORETOMAXIMIZED, {-32000,-32000}, {-1,-1}, FALSE },
+/* 44 */ { SW_MINIMIZE, TRUE, WS_VISIBLE|WS_MINIMIZE, WmMinimize_1,
+ SW_SHOWMINIMIZED, WPF_RESTORETOMAXIMIZED, {-32000,-32000}, {-1,-1}, FALSE },
+/* 45 */ { SW_MINIMIZE, TRUE, WS_VISIBLE|WS_MINIMIZE, WmMinMax_3,
+ SW_SHOWMINIMIZED, WPF_RESTORETOMAXIMIZED, {-32000,-32000}, {-1,-1}, FALSE },
+/* 46 */ { SW_RESTORE, TRUE, WS_VISIBLE|WS_MAXIMIZE, WmRestore_3,
+ SW_SHOWMAXIMIZED, WPF_RESTORETOMAXIMIZED, {-32000,-32000}, {-1,-1}, FALSE },
+/* 47 */ { SW_RESTORE, TRUE, WS_VISIBLE, WmRestore_4,
+ SW_SHOWNORMAL, WPF_RESTORETOMAXIMIZED, {-32000,-32000}, {-1,-1}, FALSE },
+/* 48 */ { SW_SHOWMAXIMIZED, TRUE, WS_VISIBLE|WS_MAXIMIZE, WmShowMaximized_3,
+ SW_SHOWMAXIMIZED, WPF_RESTORETOMAXIMIZED, {-32000,-32000}, {-1,-1}, FALSE },
+/* 49 */ { SW_SHOW, TRUE, WS_VISIBLE|WS_MAXIMIZE, WmEmptySeq,
+ SW_SHOWMAXIMIZED, WPF_RESTORETOMAXIMIZED, {-32000,-32000}, {-1,-1}, FALSE },
+/* 50 */ { SW_SHOWNORMAL, TRUE, WS_VISIBLE, WmRestore_5,
+ SW_SHOWNORMAL, WPF_RESTORETOMAXIMIZED, {-32000,-32000}, {-1,-1}, FALSE },
+/* 51 */ { SW_SHOWNORMAL, TRUE, WS_VISIBLE, WmRestore_5,
+ SW_SHOWNORMAL, WPF_RESTORETOMAXIMIZED, {-32000,-32000}, {-1,-1}, FALSE },
+/* 52 */ { SW_HIDE, TRUE, 0, WmHide_1,
+ SW_SHOWNORMAL, WPF_RESTORETOMAXIMIZED, {-32000,-32000}, {-1,-1}, FALSE },
+/* 53 */ { SW_HIDE, FALSE, 0, WmEmptySeq,
+ SW_SHOWNORMAL, WPF_RESTORETOMAXIMIZED, {-32000,-32000}, {-1,-1}, FALSE },
+/* 54 */ { SW_MINIMIZE, FALSE, WS_VISIBLE|WS_MINIMIZE, WmMinimize_3,
+ SW_SHOWMINIMIZED, 0, {-32000,-32000}, {-1,-1}, FALSE },
+/* 55 */ { SW_HIDE, TRUE, WS_MINIMIZE, WmHide_2,
+ SW_SHOWMINIMIZED, 0, {-32000,-32000}, {-1,-1}, FALSE },
+/* 56 */ { SW_SHOWNOACTIVATE, FALSE, WS_VISIBLE, WmShowNoActivate_2,
+ SW_SHOWNORMAL, 0, {-32000,-32000}, {-1,-1}, FALSE },
+/* 57 */ { SW_SHOW, TRUE, WS_VISIBLE, WmEmptySeq,
+ SW_SHOWNORMAL, 0, {-32000,-32000}, {-1,-1}, FALSE }
};
HWND hwnd;
DWORD style;
LPARAM ret;
INT i;
+ WINDOWPLACEMENT wp;
+ RECT win_rc, work_rc = {0, 0, 0, 0};
#define WS_BASE (WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX|WS_MAXIMIZEBOX|WS_POPUP|WS_CLIPSIBLINGS)
- hwnd = CreateWindowEx(0, "ShowWindowClass", NULL, WS_BASE,
+ hwnd = CreateWindowExA(0, "ShowWindowClass", NULL, WS_BASE,
120, 120, 90, 90,
0, 0, 0, NULL);
assert(hwnd);
- style = GetWindowLong(hwnd, GWL_STYLE) & ~WS_BASE;
+ style = GetWindowLongA(hwnd, GWL_STYLE) & ~WS_BASE;
ok(style == 0, "expected style 0, got %08x\n", style);
flush_events();
flush_sequence();
+ if (pGetMonitorInfoA && pMonitorFromPoint)
+ {
+ HMONITOR hmon;
+ MONITORINFO mi;
+ POINT pt = {0, 0};
+
+ SetLastError(0xdeadbeef);
+ hmon = pMonitorFromPoint(pt, MONITOR_DEFAULTTOPRIMARY);
+ ok(hmon != 0, "MonitorFromPoint error %u\n", GetLastError());
+
+ mi.cbSize = sizeof(mi);
+ SetLastError(0xdeadbeef);
+ ret = pGetMonitorInfoA(hmon, &mi);
+ ok(ret, "GetMonitorInfo error %u\n", GetLastError());
+ trace("monitor (%d,%d-%d,%d), work (%d,%d-%d,%d)\n",
+ mi.rcMonitor.left, mi.rcMonitor.top, mi.rcMonitor.right, mi.rcMonitor.bottom,
+ mi.rcWork.left, mi.rcWork.top, mi.rcWork.right, mi.rcWork.bottom);
+ work_rc = mi.rcWork;
+ }
+
+ GetWindowRect(hwnd, &win_rc);
+ OffsetRect(&win_rc, -work_rc.left, -work_rc.top);
+
+ wp.length = sizeof(wp);
+ SetLastError(0xdeadbeaf);
+ ret = GetWindowPlacement(hwnd, &wp);
+ ok(ret, "GetWindowPlacement error %u\n", GetLastError());
+ ok(wp.flags == 0, "expected 0, got %#x\n", wp.flags);
+ ok(wp.showCmd == SW_SHOWNORMAL, "expected SW_SHOWNORMAL, got %d\n", wp.showCmd);
+ ok(wp.ptMinPosition.x == -1 && wp.ptMinPosition.y == -1,
+ "expected -1,-1 got %d,%d\n", wp.ptMinPosition.x, wp.ptMinPosition.y);
+ ok(wp.ptMaxPosition.x == -1 && wp.ptMaxPosition.y == -1,
+ "expected -1,-1 got %d,%d\n", wp.ptMaxPosition.x, wp.ptMaxPosition.y);
+ if (work_rc.left || work_rc.top) todo_wine /* FIXME: remove once Wine is fixed */
+ ok(EqualRect(&win_rc, &wp.rcNormalPosition),
+ "expected %d,%d-%d,%d got %d,%d-%d,%d\n",
+ win_rc.left, win_rc.top, win_rc.right, win_rc.bottom,
+ wp.rcNormalPosition.left, wp.rcNormalPosition.top,
+ wp.rcNormalPosition.right, wp.rcNormalPosition.bottom);
+ else
+ ok(EqualRect(&win_rc, &wp.rcNormalPosition),
+ "expected %d,%d-%d,%d got %d,%d-%d,%d\n",
+ win_rc.left, win_rc.top, win_rc.right, win_rc.bottom,
+ wp.rcNormalPosition.left, wp.rcNormalPosition.top,
+ wp.rcNormalPosition.right, wp.rcNormalPosition.bottom);
+
for (i = 0; i < sizeof(sw)/sizeof(sw[0]); i++)
{
static const char * const sw_cmd_name[13] =
idx = (sw[i].cmd == SW_NORMALNA) ? 12 : sw[i].cmd;
- style = GetWindowLong(hwnd, GWL_STYLE);
+ style = GetWindowLongA(hwnd, GWL_STYLE);
trace("%d: sending %s, current window style %08x\n", i+1, sw_cmd_name[idx], style);
ret = ShowWindow(hwnd, sw[i].cmd);
ok(!ret == !sw[i].ret, "%d: cmd %s: expected ret %lu, got %lu\n", i+1, sw_cmd_name[idx], sw[i].ret, ret);
- style = GetWindowLong(hwnd, GWL_STYLE) & ~WS_BASE;
+ style = GetWindowLongA(hwnd, GWL_STYLE) & ~WS_BASE;
ok(style == sw[i].style, "%d: expected style %08x, got %08x\n", i+1, sw[i].style, style);
sprintf(comment, "%d: ShowWindow(%s)", i+1, sw_cmd_name[idx]);
ok_sequence(sw[i].msg, comment, sw[i].todo_msg);
- flush_events();
- flush_sequence();
- }
+ wp.length = sizeof(wp);
+ SetLastError(0xdeadbeaf);
+ ret = GetWindowPlacement(hwnd, &wp);
+ ok(ret, "GetWindowPlacement error %u\n", GetLastError());
+ ok(wp.flags == sw[i].wp_flags, "expected %#x, got %#x\n", sw[i].wp_flags, wp.flags);
+ ok(wp.showCmd == sw[i].wp_cmd, "expected %d, got %d\n", sw[i].wp_cmd, wp.showCmd);
+
+ /* NT moves the minimized window to -32000,-32000, win9x to 3000,3000 */
+ if ((wp.ptMinPosition.x + work_rc.left == -32000 && wp.ptMinPosition.y + work_rc.top == -32000) ||
+ (wp.ptMinPosition.x + work_rc.left == 3000 && wp.ptMinPosition.y + work_rc.top == 3000))
+ {
+ ok((wp.ptMinPosition.x + work_rc.left == sw[i].wp_min.x && wp.ptMinPosition.y + work_rc.top == sw[i].wp_min.y) ||
+ (wp.ptMinPosition.x + work_rc.left == 3000 && wp.ptMinPosition.y + work_rc.top == 3000),
+ "expected %d,%d got %d,%d\n", sw[i].wp_min.x, sw[i].wp_min.y, wp.ptMinPosition.x, wp.ptMinPosition.y);
+ }
+ else
+ {
+ ok(wp.ptMinPosition.x == sw[i].wp_min.x && wp.ptMinPosition.y == sw[i].wp_min.y,
+ "expected %d,%d got %d,%d\n", sw[i].wp_min.x, sw[i].wp_min.y, wp.ptMinPosition.x, wp.ptMinPosition.y);
+ }
+ if (wp.ptMaxPosition.x != sw[i].wp_max.x || wp.ptMaxPosition.y != sw[i].wp_max.y)
+ todo_wine
+ ok(wp.ptMaxPosition.x == sw[i].wp_max.x && wp.ptMaxPosition.y == sw[i].wp_max.y,
+ "expected %d,%d got %d,%d\n", sw[i].wp_max.x, sw[i].wp_max.y, wp.ptMaxPosition.x, wp.ptMaxPosition.y);
+ else
+ ok(wp.ptMaxPosition.x == sw[i].wp_max.x && wp.ptMaxPosition.y == sw[i].wp_max.y,
+ "expected %d,%d got %d,%d\n", sw[i].wp_max.x, sw[i].wp_max.y, wp.ptMaxPosition.x, wp.ptMaxPosition.y);
+
+if (0) /* FIXME: Wine behaves completely different here */
+ ok(EqualRect(&win_rc, &wp.rcNormalPosition),
+ "expected %d,%d-%d,%d got %d,%d-%d,%d\n",
+ win_rc.left, win_rc.top, win_rc.right, win_rc.bottom,
+ wp.rcNormalPosition.left, wp.rcNormalPosition.top,
+ wp.rcNormalPosition.right, wp.rcNormalPosition.bottom);
+ }
DestroyWindow(hwnd);
+ flush_events();
}
static INT_PTR WINAPI test_dlg_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
static void test_dialog_messages(void)
{
- WNDCLASS cls;
+ WNDCLASSA cls;
HWND hdlg, hedit1, hedit2, hfocus;
LRESULT ret;
#define set_selection(hctl, start, end) \
- ret = SendMessage(hctl, EM_SETSEL, start, end); \
+ ret = SendMessageA(hctl, EM_SETSEL, start, end); \
ok(ret == 1, "EM_SETSEL returned %ld\n", ret);
#define check_selection(hctl, start, end) \
- ret = SendMessage(hctl, EM_GETSEL, 0, 0); \
+ ret = SendMessageA(hctl, EM_GETSEL, 0, 0); \
ok(ret == MAKELRESULT(start, end), "wrong selection (%d - %d)\n", LOWORD(ret), HIWORD(ret));
subclass_edit();
- hdlg = CreateWindowEx(WS_EX_DLGMODALFRAME, "TestDialogClass", NULL,
+ hdlg = CreateWindowExA(WS_EX_DLGMODALFRAME, "TestDialogClass", NULL,
WS_VISIBLE|WS_CAPTION|WS_SYSMENU|WS_DLGFRAME,
0, 0, 100, 100, 0, 0, 0, NULL);
ok(hdlg != 0, "Failed to create custom dialog window\n");
- hedit1 = CreateWindowEx(0, "my_edit_class", NULL,
+ hedit1 = CreateWindowExA(0, "my_edit_class", NULL,
WS_CHILD|WS_BORDER|WS_VISIBLE|WS_TABSTOP,
0, 0, 80, 20, hdlg, (HMENU)1, 0, NULL);
ok(hedit1 != 0, "Failed to create edit control\n");
- hedit2 = CreateWindowEx(0, "my_edit_class", NULL,
+ hedit2 = CreateWindowExA(0, "my_edit_class", NULL,
WS_CHILD|WS_BORDER|WS_VISIBLE|WS_TABSTOP,
0, 40, 80, 20, hdlg, (HMENU)2, 0, NULL);
ok(hedit2 != 0, "Failed to create edit control\n");
- SendMessage(hedit1, WM_SETTEXT, 0, (LPARAM)"hello");
- SendMessage(hedit2, WM_SETTEXT, 0, (LPARAM)"bye");
+ SendMessageA(hedit1, WM_SETTEXT, 0, (LPARAM)"hello");
+ SendMessageA(hedit2, WM_SETTEXT, 0, (LPARAM)"bye");
hfocus = GetFocus();
ok(hfocus == hdlg, "wrong focus %p\n", hfocus);
ok(hfocus == 0, "wrong focus %p\n", hfocus);
flush_sequence();
- ret = DefDlgProc(hdlg, WM_SETFOCUS, 0, 0);
+ ret = DefDlgProcA(hdlg, WM_SETFOCUS, 0, 0);
ok(ret == 0, "WM_SETFOCUS returned %ld\n", ret);
ok_sequence(WmDefDlgSetFocus_1, "DefDlgProc(WM_SETFOCUS) 1", FALSE);
check_selection(hedit2, 0, 3);
flush_sequence();
- ret = DefDlgProc(hdlg, WM_SETFOCUS, 0, 0);
+ ret = DefDlgProcA(hdlg, WM_SETFOCUS, 0, 0);
ok(ret == 0, "WM_SETFOCUS returned %ld\n", ret);
ok_sequence(WmDefDlgSetFocus_2, "DefDlgProc(WM_SETFOCUS) 2", FALSE);
#undef set_selection
#undef check_selection
- ok(GetClassInfo(0, "#32770", &cls), "GetClassInfo failed\n");
+ ok(GetClassInfoA(0, "#32770", &cls), "GetClassInfo failed\n");
cls.lpszClassName = "MyDialogClass";
- cls.hInstance = GetModuleHandle(0);
+ cls.hInstance = GetModuleHandleA(NULL);
/* need a cast since a dlgproc is used as a wndproc */
- cls.lpfnWndProc = (WNDPROC)test_dlg_proc;
- if (!RegisterClass(&cls)) assert(0);
+ cls.lpfnWndProc = test_dlg_proc;
+ if (!RegisterClassA(&cls)) assert(0);
- hdlg = CreateDialogParam(0, "CLASS_TEST_DIALOG_2", 0, test_dlg_proc, 0);
+ hdlg = CreateDialogParamA(0, "CLASS_TEST_DIALOG_2", 0, test_dlg_proc, 0);
ok(IsWindow(hdlg), "CreateDialogParam failed\n");
ok_sequence(WmCreateDialogParamSeq_1, "CreateDialogParam_1", FALSE);
EndDialog(hdlg, 0);
DestroyWindow(hdlg);
flush_sequence();
- hdlg = CreateDialogParam(0, "CLASS_TEST_DIALOG_2", 0, NULL, 0);
+ hdlg = CreateDialogParamA(0, "CLASS_TEST_DIALOG_2", 0, NULL, 0);
ok(IsWindow(hdlg), "CreateDialogParam failed\n");
ok_sequence(WmCreateDialogParamSeq_2, "CreateDialogParam_2", FALSE);
EndDialog(hdlg, 0);
DestroyWindow(hdlg);
flush_sequence();
- UnregisterClass(cls.lpszClassName, cls.hInstance);
+ UnregisterClassA(cls.lpszClassName, cls.hInstance);
+}
+
+static void test_EndDialog(void)
+{
+ HWND hparent, hother, hactive, hdlg;
+ WNDCLASSA cls;
+
+ hparent = CreateWindowExA(0, "TestParentClass", "Test parent",
+ WS_OVERLAPPEDWINDOW | WS_VISIBLE | WS_DISABLED,
+ 100, 100, 200, 200, 0, 0, 0, NULL);
+ ok (hparent != 0, "Failed to create parent window\n");
+
+ hother = CreateWindowExA(0, "TestParentClass", "Test parent 2",
+ WS_OVERLAPPEDWINDOW | WS_VISIBLE,
+ 100, 100, 200, 200, 0, 0, 0, NULL);
+ ok (hother != 0, "Failed to create parent window\n");
+
+ ok(GetClassInfoA(0, "#32770", &cls), "GetClassInfo failed\n");
+ cls.lpszClassName = "MyDialogClass";
+ cls.hInstance = GetModuleHandleA(NULL);
+ cls.lpfnWndProc = test_dlg_proc;
+ if (!RegisterClassA(&cls)) assert(0);
+
+ flush_sequence();
+ SetForegroundWindow(hother);
+ hactive = GetForegroundWindow();
+ ok(hother == hactive, "Wrong window has focus (%p != %p)\n", hother, hactive);
+
+ /* create a dialog where the parent is disabled, this parent should still
+ receive the focus when the dialog exits (even though "normally" a
+ disabled window should not receive the focus) */
+ hdlg = CreateDialogParamA(0, "CLASS_TEST_DIALOG_2", hparent, test_dlg_proc, 0);
+ ok(IsWindow(hdlg), "CreateDialogParam failed\n");
+ SetForegroundWindow(hdlg);
+ hactive = GetForegroundWindow();
+ ok(hdlg == hactive, "Wrong window has focus (%p != %p)\n", hdlg, hactive);
+ EndDialog(hdlg, 0);
+ hactive = GetForegroundWindow();
+ ok(hparent == hactive, "Wrong window has focus (parent != active) (active: %p, parent: %p, dlg: %p, other: %p)\n", hactive, hparent, hdlg, hother);
+ DestroyWindow(hdlg);
+ flush_sequence();
+
+ DestroyWindow( hother );
+ DestroyWindow( hparent );
+ UnregisterClassA(cls.lpszClassName, cls.hInstance);
}
static void test_nullCallback(void)
CPINFOEXA cpinfo;
UINT i, j, k;
struct message wmCharSeq[2];
+ BOOL ret;
if (!pGetCPInfoExA)
{
/* posted message */
PostMessageA( hwnd, WM_CHAR, dbch[0], 0 );
- ok( !PeekMessageW( &msg, hwnd, 0, 0, PM_REMOVE ), "got message %x\n", msg.message );
+ ret = PeekMessageW( &msg, hwnd, 0, 0, PM_REMOVE );
+ ok( !ret, "got message %x\n", msg.message );
PostMessageA( hwnd, WM_CHAR, dbch[1], 0 );
- ok( PeekMessageW( &msg, hwnd, 0, 0, PM_REMOVE ), "no message\n" );
+ ret = PeekMessageW( &msg, hwnd, 0, 0, PM_REMOVE );
+ ok( ret, "no message\n" );
ok( msg.message == WM_CHAR, "unexpected message %x\n", msg.message );
ok( msg.wParam == wch, "bad wparam %lx/%x\n", msg.wParam, wch );
- ok( !PeekMessageW( &msg, hwnd, 0, 0, PM_REMOVE ), "got message %x\n", msg.message );
+ ret = PeekMessageW( &msg, hwnd, 0, 0, PM_REMOVE );
+ ok( !ret, "got message %x\n", msg.message );
/* posted thread message */
PostThreadMessageA( GetCurrentThreadId(), WM_CHAR, dbch[0], 0 );
- ok( !PeekMessageW( &msg, hwnd, 0, 0, PM_REMOVE ), "got message %x\n", msg.message );
+ ret = PeekMessageW( &msg, hwnd, 0, 0, PM_REMOVE );
+ ok( !ret, "got message %x\n", msg.message );
PostMessageA( hwnd, WM_CHAR, dbch[1], 0 );
- ok( PeekMessageW( &msg, hwnd, 0, 0, PM_REMOVE ), "no message\n" );
+ ret = PeekMessageW( &msg, hwnd, 0, 0, PM_REMOVE );
+ ok( ret, "no message\n" );
ok( msg.message == WM_CHAR, "unexpected message %x\n", msg.message );
ok( msg.wParam == wch, "bad wparam %lx/%x\n", msg.wParam, wch );
- ok( !PeekMessageW( &msg, hwnd, 0, 0, PM_REMOVE ), "got message %x\n", msg.message );
+ ret = PeekMessageW( &msg, hwnd, 0, 0, PM_REMOVE );
+ ok( !ret, "got message %x\n", msg.message );
/* sent message */
flush_sequence();
ok_sequence( WmEmptySeq, "no messages", FALSE );
SendMessageA( hwnd, WM_CHAR, dbch[1], 0 );
ok_sequence( wmCharSeq, "Unicode WM_CHAR", FALSE );
- ok( !PeekMessageW( &msg, hwnd, 0, 0, PM_REMOVE ), "got message %x\n", msg.message );
+ ret = PeekMessageW( &msg, hwnd, 0, 0, PM_REMOVE );
+ ok( !ret, "got message %x\n", msg.message );
/* sent message with timeout */
flush_sequence();
ok_sequence( WmEmptySeq, "no messages", FALSE );
SendMessageTimeoutA( hwnd, WM_CHAR, dbch[1], 0, SMTO_NORMAL, 0, &res );
ok_sequence( wmCharSeq, "Unicode WM_CHAR", FALSE );
- ok( !PeekMessageW( &msg, hwnd, 0, 0, PM_REMOVE ), "got message %x\n", msg.message );
+ ret = PeekMessageW( &msg, hwnd, 0, 0, PM_REMOVE );
+ ok( !ret, "got message %x\n", msg.message );
/* sent message with timeout and callback */
flush_sequence();
ok_sequence( WmEmptySeq, "no messages", FALSE );
SendMessageCallbackA( hwnd, WM_CHAR, dbch[1], 0, NULL, 0 );
ok_sequence( wmCharSeq, "Unicode WM_CHAR", FALSE );
- ok( !PeekMessageW( &msg, hwnd, 0, 0, PM_REMOVE ), "got message %x\n", msg.message );
+ ret = PeekMessageW( &msg, hwnd, 0, 0, PM_REMOVE );
+ ok( !ret, "got message %x\n", msg.message );
/* sent message with callback */
flush_sequence();
ok_sequence( WmEmptySeq, "no messages", FALSE );
SendMessageCallbackA( hwnd, WM_CHAR, dbch[1], 0, NULL, 0 );
ok_sequence( wmCharSeq, "Unicode WM_CHAR", FALSE );
- ok( !PeekMessageW( &msg, hwnd, 0, 0, PM_REMOVE ), "got message %x\n", msg.message );
+ ret = PeekMessageW( &msg, hwnd, 0, 0, PM_REMOVE );
+ ok( !ret, "got message %x\n", msg.message );
/* direct window proc call */
flush_sequence();
ok_sequence( WmEmptySeq, "no messages", FALSE );
SendMessageA( hwnd, WM_CHAR, dbch[1], 0 );
ok_sequence( wmCharSeq, "Unicode WM_CHAR", FALSE );
- ok( !PeekMessageW( &msg, hwnd, 0, 0, PM_REMOVE ), "got message %x\n", msg.message );
+ ret = PeekMessageW( &msg, hwnd, 0, 0, PM_REMOVE );
+ ok( !ret, "got message %x\n", msg.message );
/* interleaved post and send */
flush_sequence();
PostMessageA( hwnd2, WM_CHAR, dbch[0], 0 );
SendMessageA( hwnd2, WM_CHAR, dbch[0], 0 );
ok_sequence( WmEmptySeq, "no messages", FALSE );
- ok( !PeekMessageW( &msg, hwnd, 0, 0, PM_REMOVE ), "got message %x\n", msg.message );
+ ret = PeekMessageW( &msg, hwnd, 0, 0, PM_REMOVE );
+ ok( !ret, "got message %x\n", msg.message );
PostMessageA( hwnd, WM_CHAR, dbch[1], 0 );
ok_sequence( WmEmptySeq, "no messages", FALSE );
- ok( PeekMessageW( &msg, hwnd, 0, 0, PM_REMOVE ), "no message\n" );
+ ret = PeekMessageW( &msg, hwnd, 0, 0, PM_REMOVE );
+ ok( ret, "no message\n" );
ok( msg.message == WM_CHAR, "unexpected message %x\n", msg.message );
ok( msg.wParam == wch, "bad wparam %lx/%x\n", msg.wParam, wch );
- ok( !PeekMessageW( &msg, hwnd, 0, 0, PM_REMOVE ), "got message %x\n", msg.message );
+ ret = PeekMessageW( &msg, hwnd, 0, 0, PM_REMOVE );
+ ok( !ret, "got message %x\n", msg.message );
SendMessageA( hwnd, WM_CHAR, dbch[1], 0 );
ok_sequence( wmCharSeq, "Unicode WM_CHAR", FALSE );
- ok( !PeekMessageW( &msg, hwnd, 0, 0, PM_REMOVE ), "got message %x\n", msg.message );
+ ret = PeekMessageW( &msg, hwnd, 0, 0, PM_REMOVE );
+ ok( !ret, "got message %x\n", msg.message );
/* interleaved sent message and winproc */
flush_sequence();
flush_sequence();
SendMessageA( hwnd2, WM_CHAR, (dbch[1] << 8) | dbch[0], 0 );
ok_sequence( wmCharSeq, "Unicode WM_CHAR", FALSE );
- ok( !PeekMessageW( &msg, hwnd, 0, 0, PM_REMOVE ), "got message %x\n", msg.message );
+ ret = PeekMessageW( &msg, hwnd, 0, 0, PM_REMOVE );
+ ok( !ret, "got message %x\n", msg.message );
/* other char messages are not magic */
PostMessageA( hwnd, WM_SYSCHAR, dbch[0], 0 );
- ok( PeekMessageW( &msg, hwnd, 0, 0, PM_REMOVE ), "no message\n" );
+ ret = PeekMessageW( &msg, hwnd, 0, 0, PM_REMOVE );
+ ok( ret, "no message\n" );
ok( msg.message == WM_SYSCHAR, "unexpected message %x\n", msg.message );
ok( msg.wParam == bad_wch, "bad wparam %lx/%x\n", msg.wParam, bad_wch );
- ok( !PeekMessageW( &msg, hwnd, 0, 0, PM_REMOVE ), "got message %x\n", msg.message );
+ ret = PeekMessageW( &msg, hwnd, 0, 0, PM_REMOVE );
+ ok( !ret, "got message %x\n", msg.message );
PostMessageA( hwnd, WM_DEADCHAR, dbch[0], 0 );
- ok( PeekMessageW( &msg, hwnd, 0, 0, PM_REMOVE ), "no message\n" );
+ ret = PeekMessageW( &msg, hwnd, 0, 0, PM_REMOVE );
+ ok( ret, "no message\n" );
ok( msg.message == WM_DEADCHAR, "unexpected message %x\n", msg.message );
ok( msg.wParam == bad_wch, "bad wparam %lx/%x\n", msg.wParam, bad_wch );
- ok( !PeekMessageW( &msg, hwnd, 0, 0, PM_REMOVE ), "got message %x\n", msg.message );
+ ret = PeekMessageW( &msg, hwnd, 0, 0, PM_REMOVE );
+ ok( !ret, "got message %x\n", msg.message );
/* test retrieving messages */
PostMessageW( hwnd, WM_CHAR, wch, 0 );
- ok( PeekMessageA( &msg, hwnd, 0, 0, PM_REMOVE ), "no message\n" );
+ ret = PeekMessageA( &msg, hwnd, 0, 0, PM_REMOVE );
+ ok( ret, "no message\n" );
ok( msg.hwnd == hwnd, "unexpected hwnd %p\n", msg.hwnd );
ok( msg.message == WM_CHAR, "unexpected message %x\n", msg.message );
ok( msg.wParam == dbch[0], "bad wparam %lx/%x\n", msg.wParam, dbch[0] );
- ok( PeekMessageA( &msg, hwnd, 0, 0, PM_REMOVE ), "no message\n" );
+ ret = PeekMessageA( &msg, hwnd, 0, 0, PM_REMOVE );
+ ok( ret, "no message\n" );
ok( msg.hwnd == hwnd, "unexpected hwnd %p\n", msg.hwnd );
ok( msg.message == WM_CHAR, "unexpected message %x\n", msg.message );
ok( msg.wParam == dbch[1], "bad wparam %lx/%x\n", msg.wParam, dbch[0] );
- ok( !PeekMessageA( &msg, hwnd, 0, 0, PM_REMOVE ), "got message %x\n", msg.message );
+ ret = PeekMessageA( &msg, hwnd, 0, 0, PM_REMOVE );
+ ok( !ret, "got message %x\n", msg.message );
/* message filters */
PostMessageW( hwnd, WM_CHAR, wch, 0 );
- ok( PeekMessageA( &msg, hwnd, 0, 0, PM_REMOVE ), "no message\n" );
+ ret = PeekMessageA( &msg, hwnd, 0, 0, PM_REMOVE );
+ ok( ret, "no message\n" );
ok( msg.hwnd == hwnd, "unexpected hwnd %p\n", msg.hwnd );
ok( msg.message == WM_CHAR, "unexpected message %x\n", msg.message );
ok( msg.wParam == dbch[0], "bad wparam %lx/%x\n", msg.wParam, dbch[0] );
/* message id is filtered, hwnd is not */
- ok( !PeekMessageA( &msg, hwnd, WM_MOUSEFIRST, WM_MOUSELAST, PM_REMOVE ), "no message\n" );
- ok( PeekMessageA( &msg, hwnd2, 0, 0, PM_REMOVE ), "no message\n" );
+ ret = PeekMessageA( &msg, hwnd, WM_MOUSEFIRST, WM_MOUSELAST, PM_REMOVE );
+ ok( !ret, "no message\n" );
+ ret = PeekMessageA( &msg, hwnd2, 0, 0, PM_REMOVE );
+ ok( ret, "no message\n" );
ok( msg.hwnd == hwnd, "unexpected hwnd %p\n", msg.hwnd );
ok( msg.message == WM_CHAR, "unexpected message %x\n", msg.message );
ok( msg.wParam == dbch[1], "bad wparam %lx/%x\n", msg.wParam, dbch[0] );
- ok( !PeekMessageA( &msg, hwnd, 0, 0, PM_REMOVE ), "got message %x\n", msg.message );
+ ret = PeekMessageA( &msg, hwnd, 0, 0, PM_REMOVE );
+ ok( !ret, "got message %x\n", msg.message );
/* mixing GetMessage and PostMessage */
PostMessageW( hwnd, WM_CHAR, wch, 0xbeef );
time = msg.time;
pt = msg.pt;
ok( time - GetTickCount() <= 100, "bad time %x\n", msg.time );
- ok( PeekMessageA( &msg, 0, 0, 0, PM_REMOVE ), "no message\n" );
+ ret = PeekMessageA( &msg, 0, 0, 0, PM_REMOVE );
+ ok( ret, "no message\n" );
ok( msg.hwnd == hwnd, "unexpected hwnd %p\n", msg.hwnd );
ok( msg.message == WM_CHAR, "unexpected message %x\n", msg.message );
ok( msg.wParam == dbch[1], "bad wparam %lx/%x\n", msg.wParam, dbch[0] );
ok( msg.lParam == 0xbeef, "bad lparam %lx\n", msg.lParam );
ok( msg.time == time, "bad time %x/%x\n", msg.time, time );
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 );
- ok( !PeekMessageA( &msg, hwnd, 0, 0, PM_REMOVE ), "got message %x\n", msg.message );
+ ret = PeekMessageA( &msg, hwnd, 0, 0, PM_REMOVE );
+ ok( !ret, "got message %x\n", msg.message );
/* without PM_REMOVE */
PostMessageW( hwnd, WM_CHAR, wch, 0 );
- ok( PeekMessageA( &msg, 0, 0, 0, PM_NOREMOVE ), "no message\n" );
+ ret = PeekMessageA( &msg, 0, 0, 0, PM_NOREMOVE );
+ ok( ret, "no message\n" );
ok( msg.hwnd == hwnd, "unexpected hwnd %p\n", msg.hwnd );
ok( msg.message == WM_CHAR, "unexpected message %x\n", msg.message );
ok( msg.wParam == dbch[0], "bad wparam %lx/%x\n", msg.wParam, dbch[0] );
- ok( PeekMessageA( &msg, 0, 0, 0, PM_REMOVE ), "no message\n" );
+ ret = PeekMessageA( &msg, 0, 0, 0, PM_REMOVE );
+ ok( ret, "no message\n" );
ok( msg.hwnd == hwnd, "unexpected hwnd %p\n", msg.hwnd );
ok( msg.message == WM_CHAR, "unexpected message %x\n", msg.message );
ok( msg.wParam == dbch[0], "bad wparam %lx/%x\n", msg.wParam, dbch[0] );
- ok( PeekMessageA( &msg, 0, 0, 0, PM_NOREMOVE ), "no message\n" );
+ ret = PeekMessageA( &msg, 0, 0, 0, PM_NOREMOVE );
+ ok( ret, "no message\n" );
ok( msg.hwnd == hwnd, "unexpected hwnd %p\n", msg.hwnd );
ok( msg.message == WM_CHAR, "unexpected message %x\n", msg.message );
ok( msg.wParam == dbch[1], "bad wparam %lx/%x\n", msg.wParam, dbch[0] );
- ok( PeekMessageA( &msg, 0, 0, 0, PM_REMOVE ), "no message\n" );
+ ret = PeekMessageA( &msg, 0, 0, 0, PM_REMOVE );
+ ok( ret, "no message\n" );
ok( msg.hwnd == hwnd, "unexpected hwnd %p\n", msg.hwnd );
ok( msg.message == WM_CHAR, "unexpected message %x\n", msg.message );
ok( msg.wParam == dbch[1], "bad wparam %lx/%x\n", msg.wParam, dbch[0] );
- ok( !PeekMessageA( &msg, hwnd, 0, 0, PM_REMOVE ), "got message %x\n", msg.message );
+ ret = PeekMessageA( &msg, hwnd, 0, 0, PM_REMOVE );
+ ok( !ret, "got message %x\n", msg.message );
DestroyWindow(hwnd);
+ DestroyWindow(hwnd2);
+}
+
+static void test_unicode_wm_char(void)
+{
+ HWND hwnd;
+ MSG msg;
+ struct message seq[2];
+ HKL hkl_orig, hkl_greek;
+ DWORD cp;
+ LCID thread_locale;
+
+ hkl_orig = GetKeyboardLayout( 0 );
+ GetLocaleInfoW( LOWORD( hkl_orig ), LOCALE_IDEFAULTANSICODEPAGE | LOCALE_RETURN_NUMBER, (WCHAR*)&cp, sizeof(cp) / sizeof(WCHAR) );
+ if (cp != 1252)
+ {
+ skip( "Default codepage %d\n", cp );
+ return;
+ }
+
+ hkl_greek = LoadKeyboardLayoutA( "00000408", 0 );
+ if (!hkl_greek || hkl_greek == hkl_orig /* win2k */)
+ {
+ skip( "Unable to load Greek keyboard layout\n" );
+ return;
+ }
+
+ hwnd = CreateWindowExW( 0, testWindowClassW, NULL, WS_OVERLAPPEDWINDOW,
+ 100, 100, 200, 200, 0, 0, 0, NULL );
+ flush_sequence();
+
+ PostMessageW( hwnd, WM_CHAR, 0x3b1, 0 );
+
+ while (GetMessageW( &msg, hwnd, 0, 0 ))
+ {
+ if (!ignore_message( msg.message )) break;
+ }
+
+ ok( msg.hwnd == hwnd, "unexpected hwnd %p\n", msg.hwnd );
+ ok( msg.message == WM_CHAR, "unexpected message %x\n", msg.message );
+ ok( msg.wParam == 0x3b1, "bad wparam %lx\n", msg.wParam );
+ ok( msg.lParam == 0, "bad lparam %lx\n", msg.lParam );
+
+ DispatchMessageW( &msg );
+
+ memset( seq, 0, sizeof(seq) );
+ seq[0].message = WM_CHAR;
+ seq[0].flags = sent|wparam;
+ seq[0].wParam = 0x3b1;
+
+ ok_sequence( seq, "unicode WM_CHAR", FALSE );
+
+ flush_sequence();
+
+ /* greek alpha -> 'a' in cp1252 */
+ PostMessageW( hwnd, WM_CHAR, 0x3b1, 0 );
+
+ ok( GetMessageA( &msg, hwnd, 0, 0 ), "no message\n" );
+ ok( msg.hwnd == hwnd, "unexpected hwnd %p\n", msg.hwnd );
+ ok( msg.message == WM_CHAR, "unexpected message %x\n", msg.message );
+ ok( msg.wParam == 0x61, "bad wparam %lx\n", msg.wParam );
+ ok( msg.lParam == 0, "bad lparam %lx\n", msg.lParam );
+
+ DispatchMessageA( &msg );
+
+ seq[0].wParam = 0x61;
+ ok_sequence( seq, "unicode WM_CHAR", FALSE );
+
+ thread_locale = GetThreadLocale();
+ ActivateKeyboardLayout( hkl_greek, 0 );
+ ok( GetThreadLocale() == thread_locale, "locale changed from %08x to %08x\n",
+ thread_locale, GetThreadLocale() );
+
+ flush_sequence();
+
+ /* greek alpha -> 0xe1 in cp1253 */
+ PostMessageW( hwnd, WM_CHAR, 0x3b1, 0 );
+
+ ok( GetMessageA( &msg, hwnd, 0, 0 ), "no message\n" );
+ ok( msg.hwnd == hwnd, "unexpected hwnd %p\n", msg.hwnd );
+ ok( msg.message == WM_CHAR, "unexpected message %x\n", msg.message );
+ ok( msg.wParam == 0xe1, "bad wparam %lx\n", msg.wParam );
+ ok( msg.lParam == 0, "bad lparam %lx\n", msg.lParam );
+
+ DispatchMessageA( &msg );
+
+ seq[0].wParam = 0x3b1;
+ ok_sequence( seq, "unicode WM_CHAR", FALSE );
+
+ DestroyWindow( hwnd );
+ ActivateKeyboardLayout( hkl_orig, 0 );
+ UnloadKeyboardLayout( hkl_greek );
}
#define ID_LISTBOX 0x000f
check_lb_state(listbox, 0, LB_ERR, 0, 0);
- ret = SendMessage(listbox, LB_ADDSTRING, 0, (LPARAM)"item 0");
+ ret = SendMessageA(listbox, LB_ADDSTRING, 0, (LPARAM)"item 0");
ok(ret == 0, "expected 0, got %ld\n", ret);
- ret = SendMessage(listbox, LB_ADDSTRING, 0, (LPARAM)"item 1");
+ ret = SendMessageA(listbox, LB_ADDSTRING, 0, (LPARAM)"item 1");
ok(ret == 1, "expected 1, got %ld\n", ret);
- ret = SendMessage(listbox, LB_ADDSTRING, 0, (LPARAM)"item 2");
+ ret = SendMessageA(listbox, LB_ADDSTRING, 0, (LPARAM)"item 2");
ok(ret == 2, "expected 2, got %ld\n", ret);
check_lb_state(listbox, 3, LB_ERR, 0, 0);
log_all_parent_messages++;
trace("selecting item 0\n");
- ret = SendMessage(listbox, LB_SETCURSEL, 0, 0);
+ ret = SendMessageA(listbox, LB_SETCURSEL, 0, 0);
ok(ret == 0, "expected 0, got %ld\n", ret);
ok_sequence(wm_lb_setcursel_0, "LB_SETCURSEL 0", FALSE );
check_lb_state(listbox, 3, 0, 0, 0);
flush_sequence();
trace("selecting item 1\n");
- ret = SendMessage(listbox, LB_SETCURSEL, 1, 0);
+ ret = SendMessageA(listbox, LB_SETCURSEL, 1, 0);
ok(ret == 1, "expected 1, got %ld\n", ret);
ok_sequence(wm_lb_setcursel_1, "LB_SETCURSEL 1", FALSE );
check_lb_state(listbox, 3, 1, 1, 0);
trace("selecting item 2\n");
- ret = SendMessage(listbox, LB_SETCURSEL, 2, 0);
+ ret = SendMessageA(listbox, LB_SETCURSEL, 2, 0);
ok(ret == 2, "expected 2, got %ld\n", ret);
ok_sequence(wm_lb_setcursel_2, "LB_SETCURSEL 2", FALSE );
check_lb_state(listbox, 3, 2, 2, 0);
trace("clicking on item 0\n");
- ret = SendMessage(listbox, WM_LBUTTONDOWN, 0, MAKELPARAM(1, 1));
+ ret = SendMessageA(listbox, WM_LBUTTONDOWN, 0, MAKELPARAM(1, 1));
ok(ret == LB_OKAY, "expected LB_OKAY, got %ld\n", ret);
- ret = SendMessage(listbox, WM_LBUTTONUP, 0, 0);
+ ret = SendMessageA(listbox, WM_LBUTTONUP, 0, 0);
ok(ret == LB_OKAY, "expected LB_OKAY, got %ld\n", ret);
ok_sequence(wm_lb_click_0, "WM_LBUTTONDOWN 0", FALSE );
check_lb_state(listbox, 3, 0, 0, 0);
flush_sequence();
trace("deleting item 0\n");
- ret = SendMessage(listbox, LB_DELETESTRING, 0, 0);
+ ret = SendMessageA(listbox, LB_DELETESTRING, 0, 0);
ok(ret == 2, "expected 2, got %ld\n", ret);
ok_sequence(wm_lb_deletestring, "LB_DELETESTRING 0", FALSE );
check_lb_state(listbox, 2, -1, 0, 0);
flush_sequence();
trace("deleting item 0\n");
- ret = SendMessage(listbox, LB_DELETESTRING, 0, 0);
+ ret = SendMessageA(listbox, LB_DELETESTRING, 0, 0);
ok(ret == 1, "expected 1, got %ld\n", ret);
ok_sequence(wm_lb_deletestring, "LB_DELETESTRING 0", FALSE );
check_lb_state(listbox, 1, -1, 0, 0);
flush_sequence();
trace("deleting item 0\n");
- ret = SendMessage(listbox, LB_DELETESTRING, 0, 0);
+ ret = SendMessageA(listbox, LB_DELETESTRING, 0, 0);
ok(ret == 0, "expected 0, got %ld\n", ret);
ok_sequence(wm_lb_deletestring_reset, "LB_DELETESTRING 0", FALSE );
check_lb_state(listbox, 0, -1, 0, 0);
flush_sequence();
trace("deleting item 0\n");
- ret = SendMessage(listbox, LB_DELETESTRING, 0, 0);
+ ret = SendMessageA(listbox, LB_DELETESTRING, 0, 0);
ok(ret == LB_ERR, "expected LB_ERR, got %ld\n", ret);
check_lb_state(listbox, 0, -1, 0, 0);
flush_sequence();
{ 0 }
};
+static const struct message wm_single_menu_item[] =
+{
+ { HCBT_KEYSKIPPED, hook|wparam|lparam|optional, VK_MENU, 0x20000001 },
+ { WM_SYSKEYDOWN, sent|wparam|lparam, VK_MENU, 0x20000001 },
+ { HCBT_KEYSKIPPED, hook|wparam|lparam|optional, 'Q', 0x20000001 },
+ { WM_SYSKEYDOWN, sent|wparam|lparam, 'Q', 0x20000001 },
+ { WM_SYSCHAR, sent|wparam|lparam, 'q', 0x20000001 },
+ { HCBT_SYSCOMMAND, hook|wparam|lparam, SC_KEYMENU, 'q' },
+ { WM_ENTERMENULOOP, sent|wparam|lparam, 0, 0 },
+ { WM_INITMENU, sent|lparam, 0, 0 },
+ { WM_MENUSELECT, sent|wparam|optional, MAKEWPARAM(300,MF_HILITE) },
+ { WM_MENUSELECT, sent|wparam|lparam, MAKEWPARAM(0,0xffff), 0 },
+ { WM_EXITMENULOOP, sent|wparam|lparam, 0, 0 },
+ { WM_MENUCOMMAND, sent },
+ { HCBT_KEYSKIPPED, hook|wparam|lparam|optional, 'Q', 0xe0000001 },
+ { WM_SYSKEYUP, sent|wparam|lparam, 'Q', 0xe0000001 },
+ { HCBT_KEYSKIPPED, hook|wparam|lparam|optional, VK_MENU, 0xc0000001 },
+ { WM_KEYUP, sent|wparam|lparam, VK_MENU, 0xc0000001 },
+
+ { HCBT_KEYSKIPPED, hook|wparam|lparam|optional, VK_ESCAPE, 1 },
+ { WM_KEYDOWN, sent|wparam|lparam, VK_ESCAPE, 1 },
+ { WM_CHAR, sent|wparam|lparam, VK_ESCAPE, 0x00000001 },
+ { HCBT_KEYSKIPPED, hook|wparam|lparam|optional, VK_ESCAPE, 0xc0000001 },
+ { WM_KEYUP, sent|wparam|lparam, VK_ESCAPE, 0xc0000001 },
+ { 0 }
+};
+
static LRESULT WINAPI parent_menu_proc(HWND hwnd, UINT message, WPARAM wp, LPARAM lp)
{
if (message == WM_ENTERIDLE ||
cls.cbWndExtra = 0;
cls.hInstance = GetModuleHandleA(0);
cls.hIcon = 0;
- cls.hCursor = LoadCursorA(0, IDC_ARROW);
+ cls.hCursor = LoadCursorA(0, (LPCSTR)IDC_ARROW);
cls.hbrBackground = GetStockObject(WHITE_BRUSH);
cls.lpszMenuName = NULL;
cls.lpszClassName = "TestMenuClass";
- UnregisterClass(cls.lpszClassName, cls.hInstance);
+ UnregisterClassA(cls.lpszClassName, cls.hInstance);
if (!RegisterClassA(&cls)) assert(0);
SetLastError(0xdeadbeef);
ok(hwnd != 0, "LoadMenuA error %u\n", GetLastError());
SetLastError(0xdeadbeef);
- hmenu = LoadMenuA(GetModuleHandle(0), MAKEINTRESOURCE(1));
+ hmenu = LoadMenuA(GetModuleHandleA(NULL), MAKEINTRESOURCEA(1));
ok(hmenu != 0, "LoadMenuA error %u\n", GetLastError());
SetMenu(hwnd, hmenu);
SetForegroundWindow( hwnd );
+ flush_events();
set_menu_style(hmenu, MNS_NOTIFYBYPOS);
style = get_menu_style(hmenu);
keybd_event(VK_MENU, 0, KEYEVENTF_KEYUP, 0);
keybd_event(VK_RETURN, 0, 0, 0);
keybd_event(VK_RETURN, 0, KEYEVENTF_KEYUP, 0);
- while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
+ while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
- DispatchMessage(&msg);
+ DispatchMessageA(&msg);
}
if (!sequence_cnt) /* we didn't get any message */
{
keybd_event(VK_RIGHT, 0, KEYEVENTF_KEYUP, 0);
keybd_event(VK_RETURN, 0, 0, 0);
keybd_event(VK_RETURN, 0, KEYEVENTF_KEYUP, 0);
- while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
+ while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
- DispatchMessage(&msg);
+ DispatchMessageA(&msg);
}
ok_sequence(wm_popup_menu_2, "submenu of a popup menu command", FALSE);
+ trace("testing single menu item command\n");
+ flush_sequence();
+ keybd_event(VK_MENU, 0, 0, 0);
+ keybd_event('Q', 0, 0, 0);
+ keybd_event('Q', 0, KEYEVENTF_KEYUP, 0);
+ keybd_event(VK_MENU, 0, KEYEVENTF_KEYUP, 0);
+ keybd_event(VK_ESCAPE, 0, 0, 0);
+ keybd_event(VK_ESCAPE, 0, KEYEVENTF_KEYUP, 0);
+ while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE))
+ {
+ TranslateMessage(&msg);
+ DispatchMessageA(&msg);
+ }
+ ok_sequence(wm_single_menu_item, "single menu item command", FALSE);
+
set_menu_style(hmenu, 0);
style = get_menu_style(hmenu);
ok(style == 0, "expected 0, got %u\n", style);
keybd_event(VK_RIGHT, 0, KEYEVENTF_KEYUP, 0);
keybd_event(VK_RETURN, 0, 0, 0);
keybd_event(VK_RETURN, 0, KEYEVENTF_KEYUP, 0);
- while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
+ while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
- DispatchMessage(&msg);
+ DispatchMessageA(&msg);
}
ok_sequence(wm_popup_menu_3, "submenu of a popup menu command", FALSE);
{
HWND hwnd;
- paint_loop_done = 0;
+ paint_loop_done = FALSE;
hwnd = CreateWindowExA(0x0,"PaintLoopWindowClass",
"PaintLoopWindowClass",WS_OVERLAPPEDWINDOW,
100, 100, 100, 100, 0, 0, 0, NULL );
if (PeekMessageA(&msg, 0, 0, 0, 1))
{
TranslateMessage(&msg);
- DispatchMessage(&msg);
+ DispatchMessageA(&msg);
}
}
DestroyWindow(hwnd);
{
HWND hwnd;
MSG msg;
- int gotwmquit = FALSE;
+ BOOL gotwmquit = FALSE;
hwnd = CreateWindowExA(0, "static", "test_defwndproc", WS_POPUP, 0,0,0,0,0,0,0, NULL);
assert(hwnd);
DefWindowProcA( hwnd, WM_ENDSESSION, 1, 0);
if( msg.message == WM_QUIT) gotwmquit = TRUE;
DispatchMessageA( &msg );
}
- ok( gotwmquit == FALSE, "Unexpected WM_QUIT message!\n");
+ ok(!gotwmquit, "Unexpected WM_QUIT message!\n");
DestroyWindow( hwnd);
}
flush_events();
- PostMessage(hwnd, WM_USER+1, 0x1234, 0x5678);
- PostMessage(0, WM_USER+2, 0x5678, 0x1234);
+ PostMessageA(hwnd, WM_USER+1, 0x1234, 0x5678);
+ PostMessageA(0, WM_USER+2, 0x5678, 0x1234);
for (i = 0; i < sizeof(data)/sizeof(data[0]); i++)
{
{
MSG msg;
- PeekMessage( &msg, 0, 0, 0, PM_NOREMOVE );
+ PeekMessageA( &msg, 0, 0, 0, PM_NOREMOVE );
Sleep( 200 );
MsgWaitForMultipleObjects( 0, NULL, FALSE, 100, QS_ALLINPUT );
return 0;
static void do_wait_idle_child( int arg )
{
- WNDCLASS cls;
+ WNDCLASSA cls;
MSG msg;
HWND hwnd = 0;
HANDLE thread;
HANDLE end_event = OpenEventA( EVENT_ALL_ACCESS, FALSE, "test_WaitForInputIdle_end" );
memset( &cls, 0, sizeof(cls) );
- cls.lpfnWndProc = DefWindowProc;
+ cls.lpfnWndProc = DefWindowProcA;
cls.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
- cls.hCursor = LoadCursor(0, IDC_ARROW);
+ cls.hCursor = LoadCursorA(0, (LPCSTR)IDC_ARROW);
cls.lpszClassName = "TestClass";
- RegisterClass( &cls );
+ RegisterClassA( &cls );
- PeekMessage( &msg, 0, 0, 0, PM_NOREMOVE ); /* create the msg queue */
+ PeekMessageA( &msg, 0, 0, 0, PM_NOREMOVE ); /* create the msg queue */
ok( start_event != 0, "failed to create start event, error %u\n", GetLastError() );
ok( end_event != 0, "failed to create end event, error %u\n", GetLastError() );
case 1:
SetEvent( start_event );
Sleep( 200 );
- PeekMessage( &msg, 0, 0, 0, PM_REMOVE );
+ PeekMessageA( &msg, 0, 0, 0, PM_REMOVE );
break;
case 2:
SetEvent( start_event );
Sleep( 200 );
- PeekMessage( &msg, 0, 0, 0, PM_NOREMOVE );
- PostThreadMessage( GetCurrentThreadId(), WM_COMMAND, 0x1234, 0xabcd );
- PeekMessage( &msg, 0, 0, 0, PM_REMOVE );
+ PeekMessageA( &msg, 0, 0, 0, PM_NOREMOVE );
+ PostThreadMessageA( GetCurrentThreadId(), WM_COMMAND, 0x1234, 0xabcd );
+ PeekMessageA( &msg, 0, 0, 0, PM_REMOVE );
break;
case 3:
SetEvent( start_event );
Sleep( 200 );
- SendMessage( HWND_BROADCAST, WM_WININICHANGE, 0, 0 );
+ SendMessageA( HWND_BROADCAST, WM_WININICHANGE, 0, 0 );
break;
case 4:
SetEvent( start_event );
Sleep( 200 );
hwnd = CreateWindowExA(0, "TestClass", NULL, WS_POPUP|WS_VISIBLE, 0, 0, 10, 10, 0, 0, 0, NULL);
- while (PeekMessage( &msg, 0, 0, 0, PM_REMOVE|PM_NOYIELD )) DispatchMessage( &msg );
+ while (PeekMessageA( &msg, 0, 0, 0, PM_REMOVE|PM_NOYIELD )) DispatchMessageA( &msg );
break;
case 5:
SetEvent( start_event );
Sleep( 200 );
hwnd = CreateWindowExA(0, "TestClass", NULL, WS_POPUP|WS_VISIBLE, 0, 0, 10, 10, 0, 0, 0, NULL);
- while (PeekMessage( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessage( &msg );
+ while (PeekMessageA( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessageA( &msg );
break;
case 6:
SetEvent( start_event );
Sleep( 200 );
hwnd = CreateWindowExA(0, "TestClass", NULL, WS_POPUP|WS_VISIBLE, 0, 0, 10, 10, 0, 0, 0, NULL);
- while (PeekMessage( &msg, 0, 0, 0, PM_NOREMOVE ))
+ while (PeekMessageA( &msg, 0, 0, 0, PM_NOREMOVE ))
{
- GetMessage( &msg, 0, 0, 0 );
- DispatchMessage( &msg );
+ GetMessageA( &msg, 0, 0, 0 );
+ DispatchMessageA( &msg );
}
break;
case 7:
hwnd = CreateWindowExA(0, "TestClass", NULL, WS_POPUP|WS_VISIBLE, 0, 0, 10, 10, 0, 0, 0, NULL);
SetTimer( hwnd, 3, 1, NULL );
Sleep( 200 );
- while (PeekMessage( &msg, 0, 0, 0, PM_REMOVE|PM_NOYIELD )) DispatchMessage( &msg );
+ while (PeekMessageA( &msg, 0, 0, 0, PM_REMOVE|PM_NOYIELD )) DispatchMessageA( &msg );
break;
case 8:
SetEvent( start_event );
Sleep( 200 );
- PeekMessage( &msg, 0, 0, 0, PM_NOREMOVE );
+ PeekMessageA( &msg, 0, 0, 0, PM_NOREMOVE );
MsgWaitForMultipleObjects( 0, NULL, FALSE, 100, QS_ALLINPUT );
break;
case 9:
SetEvent( start_event );
Sleep( 200 );
hwnd = CreateWindowExA(0, "TestClass", NULL, WS_POPUP|WS_VISIBLE, 0, 0, 10, 10, 0, 0, 0, NULL);
- while (PeekMessage( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessage( &msg );
- for (;;) GetMessage( &msg, 0, 0, 0 );
+ while (PeekMessageA( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessageA( &msg );
+ for (;;) GetMessageA( &msg, 0, 0, 0 );
break;
case 10:
SetEvent( start_event );
hwnd = CreateWindowExA(0, "TestClass", NULL, WS_POPUP|WS_VISIBLE, 0, 0, 10, 10, 0, 0, 0, NULL);
SetTimer( hwnd, 3, 1, NULL );
Sleep( 200 );
- while (PeekMessage( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessage( &msg );
+ while (PeekMessageA( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessageA( &msg );
break;
case 11:
SetEvent( start_event );
Sleep( 200 );
return; /* exiting the process makes WaitForInputIdle return success too */
case 12:
- PeekMessage( &msg, 0, 0, 0, PM_NOREMOVE );
+ PeekMessageA( &msg, 0, 0, 0, PM_NOREMOVE );
Sleep( 200 );
MsgWaitForMultipleObjects( 0, NULL, FALSE, 100, QS_ALLINPUT );
SetEvent( start_event );
break;
case 13:
SetEvent( start_event );
- PeekMessage( &msg, 0, 0, 0, PM_NOREMOVE );
+ PeekMessageA( &msg, 0, 0, 0, PM_NOREMOVE );
Sleep( 200 );
thread = CreateThread( NULL, 0, do_wait_idle_child_thread, NULL, 0, &id );
WaitForSingleObject( thread, 10000 );
case 14:
SetEvent( start_event );
Sleep( 200 );
- PeekMessage( &msg, HWND_TOPMOST, 0, 0, PM_NOREMOVE );
+ PeekMessageA( &msg, HWND_TOPMOST, 0, 0, PM_NOREMOVE );
break;
case 15:
SetEvent( start_event );
Sleep( 200 );
- PeekMessage( &msg, HWND_BROADCAST, 0, 0, PM_NOREMOVE );
+ PeekMessageA( &msg, HWND_BROADCAST, 0, 0, PM_NOREMOVE );
break;
case 16:
SetEvent( start_event );
Sleep( 200 );
- PeekMessage( &msg, HWND_BOTTOM, 0, 0, PM_NOREMOVE );
+ PeekMessageA( &msg, HWND_BOTTOM, 0, 0, PM_NOREMOVE );
break;
case 17:
SetEvent( start_event );
Sleep( 200 );
- PeekMessage( &msg, (HWND)0xdeadbeef, 0, 0, PM_NOREMOVE );
+ PeekMessageA( &msg, (HWND)0xdeadbeef, 0, 0, PM_NOREMOVE );
break;
case 18:
SetEvent( start_event );
Sleep( 200 );
- PeekMessage( &msg, HWND_NOTOPMOST, 0, 0, PM_NOREMOVE );
+ PeekMessageA( &msg, HWND_NOTOPMOST, 0, 0, PM_NOREMOVE );
break;
case 19:
SetEvent( start_event );
Sleep( 200 );
- PeekMessage( &msg, HWND_MESSAGE, 0, 0, PM_NOREMOVE );
+ PeekMessageA( &msg, HWND_MESSAGE, 0, 0, PM_NOREMOVE );
break;
case 20:
SetEvent( start_event );
Sleep( 200 );
- PeekMessage( &msg, GetDesktopWindow(), 0, 0, PM_NOREMOVE );
+ PeekMessageA( &msg, GetDesktopWindow(), 0, 0, PM_NOREMOVE );
break;
}
WaitForSingleObject( end_event, 2000 );
static DWORD CALLBACK wait_idle_thread( void *arg )
{
- WNDCLASS cls;
+ WNDCLASSA cls;
MSG msg;
HWND hwnd;
memset( &cls, 0, sizeof(cls) );
cls.lpfnWndProc = wait_idle_proc;
cls.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
- cls.hCursor = LoadCursor(0, IDC_ARROW);
+ cls.hCursor = LoadCursorA(0, (LPCSTR)IDC_ARROW);
cls.lpszClassName = "TestClass";
- RegisterClass( &cls );
+ RegisterClassA( &cls );
hwnd = CreateWindowExA(0, "TestClass", NULL, WS_POPUP, 0, 0, 10, 10, 0, 0, 0, NULL);
- while (GetMessage( &msg, 0, 0, 0 )) DispatchMessage( &msg );
+ while (GetMessageA( &msg, 0, 0, 0 )) DispatchMessageA( &msg );
DestroyWindow(hwnd);
return 0;
}
}
}
CloseHandle( start_event );
- PostThreadMessage( id, WM_QUIT, 0, 0 );
+ PostThreadMessageA( id, WM_QUIT, 0, 0 );
WaitForSingleObject( thread, 10000 );
CloseHandle( thread );
}
-START_TEST(msg)
+static const struct message WmSetParentSeq_1[] = {
+ { WM_SHOWWINDOW, sent|wparam, 0 },
+ { EVENT_OBJECT_PARENTCHANGE, winevent_hook|wparam|lparam, 0, 0 },
+ { WM_WINDOWPOSCHANGING, sent|wparam, SWP_NOSIZE },
+ { WM_CHILDACTIVATE, sent },
+ { WM_WINDOWPOSCHANGED, sent|wparam, SWP_NOSIZE|SWP_NOREDRAW|SWP_NOCLIENTSIZE },
+ { WM_MOVE, sent|defwinproc|wparam, 0 },
+ { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 },
+ { WM_SHOWWINDOW, sent|wparam, 1 },
+ { 0 }
+};
+
+static const struct message WmSetParentSeq_2[] = {
+ { WM_SHOWWINDOW, sent|wparam, 0 },
+ { WM_WINDOWPOSCHANGING, sent|wparam, SWP_HIDEWINDOW|SWP_NOSIZE|SWP_NOMOVE },
+ { EVENT_OBJECT_HIDE, winevent_hook|wparam|lparam, 0, 0 },
+ { WM_WINDOWPOSCHANGED, sent|wparam, SWP_HIDEWINDOW|SWP_NOSIZE|SWP_NOMOVE|SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE },
+ { HCBT_SETFOCUS, hook|optional },
+ { WM_NCACTIVATE, sent|wparam|optional, 0 },
+ { WM_ACTIVATE, sent|wparam|optional, 0 },
+ { WM_ACTIVATEAPP, sent|wparam|optional, 0 },
+ { WM_KILLFOCUS, sent|wparam, 0 },
+ { EVENT_OBJECT_PARENTCHANGE, winevent_hook|wparam|lparam, 0, 0 },
+ { WM_WINDOWPOSCHANGING, sent|wparam, SWP_NOSIZE },
+ { HCBT_ACTIVATE, hook|optional },
+ { EVENT_SYSTEM_FOREGROUND, winevent_hook|wparam|lparam, 0, 0 },
+ { WM_WINDOWPOSCHANGING, sent|wparam|optional, SWP_NOSIZE|SWP_NOMOVE },
+ { WM_NCACTIVATE, sent|wparam|optional, 1 },
+ { WM_ACTIVATE, sent|wparam|optional, 1 },
+ { HCBT_SETFOCUS, hook|optional },
+ { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
+ { WM_SETFOCUS, sent|optional|defwinproc },
+ { WM_WINDOWPOSCHANGED, sent|wparam, SWP_NOREDRAW|SWP_NOSIZE|SWP_NOCLIENTSIZE },
+ { WM_MOVE, sent|defwinproc|wparam, 0 },
+ { EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 },
+ { WM_SHOWWINDOW, sent|wparam, 1 },
+ { WM_WINDOWPOSCHANGING, sent|wparam, SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE },
+ { EVENT_OBJECT_SHOW, winevent_hook|wparam|lparam, 0, 0 },
+ { WM_WINDOWPOSCHANGED, sent|wparam, SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE|SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE },
+ { 0 }
+};
+
+
+static void test_SetParent(void)
{
- char **test_argv;
- BOOL ret;
- BOOL (WINAPI *pIsWinEventHookInstalled)(DWORD)= 0;/*GetProcAddress(user32, "IsWinEventHookInstalled");*/
+ HWND parent1, parent2, child, popup;
+ RECT rc, rc_old;
- int argc = winetest_get_mainargs( &test_argv );
- if (argc >= 3)
- {
- unsigned int arg;
- /* Child process. */
- sscanf (test_argv[2], "%d", (unsigned int *) &arg);
- do_wait_idle_child( arg );
- return;
- }
+ parent1 = CreateWindowExA(0, "TestParentClass", NULL, WS_OVERLAPPEDWINDOW,
+ 100, 100, 200, 200, 0, 0, 0, NULL);
+ ok(parent1 != 0, "Failed to create parent1 window\n");
- init_procs();
+ parent2 = CreateWindowExA(0, "TestParentClass", NULL, WS_OVERLAPPEDWINDOW,
+ 400, 100, 200, 200, 0, 0, 0, NULL);
+ ok(parent2 != 0, "Failed to create parent2 window\n");
- if (!RegisterWindowClasses()) assert(0);
+ /* WS_CHILD window */
+ child = CreateWindowExA(0, "TestWindowClass", NULL, WS_CHILD | WS_VISIBLE,
+ 10, 10, 150, 150, parent1, 0, 0, NULL);
+ ok(child != 0, "Failed to create child window\n");
- if (pSetWinEventHook)
- {
- hEvent_hook = pSetWinEventHook(EVENT_MIN, EVENT_MAX,
- GetModuleHandleA(0), win_event_proc,
- 0, GetCurrentThreadId(),
- WINEVENT_INCONTEXT);
- if (pIsWinEventHookInstalled && hEvent_hook)
- {
- UINT event;
- for (event = EVENT_MIN; event <= EVENT_MAX; event++)
- ok(pIsWinEventHookInstalled(event), "IsWinEventHookInstalled(%u) failed\n", event);
- }
- }
- if (!hEvent_hook) win_skip( "no win event hook support\n" );
+ GetWindowRect(parent1, &rc);
+ trace("parent1 (%d,%d)-(%d,%d)\n", rc.left, rc.top, rc.right, rc.bottom);
+ GetWindowRect(child, &rc_old);
+ MapWindowPoints(0, parent1, (POINT *)&rc_old, 2);
+ trace("child (%d,%d)-(%d,%d)\n", rc_old.left, rc_old.top, rc_old.right, rc_old.bottom);
- cbt_hook_thread_id = GetCurrentThreadId();
- hCBT_hook = SetWindowsHookExA(WH_CBT, cbt_hook_proc, 0, GetCurrentThreadId());
- if (!hCBT_hook) win_skip( "cannot set global hook, will skip hook tests\n" );
+ flush_sequence();
- test_winevents();
+ SetParent(child, parent2);
+ flush_events();
+ ok_sequence(WmSetParentSeq_1, "SetParent() visible WS_CHILD", TRUE);
- /* Fix message sequences before removing 4 lines below */
-#if 1
- if (pUnhookWinEvent && hEvent_hook)
- {
- ret = pUnhookWinEvent(hEvent_hook);
+ ok(GetWindowLongA(child, GWL_STYLE) & WS_VISIBLE, "WS_VISIBLE should be set\n");
+ ok(!IsWindowVisible(child), "IsWindowVisible() should return FALSE\n");
+
+ GetWindowRect(parent2, &rc);
+ trace("parent2 (%d,%d)-(%d,%d)\n", rc.left, rc.top, rc.right, rc.bottom);
+ GetWindowRect(child, &rc);
+ MapWindowPoints(0, parent2, (POINT *)&rc, 2);
+ trace("child (%d,%d)-(%d,%d)\n", rc.left, rc.top, rc.right, rc.bottom);
+
+ ok(EqualRect(&rc_old, &rc), "rects do not match (%d,%d-%d,%d) / (%d,%d-%d,%d)\n",
+ rc_old.left, rc_old.top, rc_old.right, rc_old.bottom,
+ rc.left, rc.top, rc.right, rc.bottom );
+
+ /* WS_POPUP window */
+ popup = CreateWindowExA(0, "TestWindowClass", NULL, WS_POPUP | WS_VISIBLE,
+ 20, 20, 100, 100, 0, 0, 0, NULL);
+ ok(popup != 0, "Failed to create popup window\n");
+
+ GetWindowRect(popup, &rc_old);
+ trace("popup (%d,%d)-(%d,%d)\n", rc_old.left, rc_old.top, rc_old.right, rc_old.bottom);
+
+ flush_sequence();
+
+ SetParent(popup, child);
+ flush_events();
+ ok_sequence(WmSetParentSeq_2, "SetParent() visible WS_POPUP", TRUE);
+
+ ok(GetWindowLongA(popup, GWL_STYLE) & WS_VISIBLE, "WS_VISIBLE should be set\n");
+ ok(!IsWindowVisible(popup), "IsWindowVisible() should return FALSE\n");
+
+ GetWindowRect(child, &rc);
+ trace("parent2 (%d,%d)-(%d,%d)\n", rc.left, rc.top, rc.right, rc.bottom);
+ GetWindowRect(popup, &rc);
+ MapWindowPoints(0, child, (POINT *)&rc, 2);
+ trace("popup (%d,%d)-(%d,%d)\n", rc.left, rc.top, rc.right, rc.bottom);
+
+ ok(EqualRect(&rc_old, &rc), "rects do not match (%d,%d-%d,%d) / (%d,%d-%d,%d)\n",
+ rc_old.left, rc_old.top, rc_old.right, rc_old.bottom,
+ rc.left, rc.top, rc.right, rc.bottom );
+
+ DestroyWindow(popup);
+ DestroyWindow(child);
+ DestroyWindow(parent1);
+ DestroyWindow(parent2);
+
+ flush_sequence();
+}
+
+static const struct message WmKeyReleaseOnly[] = {
+ { HCBT_KEYSKIPPED, hook|wparam|lparam|optional, 0x41, 0x80000001 },
+ { WM_KEYUP, sent|wparam|lparam, 0x41, 0x80000001 },
+ { 0 }
+};
+static const struct message WmKeyPressNormal[] = {
+ { HCBT_KEYSKIPPED, hook|wparam|lparam|optional, 0x41, 0x1 },
+ { WM_KEYDOWN, sent|wparam|lparam, 0x41, 0x1 },
+ { 0 }
+};
+static const struct message WmKeyPressRepeat[] = {
+ { HCBT_KEYSKIPPED, hook|wparam|lparam|optional, 0x41, 0x40000001 },
+ { WM_KEYDOWN, sent|wparam|lparam, 0x41, 0x40000001 },
+ { 0 }
+};
+static const struct message WmKeyReleaseNormal[] = {
+ { HCBT_KEYSKIPPED, hook|wparam|lparam|optional, 0x41, 0xc0000001 },
+ { WM_KEYUP, sent|wparam|lparam, 0x41, 0xc0000001 },
+ { 0 }
+};
+
+static void test_keyflags(void)
+{
+ HWND test_window;
+ SHORT key_state;
+ BYTE keyboard_state[256];
+ MSG msg;
+
+ test_window = CreateWindowExA(0, "TestWindowClass", NULL, WS_OVERLAPPEDWINDOW | WS_VISIBLE,
+ 100, 100, 200, 200, 0, 0, 0, NULL);
+
+ flush_events();
+ flush_sequence();
+
+ /* keyup without a keydown */
+ keybd_event(0x41, 0, KEYEVENTF_KEYUP, 0);
+ while (PeekMessageA(&msg, NULL, WM_KEYFIRST, WM_KEYLAST, PM_REMOVE))
+ DispatchMessageA(&msg);
+ ok_sequence(WmKeyReleaseOnly, "key release only", TRUE);
+
+ key_state = GetAsyncKeyState(0x41);
+ ok((key_state & 0x8000) == 0, "unexpected key state %x\n", key_state);
+
+ key_state = GetKeyState(0x41);
+ ok((key_state & 0x8000) == 0, "unexpected key state %x\n", key_state);
+
+ /* keydown */
+ keybd_event(0x41, 0, 0, 0);
+ while (PeekMessageA(&msg, NULL, WM_KEYFIRST, WM_KEYLAST, PM_REMOVE))
+ DispatchMessageA(&msg);
+ ok_sequence(WmKeyPressNormal, "key press only", FALSE);
+
+ key_state = GetAsyncKeyState(0x41);
+ ok((key_state & 0x8000) == 0x8000, "unexpected key state %x\n", key_state);
+
+ key_state = GetKeyState(0x41);
+ ok((key_state & 0x8000) == 0x8000, "unexpected key state %x\n", key_state);
+
+ /* keydown repeat */
+ keybd_event(0x41, 0, 0, 0);
+ while (PeekMessageA(&msg, NULL, WM_KEYFIRST, WM_KEYLAST, PM_REMOVE))
+ DispatchMessageA(&msg);
+ ok_sequence(WmKeyPressRepeat, "key press repeat", FALSE);
+
+ key_state = GetAsyncKeyState(0x41);
+ ok((key_state & 0x8000) == 0x8000, "unexpected key state %x\n", key_state);
+
+ key_state = GetKeyState(0x41);
+ ok((key_state & 0x8000) == 0x8000, "unexpected key state %x\n", key_state);
+
+ /* keyup */
+ keybd_event(0x41, 0, KEYEVENTF_KEYUP, 0);
+ while (PeekMessageA(&msg, NULL, WM_KEYFIRST, WM_KEYLAST, PM_REMOVE))
+ DispatchMessageA(&msg);
+ ok_sequence(WmKeyReleaseNormal, "key release repeat", FALSE);
+
+ key_state = GetAsyncKeyState(0x41);
+ ok((key_state & 0x8000) == 0, "unexpected key state %x\n", key_state);
+
+ key_state = GetKeyState(0x41);
+ ok((key_state & 0x8000) == 0, "unexpected key state %x\n", key_state);
+
+ /* set the key state in this thread */
+ GetKeyboardState(keyboard_state);
+ keyboard_state[0x41] = 0x80;
+ SetKeyboardState(keyboard_state);
+
+ key_state = GetAsyncKeyState(0x41);
+ ok((key_state & 0x8000) == 0, "unexpected key state %x\n", key_state);
+
+ /* keydown */
+ keybd_event(0x41, 0, 0, 0);
+ while (PeekMessageA(&msg, NULL, WM_KEYFIRST, WM_KEYLAST, PM_REMOVE))
+ DispatchMessageA(&msg);
+ ok_sequence(WmKeyPressRepeat, "key press after setkeyboardstate", TRUE);
+
+ key_state = GetAsyncKeyState(0x41);
+ ok((key_state & 0x8000) == 0x8000, "unexpected key state %x\n", key_state);
+
+ key_state = GetKeyState(0x41);
+ ok((key_state & 0x8000) == 0x8000, "unexpected key state %x\n", key_state);
+
+ /* clear the key state in this thread */
+ GetKeyboardState(keyboard_state);
+ keyboard_state[0x41] = 0;
+ SetKeyboardState(keyboard_state);
+
+ key_state = GetAsyncKeyState(0x41);
+ ok((key_state & 0x8000) == 0x8000, "unexpected key state %x\n", key_state);
+
+ /* keyup */
+ keybd_event(0x41, 0, KEYEVENTF_KEYUP, 0);
+ while (PeekMessageA(&msg, NULL, WM_KEYFIRST, WM_KEYLAST, PM_REMOVE))
+ DispatchMessageA(&msg);
+ ok_sequence(WmKeyReleaseOnly, "key release after setkeyboardstate", TRUE);
+
+ key_state = GetAsyncKeyState(0x41);
+ ok((key_state & 0x8000) == 0, "unexpected key state %x\n", key_state);
+
+ key_state = GetKeyState(0x41);
+ ok((key_state & 0x8000) == 0, "unexpected key state %x\n", key_state);
+
+ DestroyWindow(test_window);
+ flush_sequence();
+}
+
+static const struct message WmHotkeyPressLWIN[] = {
+ { WM_KEYDOWN, kbd_hook|wparam|lparam, VK_LWIN, LLKHF_INJECTED },
+ { HCBT_KEYSKIPPED, hook|wparam|lparam|optional, VK_LWIN, 1 },
+ { WM_KEYDOWN, sent|wparam|lparam, VK_LWIN, 1 },
+ { 0 }
+};
+static const struct message WmHotkeyPress[] = {
+ { WM_KEYDOWN, kbd_hook|lparam, 0, LLKHF_INJECTED },
+ { WM_HOTKEY, sent|wparam, 5 },
+ { 0 }
+};
+static const struct message WmHotkeyRelease[] = {
+ { WM_KEYUP, kbd_hook|lparam, 0, LLKHF_INJECTED|LLKHF_UP },
+ { HCBT_KEYSKIPPED, hook|lparam|optional, 0, 0x80000001 },
+ { WM_KEYUP, sent|lparam, 0, 0x80000001 },
+ { 0 }
+};
+static const struct message WmHotkeyReleaseLWIN[] = {
+ { WM_KEYUP, kbd_hook|wparam|lparam, VK_LWIN, LLKHF_INJECTED|LLKHF_UP },
+ { HCBT_KEYSKIPPED, hook|wparam|lparam|optional, VK_LWIN, 0xc0000001 },
+ { WM_KEYUP, sent|wparam|lparam, VK_LWIN, 0xc0000001 },
+ { 0 }
+};
+static const struct message WmHotkeyCombined[] = {
+ { WM_KEYDOWN, kbd_hook|wparam|lparam, VK_LWIN, LLKHF_INJECTED },
+ { WM_KEYDOWN, kbd_hook|lparam, 0, LLKHF_INJECTED },
+ { WM_KEYUP, kbd_hook|lparam, 0, LLKHF_INJECTED|LLKHF_UP },
+ { WM_KEYUP, kbd_hook|wparam|lparam, VK_LWIN, LLKHF_INJECTED|LLKHF_UP },
+ { WM_APP, sent, 0, 0 },
+ { WM_HOTKEY, sent|wparam, 5 },
+ { WM_APP+1, sent, 0, 0 },
+ { HCBT_KEYSKIPPED, hook|wparam|lparam|optional, VK_LWIN, 1 },
+ { WM_KEYDOWN, sent|wparam|lparam, VK_LWIN, 1 },
+ { HCBT_KEYSKIPPED, hook|optional, 0, 0x80000001 },
+ { WM_KEYUP, sent, 0, 0x80000001 }, /* lparam not checked so the sequence isn't a todo */
+ { HCBT_KEYSKIPPED, hook|wparam|lparam|optional, VK_LWIN, 0xc0000001 },
+ { WM_KEYUP, sent|wparam|lparam, VK_LWIN, 0xc0000001 },
+ { 0 }
+};
+static const struct message WmHotkeyPrevious[] = {
+ { WM_KEYDOWN, kbd_hook|wparam|lparam, VK_LWIN, LLKHF_INJECTED },
+ { WM_KEYDOWN, kbd_hook|lparam, 0, LLKHF_INJECTED },
+ { WM_KEYUP, kbd_hook|lparam, 0, LLKHF_INJECTED|LLKHF_UP },
+ { WM_KEYUP, kbd_hook|wparam|lparam, VK_LWIN, LLKHF_INJECTED|LLKHF_UP },
+ { HCBT_KEYSKIPPED, hook|wparam|lparam|optional, VK_LWIN, 1 },
+ { WM_KEYDOWN, sent|wparam|lparam, VK_LWIN, 1 },
+ { HCBT_KEYSKIPPED, hook|lparam|optional, 0, 1 },
+ { WM_KEYDOWN, sent|lparam, 0, 1 },
+ { HCBT_KEYSKIPPED, hook|optional|lparam, 0, 0xc0000001 },
+ { WM_KEYUP, sent|lparam, 0, 0xc0000001 },
+ { HCBT_KEYSKIPPED, hook|wparam|lparam|optional, VK_LWIN, 0xc0000001 },
+ { WM_KEYUP, sent|wparam|lparam, VK_LWIN, 0xc0000001 },
+ { 0 }
+};
+static const struct message WmHotkeyNew[] = {
+ { WM_KEYDOWN, kbd_hook|lparam, 0, LLKHF_INJECTED },
+ { WM_KEYUP, kbd_hook|lparam, 0, LLKHF_INJECTED|LLKHF_UP },
+ { WM_HOTKEY, sent|wparam, 5 },
+ { HCBT_KEYSKIPPED, hook|optional, 0, 0x80000001 },
+ { WM_KEYUP, sent, 0, 0x80000001 }, /* lparam not checked so the sequence isn't a todo */
+ { 0 }
+};
+
+static int hotkey_letter;
+
+static LRESULT CALLBACK KeyboardHookProc(int nCode, WPARAM wParam, LPARAM lParam)
+{
+ struct recvd_message msg;
+
+ if (nCode == HC_ACTION)
+ {
+ KBDLLHOOKSTRUCT *kdbhookstruct = (KBDLLHOOKSTRUCT*)lParam;
+
+ msg.hwnd = 0;
+ msg.message = wParam;
+ msg.flags = kbd_hook|wparam|lparam;
+ msg.wParam = kdbhookstruct->vkCode;
+ msg.lParam = kdbhookstruct->flags;
+ msg.descr = "KeyboardHookProc";
+ add_message(&msg);
+
+ if (wParam == WM_KEYUP || wParam == WM_KEYDOWN)
+ {
+ ok(kdbhookstruct->vkCode == VK_LWIN || kdbhookstruct->vkCode == hotkey_letter,
+ "unexpected keycode %x\n", kdbhookstruct->vkCode);
+ }
+ }
+
+ return CallNextHookEx(hKBD_hook, nCode, wParam, lParam);
+}
+
+static void test_hotkey(void)
+{
+ HWND test_window, taskbar_window;
+ BOOL ret;
+ MSG msg;
+ DWORD queue_status;
+ SHORT key_state;
+
+ SetLastError(0xdeadbeef);
+ ret = UnregisterHotKey(NULL, 0);
+ ok(ret == FALSE, "expected FALSE, got %i\n", ret);
+ ok(GetLastError() == ERROR_HOTKEY_NOT_REGISTERED || broken(GetLastError() == 0xdeadbeef),
+ "unexpected error %d\n", GetLastError());
+
+ if (ret == TRUE)
+ {
+ skip("hotkeys not supported\n");
+ return;
+ }
+
+ test_window = CreateWindowExA(0, "HotkeyWindowClass", NULL, WS_OVERLAPPEDWINDOW | WS_VISIBLE,
+ 100, 100, 200, 200, 0, 0, 0, NULL);
+
+ flush_sequence();
+
+ SetLastError(0xdeadbeef);
+ ret = UnregisterHotKey(test_window, 0);
+ ok(ret == FALSE, "expected FALSE, got %i\n", ret);
+ ok(GetLastError() == ERROR_HOTKEY_NOT_REGISTERED || broken(GetLastError() == 0xdeadbeef),
+ "unexpected error %d\n", GetLastError());
+
+ /* Search for a Windows Key + letter combination that hasn't been registered */
+ for (hotkey_letter = 0x41; hotkey_letter <= 0x51; hotkey_letter ++)
+ {
+ SetLastError(0xdeadbeef);
+ ret = RegisterHotKey(test_window, 5, MOD_WIN, hotkey_letter);
+
+ if (ret == TRUE)
+ {
+ break;
+ }
+ else
+ {
+ ok(GetLastError() == ERROR_HOTKEY_ALREADY_REGISTERED || broken(GetLastError() == 0xdeadbeef),
+ "unexpected error %d\n", GetLastError());
+ }
+ }
+
+ if (hotkey_letter == 0x52)
+ {
+ ok(0, "Couldn't find any free Windows Key + letter combination\n");
+ goto end;
+ }
+
+ hKBD_hook = SetWindowsHookExA(WH_KEYBOARD_LL, KeyboardHookProc, GetModuleHandleA(NULL), 0);
+ if (!hKBD_hook) win_skip("WH_KEYBOARD_LL is not supported\n");
+
+ /* Same key combination, different id */
+ SetLastError(0xdeadbeef);
+ ret = RegisterHotKey(test_window, 4, MOD_WIN, hotkey_letter);
+ ok(ret == FALSE, "expected FALSE, got %i\n", ret);
+ ok(GetLastError() == ERROR_HOTKEY_ALREADY_REGISTERED || broken(GetLastError() == 0xdeadbeef),
+ "unexpected error %d\n", GetLastError());
+
+ /* Same key combination, different window */
+ SetLastError(0xdeadbeef);
+ ret = RegisterHotKey(NULL, 5, MOD_WIN, hotkey_letter);
+ ok(ret == FALSE, "expected FALSE, got %i\n", ret);
+ ok(GetLastError() == ERROR_HOTKEY_ALREADY_REGISTERED || broken(GetLastError() == 0xdeadbeef),
+ "unexpected error %d\n", GetLastError());
+
+ /* Register the same hotkey twice */
+ SetLastError(0xdeadbeef);
+ ret = RegisterHotKey(test_window, 5, MOD_WIN, hotkey_letter);
+ ok(ret == FALSE, "expected FALSE, got %i\n", ret);
+ ok(GetLastError() == ERROR_HOTKEY_ALREADY_REGISTERED || broken(GetLastError() == 0xdeadbeef),
+ "unexpected error %d\n", GetLastError());
+
+ /* Window on another thread */
+ taskbar_window = FindWindowA("Shell_TrayWnd", NULL);
+ if (!taskbar_window)
+ {
+ skip("no taskbar?\n");
+ }
+ else
+ {
+ SetLastError(0xdeadbeef);
+ ret = RegisterHotKey(taskbar_window, 5, 0, hotkey_letter);
+ ok(ret == FALSE, "expected FALSE, got %i\n", ret);
+ ok(GetLastError() == ERROR_WINDOW_OF_OTHER_THREAD || broken(GetLastError() == 0xdeadbeef),
+ "unexpected error %d\n", GetLastError());
+ }
+
+ /* Inject the appropriate key sequence */
+ keybd_event(VK_LWIN, 0, 0, 0);
+ while (PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE))
+ DispatchMessageA(&msg);
+ ok_sequence(WmHotkeyPressLWIN, "window hotkey press LWIN", FALSE);
+
+ keybd_event(hotkey_letter, 0, 0, 0);
+ queue_status = GetQueueStatus(QS_HOTKEY);
+ ok((queue_status & (QS_HOTKEY << 16)) == QS_HOTKEY << 16, "expected QS_HOTKEY << 16 set, got %x\n", queue_status);
+ while (PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE))
+ {
+ if (msg.message == WM_HOTKEY)
+ {
+ ok(msg.hwnd == test_window, "unexpected hwnd %p\n", msg.hwnd);
+ ok(msg.lParam == MAKELPARAM(MOD_WIN, hotkey_letter), "unexpected WM_HOTKEY lparam %lx\n", msg.lParam);
+ }
+ DispatchMessageA(&msg);
+ }
+ ok_sequence(WmHotkeyPress, "window hotkey press", FALSE);
+
+ queue_status = GetQueueStatus(QS_HOTKEY);
+ ok((queue_status & (QS_HOTKEY << 16)) == 0, "expected QS_HOTKEY << 16 cleared, got %x\n", queue_status);
+
+ key_state = GetAsyncKeyState(hotkey_letter);
+ ok((key_state & 0x8000) == 0x8000, "unexpected key state %x\n", key_state);
+
+ keybd_event(hotkey_letter, 0, KEYEVENTF_KEYUP, 0);
+ while (PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE))
+ DispatchMessageA(&msg);
+ ok_sequence(WmHotkeyRelease, "window hotkey release", TRUE);
+
+ keybd_event(VK_LWIN, 0, KEYEVENTF_KEYUP, 0);
+ while (PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE))
+ DispatchMessageA(&msg);
+ ok_sequence(WmHotkeyReleaseLWIN, "window hotkey release LWIN", FALSE);
+
+ /* normal posted WM_HOTKEY messages set QS_HOTKEY */
+ PostMessageA(test_window, WM_HOTKEY, 0, 0);
+ queue_status = GetQueueStatus(QS_HOTKEY);
+ ok((queue_status & (QS_HOTKEY << 16)) == QS_HOTKEY << 16, "expected QS_HOTKEY << 16 set, got %x\n", queue_status);
+ queue_status = GetQueueStatus(QS_POSTMESSAGE);
+ ok((queue_status & (QS_POSTMESSAGE << 16)) == QS_POSTMESSAGE << 16, "expected QS_POSTMESSAGE << 16 set, got %x\n", queue_status);
+ while (PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE))
+ DispatchMessageA(&msg);
+ flush_sequence();
+
+ /* Send and process all messages at once */
+ PostMessageA(test_window, WM_APP, 0, 0);
+ keybd_event(VK_LWIN, 0, 0, 0);
+ keybd_event(hotkey_letter, 0, 0, 0);
+ keybd_event(hotkey_letter, 0, KEYEVENTF_KEYUP, 0);
+ keybd_event(VK_LWIN, 0, KEYEVENTF_KEYUP, 0);
+
+ while (PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE))
+ {
+ if (msg.message == WM_HOTKEY)
+ {
+ ok(msg.hwnd == test_window, "unexpected hwnd %p\n", msg.hwnd);
+ ok(msg.lParam == MAKELPARAM(MOD_WIN, hotkey_letter), "unexpected WM_HOTKEY lparam %lx\n", msg.lParam);
+ }
+ DispatchMessageA(&msg);
+ }
+ ok_sequence(WmHotkeyCombined, "window hotkey combined", FALSE);
+
+ /* Register same hwnd/id with different key combination */
+ ret = RegisterHotKey(test_window, 5, 0, hotkey_letter);
+ ok(ret == TRUE, "expected TRUE, got %i, err=%d\n", ret, GetLastError());
+
+ /* Previous key combination does not work */
+ keybd_event(VK_LWIN, 0, 0, 0);
+ keybd_event(hotkey_letter, 0, 0, 0);
+ keybd_event(hotkey_letter, 0, KEYEVENTF_KEYUP, 0);
+ keybd_event(VK_LWIN, 0, KEYEVENTF_KEYUP, 0);
+
+ while (PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE))
+ DispatchMessageA(&msg);
+ ok_sequence(WmHotkeyPrevious, "window hotkey previous", FALSE);
+
+ /* New key combination works */
+ keybd_event(hotkey_letter, 0, 0, 0);
+ keybd_event(hotkey_letter, 0, KEYEVENTF_KEYUP, 0);
+
+ while (PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE))
+ {
+ if (msg.message == WM_HOTKEY)
+ {
+ ok(msg.hwnd == test_window, "unexpected hwnd %p\n", msg.hwnd);
+ ok(msg.lParam == MAKELPARAM(0, hotkey_letter), "unexpected WM_HOTKEY lparam %lx\n", msg.lParam);
+ }
+ DispatchMessageA(&msg);
+ }
+ ok_sequence(WmHotkeyNew, "window hotkey new", FALSE);
+
+ /* Unregister hotkey properly */
+ ret = UnregisterHotKey(test_window, 5);
+ ok(ret == TRUE, "expected TRUE, got %i, err=%d\n", ret, GetLastError());
+
+ /* Unregister hotkey again */
+ SetLastError(0xdeadbeef);
+ ret = UnregisterHotKey(test_window, 5);
+ ok(ret == FALSE, "expected FALSE, got %i\n", ret);
+ ok(GetLastError() == ERROR_HOTKEY_NOT_REGISTERED || broken(GetLastError() == 0xdeadbeef),
+ "unexpected error %d\n", GetLastError());
+
+ /* Register thread hotkey */
+ ret = RegisterHotKey(NULL, 5, MOD_WIN, hotkey_letter);
+ ok(ret == TRUE, "expected TRUE, got %i, err=%d\n", ret, GetLastError());
+
+ /* Inject the appropriate key sequence */
+ keybd_event(VK_LWIN, 0, 0, 0);
+ while (PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE))
+ {
+ ok(msg.hwnd != NULL, "unexpected thread message %x\n", msg.message);
+ DispatchMessageA(&msg);
+ }
+ ok_sequence(WmHotkeyPressLWIN, "thread hotkey press LWIN", FALSE);
+
+ keybd_event(hotkey_letter, 0, 0, 0);
+ while (PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE))
+ {
+ if (msg.message == WM_HOTKEY)
+ {
+ struct recvd_message message;
+ ok(msg.hwnd == NULL, "unexpected hwnd %p\n", msg.hwnd);
+ ok(msg.lParam == MAKELPARAM(MOD_WIN, hotkey_letter), "unexpected WM_HOTKEY lparam %lx\n", msg.lParam);
+ message.message = msg.message;
+ message.flags = sent|wparam|lparam;
+ message.wParam = msg.wParam;
+ message.lParam = msg.lParam;
+ message.descr = "test_hotkey thread message";
+ add_message(&message);
+ }
+ else
+ ok(msg.hwnd != NULL, "unexpected thread message %x\n", msg.message);
+ DispatchMessageA(&msg);
+ }
+ ok_sequence(WmHotkeyPress, "thread hotkey press", FALSE);
+
+ keybd_event(hotkey_letter, 0, KEYEVENTF_KEYUP, 0);
+ while (PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE))
+ {
+ ok(msg.hwnd != NULL, "unexpected thread message %x\n", msg.message);
+ DispatchMessageA(&msg);
+ }
+ ok_sequence(WmHotkeyRelease, "thread hotkey release", TRUE);
+
+ keybd_event(VK_LWIN, 0, KEYEVENTF_KEYUP, 0);
+ while (PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE))
+ {
+ ok(msg.hwnd != NULL, "unexpected thread message %x\n", msg.message);
+ DispatchMessageA(&msg);
+ }
+ ok_sequence(WmHotkeyReleaseLWIN, "thread hotkey release LWIN", FALSE);
+
+ /* Unregister thread hotkey */
+ ret = UnregisterHotKey(NULL, 5);
+ ok(ret == TRUE, "expected TRUE, got %i, err=%d\n", ret, GetLastError());
+
+ if (hKBD_hook) UnhookWindowsHookEx(hKBD_hook);
+ hKBD_hook = NULL;
+
+end:
+ UnregisterHotKey(NULL, 5);
+ UnregisterHotKey(test_window, 5);
+ DestroyWindow(test_window);
+ flush_sequence();
+}
+
+
+static const struct message WmSetFocus_1[] = {
+ { HCBT_SETFOCUS, hook }, /* child */
+ { HCBT_ACTIVATE, hook }, /* parent */
+ { WM_QUERYNEWPALETTE, sent|wparam|lparam|parent|optional, 0, 0 },
+ { WM_WINDOWPOSCHANGING, sent|parent, 0, SWP_NOSIZE|SWP_NOMOVE },
+ { WM_ACTIVATEAPP, sent|wparam|parent, 1 },
+ { WM_NCACTIVATE, sent|parent },
+ { WM_GETTEXT, sent|defwinproc|parent|optional },
+ { WM_GETTEXT, sent|defwinproc|parent|optional },
+ { WM_ACTIVATE, sent|wparam|parent, 1 },
+ { HCBT_SETFOCUS, hook }, /* parent */
+ { WM_SETFOCUS, sent|defwinproc|parent },
+ { WM_KILLFOCUS, sent|parent },
+ { WM_SETFOCUS, sent },
+ { 0 }
+};
+static const struct message WmSetFocus_2[] = {
+ { HCBT_SETFOCUS, hook }, /* parent */
+ { WM_KILLFOCUS, sent },
+ { WM_SETFOCUS, sent|parent },
+ { 0 }
+};
+static const struct message WmSetFocus_3[] = {
+ { HCBT_SETFOCUS, hook }, /* child */
+ { 0 }
+};
+static const struct message WmSetFocus_4[] = {
+ { 0 }
+};
+
+static void test_SetFocus(void)
+{
+ HWND parent, old_parent, child, old_focus, old_active;
+ MSG msg;
+ struct wnd_event wnd_event;
+ HANDLE hthread;
+ DWORD ret, tid;
+
+ wnd_event.start_event = CreateEventW(NULL, 0, 0, NULL);
+ ok(wnd_event.start_event != 0, "CreateEvent error %d\n", GetLastError());
+ hthread = CreateThread(NULL, 0, thread_proc, &wnd_event, 0, &tid);
+ ok(hthread != 0, "CreateThread error %d\n", GetLastError());
+ ret = WaitForSingleObject(wnd_event.start_event, INFINITE);
+ ok(ret == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
+ CloseHandle(wnd_event.start_event);
+
+ parent = CreateWindowExA(0, "TestParentClass", NULL, WS_OVERLAPPEDWINDOW,
+ 0, 0, 0, 0, 0, 0, 0, NULL);
+ ok(parent != 0, "failed to create parent window\n");
+ child = CreateWindowExA(0, "TestWindowClass", NULL, WS_CHILD,
+ 0, 0, 0, 0, parent, 0, 0, NULL);
+ ok(child != 0, "failed to create child window\n");
+
+ trace("parent %p, child %p, thread window %p\n", parent, child, wnd_event.hwnd);
+
+ SetFocus(0);
+ SetActiveWindow(0);
+
+ flush_events();
+ flush_sequence();
+
+ ok(GetActiveWindow() == 0, "expected active 0, got %p\n", GetActiveWindow());
+ ok(GetFocus() == 0, "expected focus 0, got %p\n", GetFocus());
+
+ log_all_parent_messages++;
+
+ old_focus = SetFocus(child);
+ while (PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
+ ok_sequence(WmSetFocus_1, "SetFocus on a child window", TRUE);
+ ok(old_focus == parent, "expected old focus %p, got %p\n", parent, old_focus);
+ ok(GetActiveWindow() == parent, "expected active %p, got %p\n", parent, GetActiveWindow());
+ ok(GetFocus() == child, "expected focus %p, got %p\n", child, GetFocus());
+
+ old_focus = SetFocus(parent);
+ while (PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
+ ok_sequence(WmSetFocus_2, "SetFocus on a parent window", FALSE);
+ ok(old_focus == child, "expected old focus %p, got %p\n", child, old_focus);
+ ok(GetActiveWindow() == parent, "expected active %p, got %p\n", parent, GetActiveWindow());
+ ok(GetFocus() == parent, "expected focus %p, got %p\n", parent, GetFocus());
+
+ SetLastError(0xdeadbeef);
+ old_focus = SetFocus((HWND)0xdeadbeef);
+ ok(GetLastError() == ERROR_INVALID_WINDOW_HANDLE || broken(GetLastError() == 0xdeadbeef),
+ "expected ERROR_INVALID_WINDOW_HANDLE, got %d\n", GetLastError());
+ while (PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
+ ok_sequence(WmEmptySeq, "SetFocus on an invalid window", FALSE);
+ ok(old_focus == 0, "expected old focus 0, got %p\n", old_focus);
+ ok(GetActiveWindow() == parent, "expected active %p, got %p\n", parent, GetActiveWindow());
+ ok(GetFocus() == parent, "expected focus %p, got %p\n", parent, GetFocus());
+
+ SetLastError(0xdeadbeef);
+ old_focus = SetFocus(GetDesktopWindow());
+ ok(GetLastError() == ERROR_ACCESS_DENIED /* Vista+ */ ||
+ broken(GetLastError() == 0xdeadbeef), "expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
+ while (PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
+ ok_sequence(WmEmptySeq, "SetFocus on a desktop window", TRUE);
+ ok(old_focus == 0, "expected old focus 0, got %p\n", old_focus);
+ ok(GetActiveWindow() == parent, "expected active %p, got %p\n", parent, GetActiveWindow());
+ ok(GetFocus() == parent, "expected focus %p, got %p\n", parent, GetFocus());
+
+ SetLastError(0xdeadbeef);
+ old_focus = SetFocus(wnd_event.hwnd);
+ ok(GetLastError() == ERROR_ACCESS_DENIED /* Vista+ */ ||
+ broken(GetLastError() == 0xdeadbeef), "expected ERROR_ACCESS_DENIED, got %d\n", GetLastError());
+ while (PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
+ ok_sequence(WmEmptySeq, "SetFocus on another thread window", TRUE);
+ ok(old_focus == 0, "expected old focus 0, got %p\n", old_focus);
+ ok(GetActiveWindow() == parent, "expected active %p, got %p\n", parent, GetActiveWindow());
+ ok(GetFocus() == parent, "expected focus %p, got %p\n", parent, GetFocus());
+
+ SetLastError(0xdeadbeef);
+ old_active = SetActiveWindow((HWND)0xdeadbeef);
+ ok(GetLastError() == ERROR_INVALID_WINDOW_HANDLE || broken(GetLastError() == 0xdeadbeef),
+ "expected ERROR_INVALID_WINDOW_HANDLE, got %d\n", GetLastError());
+ while (PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
+ ok_sequence(WmEmptySeq, "SetActiveWindow on an invalid window", FALSE);
+ ok(old_active == 0, "expected old focus 0, got %p\n", old_active);
+ ok(GetActiveWindow() == parent, "expected active %p, got %p\n", parent, GetActiveWindow());
+ ok(GetFocus() == parent, "expected focus %p, got %p\n", parent, GetFocus());
+
+ SetLastError(0xdeadbeef);
+ old_active = SetActiveWindow(GetDesktopWindow());
+todo_wine
+ ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
+ while (PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
+ ok_sequence(WmEmptySeq, "SetActiveWindow on a desktop window", TRUE);
+ ok(old_active == 0, "expected old focus 0, got %p\n", old_focus);
+ ok(GetActiveWindow() == parent, "expected active %p, got %p\n", parent, GetActiveWindow());
+ ok(GetFocus() == parent, "expected focus %p, got %p\n", parent, GetFocus());
+
+ SetLastError(0xdeadbeef);
+ old_active = SetActiveWindow(wnd_event.hwnd);
+todo_wine
+ ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
+ while (PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
+ ok_sequence(WmEmptySeq, "SetActiveWindow on another thread window", TRUE);
+ ok(old_active == 0, "expected old focus 0, got %p\n", old_active);
+ ok(GetActiveWindow() == parent, "expected active %p, got %p\n", parent, GetActiveWindow());
+ ok(GetFocus() == parent, "expected focus %p, got %p\n", parent, GetFocus());
+
+ SetLastError(0xdeadbeef);
+ ret = AttachThreadInput(GetCurrentThreadId(), tid, TRUE);
+ ok(ret, "AttachThreadInput error %d\n", GetLastError());
+
+todo_wine {
+ ok(GetActiveWindow() == parent, "expected active %p, got %p\n", parent, GetActiveWindow());
+ ok(GetFocus() == parent, "expected focus %p, got %p\n", parent, GetFocus());
+}
+ flush_events();
+ flush_sequence();
+
+ old_focus = SetFocus(wnd_event.hwnd);
+ while (PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
+ ok(old_focus == wnd_event.hwnd, "expected old focus %p, got %p\n", wnd_event.hwnd, old_focus);
+ ok(GetActiveWindow() == wnd_event.hwnd, "expected active %p, got %p\n", wnd_event.hwnd, GetActiveWindow());
+ ok(GetFocus() == wnd_event.hwnd, "expected focus %p, got %p\n", wnd_event.hwnd, GetFocus());
+
+ old_focus = SetFocus(parent);
+ while (PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
+ ok(old_focus == parent, "expected old focus %p, got %p\n", parent, old_focus);
+ ok(GetActiveWindow() == parent, "expected active %p, got %p\n", parent, GetActiveWindow());
+ ok(GetFocus() == parent, "expected focus %p, got %p\n", parent, GetFocus());
+
+ flush_events();
+ flush_sequence();
+
+ old_active = SetActiveWindow(wnd_event.hwnd);
+ while (PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
+ ok(old_active == parent, "expected old focus %p, got %p\n", parent, old_active);
+ ok(GetActiveWindow() == wnd_event.hwnd, "expected active %p, got %p\n", wnd_event.hwnd, GetActiveWindow());
+ ok(GetFocus() == wnd_event.hwnd, "expected focus %p, got %p\n", wnd_event.hwnd, GetFocus());
+
+ SetLastError(0xdeadbeef);
+ ret = AttachThreadInput(GetCurrentThreadId(), tid, FALSE);
+ ok(ret, "AttachThreadInput error %d\n", GetLastError());
+
+ ok(GetActiveWindow() == 0, "expected active 0, got %p\n", GetActiveWindow());
+ ok(GetFocus() == 0, "expected focus 0, got %p\n", GetFocus());
+
+ old_parent = SetParent(child, GetDesktopWindow());
+ ok(old_parent == parent, "expected old parent %p, got %p\n", parent, old_parent);
+
+ ok(GetActiveWindow() == 0, "expected active 0, got %p\n", GetActiveWindow());
+ ok(GetFocus() == 0, "expected focus 0, got %p\n", GetFocus());
+
+ old_focus = SetFocus(parent);
+ while (PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
+ ok(old_focus == parent, "expected old focus %p, got %p\n", parent, old_focus);
+ ok(GetActiveWindow() == parent, "expected active %p, got %p\n", parent, GetActiveWindow());
+ ok(GetFocus() == parent, "expected focus %p, got %p\n", parent, GetFocus());
+
+ flush_events();
+ flush_sequence();
+
+ SetLastError(0xdeadbeef);
+ old_focus = SetFocus(child);
+todo_wine
+ ok(GetLastError() == ERROR_INVALID_PARAMETER /* Vista+ */ ||
+ broken(GetLastError() == 0) /* XP */ ||
+ broken(GetLastError() == 0xdeadbeef), "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
+ while (PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
+ ok_sequence(WmSetFocus_3, "SetFocus on a child window", TRUE);
+ ok(old_focus == 0, "expected old focus 0, got %p\n", old_focus);
+ ok(GetActiveWindow() == parent, "expected active %p, got %p\n", parent, GetActiveWindow());
+ ok(GetFocus() == parent, "expected focus %p, got %p\n", parent, GetFocus());
+
+ SetLastError(0xdeadbeef);
+ old_active = SetActiveWindow(child);
+ ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %d\n", GetLastError());
+ while (PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
+ ok_sequence(WmEmptySeq, "SetActiveWindow on a child window", FALSE);
+ ok(old_active == parent, "expected old active %p, got %p\n", parent, old_active);
+ ok(GetActiveWindow() == parent, "expected active %p, got %p\n", parent, GetActiveWindow());
+ ok(GetFocus() == parent, "expected focus %p, got %p\n", parent, GetFocus());
+
+ log_all_parent_messages--;
+
+ DestroyWindow(child);
+ DestroyWindow(parent);
+
+ ret = PostMessageA(wnd_event.hwnd, WM_QUIT, 0, 0);
+ ok(ret, "PostMessage(WM_QUIT) error %d\n", GetLastError());
+ ret = WaitForSingleObject(hthread, INFINITE);
+ ok(ret == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
+ CloseHandle(hthread);
+}
+
+static const struct message WmSetLayeredStyle[] = {
+ { WM_STYLECHANGING, sent },
+ { WM_STYLECHANGED, sent },
+ { WM_GETTEXT, sent|defwinproc|optional },
+ { 0 }
+};
+
+static const struct message WmSetLayeredStyle2[] = {
+ { WM_STYLECHANGING, sent },
+ { WM_STYLECHANGED, sent },
+ { WM_WINDOWPOSCHANGING, sent|optional|wparam|defwinproc, SWP_FRAMECHANGED|SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOMOVE|SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE },
+ { WM_NCCALCSIZE, sent|optional|wparam|defwinproc, 1 },
+ { WM_WINDOWPOSCHANGED, sent|optional|wparam|defwinproc, SWP_FRAMECHANGED|SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOMOVE },
+ { WM_MOVE, sent|optional|defwinproc|wparam, 0 },
+ { WM_SIZE, sent|optional|defwinproc|wparam, SIZE_RESTORED },
+ { 0 }
+};
+
+struct layered_window_info
+{
+ HWND hwnd;
+ HDC hdc;
+ SIZE size;
+ HANDLE event;
+ BOOL ret;
+};
+
+static DWORD CALLBACK update_layered_proc( void *param )
+{
+ struct layered_window_info *info = param;
+ POINT src = { 0, 0 };
+
+ info->ret = pUpdateLayeredWindow( info->hwnd, 0, NULL, &info->size,
+ info->hdc, &src, 0, NULL, ULW_OPAQUE );
+ ok( info->ret, "failed\n");
+ SetEvent( info->event );
+ return 0;
+}
+
+static void test_layered_window(void)
+{
+ HWND hwnd;
+ HDC hdc;
+ HBITMAP bmp;
+ BOOL ret;
+ SIZE size;
+ POINT pos, src;
+ RECT rect, client;
+ HANDLE thread;
+ DWORD tid;
+ struct layered_window_info info;
+
+ if (!pUpdateLayeredWindow)
+ {
+ win_skip( "UpdateLayeredWindow not supported\n" );
+ return;
+ }
+
+ hdc = CreateCompatibleDC( 0 );
+ bmp = CreateCompatibleBitmap( hdc, 300, 300 );
+ SelectObject( hdc, bmp );
+
+ hwnd = CreateWindowExA(0, "TestWindowClass", NULL, WS_CAPTION | WS_THICKFRAME | WS_SYSMENU,
+ 100, 100, 300, 300, 0, 0, 0, NULL);
+ ok( hwnd != 0, "failed to create window\n" );
+ ShowWindow( hwnd, SW_SHOWNORMAL );
+ UpdateWindow( hwnd );
+ flush_events();
+ flush_sequence();
+
+ GetWindowRect( hwnd, &rect );
+ GetClientRect( hwnd, &client );
+ ok( client.right < rect.right - rect.left, "wrong client area\n" );
+ ok( client.bottom < rect.bottom - rect.top, "wrong client area\n" );
+
+ src.x = src.y = 0;
+ pos.x = pos.y = 300;
+ size.cx = size.cy = 250;
+ ret = pUpdateLayeredWindow( hwnd, 0, &pos, &size, hdc, &src, 0, NULL, ULW_OPAQUE );
+ ok( !ret, "UpdateLayeredWindow should fail on non-layered window\n" );
+ ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
+ SetWindowLongA( hwnd, GWL_EXSTYLE, GetWindowLongA(hwnd, GWL_EXSTYLE) | WS_EX_LAYERED );
+ ok_sequence( WmSetLayeredStyle, "WmSetLayeredStyle", FALSE );
+
+ ret = pUpdateLayeredWindow( hwnd, 0, &pos, &size, hdc, &src, 0, NULL, ULW_OPAQUE );
+ ok( ret, "UpdateLayeredWindow failed err %u\n", GetLastError() );
+ ok_sequence( WmEmptySeq, "UpdateLayeredWindow", FALSE );
+ GetWindowRect( hwnd, &rect );
+ ok( rect.left == 300 && rect.top == 300 && rect.right == 550 && rect.bottom == 550,
+ "wrong window rect %d,%d,%d,%d\n", rect.left, rect.top, rect.right, rect.bottom );
+ GetClientRect( hwnd, &rect );
+ ok( rect.right == client.right - 50 && rect.bottom == client.bottom - 50,
+ "wrong client rect %d,%d,%d,%d\n", rect.left, rect.top, rect.right, rect.bottom );
+
+ size.cx = 150;
+ pos.y = 200;
+ ret = pUpdateLayeredWindow( hwnd, 0, &pos, &size, hdc, &src, 0, NULL, ULW_OPAQUE );
+ ok( ret, "UpdateLayeredWindow failed err %u\n", GetLastError() );
+ ok_sequence( WmEmptySeq, "UpdateLayeredWindow", FALSE );
+ GetWindowRect( hwnd, &rect );
+ ok( rect.left == 300 && rect.top == 200 && rect.right == 450 && rect.bottom == 450,
+ "wrong window rect %d,%d,%d,%d\n", rect.left, rect.top, rect.right, rect.bottom );
+ GetClientRect( hwnd, &rect );
+ ok( rect.right == client.right - 150 && rect.bottom == client.bottom - 50,
+ "wrong client rect %d,%d,%d,%d\n", rect.left, rect.top, rect.right, rect.bottom );
+
+ SetWindowLongA( hwnd, GWL_STYLE,
+ GetWindowLongA(hwnd, GWL_STYLE) & ~(WS_CAPTION | WS_THICKFRAME | WS_SYSMENU) );
+ ok_sequence( WmSetLayeredStyle2, "WmSetLayeredStyle2", FALSE );
+
+ size.cx = 200;
+ pos.x = 200;
+ ret = pUpdateLayeredWindow( hwnd, 0, &pos, &size, hdc, &src, 0, NULL, ULW_OPAQUE );
+ ok( ret, "UpdateLayeredWindow failed err %u\n", GetLastError() );
+ ok_sequence( WmEmptySeq, "UpdateLayeredWindow", FALSE );
+ GetWindowRect( hwnd, &rect );
+ ok( rect.left == 200 && rect.top == 200 && rect.right == 400 && rect.bottom == 450,
+ "wrong window rect %d,%d,%d,%d\n", rect.left, rect.top, rect.right, rect.bottom );
+ GetClientRect( hwnd, &rect );
+ ok( (rect.right == 200 && rect.bottom == 250) ||
+ broken(rect.right == client.right - 100 && rect.bottom == client.bottom - 50),
+ "wrong client rect %d,%d,%d,%d\n", rect.left, rect.top, rect.right, rect.bottom );
+
+ size.cx = 0;
+ ret = pUpdateLayeredWindow( hwnd, 0, &pos, &size, hdc, &src, 0, NULL, ULW_OPAQUE );
+ ok( !ret, "UpdateLayeredWindow should fail on non-layered window\n" );
+ ok( GetLastError() == ERROR_INVALID_PARAMETER || broken(ERROR_MR_MID_NOT_FOUND) /* win7 */,
+ "wrong error %u\n", GetLastError() );
+ size.cx = 1;
+ size.cy = -1;
+ ret = pUpdateLayeredWindow( hwnd, 0, &pos, &size, hdc, &src, 0, NULL, ULW_OPAQUE );
+ ok( !ret, "UpdateLayeredWindow should fail on non-layered window\n" );
+ ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
+
+ SetWindowLongA( hwnd, GWL_EXSTYLE, GetWindowLongA(hwnd, GWL_EXSTYLE) & ~WS_EX_LAYERED );
+ ok_sequence( WmSetLayeredStyle, "WmSetLayeredStyle", FALSE );
+ GetWindowRect( hwnd, &rect );
+ ok( rect.left == 200 && rect.top == 200 && rect.right == 400 && rect.bottom == 450,
+ "wrong window rect %d,%d,%d,%d\n", rect.left, rect.top, rect.right, rect.bottom );
+ GetClientRect( hwnd, &rect );
+ ok( (rect.right == 200 && rect.bottom == 250) ||
+ broken(rect.right == client.right - 100 && rect.bottom == client.bottom - 50),
+ "wrong client rect %d,%d,%d,%d\n", rect.left, rect.top, rect.right, rect.bottom );
+
+ SetWindowLongA( hwnd, GWL_EXSTYLE, GetWindowLongA(hwnd, GWL_EXSTYLE) | WS_EX_LAYERED );
+ info.hwnd = hwnd;
+ info.hdc = hdc;
+ info.size.cx = 250;
+ info.size.cy = 300;
+ info.event = CreateEventA( NULL, TRUE, FALSE, NULL );
+ info.ret = FALSE;
+ thread = CreateThread( NULL, 0, update_layered_proc, &info, 0, &tid );
+ ok( WaitForSingleObject( info.event, 1000 ) == 0, "wait failed\n" );
+ ok( info.ret, "UpdateLayeredWindow failed in other thread\n" );
+ WaitForSingleObject( thread, 1000 );
+ CloseHandle( thread );
+ GetWindowRect( hwnd, &rect );
+ ok( rect.left == 200 && rect.top == 200 && rect.right == 450 && rect.bottom == 500,
+ "wrong window rect %d,%d,%d,%d\n", rect.left, rect.top, rect.right, rect.bottom );
+ GetClientRect( hwnd, &rect );
+ ok( (rect.right == 250 && rect.bottom == 300) ||
+ broken(rect.right == client.right - 50 && rect.bottom == client.bottom),
+ "wrong client rect %d,%d,%d,%d\n", rect.left, rect.top, rect.right, rect.bottom );
+
+ DestroyWindow( hwnd );
+ DeleteDC( hdc );
+ DeleteObject( bmp );
+}
+
+static HMENU hpopupmenu;
+
+static LRESULT WINAPI cancel_popup_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ if (ignore_message( message )) return 0;
+
+ switch (message) {
+ case WM_ENTERIDLE:
+ todo_wine ok(GetCapture() == hwnd, "expected %p, got %p\n", hwnd, GetCapture());
+ EndMenu();
+ break;
+ case WM_INITMENU:
+ case WM_INITMENUPOPUP:
+ case WM_UNINITMENUPOPUP:
+ ok((HMENU)wParam == hpopupmenu, "expected %p, got %lx\n", hpopupmenu, wParam);
+ break;
+ case WM_CAPTURECHANGED:
+ todo_wine ok(!lParam || (HWND)lParam == hwnd, "lost capture to %lx\n", lParam);
+ break;
+ }
+
+ return MsgCheckProc (FALSE, hwnd, message, wParam, lParam);
+}
+
+static LRESULT WINAPI cancel_init_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ if (ignore_message( message )) return 0;
+
+ switch (message) {
+ case WM_ENTERMENULOOP:
+ ok(EndMenu() == TRUE, "EndMenu() failed\n");
+ break;
+ }
+
+ return MsgCheckProc (FALSE, hwnd, message, wParam, lParam);
+}
+
+static void test_TrackPopupMenu(void)
+{
+ HWND hwnd;
+ BOOL ret;
+
+ hwnd = CreateWindowExA(0, "TestWindowClass", NULL, 0,
+ 0, 0, 1, 1, 0,
+ NULL, NULL, 0);
+ ok(hwnd != NULL, "CreateWindowEx failed with error %d\n", GetLastError());
+
+ SetWindowLongPtrA( hwnd, GWLP_WNDPROC, (LONG_PTR)cancel_popup_proc);
+
+ hpopupmenu = CreatePopupMenu();
+ ok(hpopupmenu != NULL, "CreateMenu failed with error %d\n", GetLastError());
+
+ AppendMenuA(hpopupmenu, MF_STRING, 100, "item 1");
+ AppendMenuA(hpopupmenu, MF_STRING, 100, "item 2");
+
+ flush_events();
+ flush_sequence();
+ ret = TrackPopupMenu(hpopupmenu, 0, 100,100, 0, hwnd, NULL);
+ ok_sequence(WmTrackPopupMenu, "TrackPopupMenu", TRUE);
+ ok(ret == 1, "TrackPopupMenu failed with error %i\n", GetLastError());
+
+ SetWindowLongPtrA( hwnd, GWLP_WNDPROC, (LONG_PTR)cancel_init_proc);
+
+ flush_events();
+ flush_sequence();
+ ret = TrackPopupMenu(hpopupmenu, 0, 100,100, 0, hwnd, NULL);
+ ok_sequence(WmTrackPopupMenuAbort, "WmTrackPopupMenuAbort", TRUE);
+ ok(ret == TRUE, "TrackPopupMenu failed\n");
+
+ SetWindowLongPtrA( hwnd, GWLP_WNDPROC, (LONG_PTR)cancel_popup_proc);
+
+ SetCapture(hwnd);
+
+ flush_events();
+ flush_sequence();
+ ret = TrackPopupMenu(hpopupmenu, 0, 100,100, 0, hwnd, NULL);
+ ok_sequence(WmTrackPopupMenuCapture, "TrackPopupMenuCapture", TRUE);
+ ok(ret == 1, "TrackPopupMenuCapture failed with error %i\n", GetLastError());
+
+ DestroyMenu(hpopupmenu);
+ DestroyWindow(hwnd);
+}
+
+static void test_TrackPopupMenuEmpty(void)
+{
+ HWND hwnd;
+ BOOL ret;
+
+ hwnd = CreateWindowExA(0, "TestWindowClass", NULL, 0,
+ 0, 0, 1, 1, 0,
+ NULL, NULL, 0);
+ ok(hwnd != NULL, "CreateWindowEx failed with error %d\n", GetLastError());
+
+ SetWindowLongPtrA( hwnd, GWLP_WNDPROC, (LONG_PTR)cancel_popup_proc);
+
+ hpopupmenu = CreatePopupMenu();
+ ok(hpopupmenu != NULL, "CreateMenu failed with error %d\n", GetLastError());
+
+ flush_events();
+ flush_sequence();
+ ret = TrackPopupMenu(hpopupmenu, 0, 100,100, 0, hwnd, NULL);
+ ok_sequence(WmTrackPopupMenuEmpty, "TrackPopupMenuEmpty", TRUE);
+ todo_wine ok(ret == 0, "TrackPopupMenu succeeded\n");
+
+ DestroyMenu(hpopupmenu);
+ DestroyWindow(hwnd);
+}
+
+static void init_funcs(void)
+{
+ HMODULE hKernel32 = GetModuleHandleA("kernel32.dll");
+
+#define X(f) p##f = (void*)GetProcAddress(hKernel32, #f)
+ X(ActivateActCtx);
+ X(CreateActCtxW);
+ X(DeactivateActCtx);
+ X(GetCurrentActCtx);
+ X(ReleaseActCtx);
+#undef X
+}
+
+START_TEST(msg)
+{
+ char **test_argv;
+ BOOL ret;
+ BOOL (WINAPI *pIsWinEventHookInstalled)(DWORD)= 0;/*GetProcAddress(user32, "IsWinEventHookInstalled");*/
+ HMODULE hModuleImm32;
+ BOOL (WINAPI *pImmDisableIME)(DWORD);
+ int argc;
+
+ init_funcs();
+
+ argc = winetest_get_mainargs( &test_argv );
+ if (argc >= 3)
+ {
+ unsigned int arg;
+ /* Child process. */
+ sscanf (test_argv[2], "%d", (unsigned int *) &arg);
+ do_wait_idle_child( arg );
+ return;
+ }
+
+ InitializeCriticalSection( &sequence_cs );
+ init_procs();
+
+ hModuleImm32 = LoadLibraryA("imm32.dll");
+ if (hModuleImm32) {
+ pImmDisableIME = (void *)GetProcAddress(hModuleImm32, "ImmDisableIME");
+ if (pImmDisableIME)
+ pImmDisableIME(0);
+ }
+ pImmDisableIME = NULL;
+ FreeLibrary(hModuleImm32);
+
+ if (!RegisterWindowClasses()) assert(0);
+
+ if (pSetWinEventHook)
+ {
+ hEvent_hook = pSetWinEventHook(EVENT_MIN, EVENT_MAX,
+ GetModuleHandleA(0), win_event_proc,
+ 0, GetCurrentThreadId(),
+ WINEVENT_INCONTEXT);
+ if (pIsWinEventHookInstalled && hEvent_hook)
+ {
+ UINT event;
+ for (event = EVENT_MIN; event <= EVENT_MAX; event++)
+ ok(pIsWinEventHookInstalled(event), "IsWinEventHookInstalled(%u) failed\n", event);
+ }
+ }
+ if (!hEvent_hook) win_skip( "no win event hook support\n" );
+
+ cbt_hook_thread_id = GetCurrentThreadId();
+ hCBT_hook = SetWindowsHookExA(WH_CBT, cbt_hook_proc, 0, GetCurrentThreadId());
+ if (!hCBT_hook) win_skip( "cannot set global hook, will skip hook tests\n" );
+
+ test_winevents();
+
+ /* Fix message sequences before removing 4 lines below */
+ if (pUnhookWinEvent && hEvent_hook)
+ {
+ ret = pUnhookWinEvent(hEvent_hook);
ok( ret, "UnhookWinEvent error %d\n", GetLastError());
pUnhookWinEvent = 0;
}
hEvent_hook = 0;
-#endif
-
+ test_SetFocus();
+ test_SetParent();
test_PostMessage();
test_ShowWindow();
test_PeekMessage();
test_SetWindowRgn();
test_sys_menu();
test_dialog_messages();
+ test_EndDialog();
test_nullCallback();
test_dbcs_wm_char();
+ test_unicode_wm_char();
test_menu_messages();
test_paintingloop();
test_defwinproc();
test_clipboard_viewers();
+ test_keyflags();
+ test_hotkey();
+ test_layered_window();
+ if(!winetest_interactive)
+ skip("CORE-8299 : Skip Tracking popup menu tests.\n");
+ else
+ {
+ test_TrackPopupMenu();
+ test_TrackPopupMenuEmpty();
+ }
/* keep it the last test, under Windows it tends to break the tests
* which rely on active/foreground windows being correct.
*/
GetLastError() == 0xdeadbeef, /* Win9x */
"unexpected error %d\n", GetLastError());
}
+ DeleteCriticalSection( &sequence_cs );
}