Click here to Skip to main content
15,882,163 members
Articles / Desktop Programming / MFC
Article

Buffered CScrollView

Rate me:
Please Sign up or sign in to vote.
2.89/5 (9 votes)
8 Dec 2003 55.4K   1.2K   21   2
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(),<BR>    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


Written By
Software Developer (Senior)
China China
I am a programmer with experience of twenty years. I started programming when I was a student in middle school. I have learned many programming language: pascal,c,c++,object-c,java,c#,JavaScript,lisp,smalltalk, action-script,f#,prolog. I am a iOS developer. Welcome to visit me on appstore.
https://itunes.apple.com/cn/artist/dejun-meng/id334838050

Comments and Discussions

 
GeneralOne problem... Pin
niry22-Feb-04 9:34
niry22-Feb-04 9:34 
GeneralSuggestions Pin
Shog99-Dec-03 18:43
sitebuilderShog99-Dec-03 18:43 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.