shell32/tests: Accept delays in getting ABN_POSCHANGED notifications.

This commit is contained in:
Vincent Povirk 2008-09-21 18:35:25 -05:00 committed by Alexandre Julliard
parent 0362ee3d16
commit d042d5ab28
1 changed files with 164 additions and 145 deletions

View File

@ -30,13 +30,21 @@ static const CHAR testwindow_class[] = "testwindow";
static HMONITOR (WINAPI *pMonitorFromWindow)(HWND, DWORD); static HMONITOR (WINAPI *pMonitorFromWindow)(HWND, DWORD);
typedef BOOL (*boolean_function)(void);
struct testwindow_info struct testwindow_info
{ {
HWND hwnd;
BOOL registered;
RECT desired_rect; RECT desired_rect;
UINT edge; UINT edge;
RECT allocated_rect; RECT allocated_rect;
}; };
static struct testwindow_info windows[3];
static int expected_bottom;
static void testwindow_setpos(HWND hwnd) static void testwindow_setpos(HWND hwnd)
{ {
struct testwindow_info* info = (struct testwindow_info*)GetWindowLongPtr(hwnd, GWLP_USERDATA); struct testwindow_info* info = (struct testwindow_info*)GetWindowLongPtr(hwnd, GWLP_USERDATA);
@ -45,7 +53,7 @@ static void testwindow_setpos(HWND hwnd)
ok(info != NULL, "got unexpected ABN_POSCHANGED notification\n"); ok(info != NULL, "got unexpected ABN_POSCHANGED notification\n");
if (!info) if (!info || !info->registered)
{ {
return; return;
} }
@ -102,6 +110,32 @@ static LRESULT CALLBACK testwindow_wndproc(HWND hwnd, UINT msg, WPARAM wparam, L
return DefWindowProc(hwnd, msg, wparam, lparam); return DefWindowProc(hwnd, msg, wparam, lparam);
} }
/* process pending messages until a condition is true or 3 seconds pass */
static void do_events_until(boolean_function test)
{
MSG msg;
UINT_PTR timerid;
BOOL timedout=FALSE;
timerid = SetTimer(0, 0, 3000, NULL);
while (1)
{
while (PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE))
{
if (msg.hwnd == 0 && msg.message == WM_TIMER && msg.wParam == timerid)
timedout = TRUE;
TranslateMessage(&msg);
DispatchMessageA(&msg);
}
if (timedout || test())
break;
WaitMessage();
}
KillTimer(0, timerid);
}
/* process any pending messages */ /* process any pending messages */
static void do_events(void) static void do_events(void)
{ {
@ -114,6 +148,28 @@ static void do_events(void)
} }
} }
static BOOL no_appbars_intersect(void)
{
int i, j;
RECT rc;
for (i=0; i<2; i++)
{
for (j=i+1; j<3; j++)
{
if (windows[i].registered && windows[j].registered &&
IntersectRect(&rc, &windows[i].allocated_rect, &windows[j].allocated_rect))
return FALSE;
}
}
return TRUE;
}
static BOOL got_expected_bottom(void)
{
return (no_appbars_intersect() && windows[1].allocated_rect.bottom == expected_bottom);
}
static void register_testwindow_class(void) static void register_testwindow_class(void)
{ {
WNDCLASSEXA cls; WNDCLASSEXA cls;
@ -130,26 +186,30 @@ static void register_testwindow_class(void)
RegisterClassExA(&cls); RegisterClassExA(&cls);
} }
#define test_window_rects(a, b) \
ok(!IntersectRect(&rc, &windows[a].allocated_rect, &windows[b].allocated_rect), \
"rectangles intersect (%i,%i,%i,%i)/(%i,%i,%i,%i)\n", \
windows[a].allocated_rect.left, windows[a].allocated_rect.top, windows[a].allocated_rect.right, windows[a].allocated_rect.bottom, \
windows[b].allocated_rect.left, windows[b].allocated_rect.top, windows[b].allocated_rect.right, windows[b].allocated_rect.bottom)
static void test_setpos(void) static void test_setpos(void)
{ {
APPBARDATA abd; APPBARDATA abd;
RECT rc; RECT rc;
int screen_width, screen_height, expected; int screen_width, screen_height;
HWND window1, window2, window3;
struct testwindow_info window1_info, window2_info, window3_info;
BOOL ret; BOOL ret;
screen_width = GetSystemMetrics(SM_CXSCREEN); screen_width = GetSystemMetrics(SM_CXSCREEN);
screen_height = GetSystemMetrics(SM_CYSCREEN); screen_height = GetSystemMetrics(SM_CYSCREEN);
/* create and register window1 */ /* create and register windows[0] */
window1 = CreateWindowExA(WS_EX_TOOLWINDOW|WS_EX_TOPMOST, windows[0].hwnd = CreateWindowExA(WS_EX_TOOLWINDOW|WS_EX_TOPMOST,
testwindow_class, testwindow_class, WS_POPUP|WS_VISIBLE, 0, 0, 0, 0, testwindow_class, testwindow_class, WS_POPUP|WS_VISIBLE, 0, 0, 0, 0,
NULL, NULL, NULL, NULL); NULL, NULL, NULL, NULL);
ok(window1 != NULL, "couldn't create window\n"); ok(windows[0].hwnd != NULL, "couldn't create window\n");
do_events(); do_events();
abd.cbSize = sizeof(abd); abd.cbSize = sizeof(abd);
abd.hWnd = window1; abd.hWnd = windows[0].hwnd;
abd.uCallbackMessage = MSG_APPBAR; abd.uCallbackMessage = MSG_APPBAR;
ret = SHAppBarMessage(ABM_NEW, &abd); ret = SHAppBarMessage(ABM_NEW, &abd);
ok(ret == TRUE, "SHAppBarMessage returned %i\n", ret); ok(ret == TRUE, "SHAppBarMessage returned %i\n", ret);
@ -159,181 +219,140 @@ static void test_setpos(void)
ok(ret == FALSE, "SHAppBarMessage returned %i\n", ret); ok(ret == FALSE, "SHAppBarMessage returned %i\n", ret);
do_events(); do_events();
/* dock window1 to the bottom of the screen */ /* dock windows[0] to the bottom of the screen */
window1_info.edge = ABE_BOTTOM; windows[0].registered = TRUE;
window1_info.desired_rect.left = 0; windows[0].edge = ABE_BOTTOM;
window1_info.desired_rect.right = screen_width; windows[0].desired_rect.left = 0;
window1_info.desired_rect.top = screen_height - 15; windows[0].desired_rect.right = screen_width;
window1_info.desired_rect.bottom = screen_height; windows[0].desired_rect.top = screen_height - 15;
SetWindowLongPtr(window1, GWLP_USERDATA, (LONG_PTR)&window1_info); windows[0].desired_rect.bottom = screen_height;
testwindow_setpos(window1); SetWindowLongPtr(windows[0].hwnd, GWLP_USERDATA, (LONG_PTR)&windows[0]);
testwindow_setpos(windows[0].hwnd);
do_events(); do_events();
/* create and register window2 */ /* create and register windows[1] */
window2 = CreateWindowExA(WS_EX_TOOLWINDOW|WS_EX_TOPMOST, windows[1].hwnd = CreateWindowExA(WS_EX_TOOLWINDOW|WS_EX_TOPMOST,
testwindow_class, testwindow_class, WS_POPUP|WS_VISIBLE, 0, 0, 0, 0, testwindow_class, testwindow_class, WS_POPUP|WS_VISIBLE, 0, 0, 0, 0,
NULL, NULL, NULL, NULL); NULL, NULL, NULL, NULL);
ok(window2 != NULL, "couldn't create window\n"); ok(windows[1].hwnd != NULL, "couldn't create window\n");
abd.hWnd = window2; abd.hWnd = windows[1].hwnd;
ret = SHAppBarMessage(ABM_NEW, &abd); ret = SHAppBarMessage(ABM_NEW, &abd);
ok(ret == TRUE, "SHAppBarMessage returned %i\n", ret); ok(ret == TRUE, "SHAppBarMessage returned %i\n", ret);
/* dock window2 to the bottom of the screen */ /* dock windows[1] to the bottom of the screen */
window2_info.edge = ABE_BOTTOM; windows[1].registered = TRUE;
window2_info.desired_rect.left = 0; windows[1].edge = ABE_BOTTOM;
window2_info.desired_rect.right = screen_width; windows[1].desired_rect.left = 0;
window2_info.desired_rect.top = screen_height - 10; windows[1].desired_rect.right = screen_width;
window2_info.desired_rect.bottom = screen_height; windows[1].desired_rect.top = screen_height - 10;
SetWindowLongPtr(window2, GWLP_USERDATA, (LONG_PTR)&window2_info); windows[1].desired_rect.bottom = screen_height;
testwindow_setpos(window2); SetWindowLongPtr(windows[1].hwnd, GWLP_USERDATA, (LONG_PTR)&windows[1]);
do_events(); testwindow_setpos(windows[1].hwnd);
/* the windows are adjusted to they don't overlap */ /* the windows are adjusted to they don't overlap */
ok(!IntersectRect(&rc, &window1_info.allocated_rect, &window2_info.allocated_rect), do_events_until(no_appbars_intersect);
"rectangles intersect (%i,%i,%i,%i)/(%i,%i,%i,%i)\n", test_window_rects(0, 1);
window1_info.allocated_rect.left, window1_info.allocated_rect.top, window1_info.allocated_rect.right, window1_info.allocated_rect.bottom,
window2_info.allocated_rect.left, window2_info.allocated_rect.top, window2_info.allocated_rect.right, window2_info.allocated_rect.bottom);
/* make window1 larger, forcing window2 to move out of its way */ /* make windows[0] larger, forcing windows[1] to move out of its way */
window1_info.desired_rect.top = screen_height - 20; windows[0].desired_rect.top = screen_height - 20;
testwindow_setpos(window1); testwindow_setpos(windows[0].hwnd);
do_events(); do_events_until(no_appbars_intersect);
ok(!IntersectRect(&rc, &window1_info.allocated_rect, &window2_info.allocated_rect), test_window_rects(0, 1);
"rectangles intersect (%i,%i,%i,%i)/(%i,%i,%i,%i)\n",
window1_info.allocated_rect.left, window1_info.allocated_rect.top, window1_info.allocated_rect.right, window1_info.allocated_rect.bottom,
window2_info.allocated_rect.left, window2_info.allocated_rect.top, window2_info.allocated_rect.right, window2_info.allocated_rect.bottom);
/* create and register window3 */ /* create and register windows[2] */
window3 = CreateWindowExA(WS_EX_TOOLWINDOW|WS_EX_TOPMOST, windows[2].hwnd = CreateWindowExA(WS_EX_TOOLWINDOW|WS_EX_TOPMOST,
testwindow_class, testwindow_class, WS_POPUP|WS_VISIBLE, 0, 0, 0, 0, testwindow_class, testwindow_class, WS_POPUP|WS_VISIBLE, 0, 0, 0, 0,
NULL, NULL, NULL, NULL); NULL, NULL, NULL, NULL);
ok(window3 != NULL, "couldn't create window\n"); ok(windows[2].hwnd != NULL, "couldn't create window\n");
do_events(); do_events();
abd.hWnd = window3; abd.hWnd = windows[2].hwnd;
ret = SHAppBarMessage(ABM_NEW, &abd); ret = SHAppBarMessage(ABM_NEW, &abd);
ok(ret == TRUE, "SHAppBarMessage returned %i\n", ret); ok(ret == TRUE, "SHAppBarMessage returned %i\n", ret);
/* dock window3 to the bottom of the screen */ /* dock windows[2] to the bottom of the screen */
window3_info.edge = ABE_BOTTOM; windows[2].registered = TRUE;
window3_info.desired_rect.left = 0; windows[2].edge = ABE_BOTTOM;
window3_info.desired_rect.right = screen_width; windows[2].desired_rect.left = 0;
window3_info.desired_rect.top = screen_height - 10; windows[2].desired_rect.right = screen_width;
window3_info.desired_rect.bottom = screen_height; windows[2].desired_rect.top = screen_height - 10;
SetWindowLongPtr(window3, GWLP_USERDATA, (LONG_PTR)&window3_info); windows[2].desired_rect.bottom = screen_height;
testwindow_setpos(window3); SetWindowLongPtr(windows[2].hwnd, GWLP_USERDATA, (LONG_PTR)&windows[2]);
do_events(); testwindow_setpos(windows[2].hwnd);
ok(!IntersectRect(&rc, &window1_info.allocated_rect, &window2_info.allocated_rect), do_events_until(no_appbars_intersect);
"rectangles intersect (%i,%i,%i,%i)/(%i,%i,%i,%i)\n", test_window_rects(0, 1);
window1_info.allocated_rect.left, window1_info.allocated_rect.top, window1_info.allocated_rect.right, window1_info.allocated_rect.bottom, test_window_rects(0, 2);
window2_info.allocated_rect.left, window2_info.allocated_rect.top, window2_info.allocated_rect.right, window2_info.allocated_rect.bottom); test_window_rects(1, 2);
ok(!IntersectRect(&rc, &window1_info.allocated_rect, &window3_info.allocated_rect),
"rectangles intersect (%i,%i,%i,%i)/(%i,%i,%i,%i)\n",
window1_info.allocated_rect.left, window1_info.allocated_rect.top, window1_info.allocated_rect.right, window1_info.allocated_rect.bottom,
window3_info.allocated_rect.left, window3_info.allocated_rect.top, window3_info.allocated_rect.right, window3_info.allocated_rect.bottom);
ok(!IntersectRect(&rc, &window3_info.allocated_rect, &window2_info.allocated_rect),
"rectangles intersect (%i,%i,%i,%i)/(%i,%i,%i,%i)\n",
window3_info.allocated_rect.left, window3_info.allocated_rect.top, window3_info.allocated_rect.right, window3_info.allocated_rect.bottom,
window2_info.allocated_rect.left, window2_info.allocated_rect.top, window2_info.allocated_rect.right, window2_info.allocated_rect.bottom);
/* move window3 to the right side of the screen */ /* move windows[2] to the right side of the screen */
window3_info.edge = ABE_RIGHT; windows[2].edge = ABE_RIGHT;
window3_info.desired_rect.left = screen_width - 15; windows[2].desired_rect.left = screen_width - 15;
window3_info.desired_rect.right = screen_width; windows[2].desired_rect.right = screen_width;
window3_info.desired_rect.top = 0; windows[2].desired_rect.top = 0;
window3_info.desired_rect.bottom = screen_height; windows[2].desired_rect.bottom = screen_height;
testwindow_setpos(window3); testwindow_setpos(windows[2].hwnd);
do_events();
ok(!IntersectRect(&rc, &window1_info.allocated_rect, &window2_info.allocated_rect), do_events_until(no_appbars_intersect);
"rectangles intersect (%i,%i,%i,%i)/(%i,%i,%i,%i)\n", test_window_rects(0, 1);
window1_info.allocated_rect.left, window1_info.allocated_rect.top, window1_info.allocated_rect.right, window1_info.allocated_rect.bottom, test_window_rects(0, 2);
window2_info.allocated_rect.left, window2_info.allocated_rect.top, window2_info.allocated_rect.right, window2_info.allocated_rect.bottom); test_window_rects(1, 2);
ok(!IntersectRect(&rc, &window1_info.allocated_rect, &window3_info.allocated_rect),
"rectangles intersect (%i,%i,%i,%i)/(%i,%i,%i,%i)\n",
window1_info.allocated_rect.left, window1_info.allocated_rect.top, window1_info.allocated_rect.right, window1_info.allocated_rect.bottom,
window3_info.allocated_rect.left, window3_info.allocated_rect.top, window3_info.allocated_rect.right, window3_info.allocated_rect.bottom);
ok(!IntersectRect(&rc, &window3_info.allocated_rect, &window2_info.allocated_rect),
"rectangles intersect (%i,%i,%i,%i)/(%i,%i,%i,%i)\n",
window3_info.allocated_rect.left, window3_info.allocated_rect.top, window3_info.allocated_rect.right, window3_info.allocated_rect.bottom,
window2_info.allocated_rect.left, window2_info.allocated_rect.top, window2_info.allocated_rect.right, window2_info.allocated_rect.bottom);
/* move window2 to the top of the screen */ /* move windows[1] to the top of the screen */
window2_info.edge = ABE_TOP; windows[1].edge = ABE_TOP;
window2_info.desired_rect.left = 0; windows[1].desired_rect.left = 0;
window2_info.desired_rect.right = screen_width; windows[1].desired_rect.right = screen_width;
window2_info.desired_rect.top = 0; windows[1].desired_rect.top = 0;
window2_info.desired_rect.bottom = 15; windows[1].desired_rect.bottom = 15;
testwindow_setpos(window2); testwindow_setpos(windows[1].hwnd);
do_events();
ok(!IntersectRect(&rc, &window1_info.allocated_rect, &window2_info.allocated_rect), do_events_until(no_appbars_intersect);
"rectangles intersect (%i,%i,%i,%i)/(%i,%i,%i,%i)\n", test_window_rects(0, 1);
window1_info.allocated_rect.left, window1_info.allocated_rect.top, window1_info.allocated_rect.right, window1_info.allocated_rect.bottom, test_window_rects(0, 2);
window2_info.allocated_rect.left, window2_info.allocated_rect.top, window2_info.allocated_rect.right, window2_info.allocated_rect.bottom); test_window_rects(1, 2);
ok(!IntersectRect(&rc, &window1_info.allocated_rect, &window3_info.allocated_rect),
"rectangles intersect (%i,%i,%i,%i)/(%i,%i,%i,%i)\n",
window1_info.allocated_rect.left, window1_info.allocated_rect.top, window1_info.allocated_rect.right, window1_info.allocated_rect.bottom,
window3_info.allocated_rect.left, window3_info.allocated_rect.top, window3_info.allocated_rect.right, window3_info.allocated_rect.bottom);
ok(!IntersectRect(&rc, &window3_info.allocated_rect, &window2_info.allocated_rect),
"rectangles intersect (%i,%i,%i,%i)/(%i,%i,%i,%i)\n",
window3_info.allocated_rect.left, window3_info.allocated_rect.top, window3_info.allocated_rect.right, window3_info.allocated_rect.bottom,
window2_info.allocated_rect.left, window2_info.allocated_rect.top, window2_info.allocated_rect.right, window2_info.allocated_rect.bottom);
/* move window2 back to the bottom of the screen */ /* move windows[1] back to the bottom of the screen */
window2_info.edge = ABE_BOTTOM; windows[1].edge = ABE_BOTTOM;
window2_info.desired_rect.left = 0; windows[1].desired_rect.left = 0;
window2_info.desired_rect.right = screen_width; windows[1].desired_rect.right = screen_width;
window2_info.desired_rect.top = screen_height - 10; windows[1].desired_rect.top = screen_height - 10;
window2_info.desired_rect.bottom = screen_height; windows[1].desired_rect.bottom = screen_height;
testwindow_setpos(window2); testwindow_setpos(windows[1].hwnd);
do_events();
ok(!IntersectRect(&rc, &window1_info.allocated_rect, &window2_info.allocated_rect), do_events_until(no_appbars_intersect);
"rectangles intersect (%i,%i,%i,%i)/(%i,%i,%i,%i)\n", test_window_rects(0, 1);
window1_info.allocated_rect.left, window1_info.allocated_rect.top, window1_info.allocated_rect.right, window1_info.allocated_rect.bottom, test_window_rects(0, 2);
window2_info.allocated_rect.left, window2_info.allocated_rect.top, window2_info.allocated_rect.right, window2_info.allocated_rect.bottom); test_window_rects(1, 2);
ok(!IntersectRect(&rc, &window1_info.allocated_rect, &window3_info.allocated_rect),
"rectangles intersect (%i,%i,%i,%i)/(%i,%i,%i,%i)\n",
window1_info.allocated_rect.left, window1_info.allocated_rect.top, window1_info.allocated_rect.right, window1_info.allocated_rect.bottom,
window3_info.allocated_rect.left, window3_info.allocated_rect.top, window3_info.allocated_rect.right, window3_info.allocated_rect.bottom);
ok(!IntersectRect(&rc, &window3_info.allocated_rect, &window2_info.allocated_rect),
"rectangles intersect (%i,%i,%i,%i)/(%i,%i,%i,%i)\n",
window3_info.allocated_rect.left, window3_info.allocated_rect.top, window3_info.allocated_rect.right, window3_info.allocated_rect.bottom,
window2_info.allocated_rect.left, window2_info.allocated_rect.top, window2_info.allocated_rect.right, window2_info.allocated_rect.bottom);
/* removing window1 will cause window2 to move down into its space */ /* removing windows[0] will cause windows[1] to move down into its space */
expected = max(window1_info.allocated_rect.bottom, window2_info.allocated_rect.bottom); expected_bottom = max(windows[0].allocated_rect.bottom, windows[1].allocated_rect.bottom);
SetWindowLongPtr(window1, GWLP_USERDATA, 0); /* don't expect further ABN_POSCHANGED notifications */ abd.hWnd = windows[0].hwnd;
abd.hWnd = window1;
ret = SHAppBarMessage(ABM_REMOVE, &abd); ret = SHAppBarMessage(ABM_REMOVE, &abd);
ok(ret == TRUE, "SHAppBarMessage returned %i\n", ret); ok(ret == TRUE, "SHAppBarMessage returned %i\n", ret);
do_events(); windows[0].registered = FALSE;
DestroyWindow(window1); DestroyWindow(windows[0].hwnd);
ok(window2_info.allocated_rect.bottom = expected, "window2's bottom is %i, expected %i\n", window2_info.allocated_rect.bottom, expected); do_events_until(got_expected_bottom);
ok(!IntersectRect(&rc, &window3_info.allocated_rect, &window2_info.allocated_rect), ok(windows[1].allocated_rect.bottom = expected_bottom, "windows[1]'s bottom is %i, expected %i\n", windows[1].allocated_rect.bottom, expected_bottom);
"rectangles intersect (%i,%i,%i,%i)/(%i,%i,%i,%i)\n",
window3_info.allocated_rect.left, window3_info.allocated_rect.top, window3_info.allocated_rect.right, window3_info.allocated_rect.bottom, test_window_rects(1, 2);
window2_info.allocated_rect.left, window2_info.allocated_rect.top, window2_info.allocated_rect.right, window2_info.allocated_rect.bottom);
/* remove the other windows */ /* remove the other windows */
SetWindowLongPtr(window2, GWLP_USERDATA, 0); SetWindowLongPtr(windows[1].hwnd, GWLP_USERDATA, 0);
abd.hWnd = window2; abd.hWnd = windows[1].hwnd;
ret = SHAppBarMessage(ABM_REMOVE, &abd); ret = SHAppBarMessage(ABM_REMOVE, &abd);
ok(ret == TRUE, "SHAppBarMessage returned %i\n", ret); ok(ret == TRUE, "SHAppBarMessage returned %i\n", ret);
do_events(); windows[1].registered = FALSE;
DestroyWindow(window2); DestroyWindow(windows[1].hwnd);
SetWindowLongPtr(window3, GWLP_USERDATA, 0); SetWindowLongPtr(windows[2].hwnd, GWLP_USERDATA, 0);
abd.hWnd = window3; abd.hWnd = windows[2].hwnd;
ret = SHAppBarMessage(ABM_REMOVE, &abd); ret = SHAppBarMessage(ABM_REMOVE, &abd);
ok(ret == TRUE, "SHAppBarMessage returned %i\n", ret); ok(ret == TRUE, "SHAppBarMessage returned %i\n", ret);
do_events(); windows[2].registered = FALSE;
DestroyWindow(window3); DestroyWindow(windows[2].hwnd);
} }
static void test_appbarget(void) static void test_appbarget(void)