Commit 76adb1ff authored by Martin Fuchs's avatar Martin Fuchs Committed by Alexandre Julliard

- Move shell window into the background.

- Add tests for Get/SetShellWindow().
parent f22a4720
...@@ -362,6 +362,21 @@ BOOL WINAPI SetShellWindowEx(HWND hwndShell, HWND hwndListView) ...@@ -362,6 +362,21 @@ BOOL WINAPI SetShellWindowEx(HWND hwndShell, HWND hwndListView)
{ {
BOOL ret; BOOL ret;
if (GetShellWindow())
return FALSE;
if (GetWindowLongW(hwndShell, GWL_EXSTYLE) & WS_EX_TOPMOST)
return FALSE;
if (hwndListView != hwndShell)
if (GetWindowLongW(hwndListView, GWL_EXSTYLE) & WS_EX_TOPMOST)
return FALSE;
if (hwndListView && hwndListView!=hwndShell)
SetWindowPos(hwndListView, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE);
SetWindowPos(hwndShell, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE);
SERVER_START_REQ(set_global_windows) SERVER_START_REQ(set_global_windows)
{ {
req->flags = SET_GLOBAL_SHELL_WINDOWS; req->flags = SET_GLOBAL_SHELL_WINDOWS;
...@@ -371,13 +386,6 @@ BOOL WINAPI SetShellWindowEx(HWND hwndShell, HWND hwndListView) ...@@ -371,13 +386,6 @@ BOOL WINAPI SetShellWindowEx(HWND hwndShell, HWND hwndListView)
} }
SERVER_END_REQ; SERVER_END_REQ;
if (ret)
{
if (hwndListView && hwndListView!=hwndShell)
SetWindowPos(hwndListView, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE);
SetWindowPos(hwndShell, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE);
}
return ret; return ret;
} }
......
...@@ -563,6 +563,128 @@ static LRESULT CALLBACK cbt_hook_proc(int nCode, WPARAM wParam, LPARAM lParam) ...@@ -563,6 +563,128 @@ static LRESULT CALLBACK cbt_hook_proc(int nCode, WPARAM wParam, LPARAM lParam)
return CallNextHookEx(hhook, nCode, wParam, lParam); return CallNextHookEx(hhook, nCode, wParam, lParam);
} }
static void test_shell_window()
{
BOOL ret;
DWORD error;
HMODULE hinst, hUser32;
BOOL (WINAPI*SetShellWindow)(HWND);
BOOL (WINAPI*SetShellWindowEx)(HWND, HWND);
HWND hwnd1, hwnd2, hwnd3, hwnd4, hwnd5;
HWND shellWindow, nextWnd;
shellWindow = GetShellWindow();
hinst = GetModuleHandle(0);
hUser32 = GetModuleHandleA("user32");
SetShellWindow = (void *)GetProcAddress(hUser32, "SetShellWindow");
SetShellWindowEx = (void *)GetProcAddress(hUser32, "SetShellWindowEx");
trace("previous shell window: %p\n", shellWindow);
if (shellWindow) {
DWORD pid;
HANDLE hProcess;
ret = DestroyWindow(shellWindow);
error = GetLastError();
ok(!ret, "DestroyWindow(shellWindow)\n");
/* passes on Win XP, but not on Win98
ok(error==ERROR_ACCESS_DENIED, "ERROR_ACCESS_DENIED after DestroyWindow(shellWindow)\n"); */
/* close old shell instance */
GetWindowThreadProcessId(shellWindow, &pid);
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
ret = TerminateProcess(hProcess, 0);
ok(ret, "termination of previous shell process failed: GetLastError()=%ld", GetLastError());
WaitForSingleObject(hProcess, INFINITE); /* wait for termination */
CloseHandle(hProcess);
}
hwnd1 = CreateWindowEx(0, TEXT("#32770"), TEXT("TEST1"), WS_OVERLAPPEDWINDOW/*|WS_VISIBLE*/, 100, 100, 300, 200, 0, 0, hinst, 0);
trace("created window 1: %p\n", hwnd1);
ret = SetShellWindow(hwnd1);
ok(ret, "first call to SetShellWindow(hwnd1)\n");
shellWindow = GetShellWindow();
ok(shellWindow==hwnd1, "wrong shell window: %p", shellWindow);
ret = SetShellWindow(hwnd1);
ok(!ret, "second call to SetShellWindow(hwnd1)\n");
ret = SetShellWindow(0);
error = GetLastError();
/* passes on Win XP, but not on Win98
ok(!ret, "reset shell window by SetShellWindow(0)\n");
ok(error==ERROR_INVALID_WINDOW_HANDLE, "ERROR_INVALID_WINDOW_HANDLE after SetShellWindow(0)\n"); */
ret = SetShellWindow(hwnd1);
/* passes on Win XP, but not on Win98
ok(!ret, "third call to SetShellWindow(hwnd1)\n"); */
todo_wine
{
SetWindowLong(hwnd1, GWL_EXSTYLE, GetWindowLong(hwnd1,GWL_EXSTYLE)|WS_EX_TOPMOST);
ret = GetWindowLong(hwnd1,GWL_EXSTYLE)&WS_EX_TOPMOST? TRUE: FALSE;
ok(!ret, "SetWindowExStyle(hwnd1, WS_EX_TOPMOST)\n");
}
ret = DestroyWindow(hwnd1);
ok(ret, "DestroyWindow(hwnd1)\n");
hwnd2 = CreateWindowEx(WS_EX_TOPMOST, TEXT("#32770"), TEXT("TEST2"), WS_OVERLAPPEDWINDOW/*|WS_VISIBLE*/, 150, 250, 300, 200, 0, 0, hinst, 0);
trace("created window 2: %p\n", hwnd2);
ret = SetShellWindow(hwnd2);
ok(!ret, "SetShellWindow(hwnd2) with WS_EX_TOPMOST");
hwnd3 = CreateWindowEx(0, TEXT("#32770"), TEXT("TEST3"), WS_OVERLAPPEDWINDOW/*|WS_VISIBLE*/, 200, 400, 300, 200, 0, 0, hinst, 0);
trace("created window 3: %p\n", hwnd3);
hwnd4 = CreateWindowEx(0, TEXT("#32770"), TEXT("TEST4"), WS_OVERLAPPEDWINDOW/*|WS_VISIBLE*/, 250, 500, 300, 200, 0, 0, hinst, 0);
trace("created window 4: %p\n", hwnd4);
nextWnd = GetWindow(hwnd4, GW_HWNDNEXT);
ok(nextWnd==hwnd3, "wrong next window for hwnd4: %p - expected hwnd3\n", nextWnd);
ret = SetShellWindow(hwnd4);
ok(ret, "SetShellWindow(hwnd4)\n");
shellWindow = GetShellWindow();
ok(shellWindow==hwnd4, "wrong shell window: %p - expected hwnd4", shellWindow);
nextWnd = GetWindow(hwnd4, GW_HWNDNEXT);
ok(nextWnd==0, "wrong next window for hwnd4: %p - expected 0\n", nextWnd);
ret = SetWindowPos(hwnd4, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE|SWP_NOMOVE);
ok(ret, "SetWindowPos(hwnd4, HWND_TOPMOST)\n");
ret = SetWindowPos(hwnd4, hwnd3, 0, 0, 0, 0, SWP_NOSIZE|SWP_NOMOVE);
ok(ret, "SetWindowPos(hwnd4, hwnd3");
ret = SetShellWindow(hwnd3);
ok(!ret, "SetShellWindow(hwnd3)\n");
shellWindow = GetShellWindow();
ok(shellWindow==hwnd4, "wrong shell window: %p - expected hwnd4", shellWindow);
hwnd5 = CreateWindowEx(0, TEXT("#32770"), TEXT("TEST5"), WS_OVERLAPPEDWINDOW/*|WS_VISIBLE*/, 300, 600, 300, 200, 0, 0, hinst, 0);
trace("created window 5: %p\n", hwnd5);
ret = SetWindowPos(hwnd4, hwnd5, 0, 0, 0, 0, SWP_NOSIZE|SWP_NOMOVE);
ok(ret, "SetWindowPos(hwnd4, hwnd5)\n");
todo_wine
{
nextWnd = GetWindow(hwnd4, GW_HWNDNEXT);
ok(nextWnd==0, "wrong next window for hwnd4 after SetWindowPos(): %p - expected 0\n", nextWnd);
}
/* destroy test windows */
DestroyWindow(hwnd2);
DestroyWindow(hwnd3);
DestroyWindow(hwnd4);
DestroyWindow(hwnd5);
}
START_TEST(win) START_TEST(win)
{ {
pGetAncestor = (void *)GetProcAddress( GetModuleHandleA("user32.dll"), "GetAncestor" ); pGetAncestor = (void *)GetProcAddress( GetModuleHandleA("user32.dll"), "GetAncestor" );
...@@ -586,6 +708,6 @@ START_TEST(win) ...@@ -586,6 +708,6 @@ START_TEST(win)
assert( hwndMain2 ); assert( hwndMain2 );
test_parent_owner(); test_parent_owner();
test_shell_window();
UnhookWindowsHookEx(hhook); UnhookWindowsHookEx(hhook);
} }
...@@ -836,16 +836,16 @@ DECL_HANDLER(get_window_properties) ...@@ -836,16 +836,16 @@ DECL_HANDLER(get_window_properties)
/* helper for set_global_windows request */ /* helper for set_global_windows request */
static int get_new_global_window( struct window **win, user_handle_t handle ) static int get_new_global_window( struct window **win, user_handle_t handle )
{ {
if (*win && (*win)->thread != current)
{
set_error( STATUS_ACCESS_DENIED );
return 0;
}
if (!handle) if (!handle)
{ {
*win = NULL; *win = NULL;
return 1; return 1;
} }
else if (*win)
{
set_error( STATUS_ACCESS_DENIED );
return 0;
}
*win = get_window( handle ); *win = get_window( handle );
return (*win != NULL); return (*win != NULL);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment