Index: include/commctrl.h
===================================================================
RCS file: /home/wine/wine/include/commctrl.h,v
retrieving revision 1.123
diff -u -r1.123 commctrl.h
--- include/commctrl.h	11 Nov 2003 00:29:31 -0000	1.123
+++ include/commctrl.h	21 Nov 2003 05:35:26 -0000
@@ -603,12 +603,15 @@
 #ifndef WM_MOUSEHOVER
 #define WM_MOUSEHOVER                   0x02A1
 #define WM_MOUSELEAVE                   0x02A3
+#define WM_NCMOUSEHOVER                 0x02A0
+#define WM_NCMOUSELEAVE                 0x02A2
 #endif

 #ifndef TME_HOVER

 #define TME_HOVER       0x00000001
 #define TME_LEAVE       0x00000002
+#define TME_NONCLIENT   0x00000010
 #define TME_QUERY       0x40000000
 #define TME_CANCEL      0x80000000

Index: include/winuser.h
===================================================================
RCS file: /home/wine/wine/include/winuser.h,v
retrieving revision 1.172
diff -u -r1.172 winuser.h
--- include/winuser.h	14 Nov 2003 03:32:43 -0000	1.172
+++ include/winuser.h	21 Nov 2003 05:35:28 -0000
@@ -3392,9 +3392,13 @@

 #define WM_MOUSEHOVER       0x02A1
 #define WM_MOUSELEAVE       0x02A3
+#define WM_NCMOUSEHOVER     0x02A0
+#define WM_NCMOUSELEAVE     0x02A2
+

 #define TME_HOVER       0x00000001
 #define TME_LEAVE       0x00000002
+#define TME_NONCLIENT   0x00000010
 #define TME_QUERY       0x40000000
 #define TME_CANCEL      0x80000000

Index: windows/input.c
===================================================================
RCS file: /home/wine/wine/windows/input.c,v
retrieving revision 1.96
diff -u -r1.96 input.c
--- windows/input.c	14 Nov 2003 03:32:43 -0000	1.96
+++ windows/input.c	21 Nov 2003 05:35:28 -0000
@@ -965,8 +965,6 @@
 static UINT_PTR timer;
 static const INT iTimerInterval = 50; /* msec for timer interval */

-/* FIXME: need to implement WM_NCMOUSELEAVE and WM_NCMOUSEHOVER for */
-/* TrackMouseEventProc and _TrackMouseEvent */
 static void CALLBACK TrackMouseEventProc(HWND hwndUnused, UINT uMsg, UINT_PTR idEvent,
     DWORD dwTime)
 {
@@ -974,7 +972,9 @@
     POINT pos;
     POINT posClient;
     HWND hwnd;
+    INT nonclient;
     INT hoverwidth = 0, hoverheight = 0;
+    RECT client;

     GetCursorPos(&pos);
     hwnd = WindowFromPoint(pos);
@@ -984,14 +984,45 @@

     /* 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) &&
-             (TrackingList[i].tme.hwndTrack != hwnd)) {
-            PostMessageA(TrackingList[i].tme.hwndTrack, WM_MOUSELEAVE, 0, 0);
+        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);
+                }

-            /* remove the TME_LEAVE flag */
-            TrackingList[i].tme.dwFlags ^= TME_LEAVE;
+                /* 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;
+                    }
+                }
+            }
         }

         /* see if we are tracking hovering for this hwnd */
@@ -1011,12 +1042,18 @@

             /* has the mouse hovered long enough? */
             if(TrackingList[i].iHoverTime <= TrackingList[i].tme.dwHoverTime)
-             {
+            {
 		posClient.x = pos.x;
 		posClient.y = pos.y;
 		ScreenToClient(hwnd, &posClient);
-                PostMessageW(TrackingList[i].tme.hwndTrack, WM_MOUSEHOVER,
-                             get_key_state(), MAKELPARAM( posClient.x, posClient.y ));
+                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 ));
+                }

                 /* stop tracking mouse hover */
                 TrackingList[i].tme.dwFlags ^= TME_HOVER;
@@ -1067,12 +1104,15 @@
 {
     DWORD flags = 0;
     int i = 0;
-    BOOL cancel = 0, hover = 0, leave = 0, query = 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);

     TRACE("%lx, %lx, %p, %lx\n", ptme->cbSize, ptme->dwFlags, ptme->hwndTrack, ptme->dwHoverTime);

@@ -1106,6 +1146,11 @@
         leave = 1;
     }

+    if ( flags & TME_NONCLIENT ) {
+        flags &= ~ TME_NONCLIENT;
+        nonclient = 1;
+    }
+
     /* fill the TRACKMOUSEEVENT struct with the current tracking for the given hwnd */
     if ( flags & TME_QUERY ) {
         flags &= ~ TME_QUERY;
@@ -1156,12 +1201,33 @@
         /* see if hwndTrack isn't the current window */
         if(ptme->hwndTrack != hwnd) {
             if(leave) {
-                PostMessageA(ptme->hwndTrack, WM_MOUSELEAVE, 0, 0);
+                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;
@@ -1169,6 +1235,9 @@

                     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;
