diff --git a/dlls/user32/controls.h b/dlls/user32/controls.h index bf32097f95c..2b3d405ae69 100644 --- a/dlls/user32/controls.h +++ b/dlls/user32/controls.h @@ -171,6 +171,8 @@ extern LRESULT NC_HandleNCActivate( HWND hwnd, WPARAM wParam, LPARAM lParam ) DE extern LRESULT NC_HandleNCCalcSize( HWND hwnd, WPARAM wParam, RECT *winRect ) DECLSPEC_HIDDEN; extern LRESULT NC_HandleNCHitTest( HWND hwnd, POINT pt ) DECLSPEC_HIDDEN; extern LRESULT NC_HandleNCLButtonDown( HWND hwnd, WPARAM wParam, LPARAM lParam ) DECLSPEC_HIDDEN; +extern LRESULT NC_HandleNCMouseMove( HWND hwnd, POINT pt ) DECLSPEC_HIDDEN; +extern LRESULT NC_HandleNCMouseLeave( HWND hwnd ) DECLSPEC_HIDDEN; extern LRESULT NC_HandleNCRButtonDown( HWND hwnd, WPARAM wParam, LPARAM lParam ) DECLSPEC_HIDDEN; extern LRESULT NC_HandleNCLButtonDblClk( HWND hwnd, WPARAM wParam, LPARAM lParam) DECLSPEC_HIDDEN; extern LRESULT NC_HandleSysCommand( HWND hwnd, WPARAM wParam, LPARAM lParam ) DECLSPEC_HIDDEN; @@ -184,6 +186,7 @@ extern void SCROLL_DrawNCScrollBar( HWND hwnd, HDC hdc, BOOL draw_horizontal, BO extern void SCROLL_DrawScrollBar( HWND hwnd, HDC hdc, INT nBar, enum SCROLL_HITTEST hit_test, const struct SCROLL_TRACKING_INFO *tracking_info, BOOL arrows, BOOL interior ) DECLSPEC_HIDDEN; +extern void SCROLL_HandleScrollEvent( HWND hwnd, INT nBar, UINT msg, POINT pt ) DECLSPEC_HIDDEN; extern void SCROLL_TrackScrollBar( HWND hwnd, INT scrollbar, POINT pt ) DECLSPEC_HIDDEN; /* combo box */ diff --git a/dlls/user32/defwnd.c b/dlls/user32/defwnd.c index a3d92e84aef..5eb056ebd9e 100644 --- a/dlls/user32/defwnd.c +++ b/dlls/user32/defwnd.c @@ -245,6 +245,17 @@ static LRESULT DEFWND_DefWinProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPa case WM_NCPAINT: return NC_HandleNCPaint( hwnd, (HRGN)wParam ); + case WM_NCMOUSEMOVE: + { + POINT pt; + pt.x = (short)LOWORD(lParam); + pt.y = (short)HIWORD(lParam); + return NC_HandleNCMouseMove( hwnd, pt ); + } + + case WM_NCMOUSELEAVE: + return NC_HandleNCMouseLeave( hwnd ); + case WM_NCHITTEST: { POINT pt; diff --git a/dlls/user32/nonclient.c b/dlls/user32/nonclient.c index 50ecb0c4e2e..02e6ad92320 100644 --- a/dlls/user32/nonclient.c +++ b/dlls/user32/nonclient.c @@ -635,6 +635,39 @@ LRESULT NC_HandleNCHitTest( HWND hwnd, POINT pt ) return HTNOWHERE; } +LRESULT NC_HandleNCMouseMove(HWND hwnd, POINT pt) +{ + LONG hittest; + RECT rect; + + TRACE("hwnd=%p pt=%s\n", hwnd, wine_dbgstr_point(&pt)); + + hittest = NC_HandleNCHitTest(hwnd, pt); + if (hittest != HTHSCROLL && hittest != HTVSCROLL) + return 0; + + WIN_GetRectangles(hwnd, COORDS_CLIENT, &rect, NULL); + ScreenToClient(hwnd, &pt); + pt.x -= rect.left; + pt.y -= rect.top; + SCROLL_HandleScrollEvent(hwnd, hittest == HTHSCROLL ? SB_HORZ : SB_VERT, WM_NCMOUSEMOVE, pt); + return 0; +} + +LRESULT NC_HandleNCMouseLeave(HWND hwnd) +{ + LONG style = GetWindowLongW(hwnd, GWL_STYLE); + POINT pt = {0, 0}; + + TRACE("hwnd=%p\n", hwnd); + + if (style & WS_HSCROLL) + SCROLL_HandleScrollEvent(hwnd, SB_HORZ, WM_NCMOUSELEAVE, pt); + if (style & WS_VSCROLL) + SCROLL_HandleScrollEvent(hwnd, SB_VERT, WM_NCMOUSELEAVE, pt); + + return 0; +} /****************************************************************************** * diff --git a/dlls/user32/scroll.c b/dlls/user32/scroll.c index c4c06476b9c..088e41eee43 100644 --- a/dlls/user32/scroll.c +++ b/dlls/user32/scroll.c @@ -751,7 +751,7 @@ static void SCROLL_HandleKbdEvent(HWND hwnd, WPARAM wParam, LPARAM lParam) * 'pt' is the location of the mouse event in client (for SB_CTL) or * windows coordinates. */ -static void SCROLL_HandleScrollEvent( HWND hwnd, INT nBar, UINT msg, POINT pt) +void SCROLL_HandleScrollEvent( HWND hwnd, INT nBar, UINT msg, POINT pt ) { /* Previous mouse position for timer events */ static POINT prevPt; @@ -773,7 +773,8 @@ static void SCROLL_HandleScrollEvent( HWND hwnd, INT nBar, UINT msg, POINT pt) SCROLLBAR_INFO *infoPtr = SCROLL_GetInternalInfo( hwnd, nBar, FALSE ); if (!infoPtr) return; if ((g_tracking_info.hit_test == SCROLL_NOWHERE) - && (msg != WM_LBUTTONDOWN && msg != WM_MOUSEMOVE && msg != WM_MOUSELEAVE)) + && (msg != WM_LBUTTONDOWN && msg != WM_MOUSEMOVE && msg != WM_MOUSELEAVE + && msg != WM_NCMOUSEMOVE && msg != WM_NCMOUSELEAVE)) return; if (nBar == SB_CTL && (GetWindowLongW( hwnd, GWL_STYLE ) & (SBS_SIZEGRIP | SBS_SIZEBOX))) @@ -841,6 +842,32 @@ static void SCROLL_HandleScrollEvent( HWND hwnd, INT nBar, UINT msg, POINT pt) break; + case WM_NCMOUSEMOVE: + hittest = SCROLL_HitTest( hwnd, nBar, pt, vertical == g_tracking_info.vertical && GetCapture() == hwnd ); + prevPt = pt; + + if (nBar == SB_CTL) + break; + + tme.cbSize = sizeof(tme); + tme.dwFlags = TME_QUERY; + TrackMouseEvent( &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 ); + } + + break; + + case WM_NCMOUSELEAVE: + if (nBar == SB_CTL) + return; + + hittest = SCROLL_NOWHERE; + break; + case WM_MOUSELEAVE: if (nBar != SB_CTL) return; @@ -870,7 +897,7 @@ static void SCROLL_HandleScrollEvent( HWND hwnd, INT nBar, UINT msg, POINT pt) switch (g_tracking_info.hit_test) { case SCROLL_NOWHERE: /* No tracking in progress */ - if (msg == WM_MOUSEMOVE || msg == WM_MOUSELEAVE) + if (msg == WM_MOUSEMOVE || msg == WM_MOUSELEAVE || msg == WM_NCMOUSEMOVE || msg == WM_NCMOUSELEAVE) SCROLL_DrawScrollBar( hwnd, hdc, nBar, hittest, &g_tracking_info, TRUE, TRUE ); break; @@ -1049,6 +1076,8 @@ void SCROLL_TrackScrollBar( HWND hwnd, INT scrollbar, POINT pt ) if (msg.message == WM_LBUTTONUP || msg.message == WM_MOUSEMOVE || msg.message == WM_MOUSELEAVE || + msg.message == WM_NCMOUSEMOVE || + msg.message == WM_NCMOUSELEAVE || (msg.message == WM_SYSTIMER && msg.wParam == SCROLL_TIMER)) { pt.x = (short)LOWORD(msg.lParam) - rect.left; @@ -1383,6 +1412,8 @@ LRESULT WINAPI USER_ScrollBarProc( HWND hwnd, UINT message, WPARAM wParam, LPARA } break; case WM_LBUTTONUP: + case WM_NCMOUSEMOVE: + case WM_NCMOUSELEAVE: case WM_MOUSEMOVE: case WM_MOUSELEAVE: case WM_SYSTIMER: