Add more tests for keyboard/menu activation behaviour

Dmitry Timoshkov dmitry at baikal.ru
Mon Jan 10 08:58:48 CST 2005


Hello,

Changelog:
    Dmitry Timoshkov <dmitry at codeweavers.com>
    Add more tests for keyboard/menu activation behaviour, make the tests
    pass under Wine.

diff -up cvs/hq/wine/dlls/user/menu.c wine/dlls/user/menu.c
--- cvs/hq/wine/dlls/user/menu.c	2005-01-02 15:17:19.000000000 +0800
+++ wine/dlls/user/menu.c	2005-01-10 22:39:14.000000000 +0800
@@ -1562,7 +1562,7 @@ static void MENU_SelectItem( HWND hwndOw
             MENUITEM *ip = &lppop->items[lppop->FocusedItem];
 	    SendMessageW( hwndOwner, WM_MENUSELECT,
                      MAKELONG(ip->fType & MF_POPUP ? wIndex: ip->wID,
-                     ip->fType | ip->fState | MF_MOUSESELECT |
+                     ip->fType | ip->fState |
                      (lppop->wFlags & MF_SYSMENU)), (LPARAM)hmenu);
         }
     }
@@ -1573,7 +1573,7 @@ static void MENU_SelectItem( HWND hwndOw
                 POPUPMENU *ptm = MENU_GetMenu( topmenu );
                 MENUITEM *ip = &ptm->items[pos];
                 SendMessageW( hwndOwner, WM_MENUSELECT, MAKELONG(pos,
-                         ip->fType | ip->fState | MF_MOUSESELECT |
+                         ip->fType | ip->fState |
                          (ptm->wFlags & MF_SYSMENU)), (LPARAM)topmenu);
             }
         }
@@ -2572,6 +2572,8 @@ static BOOL MENU_TrackMenu( HMENU hmenu,
 	fEndMenu = !fRemove;
     }
 
+    if (wFlags & TF_ENDMENU) fEndMenu = TRUE;
+
     MENU_SetCapture( mt.hOwnerWnd );
 
     while (!fEndMenu)
@@ -2937,7 +2939,7 @@ void MENU_TrackKbdMenuBar( HWND hwnd, UI
         {
             if( uItem == (UINT)(-1) ) MessageBeep(0);
             /* schedule end of menu tracking */
-            PostMessageW( hwnd, WM_CANCELMODE, 0, 0 );
+            wFlags |= TF_ENDMENU;
             goto track_menu;
         }
     }
@@ -2946,8 +2948,9 @@ void MENU_TrackKbdMenuBar( HWND hwnd, UI
         /* prevent sysmenu activation for managed windows on Alt down/up */
         if ((wParam & HTSYSMENU) && (GetWindowLongW(hwnd, GWL_EXSTYLE) & WS_EX_MANAGED))
         {
+            MENU_SelectItem( hwnd, hTrackMenu, 0, TRUE, 0 );
             /* schedule end of menu tracking */
-            PostMessageW( hwnd, WM_CANCELMODE, 0, 0 );
+            wFlags |= TF_ENDMENU;
             goto track_menu;
         }
     }
diff -up cvs/hq/wine/dlls/user/tests/msg.c wine/dlls/user/tests/msg.c
--- cvs/hq/wine/dlls/user/tests/msg.c	2005-01-10 13:55:55.000000000 +0800
+++ wine/dlls/user/tests/msg.c	2005-01-10 22:41:47.000000000 +0800
@@ -3,7 +3,7 @@
  *
  * Copyright 1999 Ove Kaaven
  * Copyright 2003 Dimitrie O. Paun
- * Copyright 2004 Dmitry Timoshkov
+ * Copyright 2004, 2005 Dmitry Timoshkov
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -513,6 +513,9 @@ static const struct message WmCreateCust
     { HCBT_ACTIVATE, hook },
     { EVENT_SYSTEM_FOREGROUND, winevent_hook|wparam|lparam, 0, 0 },
 
