From 271f522fa9ae11f62ed112f5316bb72855399cb0 Mon Sep 17 00:00:00 2001
From: Shaun Morris <shaun@blueneptune.com>
Date: Mon, 20 Dec 1999 03:48:25 +0000
Subject: [PATCH] Implemented _TrackMouseEvent for the TME_LEAVE flag.

---
 dlls/comctl32/comctl32.spec |   2 +-
 dlls/comctl32/commctrl.c    | 102 ++++++++++++++++++++++++++++++++++++
 include/commctrl.h          |  29 ++++++++++
 3 files changed, 132 insertions(+), 1 deletion(-)

diff --git a/dlls/comctl32/comctl32.spec b/dlls/comctl32/comctl32.spec
index e207c92800a..3fe9162b577 100644
--- a/dlls/comctl32/comctl32.spec
+++ b/dlls/comctl32/comctl32.spec
@@ -92,7 +92,7 @@ init	COMCTL32_LibMain
  84 stdcall PropertySheetA(ptr) PropertySheetA
  85 stdcall PropertySheetW(ptr) PropertySheetW
  86 stdcall UninitializeFlatSB(long) UninitializeFlatSB
- 87 stub _TrackMouseEvent
+ 87 stdcall _TrackMouseEvent(ptr) _TrackMouseEvent
 
 151 stdcall CreateMRUListA(ptr) CreateMRUListA
 152 stdcall FreeMRUList(ptr) FreeMRUListA
diff --git a/dlls/comctl32/commctrl.c b/dlls/comctl32/commctrl.c
index 7b0cf06e335..b6bfa1352fa 100644
--- a/dlls/comctl32/commctrl.c
+++ b/dlls/comctl32/commctrl.c
@@ -849,3 +849,105 @@ COMCTL32_DllGetVersion (DLLVERSIONINFO *pdvi)
 
     return S_OK;
 }
+
+
+static int iTrackMax = 0;
+static HWND TrackingList[10];
+static UINT_PTR timer;
+
+static void CALLBACK TrackMouseEventProc(HWND hwndUnused, UINT uMsg, UINT_PTR idEvent, DWORD dwTime) {
+	int i = 0;
+	POINT pos;
+	HWND hwnd;
+	BOOL keepTracking = FALSE;
+	GetCursorPos(&pos);
+	hwnd = WindowFromPoint(pos);
+	/* Loop through the list of windows waiting on mouse exit */
+	while (i < iTrackMax) {
+		if (TrackingList[i] != hwnd) 
+			PostMessageA(TrackingList[i], WM_MOUSELEAVE, 0, 0);
+		else
+			keepTracking = TRUE;
+
+
+		i++;
+	}
+	
+	if (keepTracking) {
+		iTrackMax = 1;
+		TrackingList[0] = hwnd;
+	}
+	else
+		KillTimer(0, timer);
+}
+
+/***********************************************************************
+ * _TrackMouseEvent [COMCTL32.25]
+ *
+ * Requests notification of mouse events
+ *
+ * PARAMS
+ *     ptme [I,O] pointer to TRACKMOUSEEVENT information structure.
+ *
+ * RETURNS
+ *     Success: non-zero
+ *     Failure: zero
+ *
+ */
+
+BOOL WINAPI
+_TrackMouseEvent (TRACKMOUSEEVENT *ptme)
+{
+    DWORD flags = 0;
+	int i;
+	BOOL cancel = 0, hover = 0, leave = 0, query = 0;
+	if (ptme->cbSize != sizeof(TRACKMOUSEEVENT)) {
+        WARN("wrong TRACKMOUSEEVENT size from app");
+	return E_INVALIDARG;
+    }
+
+    TRACE("%lx, %lx, %x, %lx\n", ptme->cbSize, ptme->dwFlags, ptme->hwndTrack, ptme->dwHoverTime);
+
+	flags = ptme->dwFlags;
+    if ( flags & TME_CANCEL ) {
+		cancel = 1;
+		flags &= ~ TME_CANCEL;
+	}
+    if ( flags & TME_HOVER  ) {
+		hover = 1;
+		flags &= ~ TME_HOVER;
+		FIXME("TME_HOVER unimplemented\n" );
+	}
+    if ( flags & TME_LEAVE ) {
+		leave = 1;
+		flags &= ~ TME_LEAVE;
+	}
+    if ( flags & TME_QUERY ) {
+		query = 1;
+		flags &= ~ TME_QUERY;
+		FIXME("TME_QUERY unimplemented\n" );
+	}
+
+	if ( flags )
+		FIXME("Unknown flag(s) %ld\n", flags & ~(TME_CANCEL | TME_HOVER | TME_LEAVE | TME_QUERY) );
+
+	if (leave) {
+		if (cancel) {
+			for (i = 0; i < iTrackMax; i++) 
+				if (TrackingList[i] == ptme->hwndTrack) 
+					TrackingList[i] = TrackingList[--iTrackMax];
+		}
+		else {
+			if (iTrackMax == sizeof (TrackingList) / sizeof *TrackingList) 
+				return FALSE;
+
+			/* Add hwndTrack to the track list */
+			TrackingList[iTrackMax++] = ptme->hwndTrack;
+			if (!timer)
+				timer = SetTimer(0, 0, 50, TrackMouseEventProc);
+		}
+	}
+
+	return TRUE;
+}
+
diff --git a/include/commctrl.h b/include/commctrl.h
index 7ed528614fe..a9b1edb398f 100644
--- a/include/commctrl.h
+++ b/include/commctrl.h
@@ -477,6 +477,35 @@ BOOL     WINAPI ImageList_Write(HIMAGELIST, LPSTREAM);
 #define ImageList_RemoveAll(himl) ImageList_Remove(himl,-1)
 
 
+#ifndef WM_MOUSEHOVER
+#define WM_MOUSEHOVER                   0x02A1
+#define WM_MOUSELEAVE                   0x02A3
+#endif
+
+#ifndef TME_HOVER
+
+#define TME_HOVER       0x00000001
+#define TME_LEAVE       0x00000002
+#define TME_QUERY       0x40000000
+#define TME_CANCEL      0x80000000
+
+
+#define HOVER_DEFAULT   0xFFFFFFFF
+
+typedef struct tagTRACKMOUSEEVENT {
+    DWORD cbSize;
+    DWORD dwFlags;
+    HWND  hwndTrack;
+    DWORD dwHoverTime;
+} TRACKMOUSEEVENT, *LPTRACKMOUSEEVENT;
+
+#endif 
+
+BOOL
+WINAPI
+_TrackMouseEvent(
+    LPTRACKMOUSEEVENT lpEventTrack);
+
 /* Flat Scrollbar control */
 
 #define FLATSB_CLASS16        "flatsb_class"
-- 
GitLab