user32: Test destroying the cursor of a parent process.

Eric Pouech eric.pouech at orange.fr
Tue Jan 8 14:12:47 CST 2008


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 at 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+

-- 
Eric Pouech
"The problem with designing something completely foolproof is to underestimate the ingenuity of a complete idiot." (Douglas Adams)





More information about the wine-devel mailing list