这是MFC CScrollBar的bug?

善良超锅锅 2016-04-23 09:59:00
最近使用滚动条时,当把滚动条的范围设置到很大时,滚动条就不能正常使用了,如下图我遇到的情况


滚动条的滑块下拉一段距离后就下拉不了。

我调试的时候发现void CNEWDlg::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)的nPos参数有问题。

我本来的滚动条消息处理是这样的(注意case SB_THUMBPOSITION和case SB_THUMBTRACK)
void CNEWDlg::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{

if (pScrollBar == &m_DiagramSB)
{
SCROLLINFO si;
si.cbSize = sizeof(si);
si.fMask = SIF_ALL;
pScrollBar->GetScrollInfo(&si, SIF_ALL);
int pos = si.nPos;

switch (nSBCode)
{
case SB_TOP:
pos = 1;
break;

case SB_BOTTOM:
pos = si.nMax;
break;

case SB_ENDSCROLL:
break;

case SB_LINEDOWN:
pos++;
break;

case SB_LINEUP:
pos--;
break;

case SB_PAGEDOWN:
{

if (pos < si.nMax)
pos = min(si.nMax, pos + (int)si.nPage);
}
break;

case SB_PAGEUP:
{
if (pos > si.nMin)
pos = max(si.nMin, pos - (int)si.nPage);
}
break;

case SB_THUMBPOSITION:
pos = nPos,;
break;

case SB_THUMBTRACK:
pos =nPos,;
break;

default:
break;
}

//ZeroMemory(&si, sizeof(si));
si.cbSize = sizeof(si);
si.fMask = SIF_POS;
si.nPos = pos;
pScrollBar->SetScrollInfo(&si);
}

CDialogEx::OnVScroll(nSBCode, nPos, pScrollBar);

// 刷新示意图子窗口
RECT rc;
GetDlgItem(IDC_DIAGRAM)->GetWindowRect(&rc);
ScreenToClient(&rc);
InvalidateRect(&rc, FALSE);
UpdateWindow();
}


我调试的时候发现滚动条的滑块下拉一段距离后nPos就变成一个很大很大的数,赋值给pos后发生了翻转,使pos成了负数。滑块无法下拉的原因正在与此。我把上面的nPos用si.nTrackPos就好了。

问题解决了,但是我很疑惑:OnVScroll方法是MFC框架提供的,为什么参数会有问题呢?
...全文
119 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
hurryboylqs 2016-04-23
  • 打赏
  • 举报
回复
你可以参考这个 http://www.codeproject.com/Articles/10902/Add-Scrolling-to-a-CWnd-or-CDialog-using-a-C-Helpe
schlafenhamster 2016-04-23
  • 打赏
  • 举报
回复
SIF_POS The nPos member contains the scroll box position, which is not updated while the user drags the scroll box. SIF_TRACKPOS The nTrackPos member contains the current position of the scroll box while the user is dragging it. 参考 void CxxxxDlg::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) { // TODO: Add your message handler code here and/or call default SCROLLINFO ScrollInfo; ScrollInfo.cbSize=sizeof(ScrollInfo); ScrollInfo.fMask = SIF_ALL; GetScrollInfo(SB_VERT,&ScrollInfo); // int delta=0; switch(nSBCode) { case SB_TOP: case SB_LINEUP: if(ScrollInfo.nPos > ScrollInfo.nMin) delta = -SCROLL_STEP; break; case SB_BOTTOM: case SB_LINEDOWN: if(ScrollInfo.nPos < (ScrollInfo.nMax-(int)ScrollInfo.nPage)) delta = SCROLL_STEP; break; case SB_THUMBTRACK: case SB_THUMBPOSITION: delta = ScrollInfo.nTrackPos-ScrollInfo.nPos; break; } if(delta !=0 ) {// you can adjust m_Offset in OnInitDialog() for "abc" start point m_vbPos -= delta; ScrollWindow(0,-delta); UpdateWindow(); ScrollInfo.nPos += delta; ScrollInfo.fMask=SIF_POS | SIF_RANGE; SetScrollInfo(SB_VERT,&ScrollInfo); } // CDialog::OnVScroll(nSBCode, nPos, pScrollBar); }

15,979

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 界面
社区管理员
  • 界面
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