user: Add a TrackMouseEvent test, make it pass under Wine.
This commit is contained in:
parent
8d139c8b96
commit
f1e46cbe85
|
@ -706,121 +706,101 @@ BOOL WINAPI UnloadKeyboardLayout(HKL hkl)
|
||||||
typedef struct __TRACKINGLIST {
|
typedef struct __TRACKINGLIST {
|
||||||
TRACKMOUSEEVENT tme;
|
TRACKMOUSEEVENT tme;
|
||||||
POINT pos; /* center of hover rectangle */
|
POINT pos; /* center of hover rectangle */
|
||||||
INT iHoverTime; /* elapsed time the cursor has been inside of the hover rect */
|
|
||||||
} _TRACKINGLIST;
|
} _TRACKINGLIST;
|
||||||
|
|
||||||
static _TRACKINGLIST TrackingList[10];
|
/* FIXME: move tracking stuff into a per thread data */
|
||||||
static int iTrackMax = 0;
|
static _TRACKINGLIST tracking_info;
|
||||||
static UINT_PTR timer;
|
static UINT_PTR timer;
|
||||||
static const INT iTimerInterval = 50; /* msec for timer interval */
|
|
||||||
|
|
||||||
static void CALLBACK TrackMouseEventProc(HWND hwndUnused, UINT uMsg, UINT_PTR idEvent,
|
static void CALLBACK TrackMouseEventProc(HWND hwndUnused, UINT uMsg, UINT_PTR idEvent,
|
||||||
DWORD dwTime)
|
DWORD dwTime)
|
||||||
{
|
{
|
||||||
int i = 0;
|
|
||||||
POINT pos;
|
POINT pos;
|
||||||
POINT posClient;
|
POINT posClient;
|
||||||
HWND hwnd;
|
HWND hwnd;
|
||||||
INT nonclient;
|
|
||||||
INT hoverwidth = 0, hoverheight = 0;
|
INT hoverwidth = 0, hoverheight = 0;
|
||||||
RECT client;
|
RECT client;
|
||||||
|
|
||||||
GetCursorPos(&pos);
|
GetCursorPos(&pos);
|
||||||
hwnd = WindowFromPoint(pos);
|
hwnd = WindowFromPoint(pos);
|
||||||
|
|
||||||
SystemParametersInfoA(SPI_GETMOUSEHOVERWIDTH, 0, &hoverwidth, 0);
|
SystemParametersInfoW(SPI_GETMOUSEHOVERWIDTH, 0, &hoverwidth, 0);
|
||||||
SystemParametersInfoA(SPI_GETMOUSEHOVERHEIGHT, 0, &hoverheight, 0);
|
SystemParametersInfoW(SPI_GETMOUSEHOVERHEIGHT, 0, &hoverheight, 0);
|
||||||
|
|
||||||
/* loop through tracking events we are processing */
|
/* see if this tracking event is looking for TME_LEAVE and that the */
|
||||||
while (i < iTrackMax) {
|
/* mouse has left the window */
|
||||||
if (TrackingList[i].tme.dwFlags & TME_NONCLIENT) {
|
if (tracking_info.tme.dwFlags & TME_LEAVE)
|
||||||
nonclient = 1;
|
{
|
||||||
|
if (tracking_info.tme.hwndTrack != hwnd)
|
||||||
|
{
|
||||||
|
if (tracking_info.tme.dwFlags & TME_NONCLIENT)
|
||||||
|
PostMessageW(tracking_info.tme.hwndTrack, WM_NCMOUSELEAVE, 0, 0);
|
||||||
|
else
|
||||||
|
PostMessageW(tracking_info.tme.hwndTrack, WM_MOUSELEAVE, 0, 0);
|
||||||
|
|
||||||
|
/* remove the TME_LEAVE flag */
|
||||||
|
tracking_info.tme.dwFlags &= ~TME_LEAVE;
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
nonclient = 0;
|
{
|
||||||
}
|
GetClientRect(hwnd, &client);
|
||||||
|
MapWindowPoints(hwnd, NULL, (LPPOINT)&client, 2);
|
||||||
/* see if this tracking event is looking for TME_LEAVE and that the */
|
if (PtInRect(&client, pos))
|
||||||
/* mouse has left the window */
|
|
||||||
if (TrackingList[i].tme.dwFlags & TME_LEAVE) {
|
|
||||||
if (TrackingList[i].tme.hwndTrack != hwnd) {
|
|
||||||
if (nonclient) {
|
|
||||||
PostMessageA(TrackingList[i].tme.hwndTrack, WM_NCMOUSELEAVE, 0, 0);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
PostMessageA(TrackingList[i].tme.hwndTrack, WM_MOUSELEAVE, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* remove the TME_LEAVE flag */
|
|
||||||
TrackingList[i].tme.dwFlags ^= TME_LEAVE;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
GetClientRect(hwnd, &client);
|
|
||||||
MapWindowPoints(hwnd, NULL, (LPPOINT)&client, 2);
|
|
||||||
if(PtInRect(&client, pos)) {
|
|
||||||
if (nonclient) {
|
|
||||||
PostMessageA(TrackingList[i].tme.hwndTrack, WM_NCMOUSELEAVE, 0, 0);
|
|
||||||
/* remove the TME_LEAVE flag */
|
|
||||||
TrackingList[i].tme.dwFlags ^= TME_LEAVE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (!nonclient) {
|
|
||||||
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 */
|
if (tracking_info.tme.dwFlags & TME_NONCLIENT)
|
||||||
/* the iHoverTime variable to 0 */
|
{
|
||||||
TrackingList[i].pos = pos;
|
PostMessageW(tracking_info.tme.hwndTrack, WM_NCMOUSELEAVE, 0, 0);
|
||||||
TrackingList[i].iHoverTime = 0;
|
/* remove the TME_LEAVE flag */
|
||||||
|
tracking_info.tme.dwFlags &= ~TME_LEAVE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
/* has the mouse hovered long enough? */
|
|
||||||
if(TrackingList[i].iHoverTime <= TrackingList[i].tme.dwHoverTime)
|
|
||||||
{
|
{
|
||||||
posClient.x = pos.x;
|
if (!(tracking_info.tme.dwFlags & TME_NONCLIENT))
|
||||||
posClient.y = pos.y;
|
{
|
||||||
ScreenToClient(hwnd, &posClient);
|
PostMessageW(tracking_info.tme.hwndTrack, WM_MOUSELEAVE, 0, 0);
|
||||||
if (nonclient) {
|
/* remove the TME_LEAVE flag */
|
||||||
PostMessageW(TrackingList[i].tme.hwndTrack, WM_NCMOUSEHOVER,
|
tracking_info.tme.dwFlags &= ~TME_LEAVE;
|
||||||
get_key_state(), MAKELPARAM( posClient.x, posClient.y ));
|
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
PostMessageW(TrackingList[i].tme.hwndTrack, WM_MOUSEHOVER,
|
|
||||||
get_key_state(), MAKELPARAM( posClient.x, posClient.y ));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* stop tracking mouse hover */
|
|
||||||
TrackingList[i].tme.dwFlags ^= TME_HOVER;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* see if we are still tracking TME_HOVER or TME_LEAVE for this entry */
|
/* see if we are tracking hovering for this hwnd */
|
||||||
if((TrackingList[i].tme.dwFlags & TME_HOVER) ||
|
if (tracking_info.tme.dwFlags & TME_HOVER)
|
||||||
(TrackingList[i].tme.dwFlags & TME_LEAVE)) {
|
{
|
||||||
i++;
|
/* has the cursor moved outside the rectangle centered around pos? */
|
||||||
} else { /* remove this entry from the tracking list */
|
if ((abs(pos.x - tracking_info.pos.x) > (hoverwidth / 2.0)) ||
|
||||||
TrackingList[i] = TrackingList[--iTrackMax];
|
(abs(pos.y - tracking_info.pos.y) > (hoverheight / 2.0)))
|
||||||
|
{
|
||||||
|
/* record this new position as the current position and reset */
|
||||||
|
/* the iHoverTime variable to 0 */
|
||||||
|
tracking_info.pos = pos;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
posClient.x = pos.x;
|
||||||
|
posClient.y = pos.y;
|
||||||
|
ScreenToClient(hwnd, &posClient);
|
||||||
|
|
||||||
|
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,
|
||||||
|
get_key_state(), MAKELPARAM( posClient.x, posClient.y ));
|
||||||
|
|
||||||
|
/* stop tracking mouse hover */
|
||||||
|
tracking_info.tme.dwFlags &= ~TME_HOVER;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* stop the timer if the tracking list is empty */
|
/* stop the timer if the tracking list is empty */
|
||||||
if(iTrackMax == 0) {
|
if (!(tracking_info.tme.dwFlags & (TME_HOVER | TME_LEAVE)))
|
||||||
KillTimer(0, timer);
|
{
|
||||||
|
memset(&tracking_info, 0, sizeof(tracking_info));
|
||||||
|
|
||||||
|
KillSystemTimer(0, timer);
|
||||||
timer = 0;
|
timer = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -851,167 +831,71 @@ static void CALLBACK TrackMouseEventProc(HWND hwndUnused, UINT uMsg, UINT_PTR id
|
||||||
BOOL WINAPI
|
BOOL WINAPI
|
||||||
TrackMouseEvent (TRACKMOUSEEVENT *ptme)
|
TrackMouseEvent (TRACKMOUSEEVENT *ptme)
|
||||||
{
|
{
|
||||||
DWORD flags = 0;
|
|
||||||
int i = 0;
|
|
||||||
BOOL cancel = 0, hover = 0, leave = 0, query = 0, nonclient = 0, inclient = 0;
|
|
||||||
HWND hwnd;
|
HWND hwnd;
|
||||||
POINT pos;
|
POINT pos;
|
||||||
RECT client;
|
DWORD hover_time;
|
||||||
|
|
||||||
|
|
||||||
pos.x = 0;
|
|
||||||
pos.y = 0;
|
|
||||||
SetRectEmpty(&client);
|
|
||||||
|
|
||||||
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);
|
||||||
|
|
||||||
if (ptme->cbSize != sizeof(TRACKMOUSEEVENT)) {
|
if (ptme->cbSize != sizeof(TRACKMOUSEEVENT)) {
|
||||||
WARN("wrong TRACKMOUSEEVENT size from app\n");
|
WARN("wrong TRACKMOUSEEVENT size from app\n");
|
||||||
SetLastError(ERROR_INVALID_PARAMETER); /* FIXME not sure if this is correct */
|
SetLastError(ERROR_INVALID_PARAMETER);
|
||||||
return FALSE;
|
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( flags & TME_NONCLIENT ) {
|
|
||||||
flags &= ~ TME_NONCLIENT;
|
|
||||||
nonclient = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 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 ( flags & TME_QUERY ) {
|
if (ptme->dwFlags & TME_QUERY )
|
||||||
flags &= ~ TME_QUERY;
|
{
|
||||||
query = 1;
|
*ptme = tracking_info.tme;
|
||||||
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 */
|
return TRUE; /* return here, TME_QUERY is retrieving information */
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( flags )
|
if (!IsWindow(ptme->hwndTrack))
|
||||||
FIXME("Unknown flag(s) %08lx\n", flags );
|
{
|
||||||
|
SetLastError(ERROR_INVALID_WINDOW_HANDLE);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
if(cancel) {
|
hover_time = ptme->dwHoverTime;
|
||||||
/* find a matching hwnd if one exists */
|
|
||||||
i = 0;
|
|
||||||
|
|
||||||
while((i < iTrackMax) && (TrackingList[i].tme.hwndTrack != ptme->hwndTrack)) {
|
/* if HOVER_DEFAULT was specified replace this with the systems current value */
|
||||||
i++;
|
if (hover_time == HOVER_DEFAULT || hover_time == 0)
|
||||||
}
|
SystemParametersInfoW(SPI_GETMOUSEHOVERTIME, 0, &hover_time, 0);
|
||||||
|
|
||||||
if(i < iTrackMax) {
|
GetCursorPos(&pos);
|
||||||
TrackingList[i].tme.dwFlags &= ~(ptme->dwFlags & ~TME_CANCEL);
|
hwnd = WindowFromPoint(pos);
|
||||||
|
|
||||||
|
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));
|
||||||
|
|
||||||
|
if (ptme->dwFlags & TME_CANCEL)
|
||||||
|
{
|
||||||
|
if (tracking_info.tme.hwndTrack == ptme->hwndTrack)
|
||||||
|
{
|
||||||
|
tracking_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(!((TrackingList[i].tme.dwFlags & TME_HOVER) ||
|
if (!(tracking_info.tme.dwFlags & (TME_HOVER | TME_LEAVE)))
|
||||||
(TrackingList[i].tme.dwFlags & TME_LEAVE)))
|
|
||||||
{
|
{
|
||||||
TrackingList[i] = TrackingList[--iTrackMax];
|
memset(&tracking_info, 0, sizeof(tracking_info));
|
||||||
|
|
||||||
if(iTrackMax == 0) {
|
KillSystemTimer(0, timer);
|
||||||
KillTimer(0, timer);
|
timer = 0;
|
||||||
timer = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* see if hwndTrack isn't the current window */
|
if (ptme->hwndTrack == hwnd)
|
||||||
if(ptme->hwndTrack != hwnd) {
|
{
|
||||||
if(leave) {
|
|
||||||
if(nonclient) {
|
|
||||||
PostMessageA(ptme->hwndTrack, WM_NCMOUSELEAVE, 0, 0);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
PostMessageA(ptme->hwndTrack, WM_MOUSELEAVE, 0, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
GetClientRect(ptme->hwndTrack, &client);
|
|
||||||
MapWindowPoints(ptme->hwndTrack, NULL, (LPPOINT)&client, 2);
|
|
||||||
if(PtInRect(&client, pos)) {
|
|
||||||
inclient = 1;
|
|
||||||
}
|
|
||||||
if(nonclient && inclient) {
|
|
||||||
PostMessageA(ptme->hwndTrack, WM_NCMOUSELEAVE, 0, 0);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
else if(!nonclient && !inclient) {
|
|
||||||
PostMessageA(ptme->hwndTrack, WM_MOUSELEAVE, 0, 0);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 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) {
|
|
||||||
TrackingList[i].tme.dwFlags = 0;
|
|
||||||
|
|
||||||
if(hover) {
|
|
||||||
TrackingList[i].tme.dwFlags |= TME_HOVER;
|
|
||||||
TrackingList[i].tme.dwHoverTime = ptme->dwHoverTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(leave)
|
|
||||||
TrackingList[i].tme.dwFlags |= TME_LEAVE;
|
|
||||||
|
|
||||||
if(nonclient)
|
|
||||||
TrackingList[i].tme.dwFlags |= TME_NONCLIENT;
|
|
||||||
|
|
||||||
/* 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 */
|
/* Adding new mouse event to the tracking list */
|
||||||
TrackingList[iTrackMax].tme = *ptme;
|
tracking_info.tme = *ptme;
|
||||||
|
tracking_info.tme.dwHoverTime = hover_time;
|
||||||
|
|
||||||
/* Initialize HoverInfo variables even if not hover tracking */
|
/* Initialize HoverInfo variables even if not hover tracking */
|
||||||
TrackingList[iTrackMax].iHoverTime = 0;
|
tracking_info.pos = pos;
|
||||||
TrackingList[iTrackMax].pos = pos;
|
|
||||||
|
|
||||||
iTrackMax++;
|
if (!timer)
|
||||||
|
timer = SetSystemTimer(0, 0, hover_time, TrackMouseEventProc);
|
||||||
if (!timer) {
|
|
||||||
timer = SetTimer(0, 0, iTimerInterval, TrackMouseEventProc);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7618,6 +7618,159 @@ static void test_quit_message(void)
|
||||||
ok(msg.message == WM_USER, "Received message 0x%04x instead of WM_USER\n", msg.message);
|
ok(msg.message == WM_USER, "Received message 0x%04x instead of WM_USER\n", msg.message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const struct message WmMouseHoverSeq[] = {
|
||||||
|
{ WM_SYSTIMER, sent },
|
||||||
|
{ WM_MOUSEHOVER, sent|wparam, 0 },
|
||||||
|
{ 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
static void test_TrackMouseEvent(void)
|
||||||
|
{
|
||||||
|
MSG msg;
|
||||||
|
TRACKMOUSEEVENT tme;
|
||||||
|
BOOL ret;
|
||||||
|
HWND hwnd, hchild;
|
||||||
|
RECT rc_parent, rc_child;
|
||||||
|
UINT default_hover_time;
|
||||||
|
DWORD start_ticks, end_ticks;
|
||||||
|
|
||||||
|
#define track_hover(track_hwnd, track_hover_time) \
|
||||||
|
tme.cbSize = sizeof(tme); \
|
||||||
|
tme.dwFlags = TME_HOVER; \
|
||||||
|
tme.hwndTrack = track_hwnd; \
|
||||||
|
tme.dwHoverTime = track_hover_time; \
|
||||||
|
SetLastError(0xdeadbeef); \
|
||||||
|
ret = TrackMouseEvent(&tme); \
|
||||||
|
ok(ret, "TrackMouseEvent(TME_HOVER) error %ld\n", GetLastError())
|
||||||
|
|
||||||
|
#define track_query(expected_track_flags, expected_track_hwnd, expected_hover_time) \
|
||||||
|
tme.cbSize = sizeof(tme); \
|
||||||
|
tme.dwFlags = TME_QUERY; \
|
||||||
|
tme.hwndTrack = (HWND)0xdeadbeef; \
|
||||||
|
tme.dwHoverTime = 0xdeadbeef; \
|
||||||
|
SetLastError(0xdeadbeef); \
|
||||||
|
ret = TrackMouseEvent(&tme); \
|
||||||
|
ok(ret, "TrackMouseEvent(TME_QUERY) error %ld\n", GetLastError());\
|
||||||
|
ok(tme.dwFlags == (expected_track_flags), \
|
||||||
|
"wrong tme.dwFlags %08lx, expected %08x\n", tme.dwFlags, (expected_track_flags)); \
|
||||||
|
ok(tme.hwndTrack == (expected_track_hwnd), \
|
||||||
|
"wrong tme.hwndTrack %p, expected %p\n", tme.hwndTrack, (expected_track_hwnd)); \
|
||||||
|
ok(tme.dwHoverTime == (expected_hover_time), \
|
||||||
|
"wrong tme.dwHoverTime %lu, expected %u\n", tme.dwHoverTime, (expected_hover_time))
|
||||||
|
|
||||||
|
#define track_hover_cancel(track_hwnd) \
|
||||||
|
tme.cbSize = sizeof(tme); \
|
||||||
|
tme.dwFlags = TME_HOVER | TME_CANCEL; \
|
||||||
|
tme.hwndTrack = track_hwnd; \
|
||||||
|
tme.dwHoverTime = 0xdeadbeef; \
|
||||||
|
SetLastError(0xdeadbeef); \
|
||||||
|
ret = TrackMouseEvent(&tme); \
|
||||||
|
ok(ret, "TrackMouseEvent(TME_HOVER | TME_CANCEL) error %ld\n", GetLastError())
|
||||||
|
|
||||||
|
default_hover_time = 0xdeadbeef;
|
||||||
|
ret = SystemParametersInfo(SPI_GETMOUSEHOVERTIME, 0, &default_hover_time, 0);
|
||||||
|
ok(ret, "SystemParametersInfo(SPI_GETMOUSEHOVERTIME) failed\n");
|
||||||
|
trace("SPI_GETMOUSEHOVERTIME returned %u ms\n", default_hover_time);
|
||||||
|
|
||||||
|
hwnd = CreateWindowEx(0, "TestWindowClass", NULL,
|
||||||
|
WS_OVERLAPPEDWINDOW | WS_VISIBLE,
|
||||||
|
CW_USEDEFAULT, CW_USEDEFAULT, 300, 300, 0,
|
||||||
|
NULL, NULL, 0);
|
||||||
|
assert(hwnd);
|
||||||
|
|
||||||
|
hchild = CreateWindowEx(0, "TestWindowClass", NULL,
|
||||||
|
WS_CHILD | WS_BORDER | WS_VISIBLE,
|
||||||
|
50, 50, 200, 200, hwnd,
|
||||||
|
NULL, NULL, 0);
|
||||||
|
assert(hchild);
|
||||||
|
|
||||||
|
flush_events();
|
||||||
|
flush_sequence();
|
||||||
|
|
||||||
|
tme.cbSize = 0;
|
||||||
|
tme.dwFlags = TME_QUERY;
|
||||||
|
tme.hwndTrack = (HWND)0xdeadbeef;
|
||||||
|
tme.dwHoverTime = 0xdeadbeef;
|
||||||
|
SetLastError(0xdeadbeef);
|
||||||
|
ret = TrackMouseEvent(&tme);
|
||||||
|
ok(!ret, "TrackMouseEvent should fail\n");
|
||||||
|
ok(GetLastError() == ERROR_INVALID_PARAMETER, "not expected error %ld\n", GetLastError());
|
||||||
|
|
||||||
|
tme.cbSize = sizeof(tme);
|
||||||
|
tme.dwFlags = TME_HOVER;
|
||||||
|
tme.hwndTrack = (HWND)0xdeadbeef;
|
||||||
|
tme.dwHoverTime = 0xdeadbeef;
|
||||||
|
SetLastError(0xdeadbeef);
|
||||||
|
ret = TrackMouseEvent(&tme);
|
||||||
|
ok(!ret, "TrackMouseEvent should fail\n");
|
||||||
|
ok(GetLastError() == ERROR_INVALID_WINDOW_HANDLE, "not expected error %ld\n", GetLastError());
|
||||||
|
|
||||||
|
tme.cbSize = sizeof(tme);
|
||||||
|
tme.dwFlags = TME_HOVER | TME_CANCEL;
|
||||||
|
tme.hwndTrack = (HWND)0xdeadbeef;
|
||||||
|
tme.dwHoverTime = 0xdeadbeef;
|
||||||
|
SetLastError(0xdeadbeef);
|
||||||
|
ret = TrackMouseEvent(&tme);
|
||||||
|
ok(!ret, "TrackMouseEvent should fail\n");
|
||||||
|
ok(GetLastError() == ERROR_INVALID_WINDOW_HANDLE, "not expected error %ld\n", GetLastError());
|
||||||
|
|
||||||
|
GetWindowRect(hwnd, &rc_parent);
|
||||||
|
GetWindowRect(hchild, &rc_child);
|
||||||
|
SetCursorPos(rc_child.left - 10, rc_child.top - 10);
|
||||||
|
|
||||||
|
/* Process messages so that the system updates its internal current
|
||||||
|
* window and hittest, otherwise TrackMouseEvent calls don't have any
|
||||||
|
* effect.
|
||||||
|
*/
|
||||||
|
while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessage(&msg);
|
||||||
|
flush_sequence();
|
||||||
|
|
||||||
|
track_query(0, NULL, 0);
|
||||||
|
track_hover(hchild, 0);
|
||||||
|
track_query(0, NULL, 0);
|
||||||
|
|
||||||
|
while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessage(&msg);
|
||||||
|
flush_sequence();
|
||||||
|
|
||||||
|
track_hover(hwnd, 0);
|
||||||
|
track_query(TME_HOVER, hwnd, default_hover_time);
|
||||||
|
start_ticks = GetTickCount();
|
||||||
|
do
|
||||||
|
{
|
||||||
|
while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
|
||||||
|
{
|
||||||
|
/* Timer proc messages are not dispatched to the window proc,
|
||||||
|
* and therefore not logged.
|
||||||
|
*/
|
||||||
|
if (msg.message == WM_TIMER || msg.message == WM_SYSTIMER)
|
||||||
|
{
|
||||||
|
struct message s_msg;
|
||||||
|
|
||||||
|
s_msg.message = msg.message;
|
||||||
|
s_msg.flags = sent|wparam|lparam;
|
||||||
|
s_msg.wParam = msg.wParam;
|
||||||
|
s_msg.lParam = msg.lParam;
|
||||||
|
add_message(&s_msg);
|
||||||
|
}
|
||||||
|
DispatchMessage(&msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
end_ticks = GetTickCount();
|
||||||
|
} while (start_ticks + default_hover_time >= end_ticks);
|
||||||
|
ok_sequence(WmMouseHoverSeq, "WmMouseHoverSeq", FALSE);
|
||||||
|
|
||||||
|
track_query(0, NULL, 0);
|
||||||
|
track_hover(hwnd, HOVER_DEFAULT);
|
||||||
|
track_query(TME_HOVER, hwnd, default_hover_time);
|
||||||
|
track_hover_cancel(hwnd);
|
||||||
|
|
||||||
|
DestroyWindow(hwnd);
|
||||||
|
|
||||||
|
#undef track_hover
|
||||||
|
#undef track_query
|
||||||
|
#undef track_hover_cancel
|
||||||
|
}
|
||||||
|
|
||||||
START_TEST(msg)
|
START_TEST(msg)
|
||||||
{
|
{
|
||||||
BOOL ret;
|
BOOL ret;
|
||||||
|
@ -7681,6 +7834,7 @@ START_TEST(msg)
|
||||||
test_SendMessageTimeout();
|
test_SendMessageTimeout();
|
||||||
test_edit_messages();
|
test_edit_messages();
|
||||||
test_quit_message();
|
test_quit_message();
|
||||||
|
test_TrackMouseEvent();
|
||||||
|
|
||||||
UnhookWindowsHookEx(hCBT_hook);
|
UnhookWindowsHookEx(hCBT_hook);
|
||||||
if (pUnhookWinEvent)
|
if (pUnhookWinEvent)
|
||||||
|
|
Loading…
Reference in New Issue