Visual C++ 7.1Visual C++ 7.0Windows 2003Windows 2000Visual C++ 6.0Windows XPMFC中级开发Visual StudioWindowsC++
缓冲的 CScrollView






2.89/5 (9投票s)
2003年12月9日

56254

1191
一个继承自 CScrollView 的可重用类,用于实现缓冲滚动。
摘要
本文介绍了一个可重用的类,它继承自 CScrollView
,用于实现缓冲滚动。
目标
虽然“双缓冲绘图”是每个中级程序员都熟悉的常见技术,但实现流畅无闪烁的滚动视图却颇具挑战。如果一个应用程序已经直接在 CScrollView
上绘图,想要使用这种技术怎么办?是否需要修改大量代码? 不需要。所有这些棘手的问题都可以隐藏在一个可重用的类中。你只需要将你的类从 CCachedScrollView
而不是 CScrollView
继承即可。
实现
- 第一步: 使用 MFC 类向导创建一个继承自
CScrollView
的类CCachedScrollView
。 - 第二步: 添加成员字段
CacheBitmap
,它是内存位图,CacheValid
和CacheRect
用于滚动缓冲区。最后,通过OnPaint
处理WM_PAINT
消息。
CachedScrollView.h
class CCachedScrollView : public CScrollView { DECLARE_DYNCREATE(CCachedScrollView) protected: CCachedScrollView(); virtual ~CCachedScrollView(); virtual void OnDraw(CDC* pDC) { } private: CBitmap CacheBitmap; public: BOOL CacheValid; CRect CacheRect; void SetCacheSize(SIZE sz) { if (CacheRect.IsRectNull()) CacheRect=CRect(CPoint(0,0),sz); } DECLARE_MESSAGE_MAP() afx_msg void OnPaint(); };
CachedScrollView.cpp
void CCachedScrollView::OnPaint() { CPaintDC dc(this); OnPrepareDC(&dc); if (CacheRect.IsRectNull()) { OnDraw(&dc); return; } if (CacheBitmap.m_hObject==NULL) CacheBitmap.CreateCompatibleBitmap(&dc,CacheRect.Width(),
CacheRect.Height()); CRect ClientRect; GetClientRect(ClientRect); CPoint org=dc.GetViewportOrg(); ClientRect.OffsetRect(-org.x,-org.y); if (!CacheRect.PtInRect(ClientRect.TopLeft()) || !CacheRect.PtInRect(ClientRect.BottomRight())) { CacheRect.OffsetRect( ClientRect.CenterPoint()-CacheRect.CenterPoint()); CacheValid=FALSE; } CDC mdc; mdc.CreateCompatibleDC(&dc); mdc.SelectObject(&CacheBitmap); if (!CacheValid) { mdc.SelectStockObject(WHITE_BRUSH); mdc.SelectStockObject(NULL_PEN); mdc.Rectangle(0,0,CacheRect.Width(),CacheRect.Height()); mdc.SelectStockObject(BLACK_PEN); mdc.SetViewportOrg(-CacheRect.left,-CacheRect.top); OnDraw(&mdc); mdc.SetViewportOrg(0,0); CacheValid=TRUE; } dc.SelectClipRgn(NULL); dc.BitBlt(CacheRect.left,CacheRect.top, CacheRect.Width(),CacheRect.Height(),&mdc,0,0,SRCCOPY); }
用法
你可以编写自己的视图,继承自 CCachedScrollView
,注意在 InitUpdate()
中调用SetCacheSize()
方法来设置缓冲区图像大小。