Thomas Kho : user: Extend menu conformance test.

Alexandre Julliard julliard at wine.codeweavers.com
Mon May 8 09:05:45 CDT 2006


Module: wine
Branch: refs/heads/master
Commit: bde9ca2b63a5e2d04bcd6a1c94d7bf04f4922d02
URL:    http://source.winehq.org/git/?p=wine.git;a=commit;h=bde9ca2b63a5e2d04bcd6a1c94d7bf04f4922d02

Author: Thomas Kho <tkho at ucla.edu>
Date:   Fri Apr 28 11:27:51 2006 -0700

user: Extend menu conformance test.

---

 dlls/user/tests/menu.c |  207 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 207 insertions(+), 0 deletions(-)

diff --git a/dlls/user/tests/menu.c b/dlls/user/tests/menu.c
index c2fd8f3..96195fd 100644
--- a/dlls/user/tests/menu.c
+++ b/dlls/user/tests/menu.c
@@ -52,8 +52,24 @@ static LRESULT WINAPI menu_check_wnd_pro
     return DefWindowProc(hwnd, msg, wparam, lparam);
 }
 
+/* The MSVC headers ignore our NONAMELESSUNION requests so we have to define
+ * our own type */
+typedef struct
+{
+    DWORD type;
+    union
+    {
+        MOUSEINPUT      mi;
+        KEYBDINPUT      ki;
+        HARDWAREINPUT   hi;
+    } u;
+} TEST_INPUT;
+
 /* globals to communicate between test and wndproc */
 
+static BOOL bMenuVisible;
+static HMENU hMenus[4];
+
 #define MOD_SIZE 10
 #define MOD_NRMENUS 8
 
@@ -1475,6 +1491,196 @@ void test_menu_search_bycommand( void )
     DestroyMenu(hmenuSub);
 }
 
