响应鼠标滚轮
在Windows上使用鼠标滚轮滚动一个窗口是比较方便的。在滚轮滚动时,有输入焦点的窗口将接收WM_MOUSEWHEEL消息。MFC的CSrollView类为这些消息提供了默认的处理程序,可以自动地滚动窗口,但是如果想用鼠标滚轮消息滚动一个非CSrollView窗口,则必须自己处理WM_MOUSEWHEEL。
MFC的ON_WM_MOUSEWHEEL宏将WM_MOUSEWHEEL消息映射到消息处理函数OnMouseWheel,其原型如下:
BOOL OnMouseWheel(UINT nFlags, short zDelta, CPoint point)
nFlags:指出消息生成时鼠标键以及Shift键和Ctrl键的状态。通过测试下表的位标志,可以从此参数中得到特殊按钮或键被释放还是按下的状态。
掩码 | 含义 |
---|---|
MK_LBUTTON | 鼠标左键被按下 |
MK_MBUTTON | 鼠标中键被按下 |
MK_RBUTTON | 鼠标右键被按下 |
MK_CONTROL | Ctrl键被按下 |
MK_SHIFT | Shift键被按下 |
当且仅当Ctrl键处于按下状态表达式 nFlags&MK_CONTROL 才是非零值。(Tips: Ctrl键按下,滚动滑轮网页缩放)
point:指出光标位置。
zDelta:滚轮旋转的距离,zDelta==WHEEL_DELTA(120) 表示滚轮向前旋转了一个增量(槽口),而zDelta == -WHEEL_DELTA表示滚轮向后旋转了一单位槽口。若滚轮向前旋转了5个槽口,则窗口将接收到5个WM_MOUSEWHEEL消息,每个消息都有一个zDelta值为WHEEL_DELTA。
如果OnMouseWheel滚动了窗口,则它应该返回一个非零值,否则返回零值。
响应WM_MOUSEWHEEL消息的方法之一:
当zDelta>0:对每一个WHEEL_DELTA单位都将窗口向上滚动一行;
当zDelta<0:对每一个WHEEL_DELTA单位都将窗口向下滚动一行;
//In the message map
ON_WM_MOUSEWHEEL()
BOOL CMainWindow::OnMouseWheel(UINT nFlags, short zDelta, CPoint point)
{
BOOL bUp = TRUE;
int nDelta = zDelta;
if(zDelta < 0)
{
bUp = FLASE;
nDelta = -nDelta;
}
UINT nWheelScrollLines = 0;
::SystemRarametersInfo(SPI_GETWHEELSCROLLLINES, 0, &nWheelScrollLines, 0);
//WHEEL_PAGESCROLL:一个特殊值,告诉应用程序模拟单击滚动条轴,执行向上或向下滚动一页的操作。
if(nWheelScrollLines == WHEEL_PAGESCROLL)
{
SendMessage(WM_VSCROLL, MAKEPARAW(bUp? SB_PAGEUP : SB_PAGEDOWN, 0), 0);
}
else
{
//确定滚动的行数
int nLines = (nDelta * nWheelScrollLines) / WHEEL_DELTA;
while(nLines--)
{
SendMessage(WM_VSCROLL, MAKEPARAM(bUp ? SB_LINEUP : SB_LINEDOWN, 0), 0);
}
}
return TRUE;
}
注意: 在MFC使用_AfxGetMouseScrollLines()来获得WheelScrollLines,且这个 函数具有平台中立性,它先尝试多种方法来获得滚动行数,如果都未成功,则返回默认值3。