From: Zebediah Figura zfigura@codeweavers.com
Signed-off-by: Zebediah Figura zfigura@codeweavers.com Signed-off-by: Jacek Caban jacek@codeweavers.com Signed-off-by: Huw Davies huw@codeweavers.com --- dlls/user32/input.c | 254 ----------------------------------- dlls/user32/scroll.c | 8 +- dlls/user32/user32.spec | 2 +- dlls/user32/user_main.c | 1 - dlls/user32/user_private.h | 1 - dlls/win32u/gdiobj.c | 1 + dlls/win32u/input.c | 218 ++++++++++++++++++++++++++++++ dlls/win32u/message.c | 3 +- dlls/win32u/ntuser_private.h | 1 - dlls/win32u/win32u.spec | 2 +- dlls/win32u/win32u_private.h | 2 + dlls/win32u/wrappers.c | 6 + include/ntuser.h | 1 + 13 files changed, 235 insertions(+), 265 deletions(-)
diff --git a/dlls/user32/input.c b/dlls/user32/input.c index 4ef33ab2838..dcb46df22b5 100644 --- a/dlls/user32/input.c +++ b/dlls/user32/input.c @@ -49,32 +49,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(win); WINE_DECLARE_DEBUG_CHANNEL(keyboard);
-/*********************************************************************** - * get_key_state - */ -static WORD get_key_state(void) -{ - WORD ret = 0; - - if (GetSystemMetrics( SM_SWAPBUTTON )) - { - if (NtUserGetAsyncKeyState(VK_RBUTTON) & 0x80) ret |= MK_LBUTTON; - if (NtUserGetAsyncKeyState(VK_LBUTTON) & 0x80) ret |= MK_RBUTTON; - } - else - { - if (NtUserGetAsyncKeyState(VK_LBUTTON) & 0x80) ret |= MK_LBUTTON; - if (NtUserGetAsyncKeyState(VK_RBUTTON) & 0x80) ret |= MK_RBUTTON; - } - if (NtUserGetAsyncKeyState(VK_MBUTTON) & 0x80) ret |= MK_MBUTTON; - if (NtUserGetAsyncKeyState(VK_SHIFT) & 0x80) ret |= MK_SHIFT; - if (NtUserGetAsyncKeyState(VK_CONTROL) & 0x80) ret |= MK_CONTROL; - if (NtUserGetAsyncKeyState(VK_XBUTTON1) & 0x80) ret |= MK_XBUTTON1; - if (NtUserGetAsyncKeyState(VK_XBUTTON2) & 0x80) ret |= MK_XBUTTON2; - return ret; -} - - /*********************************************************************** * get_locale_kbd_layout */ @@ -520,234 +494,6 @@ BOOL WINAPI UnloadKeyboardLayout( HKL layout ) return FALSE; }
-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 void check_mouse_leave(HWND hwnd, int hittest) -{ - 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 - { - if (hittest == HTCLIENT) - { - if (tracking_info.tme.dwFlags & TME_NONCLIENT) - { - PostMessageW(tracking_info.tme.hwndTrack, WM_NCMOUSELEAVE, 0, 0); - /* remove the TME_LEAVE flag */ - tracking_info.tme.dwFlags &= ~TME_LEAVE; - } - } - else - { - if (!(tracking_info.tme.dwFlags & TME_NONCLIENT)) - { - PostMessageW(tracking_info.tme.hwndTrack, WM_MOUSELEAVE, 0, 0); - /* remove the TME_LEAVE flag */ - tracking_info.tme.dwFlags &= ~TME_LEAVE; - } - } - } -} - -void CDECL update_mouse_tracking_info( HWND hwnd ) -{ - POINT pos; - INT hoverwidth = 0, hoverheight = 0, hittest; - - TRACE( "hwnd %p\n", hwnd ); - - GetCursorPos(&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_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 */ - /* mouse has left the window */ - if (tracking_info.tme.dwFlags & TME_LEAVE) - { - check_mouse_leave(hwnd, hittest); - } - - 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 */ - if (tracking_info.tme.dwFlags & TME_HOVER) - { - /* has the cursor moved outside the rectangle centered around pos? */ - if ((abs(pos.x - tracking_info.pos.x) > (hoverwidth / 2)) || - (abs(pos.y - tracking_info.pos.y) > (hoverheight / 2))) - { - /* record this new position as the current position */ - tracking_info.pos = pos; - } - else - { - if (hittest == HTCLIENT) - { - ScreenToClient(hwnd, &pos); - TRACE("client cursor pos %s\n", wine_dbgstr_point(&pos)); - - PostMessageW(tracking_info.tme.hwndTrack, WM_MOUSEHOVER, - 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 */ - tracking_info.tme.dwFlags &= ~TME_HOVER; - } - } - - /* stop the timer if the tracking list is empty */ - if (!(tracking_info.tme.dwFlags & (TME_HOVER | TME_LEAVE))) - { - KillSystemTimer( tracking_info.tme.hwndTrack, SYSTEM_TIMER_TRACK_MOUSE ); - tracking_info.tme.hwndTrack = 0; - tracking_info.tme.dwFlags = 0; - tracking_info.tme.dwHoverTime = 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) -{ - HWND hwnd; - POINT pos; - DWORD hover_time; - INT hittest; - - TRACE("%x, %x, %p, %u\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); - return FALSE; - } - - /* fill the TRACKMOUSEEVENT struct with the current tracking for the given hwnd */ - if (ptme->dwFlags & TME_QUERY ) - { - *ptme = tracking_info.tme; - /* set cbSize in the case it's not initialized yet */ - ptme->cbSize = sizeof(TRACKMOUSEEVENT); - - return TRUE; /* return here, TME_QUERY is retrieving information */ - } - - if (!IsWindow(ptme->hwndTrack)) - { - SetLastError(ERROR_INVALID_WINDOW_HANDLE); - return FALSE; - } - - hover_time = (ptme->dwFlags & TME_HOVER) ? ptme->dwHoverTime : HOVER_DEFAULT; - - /* if HOVER_DEFAULT was specified replace this with the system's current value. - * TME_LEAVE doesn't need to specify hover time so use default */ - if (hover_time == HOVER_DEFAULT || hover_time == 0) - SystemParametersInfoW(SPI_GETMOUSEHOVERTIME, 0, &hover_time, 0); - - GetCursorPos(&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)) - FIXME("Unknown flag(s) %08x\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 (!(tracking_info.tme.dwFlags & (TME_HOVER | TME_LEAVE))) - { - KillSystemTimer( tracking_info.tme.hwndTrack, SYSTEM_TIMER_TRACK_MOUSE ); - tracking_info.tme.hwndTrack = 0; - tracking_info.tme.dwFlags = 0; - tracking_info.tme.dwHoverTime = 0; - } - } - } else { - /* In our implementation it's possible that another window will receive a - * WM_MOUSEMOVE and call TrackMouseEvent before TrackMouseEventProc is - * called. In such a situation post the WM_MOUSELEAVE now */ - if (tracking_info.tme.dwFlags & TME_LEAVE && tracking_info.tme.hwndTrack != NULL) - check_mouse_leave(hwnd, hittest); - - KillSystemTimer( tracking_info.tme.hwndTrack, SYSTEM_TIMER_TRACK_MOUSE ); - tracking_info.tme.hwndTrack = 0; - tracking_info.tme.dwFlags = 0; - tracking_info.tme.dwHoverTime = 0; - - if (ptme->hwndTrack == hwnd) - { - /* Adding new mouse event to the tracking list */ - tracking_info.tme = *ptme; - tracking_info.tme.dwHoverTime = hover_time; - - /* Initialize HoverInfo variables even if not hover tracking */ - tracking_info.pos = pos; - - NtUserSetSystemTimer( tracking_info.tme.hwndTrack, SYSTEM_TIMER_TRACK_MOUSE, hover_time ); - } - } - - return TRUE; -}
/*********************************************************************** * EnableMouseInPointer (USER32.@) diff --git a/dlls/user32/scroll.c b/dlls/user32/scroll.c index 45980b75b2c..8f085364dab 100644 --- a/dlls/user32/scroll.c +++ b/dlls/user32/scroll.c @@ -864,12 +864,12 @@ void SCROLL_HandleScrollEvent( HWND hwnd, INT nBar, UINT msg, POINT pt )
tme.cbSize = sizeof(tme); tme.dwFlags = TME_QUERY; - TrackMouseEvent( &tme ); + NtUserTrackMouseEvent( &tme ); if (!(tme.dwFlags & TME_LEAVE) || tme.hwndTrack != hwnd) { tme.dwFlags = TME_LEAVE; tme.hwndTrack = hwnd; - TrackMouseEvent( &tme ); + NtUserTrackMouseEvent( &tme ); }
break; @@ -883,12 +883,12 @@ void SCROLL_HandleScrollEvent( HWND hwnd, INT nBar, UINT msg, POINT pt )
tme.cbSize = sizeof(tme); tme.dwFlags = TME_QUERY; - TrackMouseEvent( &tme ); + NtUserTrackMouseEvent( &tme ); if (((tme.dwFlags & (TME_NONCLIENT | TME_LEAVE)) != (TME_NONCLIENT | TME_LEAVE)) || tme.hwndTrack != hwnd) { tme.dwFlags = TME_NONCLIENT | TME_LEAVE; tme.hwndTrack = hwnd; - TrackMouseEvent( &tme ); + NtUserTrackMouseEvent( &tme ); }
break; diff --git a/dlls/user32/user32.spec b/dlls/user32/user32.spec index ec078cc7609..6f86fccdfbd 100644 --- a/dlls/user32/user32.spec +++ b/dlls/user32/user32.spec @@ -762,7 +762,7 @@ @ stdcall ToAsciiEx(long long ptr ptr long long) @ stdcall ToUnicode(long long ptr ptr long long) @ stdcall ToUnicodeEx(long long ptr ptr long long long) NtUserToUnicodeEx -@ stdcall TrackMouseEvent(ptr) +@ stdcall TrackMouseEvent(ptr) NtUserTrackMouseEvent @ stdcall TrackPopupMenu(long long long long long long ptr) @ stdcall TrackPopupMenuEx(long long long long long ptr) @ stdcall TranslateAccelerator(long long ptr) TranslateAcceleratorA diff --git a/dlls/user32/user_main.c b/dlls/user32/user_main.c index 85e22525d80..d529e49ba3a 100644 --- a/dlls/user32/user_main.c +++ b/dlls/user32/user_main.c @@ -179,7 +179,6 @@ static const struct user_callbacks user_funcs = SCROLL_SetStandardScrollPainted, toggle_caret, unpack_dde_message, - update_mouse_tracking_info, register_imm, unregister_imm, }; diff --git a/dlls/user32/user_private.h b/dlls/user32/user_private.h index b01c5b8bfda..8fa8af00326 100644 --- a/dlls/user32/user_private.h +++ b/dlls/user32/user_private.h @@ -102,7 +102,6 @@ extern void SYSPARAMS_Init(void) DECLSPEC_HIDDEN; extern void USER_CheckNotLock(void) DECLSPEC_HIDDEN; extern BOOL USER_IsExitingThread( DWORD tid ) DECLSPEC_HIDDEN; extern void CDECL toggle_caret( HWND hwnd ) DECLSPEC_HIDDEN; -extern void CDECL update_mouse_tracking_info( HWND hwnd ) DECLSPEC_HIDDEN;
typedef LRESULT (*winproc_callback_t)( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp, LRESULT *result, void *arg ); diff --git a/dlls/win32u/gdiobj.c b/dlls/win32u/gdiobj.c index 044ae8232e3..0f82d446269 100644 --- a/dlls/win32u/gdiobj.c +++ b/dlls/win32u/gdiobj.c @@ -1220,6 +1220,7 @@ static struct unix_funcs unix_funcs = NtUserSystemParametersInfo, NtUserSystemParametersInfoForDpi, NtUserToUnicodeEx, + NtUserTrackMouseEvent, NtUserTranslateMessage, NtUserUnregisterClass, NtUserUnregisterHotKey, diff --git a/dlls/win32u/input.c b/dlls/win32u/input.c index dd28170b1f0..c9d14ed746f 100644 --- a/dlls/win32u/input.c +++ b/dlls/win32u/input.c @@ -1171,6 +1171,224 @@ int WINAPI NtUserGetMouseMovePointsEx( UINT size, MOUSEMOVEPOINT *ptin, MOUSEMOV return copied; }
+static WORD get_key_state(void) +{ + WORD ret = 0; + + if (get_system_metrics( SM_SWAPBUTTON )) + { + if (NtUserGetAsyncKeyState(VK_RBUTTON) & 0x80) ret |= MK_LBUTTON; + if (NtUserGetAsyncKeyState(VK_LBUTTON) & 0x80) ret |= MK_RBUTTON; + } + else + { + if (NtUserGetAsyncKeyState(VK_LBUTTON) & 0x80) ret |= MK_LBUTTON; + if (NtUserGetAsyncKeyState(VK_RBUTTON) & 0x80) ret |= MK_RBUTTON; + } + if (NtUserGetAsyncKeyState(VK_MBUTTON) & 0x80) ret |= MK_MBUTTON; + if (NtUserGetAsyncKeyState(VK_SHIFT) & 0x80) ret |= MK_SHIFT; + if (NtUserGetAsyncKeyState(VK_CONTROL) & 0x80) ret |= MK_CONTROL; + if (NtUserGetAsyncKeyState(VK_XBUTTON1) & 0x80) ret |= MK_XBUTTON1; + if (NtUserGetAsyncKeyState(VK_XBUTTON2) & 0x80) ret |= MK_XBUTTON2; + return ret; +} + +struct tracking_list +{ + TRACKMOUSEEVENT info; + POINT pos; /* center of hover rectangle */ +}; + +/* FIXME: move tracking stuff into per-thread data */ +static struct tracking_list tracking_info; + +static void check_mouse_leave( HWND hwnd, int hittest ) +{ + if (tracking_info.info.hwndTrack != hwnd) + { + if (tracking_info.info.dwFlags & TME_NONCLIENT) + NtUserPostMessage( tracking_info.info.hwndTrack, WM_NCMOUSELEAVE, 0, 0 ); + else + NtUserPostMessage( tracking_info.info.hwndTrack, WM_MOUSELEAVE, 0, 0 ); + + tracking_info.info.dwFlags &= ~TME_LEAVE; + } + else + { + if (hittest == HTCLIENT) + { + if (tracking_info.info.dwFlags & TME_NONCLIENT) + { + NtUserPostMessage( tracking_info.info.hwndTrack, WM_NCMOUSELEAVE, 0, 0 ); + tracking_info.info.dwFlags &= ~TME_LEAVE; + } + } + else + { + if (!(tracking_info.info.dwFlags & TME_NONCLIENT)) + { + NtUserPostMessage( tracking_info.info.hwndTrack, WM_MOUSELEAVE, 0, 0 ); + tracking_info.info.dwFlags &= ~TME_LEAVE; + } + } + } +} + +void update_mouse_tracking_info( HWND hwnd ) +{ + int hover_width = 0, hover_height = 0, hittest; + POINT pos; + + TRACE( "hwnd %p\n", hwnd ); + + get_cursor_pos( &pos ); + hwnd = window_from_point( hwnd, pos, &hittest ); + + TRACE( "point %s hwnd %p hittest %d\n", wine_dbgstr_point(&pos), hwnd, hittest ); + + NtUserSystemParametersInfo( SPI_GETMOUSEHOVERWIDTH, 0, &hover_width, 0 ); + NtUserSystemParametersInfo( SPI_GETMOUSEHOVERHEIGHT, 0, &hover_height, 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), + hover_width, hover_height ); + + if (tracking_info.info.dwFlags & TME_LEAVE) + check_mouse_leave( hwnd, hittest ); + + if (tracking_info.info.hwndTrack != hwnd) + tracking_info.info.dwFlags &= ~TME_HOVER; + + if (tracking_info.info.dwFlags & TME_HOVER) + { + /* has the cursor moved outside the rectangle centered around pos? */ + if ((abs( pos.x - tracking_info.pos.x ) > (hover_width / 2)) || + (abs( pos.y - tracking_info.pos.y ) > (hover_height / 2))) + { + tracking_info.pos = pos; + } + else + { + if (hittest == HTCLIENT) + { + screen_to_client(hwnd, &pos); + TRACE( "client cursor pos %s\n", wine_dbgstr_point(&pos) ); + + NtUserPostMessage( tracking_info.info.hwndTrack, WM_MOUSEHOVER, + get_key_state(), MAKELPARAM( pos.x, pos.y ) ); + } + else + { + if (tracking_info.info.dwFlags & TME_NONCLIENT) + NtUserPostMessage( tracking_info.info.hwndTrack, WM_NCMOUSEHOVER, + hittest, MAKELPARAM( pos.x, pos.y ) ); + } + + /* stop tracking mouse hover */ + tracking_info.info.dwFlags &= ~TME_HOVER; + } + } + + /* stop the timer if the tracking list is empty */ + if (!(tracking_info.info.dwFlags & (TME_HOVER | TME_LEAVE))) + { + kill_system_timer( tracking_info.info.hwndTrack, SYSTEM_TIMER_TRACK_MOUSE ); + tracking_info.info.hwndTrack = 0; + tracking_info.info.dwFlags = 0; + tracking_info.info.dwHoverTime = 0; + } +} + +/*********************************************************************** + * NtUserTrackMouseEvent (win32u.@) + */ +BOOL WINAPI NtUserTrackMouseEvent( TRACKMOUSEEVENT *info ) +{ + DWORD hover_time; + int hittest; + HWND hwnd; + POINT pos; + + TRACE( "size %u, flags %#x, hwnd %p, time %u\n", + info->cbSize, info->dwFlags, info->hwndTrack, info->dwHoverTime ); + + if (info->cbSize != sizeof(TRACKMOUSEEVENT)) + { + WARN( "wrong size %u\n", info->cbSize ); + SetLastError( ERROR_INVALID_PARAMETER ); + return FALSE; + } + + if (info->dwFlags & TME_QUERY) + { + *info = tracking_info.info; + info->cbSize = sizeof(TRACKMOUSEEVENT); + return TRUE; + } + + if (!is_window( info->hwndTrack )) + { + SetLastError( ERROR_INVALID_WINDOW_HANDLE ); + return FALSE; + } + + hover_time = (info->dwFlags & TME_HOVER) ? info->dwHoverTime : HOVER_DEFAULT; + + if (hover_time == HOVER_DEFAULT || hover_time == 0) + NtUserSystemParametersInfo( SPI_GETMOUSEHOVERTIME, 0, &hover_time, 0 ); + + get_cursor_pos( &pos ); + hwnd = window_from_point( info->hwndTrack, pos, &hittest ); + TRACE( "point %s hwnd %p hittest %d\n", wine_dbgstr_point(&pos), hwnd, hittest ); + + if (info->dwFlags & ~(TME_CANCEL | TME_HOVER | TME_LEAVE | TME_NONCLIENT)) + FIXME( "ignoring flags %#x\n", info->dwFlags & ~(TME_CANCEL | TME_HOVER | TME_LEAVE | TME_NONCLIENT) ); + + if (info->dwFlags & TME_CANCEL) + { + if (tracking_info.info.hwndTrack == info->hwndTrack) + { + tracking_info.info.dwFlags &= ~(info->dwFlags & ~TME_CANCEL); + + /* if we aren't tracking on hover or leave remove this entry */ + if (!(tracking_info.info.dwFlags & (TME_HOVER | TME_LEAVE))) + { + kill_system_timer( tracking_info.info.hwndTrack, SYSTEM_TIMER_TRACK_MOUSE ); + tracking_info.info.hwndTrack = 0; + tracking_info.info.dwFlags = 0; + tracking_info.info.dwHoverTime = 0; + } + } + } + else + { + /* In our implementation, it's possible that another window will receive + * WM_MOUSEMOVE and call TrackMouseEvent before TrackMouseEventProc is + * called. In such a situation, post the WM_MOUSELEAVE now. */ + if ((tracking_info.info.dwFlags & TME_LEAVE) && tracking_info.info.hwndTrack != NULL) + check_mouse_leave(hwnd, hittest); + + kill_system_timer( tracking_info.info.hwndTrack, SYSTEM_TIMER_TRACK_MOUSE ); + tracking_info.info.hwndTrack = 0; + tracking_info.info.dwFlags = 0; + tracking_info.info.dwHoverTime = 0; + + if (info->hwndTrack == hwnd) + { + /* Adding new mouse event to the tracking list */ + tracking_info.info = *info; + tracking_info.info.dwHoverTime = hover_time; + + /* Initialize HoverInfo variables even if not hover tracking */ + tracking_info.pos = pos; + + NtUserSetSystemTimer( tracking_info.info.hwndTrack, SYSTEM_TIMER_TRACK_MOUSE, hover_time ); + } + } + + return TRUE; +} + /********************************************************************** * set_capture_window */ diff --git a/dlls/win32u/message.c b/dlls/win32u/message.c index 02644e71929..8ad4a0271b3 100644 --- a/dlls/win32u/message.c +++ b/dlls/win32u/message.c @@ -2479,8 +2479,7 @@ LRESULT dispatch_message( const MSG *msg, BOOL ansi ) return 0;
case SYSTEM_TIMER_TRACK_MOUSE: - if (!user_callbacks) break; - user_callbacks->update_mouse_tracking_info( msg->hwnd ); + update_mouse_tracking_info( msg->hwnd ); return 0; } } diff --git a/dlls/win32u/ntuser_private.h b/dlls/win32u/ntuser_private.h index 604817708c7..cad038dbff6 100644 --- a/dlls/win32u/ntuser_private.h +++ b/dlls/win32u/ntuser_private.h @@ -54,7 +54,6 @@ struct user_callbacks void (CDECL *toggle_caret)( HWND hwnd ); BOOL (CDECL *unpack_dde_message)( HWND hwnd, UINT message, WPARAM *wparam, LPARAM *lparam, void **buffer, size_t size ); - void (CDECL *update_mouse_tracking_info)( HWND hwnd ); BOOL (WINAPI *register_imm)( HWND hwnd ); void (WINAPI *unregister_imm)( HWND hwnd ); }; diff --git a/dlls/win32u/win32u.spec b/dlls/win32u/win32u.spec index 492ff411c1d..e94ec7f4a39 100644 --- a/dlls/win32u/win32u.spec +++ b/dlls/win32u/win32u.spec @@ -1277,7 +1277,7 @@ @ stdcall -syscall NtUserThunkedMenuInfo(long ptr) @ stub NtUserThunkedMenuItemInfo @ stdcall NtUserToUnicodeEx(long long ptr ptr long long long) -@ stub NtUserTrackMouseEvent +@ stdcall NtUserTrackMouseEvent(ptr) @ stub NtUserTrackPopupMenuEx @ stub NtUserTransformPoint @ stub NtUserTransformRect diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h index 128ff9d7281..122921431fc 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -292,6 +292,7 @@ struct unix_funcs UINT winini, UINT dpi ); INT (WINAPI *pNtUserToUnicodeEx)( UINT virt, UINT scan, const BYTE *state, WCHAR *str, int size, UINT flags, HKL layout ); + BOOL (WINAPI *pNtUserTrackMouseEvent)( TRACKMOUSEEVENT *info ); BOOL (WINAPI *pNtUserTranslateMessage)( const MSG *msg, UINT flags ); BOOL (WINAPI *pNtUserUnregisterClass)( UNICODE_STRING *name, HINSTANCE instance, struct client_menu_name *client_menu_name ); @@ -362,6 +363,7 @@ extern DWORD get_input_state(void) DECLSPEC_HIDDEN; extern BOOL WINAPI release_capture(void) DECLSPEC_HIDDEN; extern BOOL set_capture_window( HWND hwnd, UINT gui_flags, HWND *prev_ret ) DECLSPEC_HIDDEN; extern BOOL set_foreground_window( HWND hwnd, BOOL mouse ) DECLSPEC_HIDDEN; +extern void update_mouse_tracking_info( HWND hwnd ) DECLSPEC_HIDDEN;
/* menu.c */ extern HMENU create_menu( BOOL is_popup ) DECLSPEC_HIDDEN; diff --git a/dlls/win32u/wrappers.c b/dlls/win32u/wrappers.c index d22e03ac3fb..d38501f5c4c 100644 --- a/dlls/win32u/wrappers.c +++ b/dlls/win32u/wrappers.c @@ -1234,6 +1234,12 @@ INT WINAPI NtUserToUnicodeEx( UINT virt, UINT scan, const BYTE *state, return unix_funcs->pNtUserToUnicodeEx( virt, scan, state, str, size, flags, layout ); }
+BOOL WINAPI NtUserTrackMouseEvent( TRACKMOUSEEVENT *info ) +{ + if (!unix_funcs) return FALSE; + return unix_funcs->pNtUserTrackMouseEvent( info ); +} + BOOL WINAPI NtUserTranslateMessage( const MSG *msg, UINT flags ) { if (!unix_funcs) return 0; diff --git a/include/ntuser.h b/include/ntuser.h index 0a833d467b3..47bc7cbeb41 100644 --- a/include/ntuser.h +++ b/include/ntuser.h @@ -624,6 +624,7 @@ BOOL WINAPI NtUserSystemParametersInfoForDpi( UINT action, UINT val, PVOID pt BOOL WINAPI NtUserThunkedMenuInfo( HMENU menu, const MENUINFO *info ); INT WINAPI NtUserToUnicodeEx( UINT virt, UINT scan, const BYTE *state, WCHAR *str, int size, UINT flags, HKL layout ); +BOOL WINAPI NtUserTrackMouseEvent( TRACKMOUSEEVENT *info ); INT WINAPI NtUserTranslateAccelerator( HWND hwnd, HACCEL accel, MSG *msg ); BOOL WINAPI NtUserTranslateMessage( const MSG *msg, UINT flags ); BOOL WINAPI NtUserUnhookWinEvent( HWINEVENTHOOK hEventHook );