+struct menu_item_pair_s {
+    UINT uMenu; /* 1 - top level menu, [0-Menu 1-Enabled 2-Disabled]
+                 * 2 - 2nd level menu, [0-Popup 1-Enabled 2-Disabled]
+                 * 3 - 3rd level menu, [0-Enabled 1-Disabled] */
+    UINT uItem;
+};
+
+static struct menu_mouse_tests_s {
+    DWORD type;
+    struct menu_item_pair_s menu_item_pairs[5]; /* for mousing */
+    WORD wVk[5]; /* keys */
+    BOOL bMenuVisible;
+    BOOL _todo_wine;
+} menu_tests[] = {
+    /* for each test, send keys or clicks and check for menu visibility */
+    { INPUT_KEYBOARD, {{0}}, {VK_LMENU, 0}, TRUE, TRUE }, /* test 0 */
+    { INPUT_KEYBOARD, {{0}}, {VK_ESCAPE, 0}, FALSE, FALSE },
+    { INPUT_KEYBOARD, {{0}}, {VK_LMENU, 0}, TRUE, TRUE },
+    { INPUT_KEYBOARD, {{0}}, {'D', 0}, FALSE, FALSE },
+    { INPUT_KEYBOARD, {{0}}, {VK_LMENU, 0}, TRUE, TRUE },
+    { INPUT_KEYBOARD, {{0}}, {'E', 0}, FALSE, FALSE },
+    { INPUT_KEYBOARD, {{0}}, {VK_LMENU, 'M', 0}, TRUE, TRUE },
+    { INPUT_KEYBOARD, {{0}}, {VK_ESCAPE, VK_ESCAPE, 0}, FALSE, FALSE },
+    { INPUT_KEYBOARD, {{0}}, {VK_LMENU, 'M', VK_ESCAPE, 0}, TRUE, TRUE },
+    { INPUT_KEYBOARD, {{0}}, {VK_ESCAPE, 0}, FALSE, FALSE },
+    { INPUT_KEYBOARD, {{0}}, {VK_LMENU, 'M', 0}, TRUE, TRUE },
+    { INPUT_KEYBOARD, {{0}}, {'D', 0}, FALSE, FALSE },
+    { INPUT_KEYBOARD, {{0}}, {VK_LMENU, 'M', 0}, TRUE, TRUE },
+    { INPUT_KEYBOARD, {{0}}, {'E', 0}, FALSE, FALSE },
+    { INPUT_KEYBOARD, {{0}}, {VK_LMENU, 'M', 'P', 0}, TRUE, TRUE },
+    { INPUT_KEYBOARD, {{0}}, {'D', 0}, FALSE, FALSE },
+    { INPUT_KEYBOARD, {{0}}, {VK_LMENU, 'M', 'P', 0}, TRUE, TRUE },
+    { INPUT_KEYBOARD, {{0}}, {'E', 0}, FALSE, FALSE },
+
+    { INPUT_MOUSE, {{1, 2}, {0}}, {0}, TRUE, TRUE }, /* test 18 */
+    { INPUT_MOUSE, {{1, 1}, {0}}, {0}, FALSE, FALSE },
+    { INPUT_MOUSE, {{1, 0}, {0}}, {0}, TRUE, TRUE },
+    { INPUT_MOUSE, {{1, 1}, {0}}, {0}, FALSE, FALSE },
+    { INPUT_MOUSE, {{1, 0}, {2, 2}, {0}}, {0}, TRUE, TRUE },
+    { INPUT_MOUSE, {{2, 1}, {0}}, {0}, FALSE, FALSE },
+    { INPUT_MOUSE, {{1, 0}, {2, 0}, {0}}, {0}, TRUE, TRUE },
+    { INPUT_MOUSE, {{3, 0}, {0}}, {0}, FALSE, FALSE },
+    { INPUT_MOUSE, {{1, 0}, {2, 0}, {0}}, {0}, TRUE, TRUE },
+    { INPUT_MOUSE, {{3, 1}, {0}}, {0}, TRUE, TRUE },
+    { INPUT_MOUSE, {{1, 1}, {0}}, {0}, FALSE, FALSE },
+    { -1 }
+};
+
+static void send_key(WORD wVk)
+{
+    TEST_INPUT i[2];
+    memset(&i, 0, 2*sizeof(INPUT));
+    i[0].type = i[1].type = INPUT_KEYBOARD;
+    i[0].u.ki.wVk = i[1].u.ki.wVk = wVk;
+    i[1].u.ki.dwFlags = KEYEVENTF_KEYUP;
+    SendInput(2, (INPUT *) i, sizeof(INPUT));
+}
+
+static void click_menu(HANDLE hWnd, struct menu_item_pair_s *mi)
+{
+    HMENU hMenu = hMenus[mi->uMenu];
+    TEST_INPUT i[3];
+    MSG msg;
+    RECT r;
+    int screen_w = GetSystemMetrics(SM_CXSCREEN);
+    int screen_h = GetSystemMetrics(SM_CYSCREEN);
+
+    GetMenuItemRect(mi->uMenu > 2 ? NULL : hWnd, hMenu, mi->uItem, &r);
+
+    memset(&i, 0, 3*sizeof(INPUT));
+    i[0].type = i[1].type = i[2].type = INPUT_MOUSE;
+    i[0].u.mi.dx = i[1].u.mi.dx = i[2].u.mi.dx
+            = ((r.left + 5) * 65535) / screen_w;
+    i[0].u.mi.dy = i[1].u.mi.dy = i[2].u.mi.dy
+            = ((r.top + 5) * 65535) / screen_h;
+    i[0].u.mi.dwFlags = i[1].u.mi.dwFlags = i[2].u.mi.dwFlags
+            = MOUSEEVENTF_ABSOLUTE;
+    i[0].u.mi.dwFlags |= MOUSEEVENTF_MOVE;
+    i[1].u.mi.dwFlags |= MOUSEEVENTF_LEFTDOWN;
+    i[2].u.mi.dwFlags |= MOUSEEVENTF_LEFTUP;
+    SendInput(3, (INPUT *) i, sizeof(INPUT));
+
+    /* hack to prevent mouse message buildup in Wine */
+    while (PeekMessage( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessageA( &msg );
+}
+
+static DWORD WINAPI test_menu_input_thread(LPVOID lpParameter)
+{
+    int i, j;
+    HANDLE hWnd = lpParameter;
+
+    Sleep(500);
+    /* mixed keyboard/mouse test */
+    for (i = 0; menu_tests[i].type != -1; i++)
+    {
+        int elapsed = 0;
+
+        if (menu_tests[i].type == INPUT_KEYBOARD)
+            for (j = 0; menu_tests[i].wVk[j] != 0; j++)
+                send_key(menu_tests[i].wVk[j]);
+        else
+            for (j = 0; menu_tests[i].menu_item_pairs[j].uMenu != 0; j++)
+                click_menu(hWnd, &menu_tests[i].menu_item_pairs[j]);
+
+        while (menu_tests[i].bMenuVisible != bMenuVisible)
+        {
+            if (elapsed > 200)
+                break;
+            elapsed += 20;
+            Sleep(20);
+        }
+
+        if (menu_tests[i]._todo_wine)
+        {
+            todo_wine {
+                ok(menu_tests[i].bMenuVisible == bMenuVisible, "test %d\n", i);
+            }
+        }
+        else
+            ok(menu_tests[i].bMenuVisible == bMenuVisible, "test %d\n", i);
+    }
+    return 0;
+}
+
+static LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam,
+        LPARAM lParam)
+{
+    switch (msg) {
+        case WM_ENTERMENULOOP:
+            bMenuVisible = TRUE;
+            break;
+        case WM_EXITMENULOOP:
+            bMenuVisible = FALSE;
+            break;
+        default:
+            return( DefWindowProcA( hWnd, msg, wParam, lParam ) );
+    }
+    return 0;
+}
+
+static void test_menu_input(void) {
+    MSG msg;
+    WNDCLASSA  wclass;
+    HINSTANCE hInstance = GetModuleHandleA( NULL );
+    HANDLE hThread, hWnd;
+
+    wclass.lpszClassName = "MenuTestClass";
+    wclass.style         = CS_HREDRAW | CS_VREDRAW;
+    wclass.lpfnWndProc   = WndProc;
+    wclass.hInstance     = hInstance;
+    wclass.hIcon         = LoadIconA( 0, (LPSTR)IDI_APPLICATION );
+    wclass.hCursor       = LoadCursorA( NULL, (LPSTR)IDC_ARROW);
+    wclass.hbrBackground = (HBRUSH)( COLOR_WINDOW + 1);
+    wclass.lpszMenuName  = 0;
+    wclass.cbClsExtra    = 0;
+    wclass.cbWndExtra    = 0;
+    assert (RegisterClassA( &wclass ));
+    assert (hWnd = CreateWindowA( wclass.lpszClassName, "MenuTest",
+                                  WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0,
+                                  400, 200, NULL, NULL, hInstance, NULL) );
+
+    /* fixed menus */
+    hMenus[3] = CreatePopupMenu();
+    AppendMenu(hMenus[3], MF_STRING, 0, "&Enabled");
+    AppendMenu(hMenus[3], MF_STRING|MF_DISABLED, 0, "&Disabled");
+
+    hMenus[2] = CreatePopupMenu();
+    AppendMenu(hMenus[2], MF_STRING|MF_POPUP, (UINT_PTR) hMenus[3], "&Popup");
+    AppendMenu(hMenus[2], MF_STRING, 0, "&Enabled");
+    AppendMenu(hMenus[2], MF_STRING|MF_DISABLED, 0, "&Disabled");
+
+    hMenus[1] = CreateMenu();
+    AppendMenu(hMenus[1], MF_STRING|MF_POPUP, (UINT_PTR) hMenus[2], "&Menu");
+    AppendMenu(hMenus[1], MF_STRING, 0, "&Enabled");
+    AppendMenu(hMenus[1], MF_STRING|MF_DISABLED, 0, "&Disabled");
+
+    SetMenu(hWnd, hMenus[1]);
+    ShowWindow(hWnd, SW_SHOW);
+    UpdateWindow(hWnd);
+
+    hThread = CreateThread(NULL, 0, test_menu_input_thread, hWnd, 0, NULL);
+    while(1)
+    {
+        if (WAIT_TIMEOUT != WaitForSingleObject(hThread, 50))
+            break;
+        while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
+    }
+    DestroyWindow(hWnd);
+}
+
 START_TEST(menu)
 {
     pSetMenuInfo =
@@ -1490,4 +1696,5 @@ START_TEST(menu)
     test_menu_iteminfo();
     test_menu_search_bycommand();
     test_menu_bmp_and_string();
+    test_menu_input();
 }




More information about the wine-cvs mailing list