MFC CScrollView闪烁,移动滚动条重影问题解决;(只移动滚动条,不移动视图)

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);
}

 

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值