Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Buffered CScrollView

0.00/5 (No votes)
8 Dec 2003 1  
A reusable class inherited from CScrollView to implement buffered scrolling

Abstract

Article is on a reusable class inherited from CScrollView to implement buffered scrolling.

Objective

Although "double buffered drawing" is a common technique that every intermediate programmer knows, tt�s quite tricky to implement a smoothly no flicker scrolling view. What if an application already drawing directly on a CScrollView wants to use the technique? Does it need to change much code? No. All those tricky things can be concealed in one reusable class. All you need is to inherit your class from CCachedScrollView instead of CScrollView.

Implementation

  • First Step: Create a class CCachedScrollView inherited from CScrollView using the MFC class wizard.
  • Second Step: Add member fields CacheBitmap that is the memory bitmap, CacheValid and CacheRect for scroll buffer. At last, process the WM_PAINT message by OnPaint.

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

Usage

You can write your own view inherited from CCachedScrollView, pay attention to call
the SetCacheSize() method in InitUpdate() for setting the buffer image size.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here