+    { EVENT_OBJECT_DEFACTIONCHANGE, winevent_hook|wparam|lparam|optional, OBJID_CLIENT, 0 },
+    { WM_QUERYNEWPALETTE, sent|wparam|lparam|optional, 0, 0 },
+
     { EVENT_OBJECT_DEFACTIONCHANGE, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
     { WM_WINDOWPOSCHANGING, sent|wparam, SWP_NOSIZE|SWP_NOMOVE },
 
@@ -628,7 +631,10 @@ static const struct message WmShowCustom
     { EVENT_OBJECT_SHOW, winevent_hook|wparam|lparam, 0, 0 },
     { HCBT_ACTIVATE, hook },
     { EVENT_SYSTEM_FOREGROUND, winevent_hook|wparam|lparam, 0, 0 },
+
+    { EVENT_OBJECT_DEFACTIONCHANGE, winevent_hook|wparam|lparam|optional, OBJID_CLIENT, 0 },
     { WM_QUERYNEWPALETTE, sent|wparam|lparam|optional, 0, 0 },
+
     { EVENT_OBJECT_DEFACTIONCHANGE, winevent_hook|wparam|lparam|optional, OBJID_CLIENT, 0 },
     { WM_WINDOWPOSCHANGING, sent|wparam, SWP_NOSIZE|SWP_NOMOVE },
     { EVENT_OBJECT_DEFACTIONCHANGE, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
@@ -679,6 +685,7 @@ static const struct message WmModalDialo
     { WM_SHOWWINDOW, sent },
     { HCBT_ACTIVATE, hook },
     { EVENT_SYSTEM_FOREGROUND, winevent_hook|wparam|lparam, 0, 0 },
+    { WM_QUERYNEWPALETTE, sent|wparam|lparam|optional, 0, 0 },
     { WM_WINDOWPOSCHANGING, sent|wparam, SWP_NOSIZE|SWP_NOMOVE },
     { WM_NCACTIVATE, sent|wparam, 1 },
     { WM_GETICON, sent|optional },
@@ -2655,6 +2662,8 @@ static void test_messages(void)
     HMENU hmenu;
     MSG msg;
 
+    flush_sequence();
+
     hwnd = CreateWindowExA(0, "TestWindowClass", "Test overlapped", WS_OVERLAPPEDWINDOW,
                            100, 100, 200, 200, 0, 0, 0, NULL);
     ok (hwnd != 0, "Failed to create overlapped window\n");
@@ -3693,6 +3702,8 @@ static DWORD WINAPI thread_proc(void *pa
 	DispatchMessage(&msg);
     }
 
+    ok(IsWindow(wnd_event->hwnd), "window should still exist\n");
+
     return 0;
 }
 
@@ -3760,6 +3771,8 @@ static void test_interthread_messages(vo
 
     ok(WaitForSingleObject(hThread, INFINITE) == WAIT_OBJECT_0, "WaitForSingleObject failed\n");
     CloseHandle(hThread);
+
+    ok(!IsWindow(wnd_event.hwnd), "window should be destroyed on thread exit\n");
 }
 
 
@@ -3862,6 +3875,43 @@ static const struct message WmCtrlAltVkN
     { WM_KEYUP, sent|wparam|lparam, VK_CONTROL, 0xc0000001 },
     { 0 }
 };
