MFC CScrollView闪烁问题
界面刷新的时候,CScrollView会先调用OnEraseBkgnd,将背景色刷新一次后才绘制视图,会造成闪烁问题。
解决方式:在CScrollView继承类中,接收ON_WM_ERASEBKGND()消息,然后函数屏蔽背景刷新函数。
ON_WM_ERASEBKGND() // 消息
BOOL CAView::OnEraseBkgnd(CDC* pDC){
//return CScrollView::OnEraseBkgnd(pDC) // 屏蔽
return true;
}
MFC CScrollView重影问题
当移动滚动条时,CScrollView默认会先移动逻辑视图,如果你不是基于逻辑视图绘制的视图,而是基于物理视图绘制的话,快速移动滚动条时就会有重影问题。
解决方式:屏蔽掉移动滚动条时调用的移动逻辑视图函数;移动逻辑视图函数是ScrollWindow(),在CScrollView虚函数OnScrollBy中被调用到,所以重载该虚函数,将CScrollView::OnScrollBy的内容复制到重载的虚函数中,只屏蔽ScrollWindow()。
BOOL CScrollView::OnScrollBy(CSize sizeScroll, BOOL bDoScroll)
{
int xOrig, x;
int yOrig, y;
// don't scroll if there is no valid scroll range (ie. no scroll bar)
CScrollBar* pBar;
DWORD dwStyle = GetStyle();
pBar = GetScrollBarCtrl(SB_VERT);
if ((pBar != NULL && !pBar->IsWindowEnabled()) ||
(pBar == NULL && !(dwStyle & WS_VSCROLL))){
// vertical scroll bar not enabled
sizeScroll.cy = 0;
}
pBar = GetScrollBarCtrl(SB_HORZ);
if ((pBar != NULL && !pBar->IsWindowEnabled()) ||
(pBar == NULL && !(dwStyle & WS_HSCROLL))){
// horizontal scroll bar not enabled
sizeScroll.cx = 0;
}
// adjust current x position
xOrig = x = GetScrollPos(SB_HORZ);
int xMax = GetScrollLimit(SB_HORZ);
x += sizeScroll.cx;
if (x < 0)
x = 0;
else if (x > xMax)
x = xMax;
// adjust current y position
yOrig = y = GetScrollPos(SB_VERT);
int yMax = GetScrollLimit(SB_VERT);
y += sizeScroll.cy;
if (y < 0)
y = 0;
else if (y > yMax)
y = yMax;
// did anything change?
if (x == xOrig && y == yOrig)
return FALSE;
if (bDoScroll){
// do scroll and update scroll positions
// ScrollWindow(-(x-xOrig), -(y-yOrig));// 屏蔽移动逻辑视图函数
if (x != xOrig)
SetScrollPos(SB_HORZ, x);
if (y != yOrig)
SetScrollPos(SB_VERT, y);
}
return TRUE;
}
使用的父窗口是CSplitterWnd时鼠标拖拽滚动条最终会调用OnScrollBy,但使用鼠标滚动轮的话是不会调用该函数的,所以需要通过接受鼠标滚动轮消息,直接使用SetScrollPos(SB_VERT, y);(SB_VERT:垂直方向)移动滚动条位置。
BOOL CScrollView::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
SetScrollPos(SB_VERT, GetScrollPosition().y-zDelta);
Invalidate();
UpdateWindow(); // 触发视图重绘
return CScrollView::OnMouseWheel(nFlags, zDelta, pt);
}