Add a TrackMouseEvent test, make it pass under Wine

Dmitry Timoshkov dmitry at codeweavers.com
Thu Jul 20 08:27:29 CDT 2006


Hello,

this patch makes the TrackMouseEvent test pass in Wine and greatly
simplifies TrackMouseEvent implementation. Due to removing large chunks
of the code formatting has changed a lot, therefore the size of the patch.

Changelog:
    Add a TrackMouseEvent test, make it pass under Wine.

diff -up cvs/hq/wine/dlls/user/input.c wine/dlls/user/input.c
--- cvs/hq/wine/dlls/user/input.c	2006-05-24 13:16:27.000000000 +0900
+++ wine/dlls/user/input.c	2006-07-20 21:59:48.000000000 +0900
@@ -706,121 +706,101 @@ BOOL WINAPI UnloadKeyboardLayout(HKL hkl
 typedef struct __TRACKINGLIST {
     TRACKMOUSEEVENT tme;
     POINT pos; /* center of hover rectangle */
-    INT iHoverTime; /* elapsed time the cursor has been inside of the hover rect */
 } _TRACKINGLIST;
 
-static _TRACKINGLIST TrackingList[10];
-static int iTrackMax = 0;
+/* FIXME: move tracking stuff into a per thread data */
+static _TRACKINGLIST tracking_info;
 static UINT_PTR timer;
-static const INT iTimerInterval = 50; /* msec for timer interval */
 
 static void CALLBACK TrackMouseEventProc(HWND hwndUnused, UINT uMsg, UINT_PTR idEvent,
     DWORD dwTime)
 {
-    int i = 0;
     POINT pos;
     POINT posClient;
     HWND hwnd;
-    INT nonclient;
     INT hoverwidth = 0, hoverheight = 0;
     RECT client;
 
     GetCursorPos(&pos);
     hwnd = WindowFromPoint(pos);
 
-    SystemParametersInfoA(SPI_GETMOUSEHOVERWIDTH, 0, &hoverwidth, 0);
-    SystemParametersInfoA(SPI_GETMOUSEHOVERHEIGHT, 0, &hoverheight, 0);
+    SystemParametersInfoW(SPI_GETMOUSEHOVERWIDTH, 0, &hoverwidth, 0);
+    SystemParametersInfoW(SPI_GETMOUSEHOVERHEIGHT, 0, &hoverheight, 0);
 
-    /* loop through tracking events we are processing */
-    while (i < iTrackMax) {
-        if (TrackingList[i].tme.dwFlags & TME_NONCLIENT) {
-            nonclient = 1;
-        }
-        else {
-            nonclient = 0;
-        }
-
-        /* see if this tracking event is looking for TME_LEAVE and that the */
-        /* mouse has left the window */
-        if (TrackingList[i].tme.dwFlags & TME_LEAVE) {
-            if (TrackingList[i].tme.hwndTrack != hwnd) {
-                if (nonclient) {
-                    PostMessageA(TrackingList[i].tme.hwndTrack, WM_NCMOUSELEAVE, 0, 0);
-                }
-                else {
-                    PostMessageA(TrackingList[i].tme.hwndTrack, WM_MOUSELEAVE, 0, 0);
-                }
+    /* see if this tracking event is looking for TME_LEAVE and that the */
+    /* mouse has left the window */
+    if (tracking_info.tme.dwFlags & TME_LEAVE)
+    {
+        if (tracking_info.tme.hwndTrack != hwnd)
+        {
+            if (tracking_info.tme.dwFlags & TME_NONCLIENT)
+                PostMessageW(tracking_info.tme.hwndTrack, WM_NCMOUSELEAVE, 0, 0);
+            else
+                PostMessageW(tracking_info.tme.hwndTrack, WM_MOUSELEAVE, 0, 0);
 
-                /* remove the TME_LEAVE flag */
-                TrackingList[i].tme.dwFlags ^= TME_LEAVE;
-            }
-            else {
-                GetClientRect(hwnd, &client);
-                MapWindowPoints(hwnd, NULL, (LPPOINT)&client, 2);
-                if(PtInRect(&client, pos)) {
-                    if (nonclient) {
-                        PostMessageA(TrackingList[i].tme.hwndTrack, WM_NCMOUSELEAVE, 0, 0);
-                        /* remove the TME_LEAVE flag */
-                        TrackingList[i].tme.dwFlags ^= TME_LEAVE;
-                    }
-                }
-                else {
-                    if (!nonclient) {
-                        PostMessageA(TrackingList[i].tme.hwndTrack, WM_MOUSELEAVE, 0, 0);
-                        /* remove the TME_LEAVE flag */
-                        TrackingList[i].tme.dwFlags ^= TME_LEAVE;
-                    }
-                }
-            }
+            /* remove the TME_LEAVE flag */
+            tracking_info.tme.dwFlags &= ~TME_LEAVE;
         }
-
-        /* see if we are tracking hovering for this hwnd */
-        if(TrackingList[i].tme.dwFlags & TME_HOVER) {
-            /* add the timer interval to the hovering time */
-            TrackingList[i].iHoverTime+=iTimerInterval;
-
-            /* has the cursor moved outside the rectangle centered around pos? */
-            if((abs(pos.x - TrackingList[i].pos.x) > (hoverwidth / 2.0))
-              || (abs(pos.y - TrackingList[i].pos.y) > (hoverheight / 2.0)))
+        else
+        {
+            GetClientRect(hwnd, &client);
+            MapWindowPoints(hwnd, NULL, (LPPOINT)&client, 2);
+            if (PtInRect(&client, pos))
             {
-                /* record this new position as the current position and reset */
-                /* the iHoverTime variable to 0 */
-                TrackingList[i].pos = pos;
-                TrackingList[i].iHoverTime = 0;
+                if (tracking_info.tme.dwFlags & TME_NONCLIENT)
+                {
+                    PostMessageW(tracking_info.tme.hwndTrack, WM_NCMOUSELEAVE, 0, 0);
+                    /* remove the TME_LEAVE flag */
+                    tracking_info.tme.dwFlags &= ~TME_LEAVE;
+                }
             }
-
-            /* has the mouse hovered long enough? */
-            if(TrackingList[i].iHoverTime <= TrackingList[i].tme.dwHoverTime)
+            else
             {
-                posClient.x = pos.x;
-                posClient.y = pos.y;
-                ScreenToClient(hwnd, &posClient);
-                if (nonclient) {
-                    PostMessageW(TrackingList[i].tme.hwndTrack, WM_NCMOUSEHOVER,
-                                get_key_state(), MAKELPARAM( posClient.x, posClient.y ));
-                }
-                else {
-                    PostMessageW(TrackingList[i].tme.hwndTrack, WM_MOUSEHOVER,
-                                get_key_state(), MAKELPARAM( posClient.x, posClient.y ));
+                if (!(tracking_info.tme.dwFlags & TME_NONCLIENT))
+                {
+                    PostMessageW(tracking_info.tme.hwndTrack, WM_MOUSELEAVE, 0, 0);
+                    /* remove the TME_LEAVE flag */
+                    tracking_info.tme.dwFlags &= ~TME_LEAVE;
                 }
-
-                /* stop tracking mouse hover */
-                TrackingList[i].tme.dwFlags ^= TME_HOVER;
             }
         }
+    }
+
+    /* see if we are tracking hovering for this hwnd */
+    if (tracking_info.tme.dwFlags & TME_HOVER)
+    {
+        /* has the cursor moved outside the rectangle centered around pos? */
+        if ((abs(pos.x - tracking_info.pos.x) > (hoverwidth / 2.0)) ||
+            (abs(pos.y - tracking_info.pos.y) > (hoverheight / 2.0)))
+        {
+            /* record this new position as the current position and reset */
+            /* the iHoverTime variable to 0 */
+            tracking_info.pos = pos;
+        }
+        else
+        {
+            posClient.x = pos.x;
+            posClient.y = pos.y;
+            ScreenToClient(hwnd, &posClient);
+
+            if (tracking_info.tme.dwFlags & TME_NONCLIENT)
+                PostMessageW(tracking_info.tme.hwndTrack, WM_NCMOUSEHOVER,
+                            get_key_state(), MAKELPARAM( posClient.x, posClient.y ));
+            else
+                PostMessageW(tracking_info.tme.hwndTrack, WM_MOUSEHOVER,
+                            get_key_state(), MAKELPARAM( posClient.x, posClient.y ));
 
-        /* see if we are still tracking TME_HOVER or TME_LEAVE for this entry */
-        if((TrackingList[i].tme.dwFlags & TME_HOVER) ||
-           (TrackingList[i].tme.dwFlags & TME_LEAVE)) {
-            i++;
-        } else { /* remove this entry from the tracking list */
-            TrackingList[i] = TrackingList[--iTrackMax];
+            /* stop tracking mouse hover */
+            tracking_info.tme.dwFlags &= ~TME_HOVER;
         }
     }
 
     /* stop the timer if the tracking list is empty */
-    if(iTrackMax == 0) {
-        KillTimer(0, timer);
+    if (!(tracking_info.tme.dwFlags & (TME_HOVER | TME_LEAVE)))
+    {
+        memset(&tracking_info, 0, sizeof(tracking_info));
+
+        KillSystemTimer(0, timer);
         timer = 0;
     }
 }
@@ -851,167 +831,71 @@ static void CALLBACK TrackMouseEventProc
 BOOL WINAPI
 TrackMouseEvent (TRACKMOUSEEVENT *ptme)
 {
-    DWORD flags = 0;
-    int i = 0;
-    BOOL cancel = 0, hover = 0, leave = 0, query = 0, nonclient = 0, inclient = 0;
     HWND hwnd;
     POINT pos;
-    RECT client;
-
-
-    pos.x = 0;
-    pos.y = 0;
-    SetRectEmpty(&client);
+    DWORD hover_time;
 
     TRACE("%lx, %lx, %p, %lx\n", ptme->cbSize, ptme->dwFlags, ptme->hwndTrack, ptme->dwHoverTime);
 
     if (ptme->cbSize != sizeof(TRACKMOUSEEVENT)) {
         WARN("wrong TRACKMOUSEEVENT size from app\n");
-        SetLastError(ERROR_INVALID_PARAMETER); /* FIXME not sure if this is correct */
+        SetLastError(ERROR_INVALID_PARAMETER);
         return FALSE;
     }
 
-    flags = ptme->dwFlags;
-
-    /* if HOVER_DEFAULT was specified replace this with the systems current value */
-    if(ptme->dwHoverTime == HOVER_DEFAULT)
-        SystemParametersInfoA(SPI_GETMOUSEHOVERTIME, 0, &(ptme->dwHoverTime), 0);
-
-    GetCursorPos(&pos);
-    hwnd = WindowFromPoint(pos);
-
-    if ( flags & TME_CANCEL ) {
-        flags &= ~ TME_CANCEL;
-        cancel = 1;
-    }
-
-    if ( flags & TME_HOVER  ) {
-        flags &= ~ TME_HOVER;
-        hover = 1;
-    }
+    /* fill the TRACKMOUSEEVENT struct with the current tracking for the given hwnd */
+    if (ptme->dwFlags & TME_QUERY )
+    {
+        *ptme = tracking_info.tme;
 
-    if ( flags & TME_LEAVE ) {
-        flags &= ~ TME_LEAVE;
-        leave = 1;
+        return TRUE; /* return here, TME_QUERY is retrieving information */
     }
 
-    if ( flags & TME_NONCLIENT ) {
-        flags &= ~ TME_NONCLIENT;
-        nonclient = 1;
+    if (!IsWindow(ptme->hwndTrack))
+    {
+        SetLastError(ERROR_INVALID_WINDOW_HANDLE);
+        return FALSE;
     }
 
-    /* fill the TRACKMOUSEEVENT struct with the current tracking for the given hwnd */
-    if ( flags & TME_QUERY ) {
-        flags &= ~ TME_QUERY;
-        query = 1;
-        i = 0;
-
-        /* Find the tracking list entry with the matching hwnd */
-        while((i < iTrackMax) && (TrackingList[i].tme.hwndTrack != ptme->hwndTrack)) {
-            i++;
-        }
-
-        /* hwnd found, fill in the ptme struct */
-        if(i < iTrackMax)
-            *ptme = TrackingList[i].tme;
-        else
-            ptme->dwFlags = 0;
-
-        return TRUE; /* return here, TME_QUERY is retrieving information */
-    }
+    hover_time = ptme->dwHoverTime;
 
-    if ( flags )
-        FIXME("Unknown flag(s) %08lx\n", flags );
+    /* if HOVER_DEFAULT was specified replace this with the systems current value */
+    if (hover_time == HOVER_DEFAULT || hover_time == 0)
+        SystemParametersInfoW(SPI_GETMOUSEHOVERTIME, 0, &hover_time, 0);
 
-    if(cancel) {
-        /* find a matching hwnd if one exists */
-        i = 0;
+    GetCursorPos(&pos);
+    hwnd = WindowFromPoint(pos);
 
-        while((i < iTrackMax) && (TrackingList[i].tme.hwndTrack != ptme->hwndTrack)) {
-          i++;
-        }
+    if (ptme->dwFlags & ~(TME_CANCEL | TME_HOVER | TME_LEAVE | TME_NONCLIENT))
+        FIXME("Unknown flag(s) %08lx\n", ptme->dwFlags & ~(TME_CANCEL | TME_HOVER | TME_LEAVE | TME_NONCLIENT));
 
-        if(i < iTrackMax) {
-            TrackingList[i].tme.dwFlags &= ~(ptme->dwFlags & ~TME_CANCEL);
+    if (ptme->dwFlags & TME_CANCEL)
+    {
+        if (tracking_info.tme.hwndTrack == ptme->hwndTrack)
+        {
+            tracking_info.tme.dwFlags &= ~(ptme->dwFlags & ~TME_CANCEL);
 
             /* if we aren't tracking on hover or leave remove this entry */
-            if(!((TrackingList[i].tme.dwFlags & TME_HOVER) ||
-                 (TrackingList[i].tme.dwFlags & TME_LEAVE)))
+            if (!(tracking_info.tme.dwFlags & (TME_HOVER | TME_LEAVE)))
             {
-                TrackingList[i] = TrackingList[--iTrackMax];
+                memset(&tracking_info, 0, sizeof(tracking_info));
 
-                if(iTrackMax == 0) {
-                    KillTimer(0, timer);
-                    timer = 0;
-                }
+                KillSystemTimer(0, timer);
+                timer = 0;
             }
         }
     } else {
-        /* see if hwndTrack isn't the current window */
-        if(ptme->hwndTrack != hwnd) {
-            if(leave) {
-                if(nonclient) {
-                    PostMessageA(ptme->hwndTrack, WM_NCMOUSELEAVE, 0, 0);
-                }
-                else {
-                    PostMessageA(ptme->hwndTrack, WM_MOUSELEAVE, 0, 0);
-                }
-            }
-        } else {
-            GetClientRect(ptme->hwndTrack, &client);
-            MapWindowPoints(ptme->hwndTrack, NULL, (LPPOINT)&client, 2);
-            if(PtInRect(&client, pos)) {
-                inclient = 1;
-            }
-            if(nonclient && inclient) {
-                PostMessageA(ptme->hwndTrack, WM_NCMOUSELEAVE, 0, 0);
-                return TRUE;
-            }
-            else if(!nonclient && !inclient) {
-                PostMessageA(ptme->hwndTrack, WM_MOUSELEAVE, 0, 0);
-                return TRUE;
-            }
-
-            /* See if this hwnd is already being tracked and update the tracking flags */
-            for(i = 0; i < iTrackMax; i++) {
-                if(TrackingList[i].tme.hwndTrack == ptme->hwndTrack) {
-                    TrackingList[i].tme.dwFlags = 0;
-
-                    if(hover) {
-                        TrackingList[i].tme.dwFlags |= TME_HOVER;
-                        TrackingList[i].tme.dwHoverTime = ptme->dwHoverTime;
-                    }
-
-                    if(leave)
-                        TrackingList[i].tme.dwFlags |= TME_LEAVE;
-
-                    if(nonclient)
-                        TrackingList[i].tme.dwFlags |= TME_NONCLIENT;
-
-                    /* reset iHoverTime as per winapi specs */
-                    TrackingList[i].iHoverTime = 0;
-
-                    return TRUE;
-                }
-            }
-
-            /* if the tracking list is full return FALSE */
-            if (iTrackMax == sizeof (TrackingList) / sizeof(*TrackingList)) {
-                return FALSE;
-            }
-
+        if (ptme->hwndTrack == hwnd)
+        {
             /* Adding new mouse event to the tracking list */
-            TrackingList[iTrackMax].tme = *ptme;
+            tracking_info.tme = *ptme;
+            tracking_info.tme.dwHoverTime = hover_time;
 
             /* Initialize HoverInfo variables even if not hover tracking */
-            TrackingList[iTrackMax].iHoverTime = 0;
-            TrackingList[iTrackMax].pos = pos;
+            tracking_info.pos = pos;
 
-            iTrackMax++;
-
-            if (!timer) {
-                timer = SetTimer(0, 0, iTimerInterval, TrackMouseEventProc);
-            }
+            if (!timer)
+                timer = SetSystemTimer(0, 0, hover_time, TrackMouseEventProc);
         }
     }
 
diff -up cvs/hq/wine/dlls/user/tests/msg.c wine/dlls/user/tests/msg.c
--- cvs/hq/wine/dlls/user/tests/msg.c	2006-06-06 17:37:59.000000000 +0900
+++ wine/dlls/user/tests/msg.c	2006-07-20 21:57:08.000000000 +0900
@@ -7618,6 +7618,159 @@ static void test_quit_message(void)
     ok(msg.message == WM_USER, "Received message 0x%04x instead of WM_USER\n", msg.message);
 }
 
+static const struct message WmMouseHoverSeq[] = {
+    { WM_SYSTIMER, sent },
+    { WM_MOUSEHOVER, sent|wparam, 0 },
+    { 0 }
+};
+
+static void test_TrackMouseEvent(void)
+{
+    MSG msg;
+    TRACKMOUSEEVENT tme;
+    BOOL ret;
+    HWND hwnd, hchild;
+    RECT rc_parent, rc_child;
+    UINT default_hover_time;
+    DWORD start_ticks, end_ticks;
+
+#define track_hover(track_hwnd, track_hover_time) \
+    tme.cbSize = sizeof(tme); \
+    tme.dwFlags = TME_HOVER; \
+    tme.hwndTrack = track_hwnd; \
+    tme.dwHoverTime = track_hover_time; \
+    SetLastError(0xdeadbeef); \
+    ret = TrackMouseEvent(&tme); \
+    ok(ret, "TrackMouseEvent(TME_HOVER) error %ld\n", GetLastError())
+
+#define track_query(expected_track_flags, expected_track_hwnd, expected_hover_time) \
+    tme.cbSize = sizeof(tme); \
+    tme.dwFlags = TME_QUERY; \
+    tme.hwndTrack = (HWND)0xdeadbeef; \
+    tme.dwHoverTime = 0xdeadbeef; \
+    SetLastError(0xdeadbeef); \
+    ret = TrackMouseEvent(&tme); \
+    ok(ret, "TrackMouseEvent(TME_QUERY) error %ld\n", GetLastError());\
+    ok(tme.dwFlags == (expected_track_flags), \
+       "wrong tme.dwFlags %08lx, expected %08x\n", tme.dwFlags, (expected_track_flags)); \
+    ok(tme.hwndTrack == (expected_track_hwnd), \
+       "wrong tme.hwndTrack %p, expected %p\n", tme.hwndTrack, (expected_track_hwnd)); \
+    ok(tme.dwHoverTime == (expected_hover_time), \
+       "wrong tme.dwHoverTime %lu, expected %u\n", tme.dwHoverTime, (expected_hover_time))
+
+#define track_hover_cancel(track_hwnd) \
+    tme.cbSize = sizeof(tme); \
+    tme.dwFlags = TME_HOVER | TME_CANCEL; \
+    tme.hwndTrack = track_hwnd; \
+    tme.dwHoverTime = 0xdeadbeef; \
+    SetLastError(0xdeadbeef); \
+    ret = TrackMouseEvent(&tme); \
+    ok(ret, "TrackMouseEvent(TME_HOVER | TME_CANCEL) error %ld\n", GetLastError())
+
+    default_hover_time = 0xdeadbeef;
+    ret = SystemParametersInfo(SPI_GETMOUSEHOVERTIME, 0, &default_hover_time, 0);
+    ok(ret, "SystemParametersInfo(SPI_GETMOUSEHOVERTIME) failed\n");
+    trace("SPI_GETMOUSEHOVERTIME returned %u ms\n", default_hover_time);
+
+    hwnd = CreateWindowEx(0, "TestWindowClass", NULL,
+			  WS_OVERLAPPEDWINDOW | WS_VISIBLE,
+			  CW_USEDEFAULT, CW_USEDEFAULT, 300, 300, 0,
+			  NULL, NULL, 0);
+    assert(hwnd);
+
+    hchild = CreateWindowEx(0, "TestWindowClass", NULL,
+			  WS_CHILD | WS_BORDER | WS_VISIBLE,
+			  50, 50, 200, 200, hwnd,
+			  NULL, NULL, 0);
+    assert(hchild);
+
+    flush_events();
+    flush_sequence();
+
+    tme.cbSize = 0;
+    tme.dwFlags = TME_QUERY;
+    tme.hwndTrack = (HWND)0xdeadbeef;
+    tme.dwHoverTime = 0xdeadbeef;
+    SetLastError(0xdeadbeef);
+    ret = TrackMouseEvent(&tme);
+    ok(!ret, "TrackMouseEvent should fail\n");
+    ok(GetLastError() == ERROR_INVALID_PARAMETER, "not expected error %ld\n", GetLastError());
+
+    tme.cbSize = sizeof(tme);
+    tme.dwFlags = TME_HOVER;
+    tme.hwndTrack = (HWND)0xdeadbeef;
+    tme.dwHoverTime = 0xdeadbeef;
+    SetLastError(0xdeadbeef);
+    ret = TrackMouseEvent(&tme);
+    ok(!ret, "TrackMouseEvent should fail\n");
+    ok(GetLastError() == ERROR_INVALID_WINDOW_HANDLE, "not expected error %ld\n", GetLastError());
+
+    tme.cbSize = sizeof(tme);
+    tme.dwFlags = TME_HOVER | TME_CANCEL;
+    tme.hwndTrack = (HWND)0xdeadbeef;
+    tme.dwHoverTime = 0xdeadbeef;
+    SetLastError(0xdeadbeef);
+    ret = TrackMouseEvent(&tme);
+    ok(!ret, "TrackMouseEvent should fail\n");
+    ok(GetLastError() == ERROR_INVALID_WINDOW_HANDLE, "not expected error %ld\n", GetLastError());
+
+    GetWindowRect(hwnd, &rc_parent);
+    GetWindowRect(hchild, &rc_child);
+    SetCursorPos(rc_child.left - 10, rc_child.top - 10);
+
+    /* Process messages so that the system updates its internal current
+     * window and hittest, otherwise TrackMouseEvent calls don't have any
+     * effect.
+     */
+    while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessage(&msg);
+    flush_sequence();
+
+    track_query(0, NULL, 0);
+    track_hover(hchild, 0);
+    track_query(0, NULL, 0);
+
+    while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessage(&msg);
+    flush_sequence();
+
+    track_hover(hwnd, 0);
+    track_query(TME_HOVER, hwnd, default_hover_time);
+    start_ticks = GetTickCount();
+    do
+    {
+        while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
+        {
+            /* Timer proc messages are not dispatched to the window proc,
+             * and therefore not logged.
+             */
+            if (msg.message == WM_TIMER || msg.message == WM_SYSTIMER)
+            {
+                struct message s_msg;
+
+                s_msg.message = msg.message;
+                s_msg.flags = sent|wparam|lparam;
+                s_msg.wParam = msg.wParam;
+                s_msg.lParam = msg.lParam;
+                add_message(&s_msg);
+            }
+            DispatchMessage(&msg);
+        }
+
+        end_ticks = GetTickCount();
+    } while (start_ticks + default_hover_time >= end_ticks);
+    ok_sequence(WmMouseHoverSeq, "WmMouseHoverSeq", FALSE);
+
+    track_query(0, NULL, 0);
+    track_hover(hwnd, HOVER_DEFAULT);
+    track_query(TME_HOVER, hwnd, default_hover_time);
+    track_hover_cancel(hwnd);
+
+    DestroyWindow(hwnd);
+
+#undef track_hover
+#undef track_query
+#undef track_hover_cancel
+}
+
 START_TEST(msg)
 {
     BOOL ret;
@@ -7681,6 +7834,7 @@ START_TEST(msg)
     test_SendMessageTimeout();
     test_edit_messages();
     test_quit_message();
+    test_TrackMouseEvent();
 
     UnhookWindowsHookEx(hCBT_hook);
     if (pUnhookWinEvent)





More information about the wine-patches mailing list