+static const struct message WmAltPressRelease[] = {
+    { WM_SYSKEYDOWN, wparam|lparam, VK_MENU, 0x20000001 },
+    { WM_SYSKEYDOWN, sent|wparam|lparam, VK_MENU, 0x20000001 },
+    { WM_SYSKEYUP, wparam|lparam, VK_MENU, 0xc0000001 },
+    { WM_SYSKEYUP, sent|wparam|lparam, VK_MENU, 0xc0000001 },
+    { WM_SYSCOMMAND, sent|defwinproc|wparam|lparam, SC_KEYMENU, 0 },
+    { HCBT_SYSCOMMAND, hook },
+    { WM_ENTERMENULOOP, sent|defwinproc|wparam|lparam, 0, 0 },
+    { EVENT_SYSTEM_CAPTURESTART, winevent_hook|wparam|lparam, 0, 0 },
+    { WM_INITMENU, sent|defwinproc },
+    { EVENT_SYSTEM_MENUSTART, winevent_hook|wparam|lparam, OBJID_SYSMENU, 0 },
+    { WM_MENUSELECT, sent|defwinproc|wparam, MAKEWPARAM(0,MF_SYSMENU|MF_POPUP|MF_HILITE) },
+    { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_SYSMENU, 1 },
+
+    { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_SYSMENU, 0 },
+    { EVENT_SYSTEM_CAPTUREEND, winevent_hook|wparam|lparam, 0, 0, },
+    { WM_CAPTURECHANGED, sent|defwinproc },
+    { WM_MENUSELECT, sent|defwinproc|wparam|optional, MAKEWPARAM(0,0xffff) },
+    { EVENT_SYSTEM_MENUEND, winevent_hook|wparam|lparam, OBJID_SYSMENU, 0 },
+    { WM_EXITMENULOOP, sent|defwinproc },
+    { WM_SYSKEYUP, wparam|lparam, VK_MENU, 0xc0000001 },
+    { WM_SYSKEYUP, sent|wparam|lparam, VK_MENU, 0xc0000001 },
+    { 0 }
+};
+static const struct message WmAltMouseButton[] = {
+    { WM_SYSKEYDOWN, wparam|lparam, VK_MENU, 0x20000001 },
+    { WM_SYSKEYDOWN, sent|wparam|lparam, VK_MENU, 0x20000001 },
+    { WM_MOUSEMOVE, wparam|optional, 0, 0 },
+    { WM_MOUSEMOVE, sent|wparam|optional, 0, 0 },
+    { WM_LBUTTONDOWN, wparam, MK_LBUTTON, 0 },
+    { WM_LBUTTONDOWN, sent|wparam, MK_LBUTTON, 0 },
+    { WM_LBUTTONUP, wparam, 0, 0 },
+    { WM_LBUTTONUP, sent|wparam, 0, 0 },
+    { WM_SYSKEYUP, wparam|lparam, VK_MENU, 0xc0000001 },
+    { WM_SYSKEYUP, sent|wparam|lparam, VK_MENU, 0xc0000001 },
+    { 0 }
+};
 
 static void pump_msg_loop(HWND hwnd, HACCEL hAccel)
 {
@@ -3873,13 +3923,17 @@ static void pump_msg_loop(HWND hwnd, HAC
 
         trace("accel: %p, %04x, %08x, %08lx\n", msg.hwnd, msg.message, msg.wParam, msg.lParam);
 
+        /* ignore some unwanted messages */
+        if (msg.message == WM_MOUSEMOVE)
+            continue;
+
         log_msg.message = msg.message;
         log_msg.flags = wparam|lparam;
         log_msg.wParam = msg.wParam;
         log_msg.lParam = msg.lParam;
         add_message(&log_msg);
 
-        if (!TranslateAccelerator(hwnd, hAccel, &msg))
+        if (!hAccel || !TranslateAccelerator(hwnd, hAccel, &msg))
         {
             TranslateMessage(&msg);
             DispatchMessage(&msg);
@@ -3889,13 +3943,15 @@ static void pump_msg_loop(HWND hwnd, HAC
 
 static void test_accelerators(void)
 {
+    RECT rc;
     SHORT state;
     HACCEL hAccel;
-    HWND hwnd = CreateWindowExA(0, "TestWindowClass", NULL, WS_OVERLAPPEDWINDOW,
+    HWND hwnd = CreateWindowExA(0, "TestWindowClass", NULL, WS_OVERLAPPEDWINDOW | WS_VISIBLE,
                                 100, 100, 200, 200, 0, 0, 0, NULL);
     BOOL ret;
 
     assert(hwnd != 0);
+    UpdateWindow(hwnd);
     SetFocus(hwnd);
     ok(GetFocus() == hwnd, "wrong focus window %p\n", GetFocus());
 
@@ -3907,6 +3963,9 @@ static void test_accelerators(void)
     hAccel = LoadAccelerators(GetModuleHandleA(0), MAKEINTRESOURCE(1));
     assert(hAccel != 0);
 
+    pump_msg_loop(hwnd, 0);
+    flush_sequence();
+
     trace("testing VK_N press/release\n");
     flush_sequence();
     keybd_event('N', 0, 0, 0);
@@ -4006,6 +4065,33 @@ static void test_accelerators(void)
     ret = DestroyAcceleratorTable(hAccel);
     ok( ret, "DestroyAcceleratorTable error %ld\n", GetLastError());
 
+    trace("testing Alt press/release\n");
+    flush_sequence();
+    keybd_event(VK_MENU, 0, 0, 0);
+    keybd_event(VK_MENU, 0, KEYEVENTF_KEYUP, 0);
+    keybd_event(VK_MENU, 0, 0, 0);
+    keybd_event(VK_MENU, 0, KEYEVENTF_KEYUP, 0);
+    pump_msg_loop(hwnd, 0);
+    /* this test doesn't pass in Wine for managed windows */
+    ok_sequence(WmAltPressRelease, "Alt press/release", TRUE);
+
+    trace("testing Alt+MouseButton press/release\n");
+    /* first, move mouse pointer inside of the window client area */
+    GetClientRect(hwnd, &rc);
+    MapWindowPoints(hwnd, 0, (LPPOINT)&rc, 2);
+    rc.left += (rc.right - rc.left)/2;
+    rc.top += (rc.bottom - rc.top)/2;
+    SetCursorPos(rc.left, rc.top);
+
+    pump_msg_loop(hwnd, 0);
+    flush_sequence();
+    keybd_event(VK_MENU, 0, 0, 0);
+    mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);
+    mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
+    keybd_event(VK_MENU, 0, KEYEVENTF_KEYUP, 0);
+    pump_msg_loop(hwnd, 0);
+    ok_sequence(WmAltMouseButton, "Alt+MouseButton press/release", FALSE);
+
     DestroyWindow(hwnd);
 }
 
@@ -4018,15 +4104,19 @@ static LRESULT WINAPI MsgCheckProcA(HWND
     LRESULT ret;
     struct message msg;
 
-    /* do not log mouse messages */
-    if (message == WM_NCHITTEST ||
-	message == WM_SETCURSOR)
-	return 0;
-
     trace("%p, %04x, %08x, %08lx\n", hwnd, message, wParam, lParam);
 
     switch (message)
     {
+	/* test_accelerators() depends on this */
+	case WM_NCHITTEST:
+	    return HTCLIENT;
+    
+	/* ignore */
+	case WM_MOUSEMOVE:
+	case WM_SETCURSOR:
+	    return 0;
+
         case WM_WINDOWPOSCHANGING:
         case WM_WINDOWPOSCHANGED:
         {
@@ -4548,7 +4638,11 @@ static void test_winevents(void)
     flush_sequence();
 
     /* Windows ignores events with hwnd == 0 */
+    SetLastError(0xdeadbeef);
     pNotifyWinEvent(events[0].message, 0, events[0].wParam, events[0].lParam);
+    ok(GetLastError() == ERROR_INVALID_WINDOW_HANDLE || /* Win2k */
+       GetLastError() == 0xdeadbeef, /* Win9x */
+       "unexpected error %ld\n", GetLastError());
     ok_sequence(WmEmptySeq, "empty notify winevents", FALSE);
 
     for (i = 0; i < sizeof(WmWinEventsSeq)/sizeof(WmWinEventsSeq[0]); i++)
@@ -4562,7 +4656,7 @@ START_TEST(msg)
 {
     HMODULE user32 = GetModuleHandleA("user32.dll");
     FARPROC pSetWinEventHook = 0;/*GetProcAddress(user32, "SetWinEventHook");*/
-    FARPROC pUnhookWinEvent = GetProcAddress(user32, "UnhookWinEvent");
+    FARPROC pUnhookWinEvent = 0;/*GetProcAddress(user32, "UnhookWinEvent");*/
     FARPROC pIsWinEventHookInstalled = GetProcAddress(user32, "IsWinEventHookInstalled");
 
     if (!RegisterWindowClasses()) assert(0);
@@ -4599,5 +4693,13 @@ START_TEST(msg)
     test_winevents();
 
     UnhookWindowsHookEx(hCBT_hook);
-    if (pUnhookWinEvent) pUnhookWinEvent(hEvent_hook);
+    if (pUnhookWinEvent)
+    {
+	ok(pUnhookWinEvent(hEvent_hook), "UnhookWinEvent error %ld\n", GetLastError());
+	SetLastError(0xdeadbeef);
+	ok(!pUnhookWinEvent(hEvent_hook), "UnhookWinEvent succeeded\n");
+	ok(GetLastError() == ERROR_INVALID_HANDLE || /* Win2k */
+	   GetLastError() == 0xdeadbeef, /* Win9x */
+	   "unexpected error %ld\n", GetLastError());
+    }
 }
diff -up cvs/hq/wine/windows/defwnd.c wine/windows/defwnd.c
--- cvs/hq/wine/windows/defwnd.c	2005-01-06 15:17:43.000000000 +0800
+++ wine/windows/defwnd.c	2005-01-10 22:17:37.000000000 +0800
@@ -339,6 +339,12 @@ static LRESULT DEFWND_DefWinProc( HWND h
             return NC_HandleNCHitTest( hwnd, pt );
         }
 
+    case WM_LBUTTONDOWN:
+    case WM_RBUTTONDOWN:
+    case WM_MBUTTONDOWN:
+        iF10Key = iMenuSysKey = 0;
+        break;
+
     case WM_NCLBUTTONDOWN:
         return NC_HandleNCLButtonDown( hwnd, wParam, lParam );
 






More information about the wine-patches mailing list