[USER32_WINETEST] Sync with Wine Staging 1.7.37. CORE-9246

svn path=/trunk/; revision=66465
This commit is contained in:
Amine Khaldi
2015-02-26 09:05:15 +00:00
parent 07f05e1c23
commit f63b100488
8 changed files with 972 additions and 165 deletions
+47
View File
@@ -1101,6 +1101,52 @@ static void test_comctl32_classes(void)
}
}
static void test_IME(void)
{
static const WCHAR ime_classW[] = {'I','M','E',0};
char module_name[MAX_PATH], *ptr;
MEMORY_BASIC_INFORMATION mbi;
WNDCLASSW wnd_classw;
WNDCLASSA wnd_class;
SIZE_T size;
BOOL ret;
if (!GetProcAddress(GetModuleHandleA("user32.dll"), "BroadcastSystemMessageExA"))
{
win_skip("BroadcastSystemMessageExA not available, skipping IME class test\n");
return;
}
ok(GetModuleHandleA("imm32") != 0, "imm32.dll is not loaded\n");
ret = GetClassInfoA(NULL, "IME", &wnd_class);
ok(ret, "GetClassInfo failed: %d\n", GetLastError());
size = VirtualQuery(wnd_class.lpfnWndProc, &mbi, sizeof(mbi));
ok(size == sizeof(mbi), "VirtualQuery returned %ld\n", size);
if (size == sizeof(mbi)) {
size = GetModuleFileNameA(mbi.AllocationBase, module_name, sizeof(module_name));
ok(size, "GetModuleFileName failed\n");
for (ptr = module_name+size-1; ptr > module_name; ptr--)
if (*ptr == '\\' || *ptr == '/') break;
if (*ptr == '\\' || *ptr=='/') ptr++;
ok(!lstrcmpiA(ptr, "user32.dll") || !lstrcmpiA(ptr, "ntdll.dll"), "IME window proc implemented in %s\n", ptr);
}
ret = GetClassInfoW(NULL, ime_classW, &wnd_classw);
ok(ret, "GetClassInfo failed: %d\n", GetLastError());
size = VirtualQuery(wnd_classw.lpfnWndProc, &mbi, sizeof(mbi));
ok(size == sizeof(mbi), "VirtualQuery returned %ld\n", size);
size = GetModuleFileNameA(mbi.AllocationBase, module_name, sizeof(module_name));
ok(size, "GetModuleFileName failed\n");
for (ptr = module_name+size-1; ptr > module_name; ptr--)
if (*ptr == '\\' || *ptr == '/') break;
if (*ptr == '\\' || *ptr=='/') ptr++;
ok(!lstrcmpiA(ptr, "user32.dll") || !lstrcmpiA(ptr, "ntdll.dll"), "IME window proc implemented in %s\n", ptr);
}
START_TEST(class)
{
char **argv;
@@ -1113,6 +1159,7 @@ START_TEST(class)
return;
}
test_IME();
test_GetClassInfo();
test_extra_values();
+48 -3
View File
@@ -33,7 +33,7 @@
#define DCX_USESTYLE 0x00010000
#endif
static HWND hwnd_cache, hwnd_owndc, hwnd_classdc, hwnd_classdc2;
static HWND hwnd_cache, hwnd_owndc, hwnd_classdc, hwnd_classdc2, hwnd_parent, hwnd_parentdc;
/* test behavior of DC attributes with various GetDC/ReleaseDC combinations */
static void test_dc_attributes(void)
@@ -190,7 +190,7 @@ static void test_dc_visrgn(void)
{
HDC old_hdc, hdc;
HRGN hrgn, hrgn2;
RECT rect;
RECT rect, parent_rect;
/* cache DC */
@@ -325,6 +325,20 @@ static void test_dc_visrgn(void)
ok( !(rect.left >= 20 && rect.top >= 20 && rect.right <= 30 && rect.bottom <= 30),
"clip box must have been reset %d,%d-%d,%d\n", rect.left, rect.top, rect.right, rect.bottom );
ReleaseDC( hwnd_classdc2, hdc );
/* parent DC */
hdc = GetDC( hwnd_parentdc );
GetClipBox( hdc, &rect );
ReleaseDC( hwnd_parentdc, hdc );
hdc = GetDC( hwnd_parent );
GetClipBox( hdc, &parent_rect );
ReleaseDC( hwnd_parent, hdc );
ok( rect.left == parent_rect.left, "rect.left = %d, expected %d\n", rect.left, parent_rect.left );
ok( rect.top == parent_rect.top, "rect.top = %d, expected %d\n", rect.top, parent_rect.top );
ok( rect.right == parent_rect.right, "rect.right = %d, expected %d\n", rect.right, parent_rect.right );
ok( rect.bottom == parent_rect.bottom, "rect.bottom = %d, expected %d\n", rect.bottom, parent_rect.bottom );
}
@@ -332,8 +346,9 @@ static void test_dc_visrgn(void)
static void test_begin_paint(void)
{
HDC old_hdc, hdc;
RECT rect;
RECT rect, parent_rect;
PAINTSTRUCT ps;
COLORREF cr;
/* cache DC */
@@ -405,6 +420,27 @@ static void test_begin_paint(void)
GetClipBox( hdc, &rect );
ok( !(rect.left >= 10 && rect.top >= 10 && rect.right <= 20 && rect.bottom <= 20),
"clip box should have been reset %d,%d-%d,%d\n", rect.left, rect.top, rect.right, rect.bottom );
ReleaseDC( hwnd_classdc2, hdc );
EndPaint( hwnd_classdc, &ps );
/* parent DC */
RedrawWindow( hwnd_parent, NULL, 0, RDW_VALIDATE|RDW_NOFRAME|RDW_NOERASE );
RedrawWindow( hwnd_parentdc, NULL, 0, RDW_INVALIDATE );
hdc = BeginPaint( hwnd_parentdc, &ps );
GetClipBox( hdc, &rect );
cr = SetPixel( hdc, 10, 10, RGB(255, 0, 0) );
ok( cr != -1, "error drawing outside of window client area\n" );
EndPaint( hwnd_parentdc, &ps );
GetClientRect( hwnd_parent, &parent_rect );
ok( rect.left == parent_rect.left, "rect.left = %d, expected %d\n", rect.left, parent_rect.left );
ok( rect.top == parent_rect.top, "rect.top = %d, expected %d\n", rect.top, parent_rect.top );
todo_wine ok( rect.right == parent_rect.right, "rect.right = %d, expected %d\n", rect.right, parent_rect.right );
todo_wine ok( rect.bottom == parent_rect.bottom, "rect.bottom = %d, expected %d\n", rect.bottom, parent_rect.bottom );
hdc = GetDC( hwnd_parent );
todo_wine ok( GetPixel( hdc, 10, 10 ) == cr, "error drawing outside of window client area\n" );
ReleaseDC( hwnd_parent, hdc );
}
/* test ScrollWindow with window DCs */
@@ -593,6 +629,9 @@ START_TEST(dce)
cls.style = CS_DBLCLKS | CS_CLASSDC;
cls.lpszClassName = "classdc_class";
RegisterClassA(&cls);
cls.style = CS_PARENTDC;
cls.lpszClassName = "parentdc_class";
RegisterClassA(&cls);
hwnd_cache = CreateWindowA("cache_class", NULL, WS_OVERLAPPED | WS_VISIBLE,
0, 0, 100, 100,
@@ -606,6 +645,11 @@ START_TEST(dce)
hwnd_classdc2 = CreateWindowA("classdc_class", NULL, WS_OVERLAPPED | WS_VISIBLE,
200, 200, 100, 100,
0, 0, GetModuleHandleA(0), NULL );
hwnd_parent = CreateWindowA("static", NULL, WS_OVERLAPPED | WS_VISIBLE,
400, 0, 100, 100, 0, 0, 0, NULL );
hwnd_parentdc = CreateWindowA("parentdc_class", NULL, WS_CHILD | WS_VISIBLE,
0, 0, 1, 1, hwnd_parent, 0, 0, NULL );
test_dc_attributes();
test_parameters();
test_dc_visrgn();
@@ -614,6 +658,7 @@ START_TEST(dce)
test_invisible_create();
test_dc_layout();
DestroyWindow(hwnd_parent);
DestroyWindow(hwnd_classdc2);
DestroyWindow(hwnd_classdc);
DestroyWindow(hwnd_owndc);
+1 -2
View File
@@ -776,7 +776,6 @@ static HDDEDATA CALLBACK server_ddeml_callback(UINT uType, UINT uFmt, HCONV hcon
else if (msg_index == 10)
{
DWORD rsize = 0;
size = 0;
size = DdeGetData(hdata, NULL, 0, 0);
ok(size == 17, "DdeGetData should have returned 17 not %d\n", size);
@@ -1591,7 +1590,7 @@ static void test_dde_aw_transaction( BOOL client_unicode, BOOL server_unicode )
info.cb = sizeof(info);
ret = DdeQueryConvInfo(hconv, QID_SYNC, &info);
ok(ret, "wrong info size %d, DdeQueryConvInfo error %x\n", ret, DdeGetLastError(dde_inst));
ok(info.ConvCtxt.iCodePage == client_unicode ? CP_WINUNICODE : CP_WINANSI,
ok(info.ConvCtxt.iCodePage == (client_unicode ? CP_WINUNICODE : CP_WINANSI),
"wrong iCodePage %d\n", info.ConvCtxt.iCodePage);
ok(!info.hConvPartner, "unexpected info.hConvPartner: %p\n", info.hConvPartner);
todo_wine {
+312 -1
View File
@@ -1361,7 +1361,7 @@ static void test_GetMouseMovePointsEx(void)
/* Get a valid content for the input struct */
if(!GetCursorPos(&point)) {
skip("GetCursorPos() failed with error %u\n", GetLastError());
win_skip("GetCursorPos() failed with error %u\n", GetLastError());
return;
}
memset(&in, 0, sizeof(MOUSEMOVEPOINT));
@@ -1595,6 +1595,14 @@ static void test_keyboard_layout_name(void)
BOOL ret;
char klid[KL_NAMELENGTH];
if (0) /* crashes on native system */
ret = GetKeyboardLayoutNameA(NULL);
SetLastError(0xdeadbeef);
ret = GetKeyboardLayoutNameW(NULL);
ok(!ret, "got %d\n", ret);
ok(GetLastError() == ERROR_NOACCESS, "got %d\n", GetLastError());
if (GetKeyboardLayout(0) != (HKL)(ULONG_PTR)0x04090409) return;
klid[0] = 0;
@@ -1643,6 +1651,308 @@ static void test_key_names(void)
ok( bufferW[0] == 0xcccc, "wrong string %s\n", wine_dbgstr_w(bufferW) );
}
static void simulate_click(BOOL left, int x, int y)
{
INPUT input[2];
UINT events_no;
SetCursorPos(x, y);
memset(input, 0, sizeof(input));
input[0].type = INPUT_MOUSE;
U(input[0]).mi.dx = x;
U(input[0]).mi.dy = y;
U(input[0]).mi.dwFlags = left ? MOUSEEVENTF_LEFTDOWN : MOUSEEVENTF_RIGHTDOWN;
input[1].type = INPUT_MOUSE;
U(input[1]).mi.dx = x;
U(input[1]).mi.dy = y;
U(input[1]).mi.dwFlags = left ? MOUSEEVENTF_LEFTUP : MOUSEEVENTF_RIGHTUP;
events_no = SendInput(2, input, sizeof(input[0]));
ok(events_no == 2, "SendInput returned %d\n", events_no);
}
static BOOL wait_for_message( MSG *msg )
{
BOOL ret;
for (;;)
{
ret = PeekMessageA(msg, 0, 0, 0, PM_REMOVE);
if (ret)
{
if (msg->message == WM_PAINT) DispatchMessageA(msg);
else break;
}
else if (MsgWaitForMultipleObjects(0, NULL, FALSE, 100, QS_ALLINPUT) == WAIT_TIMEOUT) break;
}
if (!ret) msg->message = 0;
return ret;
}
static BOOL wait_for_event(HANDLE event, int timeout)
{
DWORD end_time = GetTickCount() + timeout;
MSG msg;
do {
if(MsgWaitForMultipleObjects(1, &event, FALSE, timeout, QS_ALLINPUT) == WAIT_OBJECT_0)
return TRUE;
while(PeekMessageA(&msg, 0, 0, 0, PM_REMOVE))
DispatchMessageA(&msg);
timeout = end_time - GetTickCount();
}while(timeout > 0);
return FALSE;
}
static WNDPROC def_static_proc;
static DWORD hittest_no;
static LRESULT WINAPI static_hook_proc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
{
if (msg == WM_NCHITTEST)
{
/* break infinite hittest loop */
if(hittest_no > 50) return HTCLIENT;
hittest_no++;
}
return def_static_proc(hwnd, msg, wp, lp);
}
struct thread_data
{
HANDLE start_event;
HANDLE end_event;
HWND win;
};
static DWORD WINAPI create_static_win(void *arg)
{
struct thread_data *thread_data = arg;
HWND win;
win = CreateWindowA("static", "static", WS_VISIBLE | WS_POPUP,
100, 100, 100, 100, 0, NULL, NULL, NULL);
ok(win != 0, "CreateWindow failed\n");
def_static_proc = (void*)SetWindowLongPtrA(win,
GWLP_WNDPROC, (LONG_PTR)static_hook_proc);
thread_data->win = win;
SetEvent(thread_data->start_event);
wait_for_event(thread_data->end_event, 5000);
return 0;
}
static void test_Input_mouse(void)
{
BOOL got_button_down, got_button_up;
HWND hwnd, button_win, static_win;
struct thread_data thread_data;
HANDLE thread;
DWORD thread_id;
POINT pt;
MSG msg;
button_win = CreateWindowA("button", "button", WS_VISIBLE | WS_POPUP,
100, 100, 100, 100, 0, NULL, NULL, NULL);
ok(button_win != 0, "CreateWindow failed\n");
pt.x = pt.y = 150;
hwnd = WindowFromPoint(pt);
if (hwnd != button_win)
{
skip("there's another window covering test window\n");
DestroyWindow(button_win);
return;
}
/* simple button click test */
simulate_click(TRUE, 150, 150);
got_button_down = got_button_up = FALSE;
while (wait_for_message(&msg))
{
DispatchMessageA(&msg);
if (msg.message == WM_LBUTTONDOWN)
{
got_button_down = TRUE;
}
else if (msg.message == WM_LBUTTONUP)
{
got_button_up = TRUE;
break;
}
}
ok(got_button_down, "expected WM_LBUTTONDOWN message\n");
ok(got_button_up, "expected WM_LBUTTONUP message\n");
/* click through HTTRANSPARENT child window */
static_win = CreateWindowA("static", "static", WS_VISIBLE | WS_CHILD,
0, 0, 100, 100, button_win, NULL, NULL, NULL);
ok(static_win != 0, "CreateWindow failed\n");
def_static_proc = (void*)SetWindowLongPtrA(static_win,
GWLP_WNDPROC, (LONG_PTR)static_hook_proc);
simulate_click(FALSE, 150, 150);
hittest_no = 0;
got_button_down = got_button_up = FALSE;
while (wait_for_message(&msg))
{
DispatchMessageA(&msg);
if (msg.message == WM_RBUTTONDOWN)
{
ok(msg.hwnd == button_win, "msg.hwnd = %p\n", msg.hwnd);
got_button_down = TRUE;
}
else if (msg.message == WM_RBUTTONUP)
{
ok(msg.hwnd == button_win, "msg.hwnd = %p\n", msg.hwnd);
got_button_up = TRUE;
break;
}
}
ok(hittest_no && hittest_no<50, "expected WM_NCHITTEST message\n");
ok(got_button_down, "expected WM_RBUTTONDOWN message\n");
ok(got_button_up, "expected WM_RBUTTONUP message\n");
DestroyWindow(static_win);
/* click through HTTRANSPARENT top-level window */
static_win = CreateWindowA("static", "static", WS_VISIBLE | WS_POPUP,
100, 100, 100, 100, 0, NULL, NULL, NULL);
ok(static_win != 0, "CreateWindow failed\n");
def_static_proc = (void*)SetWindowLongPtrA(static_win,
GWLP_WNDPROC, (LONG_PTR)static_hook_proc);
simulate_click(TRUE, 150, 150);
hittest_no = 0;
got_button_down = got_button_up = FALSE;
while (wait_for_message(&msg))
{
DispatchMessageA(&msg);
if (msg.message == WM_LBUTTONDOWN)
{
ok(msg.hwnd == button_win, "msg.hwnd = %p\n", msg.hwnd);
got_button_down = TRUE;
}
else if (msg.message == WM_LBUTTONUP)
{
ok(msg.hwnd == button_win, "msg.hwnd = %p\n", msg.hwnd);
got_button_up = TRUE;
break;
}
}
ok(hittest_no && hittest_no<50, "expected WM_NCHITTEST message\n");
ok(got_button_down, "expected WM_LBUTTONDOWN message\n");
ok(got_button_up, "expected WM_LBUTTONUP message\n");
DestroyWindow(static_win);
/* click on HTTRANSPARENT top-level window that belongs to other thread */
thread_data.start_event = CreateEventA(NULL, FALSE, FALSE, NULL);
ok(thread_data.start_event != NULL, "CreateEvent failed\n");
thread_data.end_event = CreateEventA(NULL, FALSE, FALSE, NULL);
ok(thread_data.end_event != NULL, "CreateEvent failed\n");
thread = CreateThread(NULL, 0, create_static_win, &thread_data, 0, NULL);
ok(thread != NULL, "CreateThread failed\n");
hittest_no = 0;
got_button_down = got_button_up = FALSE;
WaitForSingleObject(thread_data.start_event, INFINITE);
simulate_click(FALSE, 150, 150);
while (wait_for_message(&msg))
{
DispatchMessageA(&msg);
if (msg.message == WM_RBUTTONDOWN)
got_button_down = TRUE;
else if (msg.message == WM_RBUTTONUP)
got_button_up = TRUE;
}
SetEvent(thread_data.end_event);
WaitForSingleObject(thread, INFINITE);
ok(hittest_no && hittest_no<50, "expected WM_NCHITTEST message\n");
ok(!got_button_down, "unexpected WM_RBUTTONDOWN message\n");
ok(!got_button_up, "unexpected WM_RBUTTONUP message\n");
/* click on HTTRANSPARENT top-level window that belongs to other thread,
* thread input queues are attached */
thread = CreateThread(NULL, 0, create_static_win, &thread_data, 0, &thread_id);
ok(thread != NULL, "CreateThread failed\n");
hittest_no = 0;
got_button_down = got_button_up = FALSE;
WaitForSingleObject(thread_data.start_event, INFINITE);
ok(AttachThreadInput(thread_id, GetCurrentThreadId(), TRUE),
"AttachThreadInput failed\n");
while (wait_for_message(&msg)) DispatchMessageA(&msg);
SetWindowPos(thread_data.win, button_win, 0, 0, 0, 0, SWP_NOSIZE|SWP_NOMOVE);
simulate_click(TRUE, 150, 150);
while (wait_for_message(&msg))
{
DispatchMessageA(&msg);
if (msg.message == WM_LBUTTONDOWN)
got_button_down = TRUE;
else if (msg.message == WM_LBUTTONUP)
got_button_up = TRUE;
}
SetEvent(thread_data.end_event);
WaitForSingleObject(thread, INFINITE);
todo_wine ok(hittest_no > 50, "expected loop with WM_NCHITTEST messages\n");
ok(!got_button_down, "unexpected WM_LBUTTONDOWN message\n");
ok(!got_button_up, "unexpected WM_LBUTTONUP message\n");
/* click after SetCapture call */
SetCapture(button_win);
got_button_down = got_button_up = FALSE;
simulate_click(FALSE, 50, 50);
while (wait_for_message(&msg))
{
DispatchMessageA(&msg);
if (msg.message == WM_RBUTTONDOWN)
{
ok(msg.hwnd == button_win, "msg.hwnd = %p\n", msg.hwnd);
got_button_down = TRUE;
}
else if (msg.message == WM_RBUTTONUP)
{
ok(msg.hwnd == button_win, "msg.hwnd = %p\n", msg.hwnd);
got_button_up = TRUE;
break;
}
}
ok(got_button_down, "expected WM_RBUTTONDOWN message\n");
ok(got_button_up, "expected WM_RBUTTONUP message\n");
/* click on child window after SetCapture call */
hwnd = CreateWindowA("button", "button2", WS_VISIBLE | WS_CHILD,
0, 0, 100, 100, button_win, NULL, NULL, NULL);
ok(hwnd != 0, "CreateWindow failed\n");
got_button_down = got_button_up = FALSE;
simulate_click(TRUE, 150, 150);
while (wait_for_message(&msg))
{
DispatchMessageA(&msg);
if (msg.message == WM_LBUTTONDOWN)
{
ok(msg.hwnd == button_win, "msg.hwnd = %p\n", msg.hwnd);
got_button_down = TRUE;
}
else if (msg.message == WM_LBUTTONUP)
{
ok(msg.hwnd == button_win, "msg.hwnd = %p\n", msg.hwnd);
got_button_up = TRUE;
break;
}
}
ok(got_button_down, "expected WM_LBUTTONDOWN message\n");
ok(got_button_up, "expected WM_LBUTTONUP message\n");
DestroyWindow(hwnd);
ok(ReleaseCapture(), "ReleaseCapture failed\n");
CloseHandle(thread_data.start_event);
CloseHandle(thread_data.end_event);
DestroyWindow(button_win);
}
START_TEST(input)
{
init_function_pointers();
@@ -1652,6 +1962,7 @@ START_TEST(input)
test_Input_blackbox();
test_Input_whitebox();
test_Input_unicode();
test_Input_mouse();
}
else win_skip("SendInput is not available\n");
+26
View File
@@ -2976,6 +2976,7 @@ static void test_menu_setmenuinfo(void)
MENUITEMINFOA mii = { sizeof(MENUITEMINFOA) };
BOOL ret;
DWORD gle;
HBRUSH brush;
if (!pGetMenuInfo || !pSetMenuInfo)
{
@@ -3091,6 +3092,31 @@ static void test_menu_setmenuinfo(void)
ok( ret, "GetMenuInfo() should have succeeded\n");
ok( gle == 0xdeadbeef, "GetMenuInfo() error got %u\n", gle);
ok( !(mi.dwStyle & MNS_NOCHECK), "menustyle was not expected to have the MNS_NOCHECK flag\n");
/* test background brush */
mi.cbSize = sizeof(mi);
mi.fMask = MIM_BACKGROUND;
ret = pGetMenuInfo( hmenu, &mi );
ok( ret, "GetMenuInfo() should have succeeded\n" );
ok( mi.hbrBack == NULL, "got %p\n", mi.hbrBack );
brush = CreateSolidBrush( RGB(0xff, 0, 0) );
mi.hbrBack = brush;
ret = pSetMenuInfo( hmenu, &mi );
ok( ret, "SetMenuInfo() should have succeeded\n" );
mi.hbrBack = NULL;
ret = pGetMenuInfo( hmenu, &mi );
ok( ret, "GetMenuInfo() should have succeeded\n" );
ok( mi.hbrBack == brush, "got %p original %p\n", mi.hbrBack, brush );
mi.hbrBack = NULL;
ret = pSetMenuInfo( hmenu, &mi );
ok( ret, "SetMenuInfo() should have succeeded\n" );
ret = pGetMenuInfo( hmenu, &mi );
ok( ret, "GetMenuInfo() should have succeeded\n" );
ok( mi.hbrBack == NULL, "got %p\n", mi.hbrBack );
DeleteObject( brush );
/* clean up */
DestroyMenu( hsubmenu);
DestroyMenu( hmenu);
+139 -127
View File
@@ -1172,51 +1172,6 @@ static const struct message WmDestroyInvisibleChildSeq[] = {
{ WM_NCDESTROY, sent },
{ 0 }
};
/* Moving the mouse in nonclient area */
static const struct message WmMouseMoveInNonClientAreaSeq[] = { /* FIXME: add */
{ WM_NCHITTEST, sent },
{ WM_SETCURSOR, sent },
{ WM_NCMOUSEMOVE, posted },
{ 0 }
};
/* Moving the mouse in client area */
static const struct message WmMouseMoveInClientAreaSeq[] = { /* FIXME: add */
{ WM_NCHITTEST, sent },
{ WM_SETCURSOR, sent },
{ WM_MOUSEMOVE, posted },
{ 0 }
};
/* Moving by dragging the title bar (after WM_NCHITTEST and WM_SETCURSOR) (outline move) */
static const struct message WmDragTitleBarSeq[] = { /* FIXME: add */
{ WM_NCLBUTTONDOWN, sent|wparam, HTCAPTION },
{ WM_SYSCOMMAND, sent|defwinproc|wparam, SC_MOVE+2 },
{ WM_GETMINMAXINFO, sent|defwinproc },
{ WM_ENTERSIZEMOVE, sent|defwinproc },
{ WM_WINDOWPOSCHANGING, sent|wparam|defwinproc, 0 },
{ WM_WINDOWPOSCHANGED, sent|wparam|defwinproc, 0 },
{ WM_MOVE, sent|defwinproc },
{ WM_EXITSIZEMOVE, sent|defwinproc },
{ 0 }
};
/* Sizing by dragging the thick borders (after WM_NCHITTEST and WM_SETCURSOR) (outline move) */
static const struct message WmDragThickBordersBarSeq[] = { /* FIXME: add */
{ WM_NCLBUTTONDOWN, sent|wparam, 0xd },
{ WM_SYSCOMMAND, sent|defwinproc|wparam, 0xf004 },
{ WM_GETMINMAXINFO, sent|defwinproc },
{ WM_ENTERSIZEMOVE, sent|defwinproc },
{ WM_SIZING, sent|defwinproc|wparam, 4}, /* one for each mouse movement */
{ WM_WINDOWPOSCHANGING, sent|wparam|defwinproc, 0 },
{ WM_GETMINMAXINFO, sent|defwinproc },
{ WM_NCCALCSIZE, sent|defwinproc|wparam, 1 },
{ WM_NCPAINT, sent|defwinproc|wparam, 1 },
{ WM_GETTEXT, sent|defwinproc },
{ WM_ERASEBKGND, sent|defwinproc },
{ WM_WINDOWPOSCHANGED, sent|wparam|defwinproc, 0 },
{ WM_MOVE, sent|defwinproc },
{ WM_SIZE, sent|defwinproc|wparam, SIZE_RESTORED },
{ WM_EXITSIZEMOVE, sent|defwinproc },
{ 0 }
};
/* Resizing child window with MoveWindow (32) */
static const struct message WmResizingChildWithMoveWindowSeq[] = {
{ WM_WINDOWPOSCHANGING, sent|wparam, SWP_NOACTIVATE },
@@ -1229,41 +1184,6 @@ static const struct message WmResizingChildWithMoveWindowSeq[] = {
{ EVENT_OBJECT_LOCATIONCHANGE, winevent_hook|wparam|lparam, 0, 0 },
{ 0 }
};
/* Clicking on inactive button */
static const struct message WmClickInactiveButtonSeq[] = { /* FIXME: add */
{ WM_NCHITTEST, sent },
{ WM_PARENTNOTIFY, sent|parent|wparam, WM_LBUTTONDOWN },
{ WM_MOUSEACTIVATE, sent },
{ WM_MOUSEACTIVATE, sent|parent|defwinproc },
{ WM_SETCURSOR, sent },
{ WM_SETCURSOR, sent|parent|defwinproc },
{ WM_LBUTTONDOWN, posted },
{ WM_KILLFOCUS, posted|parent },
{ WM_SETFOCUS, posted },
{ WM_CTLCOLORBTN, posted|parent },
{ BM_SETSTATE, posted },
{ WM_CTLCOLORBTN, posted|parent },
{ WM_LBUTTONUP, posted },
{ BM_SETSTATE, posted },
{ WM_CTLCOLORBTN, posted|parent },
{ WM_COMMAND, posted|parent },
{ 0 }
};
/* Reparenting a button (16/32) */
/* The last child (button) reparented gets topmost for its new parent. */
static const struct message WmReparentButtonSeq[] = { /* FIXME: add */
{ WM_SHOWWINDOW, sent|wparam, 0 },
{ WM_WINDOWPOSCHANGING, sent|wparam, SWP_HIDEWINDOW|SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOSIZE },
{ EVENT_OBJECT_HIDE, winevent_hook|wparam|lparam, 0, 0 },
{ WM_ERASEBKGND, sent|parent },
{ WM_WINDOWPOSCHANGED, sent|wparam, SWP_HIDEWINDOW|SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOSIZE },
{ WM_WINDOWPOSCHANGING, sent|wparam, SWP_NOSIZE },
{ WM_CHILDACTIVATE, sent },
{ WM_WINDOWPOSCHANGED, sent|wparam, SWP_NOSIZE|SWP_NOREDRAW },
{ WM_MOVE, sent|defwinproc },
{ WM_SHOWWINDOW, sent|wparam, 1 },
{ 0 }
};
/* Creation of a custom dialog (32) */
static const struct message WmCreateCustomDialogSeq[] = {
{ HCBT_CREATEWND, hook },
@@ -1464,35 +1384,6 @@ static const struct message WmModalDialogSeq[] = {
{ WM_NCDESTROY, sent },
{ 0 }
};
/* Creation of a modal dialog that is resized inside WM_INITDIALOG (32) */
static const struct message WmCreateModalDialogResizeSeq[] = { /* FIXME: add */
/* (inside dialog proc, handling WM_INITDIALOG) */
{ WM_WINDOWPOSCHANGING, sent|wparam, 0 },
{ WM_NCCALCSIZE, sent },
{ WM_NCACTIVATE, sent|parent|wparam, 0 },
{ WM_GETTEXT, sent|defwinproc },
{ WM_ACTIVATE, sent|parent|wparam, 0 },
{ WM_WINDOWPOSCHANGING, sent|wparam, 0 },
{ WM_WINDOWPOSCHANGING, sent|parent },
{ WM_NCACTIVATE, sent|wparam, 1 },
{ WM_ACTIVATE, sent|wparam, 1 },
{ WM_WINDOWPOSCHANGED, sent|wparam, 0 },
{ WM_SIZE, sent|defwinproc|wparam, SIZE_RESTORED },
/* (setting focus) */
{ WM_SHOWWINDOW, sent|wparam, 1 },
{ WM_WINDOWPOSCHANGING, sent|wparam, 0 },
{ WM_NCPAINT, sent },
{ WM_GETTEXT, sent|defwinproc },
{ WM_ERASEBKGND, sent },
{ WM_CTLCOLORDLG, sent|defwinproc },
{ WM_WINDOWPOSCHANGED, sent|wparam, 0 },
{ WM_PAINT, sent },
/* (bunch of WM_CTLCOLOR* for each control) */
{ WM_PAINT, sent|parent },
{ WM_ENTERIDLE, sent|parent|wparam, 0 },
{ WM_SETCURSOR, sent|parent },
{ 0 }
};
/* SetMenu for NonVisible windows with size change*/
static const struct message WmSetMenuNonVisibleSizeChangeSeq[] = {
{ WM_WINDOWPOSCHANGING, sent|wparam, SWP_FRAMECHANGED|SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOMOVE },
@@ -4542,6 +4433,11 @@ static const struct message WmZOrder[] = {
{ 0 }
};
static void CALLBACK apc_test_proc(ULONG_PTR param)
{
/* nothing */
}
static void test_MsgWaitForMultipleObjects(HWND hwnd)
{
DWORD ret;
@@ -4583,17 +4479,61 @@ static void test_MsgWaitForMultipleObjects(HWND hwnd)
ok(msg.message == WM_USER, "got %04x instead of WM_USER\n", msg.message);
ok(PeekMessageA( &msg, 0, 0, 0, PM_REMOVE ), "PeekMessage should succeed\n");
ok(msg.message == WM_USER, "got %04x instead of WM_USER\n", msg.message);
/* MWMO_INPUTAVAILABLE should succeed even if the message was already seen */
PostMessageA( hwnd, WM_USER, 0, 0 );
ok(PeekMessageA( &msg, 0, 0, 0, PM_NOREMOVE ), "PeekMessage should succeed\n");
ok(msg.message == WM_USER, "got %04x instead of WM_USER\n", msg.message);
ret = MsgWaitForMultipleObjectsEx( 0, NULL, 0, QS_POSTMESSAGE, MWMO_INPUTAVAILABLE );
ok(ret == WAIT_OBJECT_0, "MsgWaitForMultipleObjectsEx returned %x\n", ret);
ok(PeekMessageA( &msg, 0, 0, 0, PM_REMOVE ), "PeekMessage should succeed\n");
ok(msg.message == WM_USER, "got %04x instead of WM_USER\n", msg.message);
/* without MWMO_ALERTABLE the result is never WAIT_IO_COMPLETION */
ret = QueueUserAPC( apc_test_proc, GetCurrentThread(), 0 );
ok(ret, "QueueUserAPC failed %u\n", GetLastError());
ret = MsgWaitForMultipleObjectsEx( 0, NULL, 0, QS_POSTMESSAGE, 0 );
ok(ret == WAIT_TIMEOUT, "MsgWaitForMultipleObjectsEx returned %x\n", ret);
/* but even with MWMO_ALERTABLE window events are preferred */
PostMessageA( hwnd, WM_USER, 0, 0 );
ret = MsgWaitForMultipleObjectsEx( 0, NULL, 0, QS_POSTMESSAGE, MWMO_ALERTABLE );
ok(ret == WAIT_OBJECT_0, "MsgWaitForMultipleObjectsEx returned %x\n", ret);
ok(PeekMessageA( &msg, 0, 0, 0, PM_REMOVE ), "PeekMessage should succeed\n");
ok(msg.message == WM_USER, "got %04x instead of WM_USER\n", msg.message);
/* the APC call is still queued */
ret = MsgWaitForMultipleObjectsEx( 0, NULL, 0, QS_POSTMESSAGE, MWMO_ALERTABLE );
ok(ret == WAIT_IO_COMPLETION, "MsgWaitForMultipleObjectsEx returned %x\n", ret);
}
static DWORD CALLBACK show_window_thread(LPVOID arg)
{
HWND hwnd = arg;
/* function will not return if ShowWindow(SW_HIDE) calls SendMessage() */
ok(ShowWindow(hwnd, SW_HIDE) == FALSE, "ShowWindow(SW_HIDE) expected FALSE\n");
return 0;
}
/* test if we receive the right sequence of messages */
static void test_messages(void)
{
DWORD tid;
HANDLE hthread;
HWND hwnd, hparent, hchild;
HWND hchild2, hbutton;
HMENU hmenu;
MSG msg;
LRESULT res;
POINT pos;
BOOL ret;
flush_sequence();
@@ -4620,6 +4560,19 @@ static void test_messages(void)
flush_events();
ok_sequence(WmHideOverlappedSeq, "ShowWindow(SW_HIDE):overlapped", FALSE);
/* test ShowWindow(SW_HIDE) on a hidden window - single threaded */
ok(ShowWindow(hwnd, SW_HIDE) == FALSE, "ShowWindow(SW_HIDE) expected FALSE\n");
flush_events();
ok_sequence(WmEmptySeq, "ShowWindow(SW_HIDE):overlapped", FALSE);
/* test ShowWindow(SW_HIDE) on a hidden window - multi-threaded */
hthread = CreateThread(NULL, 0, show_window_thread, hwnd, 0, &tid);
ok(hthread != NULL, "CreateThread failed, error %d\n", GetLastError());
ok(WaitForSingleObject(hthread, INFINITE) == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
CloseHandle(hthread);
flush_events();
ok_sequence(WmEmptySeq, "ShowWindow(SW_HIDE):overlapped", FALSE);
ShowWindow(hwnd, SW_SHOW);
flush_events();
ok_sequence(WmShowOverlappedSeq, "ShowWindow(SW_SHOW):overlapped", TRUE);
@@ -4867,10 +4820,24 @@ static void test_messages(void)
flush_events();
flush_sequence();
ok(DrawMenuBar(hwnd), "DrawMenuBar failed: %d\n", GetLastError());
ret = DrawMenuBar(hwnd);
ok(ret, "DrawMenuBar failed: %d\n", GetLastError());
flush_events();
ok_sequence(WmDrawMenuBarSeq, "DrawMenuBar", FALSE);
ok(SetCursorPos(pos.x, pos.y), "SetCursorPos failed\n");
DestroyWindow(hwnd);
hwnd = CreateWindowExA(0, "TestDialogClass", NULL, WS_CHILD|WS_VISIBLE,
0, 0, 100, 100, hparent, 0, GetModuleHandleA(0), NULL);
ok(hwnd != 0, "Failed to create custom dialog window\n");
flush_events();
flush_sequence();
ret = DrawMenuBar(hwnd);
ok(ret, "DrawMenuBar failed: %d\n", GetLastError());
flush_events();
ok_sequence(WmEmptySeq, "DrawMenuBar for a child window", FALSE);
DestroyWindow(hwnd);
flush_sequence();
@@ -8400,6 +8367,13 @@ static void CALLBACK callback_count(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWOR
count++;
}
static DWORD exception;
static void CALLBACK callback_exception(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
{
count++;
RaiseException(exception, 0, 0, NULL);
}
static DWORD WINAPI timer_thread_proc(LPVOID x)
{
struct timer_info *info = x;
@@ -8530,6 +8504,41 @@ static void test_timers_no_wnd(void)
/* Note: SetSystemTimer doesn't support a NULL window, see test_timers */
}
static void test_timers_exception(DWORD code)
{
UINT_PTR id;
MSG msg;
exception = code;
id = SetTimer(NULL, 0, 1000, callback_exception);
ok(id != 0, "did not get id from SetTimer.\n");
memset(&msg, 0, sizeof(msg));
msg.message = WM_TIMER;
msg.wParam = id;
msg.lParam = (LPARAM)callback_exception;
count = 0;
DispatchMessageA(&msg);
ok(count == 1, "did not get one count as expected (%i).\n", count);
KillTimer(NULL, id);
}
static void test_timers_exceptions(void)
{
test_timers_exception(EXCEPTION_ACCESS_VIOLATION);
test_timers_exception(EXCEPTION_DATATYPE_MISALIGNMENT);
test_timers_exception(EXCEPTION_BREAKPOINT);
test_timers_exception(EXCEPTION_SINGLE_STEP);
test_timers_exception(EXCEPTION_ARRAY_BOUNDS_EXCEEDED);
test_timers_exception(EXCEPTION_FLT_DENORMAL_OPERAND);
test_timers_exception(EXCEPTION_FLT_DIVIDE_BY_ZERO);
test_timers_exception(EXCEPTION_FLT_INEXACT_RESULT);
test_timers_exception(EXCEPTION_ILLEGAL_INSTRUCTION);
test_timers_exception(0xE000BEEF); /* customer exception */
}
/* Various win events with arbitrary parameters */
static const struct message WmWinEventsSeq[] = {
{ EVENT_SYSTEM_SOUND, winevent_hook|wparam|lparam, OBJID_WINDOW, 0 },
@@ -10491,6 +10500,10 @@ static void test_quit_message(void)
flush_events();
PostQuitMessage(0xbeef);
msg.message = 0;
ret = PeekMessageA(&msg, 0, 0, 0, PM_QS_SENDMESSAGE);
ok(!ret, "got %x message\n", msg.message);
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);
@@ -13324,7 +13337,7 @@ static void test_WaitForInputIdle( char *argv0 )
{
ResetEvent( start_event );
ResetEvent( end_event );
#if 0
#ifndef __REACTOS__
sprintf( path, "%s msg %u", argv0, i );
#else
sprintf( path, "%s msg_queue %u", argv0, i );
@@ -13996,9 +14009,6 @@ static const struct message WmSetFocus_3[] = {
{ HCBT_SETFOCUS, hook }, /* child */
{ 0 }
};
static const struct message WmSetFocus_4[] = {
{ 0 }
};
static void test_SetFocus(void)
{
@@ -14487,7 +14497,7 @@ static void init_funcs(void)
#undef X
}
#if 0
#ifndef __REACTOS__
START_TEST(msg)
{
char **test_argv;
@@ -14576,6 +14586,7 @@ START_TEST(msg)
test_accelerators();
test_timers();
test_timers_no_wnd();
test_timers_exceptions();
if (hCBT_hook) test_set_hook();
test_DestroyWindow();
test_DispatchMessage();
@@ -14628,7 +14639,7 @@ START_TEST(msg)
}
DeleteCriticalSection( &sequence_cs );
}
#endif
#endif /* __REACTOS__ */
static void init_tests()
{
@@ -14662,12 +14673,12 @@ static void cleanup_tests()
UnhookWindowsHookEx(hCBT_hook);
if (pUnhookWinEvent && hEvent_hook)
{
ret = pUnhookWinEvent(hEvent_hook);
ok( ret, "UnhookWinEvent error %d\n", GetLastError());
SetLastError(0xdeadbeef);
ok(!pUnhookWinEvent(hEvent_hook), "UnhookWinEvent succeeded\n");
ok(GetLastError() == ERROR_INVALID_HANDLE || /* Win2k */
GetLastError() == 0xdeadbeef, /* Win9x */
ret = pUnhookWinEvent(hEvent_hook);
ok( ret, "UnhookWinEvent error %d\n", GetLastError());
SetLastError(0xdeadbeef);
ok(!pUnhookWinEvent(hEvent_hook), "UnhookWinEvent succeeded\n");
ok(GetLastError() == ERROR_INVALID_HANDLE || /* Win2k */
GetLastError() == 0xdeadbeef, /* Win9x */
"unexpected error %d\n", GetLastError());
}
DeleteCriticalSection( &sequence_cs );
@@ -14770,6 +14781,7 @@ START_TEST(msg_timer)
init_tests();
test_timers();
test_timers_no_wnd();
test_timers_exceptions();
cleanup_tests();
}
@@ -14790,11 +14802,11 @@ START_TEST(msg_hook)
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);
}
{
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" );
+398 -31
View File
@@ -63,6 +63,8 @@ static DWORD (WINAPI *pGetLayout)(HDC hdc);
static BOOL (WINAPI *pMirrorRgn)(HWND hwnd, HRGN hrgn);
static BOOL test_lbuttondown_flag;
static DWORD num_gettext_msgs;
static DWORD num_settext_msgs;
static HWND hwndMessage;
static HWND hwndMain, hwndMain2;
static HHOOK hhook;
@@ -103,6 +105,22 @@ static void flush_events( BOOL remove_messages )
}
}
static BOOL wait_for_event(HANDLE event, int timeout)
{
DWORD end_time = GetTickCount() + timeout;
MSG msg;
do {
if(MsgWaitForMultipleObjects(1, &event, FALSE, timeout, QS_ALLINPUT) == WAIT_OBJECT_0)
return TRUE;
while(PeekMessageA(&msg, 0, 0, 0, PM_REMOVE))
DispatchMessageA(&msg);
timeout = end_time - GetTickCount();
}while(timeout > 0);
return FALSE;
}
/* check the values returned by the various parent/owner functions on a given window */
static void check_parents( HWND hwnd, HWND ga_parent, HWND gwl_parent, HWND get_parent,
HWND gw_owner, HWND ga_root, HWND ga_root_owner )
@@ -778,6 +796,12 @@ static LRESULT WINAPI main_window_procA(HWND hwnd, UINT msg, WPARAM wparam, LPAR
flush_events( FALSE );
}
break;
case WM_GETTEXT:
num_gettext_msgs++;
break;
case WM_SETTEXT:
num_settext_msgs++;
break;
}
return DefWindowProcA(hwnd, msg, wparam, lparam);
@@ -5669,23 +5693,132 @@ static void test_ShowWindow(void)
ok(!IsWindow(hwnd), "window should not exist\n");
}
static DWORD CALLBACK gettext_msg_thread( LPVOID arg )
{
HWND hwnd = arg;
char buf[32];
INT buf_len;
/* test GetWindowTextA */
num_gettext_msgs = 0;
memset( buf, 0, sizeof(buf) );
buf_len = GetWindowTextA( hwnd, buf, sizeof(buf) );
ok( buf_len != 0, "expected a nonempty window text\n" );
ok( !strcmp(buf, "another_caption"), "got wrong window text '%s'\n", buf );
ok( num_gettext_msgs == 1, "got %u WM_GETTEXT messages\n", num_gettext_msgs );
return 0;
}
static DWORD CALLBACK settext_msg_thread( LPVOID arg )
{
HWND hwnd = arg;
BOOL success;
/* test SetWindowTextA */
num_settext_msgs = 0;
success = SetWindowTextA( hwnd, "thread_caption" );
ok( success, "SetWindowTextA failed\n" );
ok( num_settext_msgs == 1, "got %u WM_SETTEXT messages\n", num_settext_msgs );
return 0;
}
static void test_gettext(void)
{
WNDCLASSA cls;
LPCSTR clsname = "gettexttest";
DWORD tid, num_msgs;
HANDLE thread;
BOOL success;
char buf[32];
INT buf_len;
HWND hwnd;
LRESULT r;
MSG msg;
memset( &cls, 0, sizeof cls );
cls.lpfnWndProc = DefWindowProcA;
cls.lpszClassName = clsname;
cls.hInstance = GetModuleHandleA(NULL);
hwnd = CreateWindowExA( 0, "MainWindowClass", "caption", WS_POPUP, 0, 0, 0, 0, 0, 0, 0, NULL );
ok( hwnd != 0, "CreateWindowExA error %d\n", GetLastError() );
if (!RegisterClassA( &cls )) return;
/* test GetWindowTextA */
num_gettext_msgs = 0;
memset( buf, 0, sizeof(buf) );
buf_len = GetWindowTextA( hwnd, buf, sizeof(buf) );
ok( buf_len != 0, "expected a nonempty window text\n" );
ok( !strcmp(buf, "caption"), "got wrong window text '%s'\n", buf );
ok( num_gettext_msgs == 1, "got %u WM_GETTEXT messages\n", num_gettext_msgs );
hwnd = CreateWindowA( clsname, "test text", WS_OVERLAPPED, 0, 0, 10, 10, 0, NULL, NULL, NULL);
ok( hwnd != NULL, "window was null\n");
/* test WM_GETTEXT */
num_gettext_msgs = 0;
memset( buf, 0, sizeof(buf) );
r = SendMessageA( hwnd, WM_GETTEXT, sizeof(buf), (LONG_PTR)buf );
ok( r != 0, "expected a nonempty window text\n" );
ok( !strcmp(buf, "caption"), "got wrong window text '%s'\n", buf );
ok( num_gettext_msgs == 1, "got %u WM_GETTEXT messages\n", num_gettext_msgs );
/* test SetWindowTextA */
num_settext_msgs = 0;
success = SetWindowTextA( hwnd, "new_caption" );
ok( success, "SetWindowTextA failed\n" );
ok( num_settext_msgs == 1, "got %u WM_SETTEXT messages\n", num_settext_msgs );
num_gettext_msgs = 0;
memset( buf, 0, sizeof(buf) );
buf_len = GetWindowTextA( hwnd, buf, sizeof(buf) );
ok( buf_len != 0, "expected a nonempty window text\n" );
ok( !strcmp(buf, "new_caption"), "got wrong window text '%s'\n", buf );
ok( num_gettext_msgs == 1, "got %u WM_GETTEXT messages\n", num_gettext_msgs );
/* test WM_SETTEXT */
num_settext_msgs = 0;
r = SendMessageA( hwnd, WM_SETTEXT, 0, (ULONG_PTR)"another_caption" );
ok( r != 0, "WM_SETTEXT failed\n" );
ok( num_settext_msgs == 1, "got %u WM_SETTEXT messages\n", num_settext_msgs );
num_gettext_msgs = 0;
memset( buf, 0, sizeof(buf) );
buf_len = GetWindowTextA( hwnd, buf, sizeof(buf) );
ok( buf_len != 0, "expected a nonempty window text\n" );
ok( !strcmp(buf, "another_caption"), "got wrong window text '%s'\n", buf );
ok( num_gettext_msgs == 1, "got %u WM_GETTEXT messages\n", num_gettext_msgs );
while (PeekMessageA( &msg, 0, 0, 0, PM_REMOVE | PM_QS_SENDMESSAGE ))
DispatchMessageA( &msg );
/* test interthread GetWindowTextA */
num_msgs = 0;
thread = CreateThread( NULL, 0, gettext_msg_thread, hwnd, 0, &tid );
ok(thread != NULL, "CreateThread failed, error %d\n", GetLastError());
while (MsgWaitForMultipleObjects( 1, &thread, FALSE, INFINITE, QS_SENDMESSAGE ) != WAIT_OBJECT_0)
{
while (PeekMessageA( &msg, 0, 0, 0, PM_REMOVE | PM_QS_SENDMESSAGE ))
DispatchMessageA( &msg );
num_msgs++;
}
CloseHandle( thread );
ok( num_msgs == 1, "got %u wakeups from MsgWaitForMultipleObjects\n", num_msgs );
/* test interthread SetWindowText */
num_msgs = 0;
thread = CreateThread( NULL, 0, settext_msg_thread, hwnd, 0, &tid );
ok(thread != NULL, "CreateThread failed, error %d\n", GetLastError());
while (MsgWaitForMultipleObjects( 1, &thread, FALSE, INFINITE, QS_SENDMESSAGE ) != WAIT_OBJECT_0)
{
while (PeekMessageA( &msg, 0, 0, 0, PM_REMOVE | PM_QS_SENDMESSAGE ))
DispatchMessageA( &msg );
num_msgs++;
}
CloseHandle( thread );
ok( num_msgs == 1, "got %u wakeups from MsgWaitForMultipleObjects\n", num_msgs );
num_gettext_msgs = 0;
memset( buf, 0, sizeof(buf) );
buf_len = GetWindowTextA( hwnd, buf, sizeof(buf) );
ok( buf_len != 0, "expected a nonempty window text\n" );
ok( !strcmp(buf, "thread_caption"), "got wrong window text '%s'\n", buf );
ok( num_gettext_msgs == 1, "got %u WM_GETTEXT messages\n", num_gettext_msgs );
/* seems to crash on every modern Windows version */
if (0)
{
r = SendMessageA( hwnd, WM_GETTEXT, 0x10, 0x1000);
ok( r == 0, "settext should return zero\n");
@@ -5697,9 +5830,9 @@ static void test_gettext(void)
r = SendMessageA( hwnd, WM_GETTEXT, 0x1000, 0xff000000);
ok( r == 0, "settext should return zero (%ld)\n", r);
}
DestroyWindow(hwnd);
UnregisterClassA( clsname, NULL );
}
@@ -6915,32 +7048,44 @@ todo_wine
static void test_FindWindowEx(void)
{
HWND hwnd, found;
CHAR title[1];
hwnd = CreateWindowExA( 0, "MainWindowClass", "caption", WS_POPUP, 0,0,0,0, 0, 0, 0, NULL );
ok( hwnd != 0, "CreateWindowExA error %d\n", GetLastError() );
title[0] = 0;
found = FindWindowExA( 0, 0, "MainWindowClass", title );
num_gettext_msgs = 0;
found = FindWindowExA( 0, 0, "MainWindowClass", "" );
ok( found == NULL, "expected a NULL hwnd\n" );
ok( num_gettext_msgs == 0, "got %u WM_GETTEXT messages\n", num_gettext_msgs );
num_gettext_msgs = 0;
found = FindWindowExA( 0, 0, "MainWindowClass", NULL );
ok( found == hwnd, "found is %p, expected a valid hwnd\n", found );
ok( num_gettext_msgs == 0, "got %u WM_GETTEXT messages\n", num_gettext_msgs );
num_gettext_msgs = 0;
found = FindWindowExA( 0, 0, "MainWindowClass", "caption" );
ok( found == hwnd, "found is %p, expected a valid hwnd\n", found );
ok( num_gettext_msgs == 0, "got %u WM_GETTEXT messages\n", num_gettext_msgs );
DestroyWindow( hwnd );
hwnd = CreateWindowExA( 0, "MainWindowClass", NULL, WS_POPUP, 0,0,0,0, 0, 0, 0, NULL );
ok( hwnd != 0, "CreateWindowExA error %d\n", GetLastError() );
found = FindWindowExA( 0, 0, "MainWindowClass", title );
num_gettext_msgs = 0;
found = FindWindowExA( 0, 0, "MainWindowClass", "" );
ok( found == hwnd, "found is %p, expected a valid hwnd\n", found );
ok( num_gettext_msgs == 0, "got %u WM_GETTEXT messages\n", num_gettext_msgs );
num_gettext_msgs = 0;
found = FindWindowExA( 0, 0, "MainWindowClass", NULL );
ok( found == hwnd, "found is %p, expected a valid hwnd\n", found );
ok( num_gettext_msgs == 0, "got %u WM_GETTEXT messages\n", num_gettext_msgs );
DestroyWindow( hwnd );
/* test behaviour with a window title that is an empty character */
found = FindWindowExA( 0, 0, "Shell_TrayWnd", title );
found = FindWindowExA( 0, 0, "Shell_TrayWnd", "" );
ok( found != NULL, "found is NULL, expected a valid hwnd\n" );
found = FindWindowExA( 0, 0, "Shell_TrayWnd", NULL );
ok( found != NULL, "found is NULL, expected a valid hwnd\n" );
@@ -7200,6 +7345,167 @@ todo_wine
ok(ret, "UnregisterClass(my_window) failed\n");
}
static void simulate_click(int x, int y)
{
INPUT input[2];
UINT events_no;
SetCursorPos(x, y);
memset(input, 0, sizeof(input));
input[0].type = INPUT_MOUSE;
U(input[0]).mi.dx = x;
U(input[0]).mi.dy = y;
U(input[0]).mi.dwFlags = MOUSEEVENTF_LEFTDOWN;
input[1].type = INPUT_MOUSE;
U(input[1]).mi.dx = x;
U(input[1]).mi.dy = y;
U(input[1]).mi.dwFlags = MOUSEEVENTF_LEFTUP;
events_no = SendInput(2, input, sizeof(input[0]));
ok(events_no == 2, "SendInput returned %d\n", events_no);
}
static WNDPROC def_static_proc;
static BOOL got_hittest;
static LRESULT WINAPI static_hook_proc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
{
if(msg == WM_NCHITTEST)
got_hittest = TRUE;
if(msg == WM_LBUTTONDOWN)
ok(0, "unexpected call\n");
return def_static_proc(hwnd, msg, wp, lp);
}
static void window_from_point_proc(HWND parent)
{
HANDLE start_event, end_event;
HANDLE win, child_static, child_button;
BOOL got_click;
DWORD ret;
POINT pt;
MSG msg;
start_event = OpenEventA(EVENT_ALL_ACCESS, FALSE, "test_wfp_start");
ok(start_event != 0, "OpenEvent failed\n");
end_event = OpenEventA(EVENT_ALL_ACCESS, FALSE, "test_wfp_end");
ok(end_event != 0, "OpenEvent failed\n");
child_static = CreateWindowExA(0, "static", "static", WS_CHILD | WS_VISIBLE,
0, 0, 100, 100, parent, 0, NULL, NULL);
ok(child_static != 0, "CreateWindowEx failed\n");
pt.x = pt.y = 150;
win = WindowFromPoint(pt);
ok(win == parent, "WindowFromPoint returned %p, expected %p\n", win, parent);
child_button = CreateWindowExA(0, "button", "button", WS_CHILD | WS_VISIBLE,
100, 0, 100, 100, parent, 0, NULL, NULL);
ok(child_button != 0, "CreateWindowEx failed\n");
pt.x = 250;
win = WindowFromPoint(pt);
ok(win == child_button, "WindowFromPoint returned %p, expected %p\n", win, child_button);
/* without this window simulate click test keeps sending WM_NCHITTEST
* message to child_static in an infinite loop */
win = CreateWindowExA(0, "button", "button", WS_CHILD | WS_VISIBLE,
0, 0, 100, 100, parent, 0, NULL, NULL);
ok(win != 0, "CreateWindowEx failed\n");
def_static_proc = (void*)SetWindowLongPtrA(child_static,
GWLP_WNDPROC, (LONG_PTR)static_hook_proc);
flush_events(TRUE);
SetEvent(start_event);
got_hittest = FALSE;
got_click = FALSE;
while(!got_click && wait_for_message(&msg)) {
if(msg.message == WM_LBUTTONUP) {
ok(msg.hwnd == win, "msg.hwnd = %p, expected %p\n", msg.hwnd, win);
got_click = TRUE;
}
DispatchMessageA(&msg);
}
ok(got_hittest, "transparent window didn't get WM_NCHITTEST message\n");
ok(got_click, "button under static window didn't get WM_LBUTTONUP\n");
ret = WaitForSingleObject(end_event, 5000);
ok(ret == WAIT_OBJECT_0, "WaitForSingleObject returned %x\n", ret);
CloseHandle(start_event);
CloseHandle(end_event);
}
static void test_window_from_point(const char *argv0)
{
HWND hwnd, child, win;
POINT pt;
PROCESS_INFORMATION info;
STARTUPINFOA startup;
char cmd[MAX_PATH];
HANDLE start_event, end_event;
hwnd = CreateWindowExA(0, "MainWindowClass", NULL, WS_POPUP | WS_VISIBLE,
100, 100, 200, 100, 0, 0, NULL, NULL);
ok(hwnd != 0, "CreateWindowEx failed\n");
pt.x = pt.y = 150;
win = WindowFromPoint(pt);
pt.x = 250;
if(win == hwnd)
win = WindowFromPoint(pt);
if(win != hwnd) {
skip("there's another window covering test window\n");
DestroyWindow(hwnd);
return;
}
child = CreateWindowExA(0, "static", "static", WS_CHILD | WS_VISIBLE,
0, 0, 100, 100, hwnd, 0, NULL, NULL);
ok(child != 0, "CreateWindowEx failed\n");
pt.x = pt.y = 150;
win = WindowFromPoint(pt);
ok(win == hwnd, "WindowFromPoint returned %p, expected %p\n", win, hwnd);
DestroyWindow(child);
child = CreateWindowExA(0, "button", "button", WS_CHILD | WS_VISIBLE,
0, 0, 100, 100, hwnd, 0, NULL, NULL);
ok(child != 0, "CreateWindowEx failed\n");
win = WindowFromPoint(pt);
ok(win == child, "WindowFromPoint returned %p, expected %p\n", win, child);
DestroyWindow(child);
start_event = CreateEventA(NULL, FALSE, FALSE, "test_wfp_start");
ok(start_event != 0, "CreateEvent failed\n");
end_event = CreateEventA(NULL, FALSE, FALSE, "test_wfp_end");
ok(start_event != 0, "CreateEvent failed\n");
sprintf(cmd, "%s win create_children %p\n", argv0, hwnd);
memset(&startup, 0, sizeof(startup));
startup.cb = sizeof(startup);
ok(CreateProcessA(NULL, cmd, NULL, NULL, FALSE, 0, NULL, NULL,
&startup, &info), "CreateProcess failed.\n");
ok(wait_for_event(start_event, 1000), "didn't get start_event\n");
child = GetWindow(hwnd, GW_CHILD);
win = WindowFromPoint(pt);
ok(win == child, "WindowFromPoint returned %p, expected %p\n", win, child);
simulate_click(150, 150);
flush_events(TRUE);
child = GetWindow(child, GW_HWNDNEXT);
pt.x = 250;
win = WindowFromPoint(pt);
ok(win == child, "WindowFromPoint returned %p, expected %p\n", win, child);
SetEvent(end_event);
winetest_wait_child_process(info.hProcess);
CloseHandle(start_event);
CloseHandle(end_event);
CloseHandle(info.hProcess);
CloseHandle(info.hThread);
DestroyWindow(hwnd);
}
static void test_map_points(void)
{
BOOL ret;
@@ -7673,8 +7979,71 @@ static void test_smresult(void)
CloseHandle(data.thread_replied);
}
static void test_GetMessagePos(void)
{
HWND button;
DWORD pos;
MSG msg;
button = CreateWindowExA(0, "button", "button", WS_VISIBLE,
100, 100, 100, 100, 0, 0, 0, NULL);
ok(button != 0, "CreateWindowExA failed\n");
SetCursorPos(120, 140);
flush_events(TRUE);
pos = GetMessagePos();
ok(pos == MAKELONG(120, 140), "pos = %08x\n", pos);
SetCursorPos(340, 320);
pos = GetMessagePos();
ok(pos == MAKELONG(120, 140), "pos = %08x\n", pos);
SendMessageW(button, WM_APP, 0, 0);
pos = GetMessagePos();
ok(pos == MAKELONG(120, 140), "pos = %08x\n", pos);
PostMessageA(button, WM_APP, 0, 0);
GetMessageA(&msg, button, 0, 0);
ok(msg.message == WM_APP, "msg.message = %x\n", msg.message);
pos = GetMessagePos();
todo_wine ok(pos == MAKELONG(340, 320), "pos = %08x\n", pos);
PostMessageA(button, WM_APP, 0, 0);
SetCursorPos(350, 330);
GetMessageA(&msg, button, 0, 0);
ok(msg.message == WM_APP, "msg.message = %x\n", msg.message);
pos = GetMessagePos();
todo_wine ok(pos == MAKELONG(340, 320), "pos = %08x\n", pos);
PostMessageA(button, WM_APP, 0, 0);
SetCursorPos(320, 340);
PostMessageA(button, WM_APP+1, 0, 0);
pos = GetMessagePos();
todo_wine ok(pos == MAKELONG(340, 320), "pos = %08x\n", pos);
GetMessageA(&msg, button, 0, 0);
ok(msg.message == WM_APP, "msg.message = %x\n", msg.message);
pos = GetMessagePos();
todo_wine ok(pos == MAKELONG(350, 330), "pos = %08x\n", pos);
GetMessageA(&msg, button, 0, 0);
ok(msg.message == WM_APP+1, "msg.message = %x\n", msg.message);
pos = GetMessagePos();
todo_wine ok(pos == MAKELONG(320, 340), "pos = %08x\n", pos);
SetTimer(button, 1, 250, NULL);
SetCursorPos(330, 350);
GetMessageA(&msg, button, 0, 0);
ok(msg.message == WM_TIMER, "msg.message = %x\n", msg.message);
pos = GetMessagePos();
todo_wine ok(pos == MAKELONG(330, 350), "pos = %08x\n", pos);
KillTimer(button, 1);
DestroyWindow(button);
}
START_TEST(win)
{
char **argv;
int argc = winetest_get_mainargs( &argv );
HMODULE user32 = GetModuleHandleA( "user32.dll" );
HMODULE gdi32 = GetModuleHandleA("gdi32.dll");
pGetAncestor = (void *)GetProcAddress( user32, "GetAncestor" );
@@ -7695,6 +8064,15 @@ START_TEST(win)
pSetLayout = (void *)GetProcAddress( gdi32, "SetLayout" );
pMirrorRgn = (void *)GetProcAddress( gdi32, "MirrorRgn" );
if (argc==4 && !strcmp(argv[2], "create_children"))
{
HWND hwnd;
sscanf(argv[3], "%p", &hwnd);
window_from_point_proc(hwnd);
return;
}
if (!RegisterWindowClasses()) assert(0);
hwndMain = CreateWindowExA(/*WS_EX_TOOLWINDOW*/ 0, "MainWindowClass", "Main window",
@@ -7706,20 +8084,7 @@ START_TEST(win)
if(!SetForegroundWindow(hwndMain)) {
/* workaround for foreground lock timeout */
INPUT input[2];
UINT events_no;
memset(input, 0, sizeof(input));
input[0].type = INPUT_MOUSE;
U(input[0]).mi.dx = 101;
U(input[0]).mi.dy = 101;
U(input[0]).mi.dwFlags = MOUSEEVENTF_LEFTDOWN;
input[0].type = INPUT_MOUSE;
U(input[0]).mi.dx = 101;
U(input[0]).mi.dy = 101;
U(input[0]).mi.dwFlags = MOUSEEVENTF_LEFTUP;
events_no = SendInput(2, input, sizeof(input[0]));
ok(events_no == 2, "SendInput returned %d\n", events_no);
simulate_click(101, 101);
ok(SetForegroundWindow(hwndMain), "SetForegroundWindow failed\n");
}
@@ -7745,6 +8110,7 @@ START_TEST(win)
/* Add the tests below this line */
test_child_window_from_point();
test_window_from_point(argv[0]);
test_thick_child_size(hwndMain);
test_fullscreen();
test_hwnd_message();
@@ -7792,7 +8158,7 @@ START_TEST(win)
test_csparentdc();
test_SetWindowLong();
test_ShowWindow();
if (0) test_gettext(); /* crashes on NT4 */
test_gettext();
test_GetUpdateRect();
test_Expose();
test_layered_window();
@@ -7805,6 +8171,7 @@ START_TEST(win)
test_update_region();
test_window_without_child_style();
test_smresult();
test_GetMessagePos();
/* add the tests above this line */
if (hhook) UnhookWindowsHookEx(hhook);
+1 -1
View File
@@ -932,7 +932,7 @@ START_TEST(winstation)
GetProcessWindowStation();
if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
{
skip("WindowStation calls not supported on this platform\n");
win_skip("WindowStation calls not supported on this platform\n");
return;
}