Andrew Riedi a écrit :
changelog: user32: Test destroying the cursor of a parent process.
-- Andrew Riedi
From 25a6a6a2eee92c4325d730ff85bd7cdf01bf2ace Mon Sep 17 00:00:00 2001 From: Andrew Riedi andrewriedi@gmail.com Date: Tue, 8 Jan 2008 05:03:55 -0800 Subject: [PATCH] user32: Test destroying the cursor of a parent process.
dlls/user32/tests/cursoricon.c | 201 ++++++++++++++++++++++++++++++++++++++++ 1 files changed, 201 insertions(+), 0 deletions(-)
diff --git a/dlls/user32/tests/cursoricon.c b/dlls/user32/tests/cursoricon.c index 781282c..c2beffa 100644 --- a/dlls/user32/tests/cursoricon.c +++ b/dlls/user32/tests/cursoricon.c @@ -32,6 +32,205 @@ #include "wingdi.h" #include "winuser.h"
+static char **test_argv; +static int test_argc; +static HWND child = 0; +static HWND parent = 0; +static HANDLE child_process;
+#define PROC_INIT (WM_USER+1)
+LRESULT CALLBACK callback_child(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{
- BOOL ret;
- DWORD error;
- switch (msg)
- {
/* Destroy the cursor. */
case WM_USER+1:
SetLastError(0xdeadbeef);
ret = DestroyCursor((HCURSOR) lParam);
error = GetLastError();
todo_wine {
ok(!ret, "DestroyCursor on the active cursor succeeded.\n");
ok(error == ERROR_DESTROY_OBJECT_OF_OTHER_THREAD,
"Last error: 0x%08x\n", error);
}
return TRUE;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
- }
- return DefWindowProc(hwnd, msg, wParam, lParam);
+}
+LRESULT CALLBACK callback_parent(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{
- if (msg == PROC_INIT)
- {
child = (HWND) wParam;
return TRUE;
- }
- return DefWindowProc(hwnd, msg, wParam, lParam);
+}
+static void do_child(void) +{
- WNDCLASS class;
- MSG msg;
- BOOL ret;
- /* Register a new class. */
- class.style = CS_GLOBALCLASS;
- class.lpfnWndProc = callback_child;
- class.cbClsExtra = 0;
- class.cbWndExtra = 0;
- class.hInstance = GetModuleHandle(NULL);
- class.hIcon = NULL;
- class.hCursor = NULL;
- class.hbrBackground = NULL;
- class.lpszMenuName = NULL;
- class.lpszClassName = "cursor_child";
- SetLastError(0xdeadbeef);
- ret = RegisterClass(&class);
- ok(ret, "Failed to register window class. Error: %d\n", GetLastError());
- /* Create a window. */
- child = CreateWindowA("cursor_child", "cursor_child", WS_POPUP | WS_VISIBLE,
0, 0, 200, 200, 0, 0, 0, NULL);
- ok(child != 0, "CreateWindowA error %d\n", GetLastError());
- /* Let the parent know our HWND. */
- PostMessage(parent, PROC_INIT, (WPARAM) child, 0);
- /* Receive messages. */
- while ((ret = GetMessage(&msg, child, 0, 0)))
- {
ok(ret != -1, "GetMessage failed. Error: %d\n", GetLastError());
TranslateMessage(&msg);
DispatchMessage(&msg);
- }
+}
+static void do_parent(void) +{
- char path_name[MAX_PATH];
- PROCESS_INFORMATION info;
- STARTUPINFOA startup;
- WNDCLASS class;
- MSG msg;
- BOOL ret;
- /* Register a new class. */
- class.style = CS_GLOBALCLASS;
- class.lpfnWndProc = callback_parent;
- class.cbClsExtra = 0;
- class.cbWndExtra = 0;
- class.hInstance = GetModuleHandle(NULL);
- class.hIcon = NULL;
- class.hCursor = NULL;
- class.hbrBackground = NULL;
- class.lpszMenuName = NULL;
- class.lpszClassName = "cursor_parent";
- SetLastError(0xdeadbeef);
- ret = RegisterClass(&class);
- ok(ret, "Failed to register window class. Error: %d\n", GetLastError());
- /* Create a window. */
- parent = CreateWindowA("cursor_parent", "cursor_parent", WS_POPUP | WS_VISIBLE,
0, 0, 200, 200, 0, 0, 0, NULL);
- ok(parent != 0, "CreateWindowA error %d\n", GetLastError());
- /* Start child process. */
- memset(&startup, 0, sizeof(startup));
- startup.cb = sizeof(startup);
- startup.dwFlags = STARTF_USESHOWWINDOW;
- startup.wShowWindow = SW_SHOWNORMAL;
- sprintf(path_name, "%s cursoricon %x", test_argv[0], (unsigned int) parent);
- ok(CreateProcessA(NULL, path_name, NULL, NULL, FALSE, 0L, NULL, NULL, &startup, &info), "CreateProcess failed.\n");
- child_process = info.hProcess;
- /* Wait for child window handle. */
- while ((child == 0) && (ret = GetMessage(&msg, parent, 0, 0)))
- {
ok(ret != -1, "GetMessage failed. Error: %d\n", GetLastError());
TranslateMessage(&msg);
DispatchMessage(&msg);
- }
+}
+static void init(void) +{
- test_argc = winetest_get_mainargs(&test_argv);
- /* Child process. */
- if (test_argc >= 3)
- {
sscanf (test_argv[2], "%x", (unsigned int *) &parent);
ok(parent != NULL, "Parent not found.\n");
if (parent == NULL)
exit(1);
do_child();
exit(0);
- }
- else
- {
do_parent();
- }
+}
+static void finish_process(void) +{
- DWORD exit_code;
- BOOL ret;
- SendMessage(child, WM_CLOSE, 0, 0);
- ok(WaitForSingleObject(child_process, 30000) == WAIT_OBJECT_0, "Child process termination failed.\n");
- ret = GetExitCodeProcess(child_process, &exit_code);
- ok(ret, "GetExitCodeProcess() failed. Error: 0x%08x\n", GetLastError());
- ok(exit_code == 0, "Exit code == %d.\n", exit_code);
+}
+static void test_child_process(void) +{
- static const BYTE bmp_bits[4096];
- HCURSOR cursor;
- ICONINFO cursorInfo;
- UINT display_bpp;
- HDC hdc;
- /* Create and set a dummy cursor. */
- hdc = GetDC(0);
- display_bpp = GetDeviceCaps(hdc, BITSPIXEL);
- ReleaseDC(0, hdc);
- cursorInfo.fIcon = FALSE;
- cursorInfo.xHotspot = 0;
- cursorInfo.yHotspot = 0;
- cursorInfo.hbmMask = CreateBitmap(32, 32, 1, 1, bmp_bits);
- cursorInfo.hbmColor = CreateBitmap(32, 32, 1, display_bpp, bmp_bits);
- cursor = CreateIconIndirect(&cursorInfo);
- ok(cursor != NULL, "CreateIconIndirect returned %p.\n", cursor);
- SetCursor(cursor);
- /* Destroy the cursor. */
- SendMessage(child, WM_USER+1, (WPARAM) parent, (LPARAM) cursor);
- /* Finish the child process. */
- finish_process();
+}
static void test_CopyImage_Check(HBITMAP bitmap, UINT flags, INT copyWidth, INT copyHeight, INT expectedWidth, INT expectedHeight, WORD expectedDepth, BOOL dibExpected) { @@ -471,6 +670,7 @@ static void test_DestroyCursor(void)
START_TEST(cursoricon) {
- init(); test_CopyImage_Bitmap(1); test_CopyImage_Bitmap(4); test_CopyImage_Bitmap(8);
@@ -480,4 +680,5 @@ START_TEST(cursoricon) test_initial_cursor(); test_CreateIcon(); test_DestroyCursor();
- test_child_process();
}
IMO, the ok() tests in the child process are a bad idea (they won't be counted, nor returned as errors, by the parent process) all the tests should be done in parent, see kernel32/tests/process.c for some example on how to do it properly
A+
* On Tue, 8 Jan 2008, Eric Pouech wrote:
- Andrew Riedi a écrit :
dlls/user32/tests/cursoricon.c | 201 ++++++++++++++++++++++++++++++++++++++++
...
+static void do_child(void) +{
- WNDCLASS class;
- MSG msg;
- BOOL ret;
- /* Register a new class. */
- class.style = CS_GLOBALCLASS;
- class.lpfnWndProc = callback_child;
- class.cbClsExtra = 0;
- class.cbWndExtra = 0;
- class.hInstance = GetModuleHandle(NULL);
- class.hIcon = NULL;
- class.hCursor = NULL;
- class.hbrBackground = NULL;
- class.lpszMenuName = NULL;
- class.lpszClassName = "cursor_child";
- SetLastError(0xdeadbeef);
- ret = RegisterClass(&class);
- ok(ret, "Failed to register window class. Error: %d\n", GetLastError());
...
IMO, the ok() tests in the child process are a bad idea (they won't be counted, nor returned as errors, by the parent process)
Was Wine test framework architecture done such way on a purpose? Why would it be a bad idea to take into account a child output also?
Saulius Krasuckas wrote:
- On Tue, 8 Jan 2008, Eric Pouech wrote:
- Andrew Riedi a écrit :
dlls/user32/tests/cursoricon.c | 201 ++++++++++++++++++++++++++++++++++++++++
...
+static void do_child(void) +{
- WNDCLASS class;
- MSG msg;
- BOOL ret;
- /* Register a new class. */
- class.style = CS_GLOBALCLASS;
- class.lpfnWndProc = callback_child;
- class.cbClsExtra = 0;
- class.cbWndExtra = 0;
- class.hInstance = GetModuleHandle(NULL);
- class.hIcon = NULL;
- class.hCursor = NULL;
- class.hbrBackground = NULL;
- class.lpszMenuName = NULL;
- class.lpszClassName = "cursor_child";
- SetLastError(0xdeadbeef);
- ret = RegisterClass(&class);
- ok(ret, "Failed to register window class. Error: %d\n", GetLastError());
...
IMO, the ok() tests in the child process are a bad idea (they won't be counted, nor returned as errors, by the parent process)
Was Wine test framework architecture done such way on a purpose? Why would it be a bad idea to take into account a child output also?
The architecture has been fixed since the introduction of the winetest_wait_child_process function in include/wine/test.h.