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"