mirror of
https://github.com/reactos/reactos.git
synced 2025-08-03 20:56:26 +00:00
Bugfix TrackMouseEvent
patch from Yaroslav Ponomarenko yarryp at gmail dot com 1. make it thread safe 2. fixing so ToolBar works /* greatlord */ 1. I did smaller change to the patch 2. I also fixed if with missing { } alredy in ros code See issue #2359 for more details. svn path=/trunk/; revision=27402
This commit is contained in:
parent
05fa42912f
commit
1abc4ee915
2 changed files with 77 additions and 51 deletions
|
@ -122,10 +122,18 @@
|
||||||
/* Internal Thread Data */
|
/* Internal Thread Data */
|
||||||
extern HINSTANCE User32Instance;
|
extern HINSTANCE User32Instance;
|
||||||
|
|
||||||
|
typedef struct _USER32_TRACKINGLIST {
|
||||||
|
TRACKMOUSEEVENT tme;
|
||||||
|
POINT pos; /* center of hover rectangle */
|
||||||
|
UINT_PTR timer;
|
||||||
|
} USER32_TRACKINGLIST,*PUSER32_TRACKINGLIST;
|
||||||
|
|
||||||
|
|
||||||
typedef struct _USER32_THREAD_DATA
|
typedef struct _USER32_THREAD_DATA
|
||||||
{
|
{
|
||||||
MSG LastMessage;
|
MSG LastMessage;
|
||||||
HKL KeyboardLayoutHandle;
|
HKL KeyboardLayoutHandle;
|
||||||
|
USER32_TRACKINGLIST tracking_info; /* TrackMouseEvent stuff */
|
||||||
} USER32_THREAD_DATA, *PUSER32_THREAD_DATA;
|
} USER32_THREAD_DATA, *PUSER32_THREAD_DATA;
|
||||||
|
|
||||||
PUSER32_THREAD_DATA User32GetThreadData();
|
PUSER32_THREAD_DATA User32GetThreadData();
|
||||||
|
|
|
@ -35,15 +35,6 @@
|
||||||
|
|
||||||
/* GLOBALS *******************************************************************/
|
/* GLOBALS *******************************************************************/
|
||||||
|
|
||||||
typedef struct __TRACKINGLIST {
|
|
||||||
TRACKMOUSEEVENT tme;
|
|
||||||
POINT pos; /* center of hover rectangle */
|
|
||||||
} _TRACKINGLIST;
|
|
||||||
|
|
||||||
/* FIXME: move tracking stuff into a per thread data */
|
|
||||||
static _TRACKINGLIST tracking_info;
|
|
||||||
static UINT_PTR timer;
|
|
||||||
static const INT iTimerInterval = 50; /* msec for timer interval */
|
|
||||||
|
|
||||||
|
|
||||||
/* FUNCTIONS *****************************************************************/
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
@ -688,28 +679,41 @@ static void CALLBACK TrackMouseEventProc(HWND hwndUnused, UINT uMsg, UINT_PTR id
|
||||||
HWND hwnd;
|
HWND hwnd;
|
||||||
INT hoverwidth = 0, hoverheight = 0;
|
INT hoverwidth = 0, hoverheight = 0;
|
||||||
RECT client;
|
RECT client;
|
||||||
|
PUSER32_TRACKINGLIST ptracking_info;
|
||||||
|
|
||||||
|
ptracking_info = & User32GetThreadData()->tracking_info;
|
||||||
|
|
||||||
GetCursorPos(&pos);
|
GetCursorPos(&pos);
|
||||||
hwnd = WindowFromPoint(pos);
|
hwnd = WindowFromPoint(pos);
|
||||||
|
|
||||||
// SystemParametersInfoW(SPI_GETMOUSEHOVERWIDTH, 0, &hoverwidth, 0);
|
/* FIXME WIN32k does not support SPI_GETMOUSEHOVERWIDTH and SPI_GETMOUSEHOVERHEIGHT
|
||||||
|
* SystemParametersInfoW(SPI_GETMOUSEHOVERWIDTH, 0, &hoverwidth, 0);
|
||||||
|
* SystemParametersInfoW(SPI_GETMOUSEHOVERHEIGHT, 0, &hoverheight, 0);
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* FIXME hack until win32k support SPI_GETMOUSEHOVERWIDTH and SPI_GETMOUSEHOVERHEIGHT
|
||||||
|
* it take care of some program that does not working
|
||||||
|
*/
|
||||||
hoverwidth = 4;
|
hoverwidth = 4;
|
||||||
// SystemParametersInfoW(SPI_GETMOUSEHOVERHEIGHT, 0, &hoverheight, 0);
|
|
||||||
hoverheight = 4;
|
hoverheight = 4;
|
||||||
|
|
||||||
/* 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 (ptracking_info->tme.dwFlags & TME_LEAVE)
|
||||||
{
|
{
|
||||||
if (tracking_info.tme.hwndTrack != hwnd)
|
if (ptracking_info->tme.hwndTrack != hwnd)
|
||||||
{
|
{
|
||||||
if (tracking_info.tme.dwFlags & TME_NONCLIENT)
|
if (ptracking_info->tme.dwFlags & TME_NONCLIENT)
|
||||||
PostMessageW(tracking_info.tme.hwndTrack, WM_NCMOUSELEAVE, 0, 0);
|
{
|
||||||
|
PostMessageW(ptracking_info->tme.hwndTrack, WM_NCMOUSELEAVE, 0, 0);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
PostMessageW(tracking_info.tme.hwndTrack, WM_MOUSELEAVE, 0, 0);
|
{
|
||||||
|
PostMessageW(ptracking_info->tme.hwndTrack, WM_MOUSELEAVE, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
/* remove the TME_LEAVE flag */
|
/* remove the TME_LEAVE flag */
|
||||||
tracking_info.tme.dwFlags &= ~TME_LEAVE;
|
ptracking_info->tme.dwFlags &= ~TME_LEAVE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -717,35 +721,35 @@ static void CALLBACK TrackMouseEventProc(HWND hwndUnused, UINT uMsg, UINT_PTR id
|
||||||
MapWindowPoints(hwnd, NULL, (LPPOINT)&client, 2);
|
MapWindowPoints(hwnd, NULL, (LPPOINT)&client, 2);
|
||||||
if (PtInRect(&client, pos))
|
if (PtInRect(&client, pos))
|
||||||
{
|
{
|
||||||
if (tracking_info.tme.dwFlags & TME_NONCLIENT)
|
if (ptracking_info->tme.dwFlags & TME_NONCLIENT)
|
||||||
{
|
{
|
||||||
PostMessageW(tracking_info.tme.hwndTrack, WM_NCMOUSELEAVE, 0, 0);
|
PostMessageW(ptracking_info->tme.hwndTrack, WM_NCMOUSELEAVE, 0, 0);
|
||||||
/* remove the TME_LEAVE flag */
|
/* remove the TME_LEAVE flag */
|
||||||
tracking_info.tme.dwFlags &= ~TME_LEAVE;
|
ptracking_info->tme.dwFlags &= ~TME_LEAVE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!(tracking_info.tme.dwFlags & TME_NONCLIENT))
|
if (!(ptracking_info->tme.dwFlags & TME_NONCLIENT))
|
||||||
{
|
{
|
||||||
PostMessageW(tracking_info.tme.hwndTrack, WM_MOUSELEAVE, 0, 0);
|
PostMessageW(ptracking_info->tme.hwndTrack, WM_MOUSELEAVE, 0, 0);
|
||||||
/* remove the TME_LEAVE flag */
|
/* remove the TME_LEAVE flag */
|
||||||
tracking_info.tme.dwFlags &= ~TME_LEAVE;
|
ptracking_info->tme.dwFlags &= ~TME_LEAVE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 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 (ptracking_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 - ptracking_info->pos.x) > (hoverwidth / 2.0)) ||
|
||||||
(abs(pos.y - tracking_info.pos.y) > (hoverheight / 2.0)))
|
(abs(pos.y - ptracking_info->pos.y) > (hoverheight / 2.0)))
|
||||||
{
|
{
|
||||||
/* record this new position as the current position and reset */
|
/* record this new position as the current position and reset */
|
||||||
/* the iHoverTime variable to 0 */
|
/* the iHoverTime variable to 0 */
|
||||||
tracking_info.pos = pos;
|
ptracking_info->pos = pos;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -753,25 +757,27 @@ static void CALLBACK TrackMouseEventProc(HWND hwndUnused, UINT uMsg, UINT_PTR id
|
||||||
posClient.y = pos.y;
|
posClient.y = pos.y;
|
||||||
ScreenToClient(hwnd, &posClient);
|
ScreenToClient(hwnd, &posClient);
|
||||||
|
|
||||||
if (tracking_info.tme.dwFlags & TME_NONCLIENT)
|
if (ptracking_info->tme.dwFlags & TME_NONCLIENT)
|
||||||
PostMessageW(tracking_info.tme.hwndTrack, WM_NCMOUSEHOVER,
|
{
|
||||||
|
PostMessageW(ptracking_info->tme.hwndTrack, WM_NCMOUSEHOVER,
|
||||||
get_key_state(), MAKELPARAM( posClient.x, posClient.y ));
|
get_key_state(), MAKELPARAM( posClient.x, posClient.y ));
|
||||||
|
}
|
||||||
else
|
else
|
||||||
PostMessageW(tracking_info.tme.hwndTrack, WM_MOUSEHOVER,
|
{
|
||||||
|
PostMessageW(ptracking_info->tme.hwndTrack, WM_MOUSEHOVER,
|
||||||
get_key_state(), MAKELPARAM( posClient.x, posClient.y ));
|
get_key_state(), MAKELPARAM( posClient.x, posClient.y ));
|
||||||
|
}
|
||||||
|
|
||||||
/* stop tracking mouse hover */
|
/* stop tracking mouse hover */
|
||||||
tracking_info.tme.dwFlags &= ~TME_HOVER;
|
ptracking_info->tme.dwFlags &= ~TME_HOVER;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 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 (!(ptracking_info->tme.dwFlags & (TME_HOVER | TME_LEAVE)))
|
||||||
{
|
{
|
||||||
memset(&tracking_info, 0, sizeof(tracking_info));
|
KillTimer(0, ptracking_info->timer);
|
||||||
|
RtlZeroMemory(ptracking_info,sizeof(USER32_TRACKINGLIST));
|
||||||
KillTimer(0, timer);
|
|
||||||
timer = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -798,7 +804,7 @@ static void CALLBACK TrackMouseEventProc(HWND hwndUnused, UINT uMsg, UINT_PTR id
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
* @unimplemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
BOOL
|
BOOL
|
||||||
STDCALL
|
STDCALL
|
||||||
|
@ -808,6 +814,7 @@ TrackMouseEvent(
|
||||||
HWND hwnd;
|
HWND hwnd;
|
||||||
POINT pos;
|
POINT pos;
|
||||||
DWORD hover_time;
|
DWORD hover_time;
|
||||||
|
PUSER32_TRACKINGLIST ptracking_info;
|
||||||
|
|
||||||
TRACE("%lx, %lx, %p, %lx\n", ptme->cbSize, ptme->dwFlags, ptme->hwndTrack, ptme->dwHoverTime);
|
TRACE("%lx, %lx, %p, %lx\n", ptme->cbSize, ptme->dwFlags, ptme->hwndTrack, ptme->dwHoverTime);
|
||||||
|
|
||||||
|
@ -817,10 +824,13 @@ TrackMouseEvent(
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ptracking_info = & User32GetThreadData()->tracking_info;
|
||||||
|
|
||||||
/* fill the TRACKMOUSEEVENT struct with the current tracking for the given hwnd */
|
/* fill the TRACKMOUSEEVENT struct with the current tracking for the given hwnd */
|
||||||
if (ptme->dwFlags & TME_QUERY )
|
if (ptme->dwFlags & TME_QUERY )
|
||||||
{
|
{
|
||||||
*ptme = tracking_info.tme;
|
*ptme = ptracking_info->tme;
|
||||||
|
ptme->cbSize = sizeof(TRACKMOUSEEVENT);
|
||||||
|
|
||||||
return TRUE; /* return here, TME_QUERY is retrieving information */
|
return TRUE; /* return here, TME_QUERY is retrieving information */
|
||||||
}
|
}
|
||||||
|
@ -835,42 +845,50 @@ TrackMouseEvent(
|
||||||
|
|
||||||
/* if HOVER_DEFAULT was specified replace this with the systems current value */
|
/* if HOVER_DEFAULT was specified replace this with the systems current value */
|
||||||
if (hover_time == HOVER_DEFAULT || hover_time == 0)
|
if (hover_time == HOVER_DEFAULT || hover_time == 0)
|
||||||
// SystemParametersInfoW(SPI_GETMOUSEHOVERTIME, 0, &hover_time, 0);
|
{
|
||||||
|
/* FIXME SPI_GETMOUSEHOVERTIME are not implement in win32k
|
||||||
|
* SystemParametersInfoW(SPI_GETMOUSEHOVERTIME, 0, &hover_time, 0);
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* FIXME Hack until SPI_GETMOUSEHOVERTIME are implement some program need this being set to working */
|
||||||
hover_time = 400;
|
hover_time = 400;
|
||||||
|
}
|
||||||
|
|
||||||
GetCursorPos(&pos);
|
GetCursorPos(&pos);
|
||||||
hwnd = WindowFromPoint(pos);
|
hwnd = WindowFromPoint(pos);
|
||||||
|
|
||||||
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));
|
||||||
|
}
|
||||||
|
|
||||||
if (ptme->dwFlags & TME_CANCEL)
|
if (ptme->dwFlags & TME_CANCEL)
|
||||||
{
|
{
|
||||||
if (tracking_info.tme.hwndTrack == ptme->hwndTrack)
|
if (ptracking_info->tme.hwndTrack == ptme->hwndTrack)
|
||||||
{
|
{
|
||||||
tracking_info.tme.dwFlags &= ~(ptme->dwFlags & ~TME_CANCEL);
|
ptracking_info->tme.dwFlags &= ~(ptme->dwFlags & ~TME_CANCEL);
|
||||||
|
|
||||||
/* 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 (!(ptracking_info->tme.dwFlags & (TME_HOVER | TME_LEAVE)))
|
||||||
{
|
{
|
||||||
memset(&tracking_info, 0, sizeof(tracking_info));
|
KillTimer(0, ptracking_info->timer);
|
||||||
|
RtlZeroMemory(ptracking_info,sizeof(USER32_TRACKINGLIST));
|
||||||
KillTimer(0, timer);
|
|
||||||
timer = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (ptme->hwndTrack == hwnd)
|
if (ptme->hwndTrack == hwnd)
|
||||||
{
|
{
|
||||||
/* Adding new mouse event to the tracking list */
|
/* Adding new mouse event to the tracking list */
|
||||||
tracking_info.tme = *ptme;
|
ptracking_info->tme = *ptme;
|
||||||
tracking_info.tme.dwHoverTime = hover_time;
|
ptracking_info->tme.dwHoverTime = hover_time;
|
||||||
|
|
||||||
/* Initialize HoverInfo variables even if not hover tracking */
|
/* Initialize HoverInfo variables even if not hover tracking */
|
||||||
tracking_info.pos = pos;
|
ptracking_info->pos = pos;
|
||||||
|
|
||||||
if (!timer)
|
if (!ptracking_info->timer)
|
||||||
timer = SetTimer(0, 0, hover_time, TrackMouseEventProc);
|
{
|
||||||
|
ptracking_info->timer = SetTimer(0, 0, hover_time, TrackMouseEventProc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue