From 49762a3a5077dd2ef405c19a3d9c602a0a7ae07d Mon Sep 17 00:00:00 2001 From: Rein Klazes Date: Tue, 15 Jan 2002 20:41:41 +0000 Subject: [PATCH] Move the implementation of comctl32._TrackMouseEvent to user32.TrackMouseEvent and call this function in accordance with the specs. --- dlls/comctl32/commctrl.c | 218 +--------------------------------- dlls/user/user32.spec | 2 +- include/winuser.h | 19 +++ windows/input.c | 245 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 268 insertions(+), 216 deletions(-) diff --git a/dlls/comctl32/commctrl.c b/dlls/comctl32/commctrl.c index 60c05f4cb88..1a999b729ba 100644 --- a/dlls/comctl32/commctrl.c +++ b/dlls/comctl32/commctrl.c @@ -918,87 +918,6 @@ HRESULT WINAPI COMCTL32_DllInstall(BOOL bInstall, LPCWSTR cmdline) return S_OK; } - -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; -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) -{ - int i = 0; - POINT pos; - HWND hwnd; - INT hoverwidth = 0, hoverheight = 0; - - GetCursorPos(&pos); - hwnd = WindowFromPoint(pos); - - SystemParametersInfoA(SPI_GETMOUSEHOVERWIDTH, 0, &hoverwidth, 0); - SystemParametersInfoA(SPI_GETMOUSEHOVERHEIGHT, 0, &hoverheight, 0); - - /* loop through tracking events we are processing */ - while (i < iTrackMax) { - /* 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); - - /* remove the TME_LEAVE flag */ - TrackingList[i].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))) - { - /* record this new position as the current position and reset */ - /* the iHoverTime variable to 0 */ - TrackingList[i].pos = pos; - TrackingList[i].iHoverTime = 0; - } - - /* has the mouse hovered long enough? */ - if(TrackingList[i].iHoverTime <= TrackingList[i].tme.dwHoverTime) - { - PostMessageA(TrackingList[i].tme.hwndTrack, WM_MOUSEHOVER, 0, 0); - - /* stop tracking mouse hover */ - TrackingList[i].tme.dwFlags ^= TME_HOVER; - } - } - - /* 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 the timer if the tracking list is empty */ - if(iTrackMax == 0) { - KillTimer(0, timer); - timer = 0; - } -} - /*********************************************************************** * _TrackMouseEvent [COMCTL32.91] * @@ -1019,147 +938,16 @@ static void CALLBACK TrackMouseEventProc(HWND hwndUnused, UINT uMsg, UINT_PTR id * Success: non-zero * Failure: zero * + * IMPLEMENTATION moved to USER32.TrackMouseEvent + * */ BOOL WINAPI _TrackMouseEvent (TRACKMOUSEEVENT *ptme) { - DWORD flags = 0; - int i = 0; - BOOL cancel = 0, hover = 0, leave = 0, query = 0; - HWND hwnd; - POINT pos; - - pos.x = 0; - pos.y = 0; - - TRACE("%lx, %lx, %x, %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 */ - 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; - } - - if ( flags & TME_LEAVE ) { - flags &= ~ TME_LEAVE; - leave = 1; - } - - /* 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 */ - } - - if ( flags ) - FIXME("Unknown flag(s) %08lx\n", flags ); - - if(cancel) { - /* find a matching hwnd if one exists */ - i = 0; - - while((i < iTrackMax) && (TrackingList[i].tme.hwndTrack != ptme->hwndTrack)) { - i++; - } - - if(i < iTrackMax) { - TrackingList[i].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))) - { - TrackingList[i] = TrackingList[--iTrackMax]; - - if(iTrackMax == 0) { - KillTimer(0, timer); - timer = 0; - } - } - } - } else { - /* see if hwndTrack isn't the current window */ - if(ptme->hwndTrack != hwnd) { - if(leave) { - PostMessageA(ptme->hwndTrack, WM_MOUSELEAVE, 0, 0); - } - } else { - /* 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) { - if(hover) { - TrackingList[i].tme.dwFlags |= TME_HOVER; - TrackingList[i].tme.dwHoverTime = ptme->dwHoverTime; - } - - if(leave) - TrackingList[i].tme.dwFlags |= TME_LEAVE; - - /* 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; - } - - /* Adding new mouse event to the tracking list */ - TrackingList[iTrackMax].tme = *ptme; - - /* Initialize HoverInfo variables even if not hover tracking */ - TrackingList[iTrackMax].iHoverTime = 0; - TrackingList[iTrackMax].pos = pos; - - iTrackMax++; - - if (!timer) { - timer = SetTimer(0, 0, iTimerInterval, TrackMouseEventProc); - } - } - } - - return TRUE; + return TrackMouseEvent (ptme); } - /************************************************************************* * GetMUILanguage [COMCTL32.39] * diff --git a/dlls/user/user32.spec b/dlls/user/user32.spec index e26d0826519..828239f3452 100644 --- a/dlls/user/user32.spec +++ b/dlls/user/user32.spec @@ -650,7 +650,7 @@ debug_channels (accel caret class clipboard combo comm cursor dc ddeml dialog @ stdcall SetProcessDefaultLayout(long) SetProcessDefaultLayout @ stdcall RegisterDeviceNotificationA(long ptr long) RegisterDeviceNotificationA @ stub RegisterDeviceNotificationW -@ stub TrackMouseEvent +@ stdcall TrackMouseEvent(ptr) TrackMouseEvent @ stub UnregisterDeviceNotification # win98/win2k diff --git a/include/winuser.h b/include/winuser.h index 883824200aa..d558b29182d 100644 --- a/include/winuser.h +++ b/include/winuser.h @@ -3328,6 +3328,24 @@ typedef struct #define MK_XBUTTON1 0x0020 #define MK_XBUTTON2 0x0040 + +#define WM_MOUSEHOVER 0x02A1 +#define WM_MOUSELEAVE 0x02A3 + +#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; + /* Queue status flags */ #define QS_KEY 0x0001 #define QS_MOUSEMOVE 0x0002 @@ -4143,6 +4161,7 @@ LONG WINAPI TabbedTextOutW(HDC,INT,INT,LPCWSTR,INT,INT,const INT*,INT); #define TabbedTextOut WINELIB_NAME_AW(TabbedTextOut) INT WINAPI ToAscii(UINT,UINT,LPBYTE,LPWORD,UINT); INT WINAPI ToAsciiEx(UINT,UINT,LPBYTE,LPWORD,UINT,HKL); +BOOL WINAPI TrackMouseEvent(LPTRACKMOUSEEVENT); BOOL WINAPI TrackPopupMenu(HMENU,UINT,INT,INT,INT,HWND,const RECT*); INT WINAPI TranslateAccelerator(HWND,HACCEL,LPMSG); BOOL WINAPI TranslateMDISysAccel(HWND,LPMSG); diff --git a/windows/input.c b/windows/input.c index 7a916a7fd82..991289263c5 100644 --- a/windows/input.c +++ b/windows/input.c @@ -929,3 +929,248 @@ HKL WINAPI LoadKeyboardLayoutW(LPCWSTR pwszKLID, UINT Flags) buf[8] = 0; return LoadKeyboardLayoutA(buf, Flags); } + + +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; +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) +{ + int i = 0; + POINT pos; + HWND hwnd; + INT hoverwidth = 0, hoverheight = 0; + + GetCursorPos(&pos); + hwnd = WindowFromPoint(pos); + + SystemParametersInfoA(SPI_GETMOUSEHOVERWIDTH, 0, &hoverwidth, 0); + SystemParametersInfoA(SPI_GETMOUSEHOVERHEIGHT, 0, &hoverheight, 0); + + /* loop through tracking events we are processing */ + while (i < iTrackMax) { + /* 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); + + /* remove the TME_LEAVE flag */ + TrackingList[i].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))) + { + /* record this new position as the current position and reset */ + /* the iHoverTime variable to 0 */ + TrackingList[i].pos = pos; + TrackingList[i].iHoverTime = 0; + } + + /* has the mouse hovered long enough? */ + if(TrackingList[i].iHoverTime <= TrackingList[i].tme.dwHoverTime) + { + PostMessageA(TrackingList[i].tme.hwndTrack, WM_MOUSEHOVER, 0, 0); + + /* stop tracking mouse hover */ + TrackingList[i].tme.dwFlags ^= TME_HOVER; + } + } + + /* 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 the timer if the tracking list is empty */ + if(iTrackMax == 0) { + KillTimer(0, timer); + timer = 0; + } +} + + +/*********************************************************************** + * TrackMouseEvent [USER32] + * + * Requests notification of mouse events + * + * During mouse tracking WM_MOUSEHOVER or WM_MOUSELEAVE events are posted + * to the hwnd specified in the ptme structure. After the event message + * is posted to the hwnd, the entry in the queue is removed. + * + * If the current hwnd isn't ptme->hwndTrack the TME_HOVER flag is completely + * ignored. The TME_LEAVE flag results in a WM_MOUSELEAVE message being posted + * immediately and the TME_LEAVE flag being ignored. + * + * 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 = 0; + BOOL cancel = 0, hover = 0, leave = 0, query = 0; + HWND hwnd; + POINT pos; + + pos.x = 0; + pos.y = 0; + + TRACE("%lx, %lx, %x, %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 */ + 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; + } + + if ( flags & TME_LEAVE ) { + flags &= ~ TME_LEAVE; + leave = 1; + } + + /* 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 */ + } + + if ( flags ) + FIXME("Unknown flag(s) %08lx\n", flags ); + + if(cancel) { + /* find a matching hwnd if one exists */ + i = 0; + + while((i < iTrackMax) && (TrackingList[i].tme.hwndTrack != ptme->hwndTrack)) { + i++; + } + + if(i < iTrackMax) { + TrackingList[i].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))) + { + TrackingList[i] = TrackingList[--iTrackMax]; + + if(iTrackMax == 0) { + KillTimer(0, timer); + timer = 0; + } + } + } + } else { + /* see if hwndTrack isn't the current window */ + if(ptme->hwndTrack != hwnd) { + if(leave) { + PostMessageA(ptme->hwndTrack, WM_MOUSELEAVE, 0, 0); + } + } else { + /* 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) { + if(hover) { + TrackingList[i].tme.dwFlags |= TME_HOVER; + TrackingList[i].tme.dwHoverTime = ptme->dwHoverTime; + } + + if(leave) + TrackingList[i].tme.dwFlags |= TME_LEAVE; + + /* 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; + } + + /* Adding new mouse event to the tracking list */ + TrackingList[iTrackMax].tme = *ptme; + + /* Initialize HoverInfo variables even if not hover tracking */ + TrackingList[iTrackMax].iHoverTime = 0; + TrackingList[iTrackMax].pos = pos; + + iTrackMax++; + + if (!timer) { + timer = SetTimer(0, 0, iTimerInterval, TrackMouseEventProc); + } + } + } + + return TRUE; +} + + +