跟踪滚动条上的鼠标事件

Tracking mouse events on scrollbar

本文关键字:鼠标 事件 滚动条 跟踪      更新时间:2023-10-16

我有一个组件,它被细分为对话框,我在该组件中处理鼠标事件。我试图实现的是根据鼠标事件更改滚动条的可见性(即,只有当鼠标悬停在该区域时,滚动条才会出现(。我在WM_MOUSEMOVE消息上处理TrackMouseEvent,在WM_MOUSEHOVERWM_MOUSELEAVE上分别使用ShowScrollBar

除了鼠标悬停在滚动条上时,它可以按预期工作。它不断地发送WM_MOUSEHOVERWM_MOUSELEAVE消息,整个区域闪烁,就像每秒都被重新绘制一样。

我不太确定ShowScrollbarTrackMouseEvent的行为。有人能帮我找到解决这个问题的方法吗?

我的应用程序是在没有MFC的Win32下开发的,下面是我的一小段代码。

// gets called once on initialize
void CUDComment::InitScrollRange(int cyWindow)
{
int nTotal = _getTotalItemHeight();
int nRangeY = nTotal - cyWindow + _getItemHeight();
if( nRangeY < 0 ) nRangeY = 0;
if( m_nVerPos >= nRangeY )
{
m_nVerPos = nRangeY;
}
DWORD dwScrollState = 0;
// Hide scrollbar when the content is just one line
if( nTotal > cyWindow )
{
dwScrollState = 1;
m_bShowScroll = TRUE;
}
else
{
if( m_bShowScroll )
{
dwScrollState = 2;
m_bShowScroll = FALSE;
}
}
if( dwScrollState > 0 )
{
SCROLLINFO siVer;
siVer.cbSize = sizeof(SCROLLINFO);
siVer.fMask = SIF_PAGE | SIF_RANGE | SIF_POS;
siVer.nMin = 0;
if( dwScrollState == 2 )
{
siVer.nMax = 0;
siVer.nPage = 0;
siVer.nPos = 0;
}
else
{
siVer.nMax = nRangeY;
siVer.nPage = min(nRangeY, (int)_getItemHeight());
siVer.nPos = m_nVerPos;
}
SetScrollInfo(m_hWnd, SB_VERT, &siVer, TRUE);
}
}
void CUDComment::OnMouseMove(HWND hWnd, WPARAM wParam, LPARAM lParam)
{
if( !m_bTracking )
{
TRACKMOUSEEVENT tme;
tme.cbSize = sizeof(tme);
tme.hwndTrack = m_hWnd;
tme.dwFlags = TME_LEAVE | TME_HOVER;
tme.dwHoverTime = 500;
m_bTracking = TrackMouseEvent(&tme);
}
}
void CUDComment::OnMouseHover(HWND hWnd, WPARAM wParam, LPARAM lParam)
{
ShowScrollBar(m_hWnd, SB_VERT, TRUE);
}
void CUDComment::OnMouseLeave(HWND hWnd, WPARAM wParam, LPARAM lParam)
{
m_bTracking = FALSE;
ShowScrollBar(m_hWnd, SB_VERT, FALSE);
}

我尝试了Johnathan的方法,但当我为TrackMouseEvent设置TME_LEAVETME_NONCLIENT触发器时,它不太起作用。我无法让鼠标捕捉非客户端区域。我所做的基本上是计算滚动条的大小(GetSystemMetrics(SM_CXVSCROLL)(及其坐标,然后在鼠标悬停在滚动条区域时忽略留言。因此,在处理WM_MOUSELEAVE消息时,我基本上创建了一个异常情况。

除了我的OnMouseLeave函数外,总体代码看起来相似。

void CUDComment::OnMouseLeave(HWND hWnd, WPARAM wParam, LPARAM lParam)
{
POINT ptCurrent;
GetCursorPos(&ptCurrent);
ScreenToClient(hWnd, &ptCurrent);
if (!PtInRect(&m_rcScrollbar, ptCurrent))
{
ShowScrollBar(hWnd, SB_VERT, FALSE);
m_bTracking = FALSE;
}
}