user: Various TrackMouseEvent fixes.

- Use WINPOS_WindowFromPoint instead of WindowFromPoint in order to
  use hittest directly to simplify the code. 
- WM_NCMOUSEHOVER and WM_MOUSEHOVER take different parameters.
This commit is contained in:
Dmitry Timoshkov 2006-07-24 21:19:25 +09:00 committed by Alexandre Julliard
parent e882cdf55c
commit 5292f97611
1 changed files with 56 additions and 32 deletions

View File

@ -745,21 +745,26 @@ typedef struct __TRACKINGLIST {
static _TRACKINGLIST tracking_info; static _TRACKINGLIST tracking_info;
static UINT_PTR timer; static UINT_PTR timer;
static void CALLBACK TrackMouseEventProc(HWND hwndUnused, UINT uMsg, UINT_PTR idEvent, static void CALLBACK TrackMouseEventProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent,
DWORD dwTime) DWORD dwTime)
{ {
POINT pos; POINT pos;
POINT posClient; INT hoverwidth = 0, hoverheight = 0, hittest;
HWND hwnd;
INT hoverwidth = 0, hoverheight = 0; TRACE("hwnd %p, msg %04x, id %04x, time %lu\n", hwnd, uMsg, idEvent, dwTime);
RECT client;
GetCursorPos(&pos); GetCursorPos(&pos);
hwnd = WindowFromPoint(pos); hwnd = WINPOS_WindowFromPoint(hwnd, pos, &hittest);
TRACE("point %s hwnd %p hittest %d\n", wine_dbgstr_point(&pos), hwnd, hittest);
SystemParametersInfoW(SPI_GETMOUSEHOVERWIDTH, 0, &hoverwidth, 0); SystemParametersInfoW(SPI_GETMOUSEHOVERWIDTH, 0, &hoverwidth, 0);
SystemParametersInfoW(SPI_GETMOUSEHOVERHEIGHT, 0, &hoverheight, 0); SystemParametersInfoW(SPI_GETMOUSEHOVERHEIGHT, 0, &hoverheight, 0);
TRACE("tracked pos %s, current pos %s, hover width %d, hover height %d\n",
wine_dbgstr_point(&tracking_info.pos), wine_dbgstr_point(&pos),
hoverwidth, hoverheight);
/* see if this tracking event is looking for TME_LEAVE and that the */ /* see if this tracking event is looking for TME_LEAVE and that the */
/* mouse has left the window */ /* mouse has left the window */
if (tracking_info.tme.dwFlags & TME_LEAVE) if (tracking_info.tme.dwFlags & TME_LEAVE)
@ -776,9 +781,7 @@ static void CALLBACK TrackMouseEventProc(HWND hwndUnused, UINT uMsg, UINT_PTR id
} }
else else
{ {
GetClientRect(hwnd, &client); if (hittest == HTCLIENT)
MapWindowPoints(hwnd, NULL, (LPPOINT)&client, 2);
if (PtInRect(&client, pos))
{ {
if (tracking_info.tme.dwFlags & TME_NONCLIENT) if (tracking_info.tme.dwFlags & TME_NONCLIENT)
{ {
@ -799,29 +802,38 @@ static void CALLBACK TrackMouseEventProc(HWND hwndUnused, UINT uMsg, UINT_PTR id
} }
} }
if (tracking_info.tme.hwndTrack != hwnd)
{
/* mouse is gone, stop tracking mouse hover */
tracking_info.tme.dwFlags &= ~TME_HOVER;
}
/* see if we are tracking hovering for this hwnd */ /* see if we are tracking hovering for this hwnd */
if (tracking_info.tme.dwFlags & TME_HOVER) if (tracking_info.tme.dwFlags & TME_HOVER)
{ {
/* has the cursor moved outside the rectangle centered around pos? */ /* has the cursor moved outside the rectangle centered around pos? */
if ((abs(pos.x - tracking_info.pos.x) > (hoverwidth / 2.0)) || if ((abs(pos.x - tracking_info.pos.x) > (hoverwidth / 2)) ||
(abs(pos.y - tracking_info.pos.y) > (hoverheight / 2.0))) (abs(pos.y - tracking_info.pos.y) > (hoverheight / 2)))
{ {
/* record this new position as the current position and reset */ /* record this new position as the current position */
/* the iHoverTime variable to 0 */
tracking_info.pos = pos; tracking_info.pos = pos;
} }
else else
{ {
posClient.x = pos.x; if (hittest == HTCLIENT)
posClient.y = pos.y; {
ScreenToClient(hwnd, &posClient); ScreenToClient(hwnd, &pos);
TRACE("client cursor pos %s\n", wine_dbgstr_point(&pos));
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, PostMessageW(tracking_info.tme.hwndTrack, WM_MOUSEHOVER,
get_key_state(), MAKELPARAM( posClient.x, posClient.y )); get_key_state(), MAKELPARAM( pos.x, pos.y ));
}
else
{
if (tracking_info.tme.dwFlags & TME_NONCLIENT)
PostMessageW(tracking_info.tme.hwndTrack, WM_NCMOUSEHOVER,
hittest, MAKELPARAM( pos.x, pos.y ));
}
/* stop tracking mouse hover */ /* stop tracking mouse hover */
tracking_info.tme.dwFlags &= ~TME_HOVER; tracking_info.tme.dwFlags &= ~TME_HOVER;
@ -831,10 +843,11 @@ static void CALLBACK TrackMouseEventProc(HWND hwndUnused, UINT uMsg, UINT_PTR id
/* stop the timer if the tracking list is empty */ /* stop the timer if the tracking list is empty */
if (!(tracking_info.tme.dwFlags & (TME_HOVER | TME_LEAVE))) if (!(tracking_info.tme.dwFlags & (TME_HOVER | TME_LEAVE)))
{ {
memset(&tracking_info, 0, sizeof(tracking_info)); KillSystemTimer(tracking_info.tme.hwndTrack, timer);
KillSystemTimer(0, timer);
timer = 0; timer = 0;
tracking_info.tme.hwndTrack = 0;
tracking_info.tme.dwFlags = 0;
tracking_info.tme.dwHoverTime = 0;
} }
} }
@ -867,8 +880,9 @@ TrackMouseEvent (TRACKMOUSEEVENT *ptme)
HWND hwnd; HWND hwnd;
POINT pos; POINT pos;
DWORD hover_time; DWORD hover_time;
INT hittest;
TRACE("%lx, %lx, %p, %lx\n", ptme->cbSize, ptme->dwFlags, ptme->hwndTrack, ptme->dwHoverTime); TRACE("%lx, %lx, %p, %lu\n", ptme->cbSize, ptme->dwFlags, ptme->hwndTrack, ptme->dwHoverTime);
if (ptme->cbSize != sizeof(TRACKMOUSEEVENT)) { if (ptme->cbSize != sizeof(TRACKMOUSEEVENT)) {
WARN("wrong TRACKMOUSEEVENT size from app\n"); WARN("wrong TRACKMOUSEEVENT size from app\n");
@ -897,7 +911,8 @@ TrackMouseEvent (TRACKMOUSEEVENT *ptme)
SystemParametersInfoW(SPI_GETMOUSEHOVERTIME, 0, &hover_time, 0); SystemParametersInfoW(SPI_GETMOUSEHOVERTIME, 0, &hover_time, 0);
GetCursorPos(&pos); GetCursorPos(&pos);
hwnd = WindowFromPoint(pos); hwnd = WINPOS_WindowFromPoint(ptme->hwndTrack, pos, &hittest);
TRACE("point %s hwnd %p hittest %d\n", wine_dbgstr_point(&pos), hwnd, hittest);
if (ptme->dwFlags & ~(TME_CANCEL | TME_HOVER | TME_LEAVE | TME_NONCLIENT)) 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)); FIXME("Unknown flag(s) %08lx\n", ptme->dwFlags & ~(TME_CANCEL | TME_HOVER | TME_LEAVE | TME_NONCLIENT));
@ -911,13 +926,23 @@ TrackMouseEvent (TRACKMOUSEEVENT *ptme)
/* if we aren't tracking on hover or leave remove this entry */ /* if we aren't tracking on hover or leave remove this entry */
if (!(tracking_info.tme.dwFlags & (TME_HOVER | TME_LEAVE))) if (!(tracking_info.tme.dwFlags & (TME_HOVER | TME_LEAVE)))
{ {
memset(&tracking_info, 0, sizeof(tracking_info)); KillSystemTimer(tracking_info.tme.hwndTrack, timer);
KillSystemTimer(0, timer);
timer = 0; timer = 0;
tracking_info.tme.hwndTrack = 0;
tracking_info.tme.dwFlags = 0;
tracking_info.tme.dwHoverTime = 0;
} }
} }
} else { } else {
if (timer)
{
KillSystemTimer(tracking_info.tme.hwndTrack, timer);
timer = 0;
tracking_info.tme.hwndTrack = 0;
tracking_info.tme.dwFlags = 0;
tracking_info.tme.dwHoverTime = 0;
}
if (ptme->hwndTrack == hwnd) if (ptme->hwndTrack == hwnd)
{ {
/* Adding new mouse event to the tracking list */ /* Adding new mouse event to the tracking list */
@ -927,8 +952,7 @@ TrackMouseEvent (TRACKMOUSEEVENT *ptme)
/* Initialize HoverInfo variables even if not hover tracking */ /* Initialize HoverInfo variables even if not hover tracking */
tracking_info.pos = pos; tracking_info.pos = pos;
if (!timer) timer = SetSystemTimer(tracking_info.tme.hwndTrack, 0, hover_time, TrackMouseEventProc);
timer = SetSystemTimer(0, 0, hover_time, TrackMouseEventProc);
} }
} }