65.9K
CodeProject 正在变化。 阅读更多。
Home

缓冲的 CScrollView

starIconstarIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIcon

2.89/5 (9投票s)

2003年12月9日

viewsIcon

56254

downloadIcon

1191

一个继承自 CScrollView 的可重用类,用于实现缓冲滚动。

摘要

本文介绍了一个可重用的类,它继承自 CScrollView,用于实现缓冲滚动。

目标

虽然“双缓冲绘图”是每个中级程序员都熟悉的常见技术,但实现流畅无闪烁的滚动视图却颇具挑战。如果一个应用程序已经直接在 CScrollView 上绘图,想要使用这种技术怎么办?是否需要修改大量代码? 不需要。所有这些棘手的问题都可以隐藏在一个可重用的类中。你只需要将你的类从 CCachedScrollView 而不是 CScrollView 继承即可。

实现

  • 第一步: 使用 MFC 类向导创建一个继承自 CScrollView 的类 CCachedScrollView
  • 第二步: 添加成员字段 CacheBitmap,它是内存位图,CacheValidCacheRect 用于滚动缓冲区。最后,通过 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() 方法来设置缓冲区图像大小。

© . All rights reserved.