Solved

flickering image

Posted on 1998-11-02
5
694 Views
Last Modified: 2013-11-20
Hi,

I have a small example that draws some shapes on screen (such as circles, squares, etc).   I use a memory compatible DC for drawing all these and display them to screen all at once.  The code for OnPaint() and OnDraw() are below and they works fine.  However,  when I resize my window,  it looks to me that OnPaint()/OnDraw() get called twice, so
everthing seems to be redrawn twice.  So if my OnDraw() takes a long time to render my shapes, then it causes flickering since it first draws the shapes in memory, clear the screen, display the shapes, then again draw the shapes in memory, clear the screen, display the shapes again.

I think maybe somehow window resizing send at least more than one WM_PAINT messages and that forces everything to be redrawn more than one.  If that is true, is there a way just to regconize/response to these consecutive VW_PAINT messages once?  Or if I do the wrong thing here, please help.  Thanks much in advance,
-Thang


void CEx10bView::OnDraw(CDC* pDC)
{
 CBrush brushHatch(HS_DIAGCROSS, RGB(255, 0, 0));
 CPoint point(0, 0);      // logical (0, 0)

 pDC->LPtoDP(&point);     // In device coordinates,
 pDC->SetBrushOrg(point); //  align the brush with
                          //  the window origin
 pDC->SelectObject(&brushHatch);
 pDC->Ellipse(CRect(m_pointTopLeft, m_sizeEllipse));
 pDC->SelectStockObject(BLACK_BRUSH); // Deselect brushHatch
 pDC->Rectangle(CRect(100, -100, 200, -200)); // Test invalid rect
 for (int i = 1; i < 10000000; i++);  // here is some dummy delay...
}


void CEx10bView::OnPaint()
{
 CPaintDC dc(this); // device context for painting
 OnPrepareDC(&dc);
 CRect rectUpdate;
 dc.GetClipBox(&rectUpdate);
 CBitmap* pOldBitmap = m_pdcMemory->SelectObject(m_pBitmap);
 m_pdcMemory->SelectClipRgn(NULL);
 m_pdcMemory->IntersectClipRect(&rectUpdate);
 CBrush backgroundBrush((COLORREF) ::GetSysColor(COLOR_WINDOW));
 CBrush* pOldBrush =  m_pdcMemory->SelectObject(&backgroundBrush);
 m_pdcMemory->PatBlt(rectUpdate.left, rectUpdate.top,
                     rectUpdate.Width(), rectUpdate.Height(),
                     PATCOPY);
 OnDraw(m_pdcMemory);
 dc.BitBlt(rectUpdate.left, rectUpdate.top,
           rectUpdate.Width(), rectUpdate.Height(),
           m_pdcMemory, rectUpdate.left, rectUpdate.top,
           SRCCOPY);
 m_pdcMemory->SelectObject(pOldBitmap);
 m_pdcMemory->SelectObject(pOldBrush);
}

0
Comment
Question by:tpnguyen
  • 2
  • 2
5 Comments
 
LVL 3

Accepted Solution

by:
plaroche earned 50 total points
ID: 1324167
Check for OnEraseBkgnd(), just return  from this call without erasing the window's background.
0
 

Author Comment

by:tpnguyen
ID: 1324168
Hi plaroche,
In my code, I do not have OnEraseBkgnd().   However, I tried to do  what you suggested anyway by adding the below.  It basically did not cause flickering, but it caused other problem instead, the background did not get erased, so it has garbages (images of other windows), and resizing window seemed very slow.   I don't mind to ease the background though, but I would like the OnDraw() called once when I resize the window, that way it does not have to draw the shapes twice.

BOOL CEx10bView::OnEraseBkgnd(CDC* pDC)
{
      // TODO: Add your message handler code here and/or call default
      //return 1;   // I did try with both 0 and 1
      return CScrollView::OnEraseBkgnd(pDC);
}
0
 
LVL 1

Expert Comment

by:TheGrinch
ID: 1324169
Why OnPaint? Do everything in OnDraw.
0
 

Author Comment

by:tpnguyen
ID: 1324170
Hi,
I have tried OnDraw() only.  The same thing occurred.   I think what really happenned was that everytime I resize the window, OnDraw() or OnPain() got called more than once. And that made my drawing flashes twice.    I further noticed that if I tried resizing the window with a tiny amount (I must be very careful, precise and quick here by clicking on the mouse and try to resize it in one direction just a tiny bit..  it took a lot of practice...), then I saw the drawing only flashed once and that was what I wanted.

The question now becomes:   Is there a way to tell window to draw when  we are done with resizing (when you release the mouse button)?  Thanks,
-Thang


0
 
LVL 1

Expert Comment

by:TheGrinch
ID: 1324171
Windows doesn't call OnDraw twice in the normal case.
Look for a misplaced Invalidate() somewhere.

Also -- something is very strange about your program if you call OnPaint() for a view. CView has OnDraw() but not OnPaint(). OnPaint is a member of the base class CWnd.

Suggestion -- remove OnPaint() entirely if you are using CView. Do all drawing in OnDraw(). That's the way it was designed to work.
0

Featured Post

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Question regarding Copy/Paste 16 98
How to know only "File created" with EventLog 3 35
sum67 challenge 35 116
matchUp  challenge 9 125
This is to be the first in a series of articles demonstrating the development of a complete windows based application using the MFC classes.  I’ll try to keep each article focused on one (or a couple) of the tasks that one may meet.   Introductio…
Introduction: Dynamic window placements and drawing on a form, simple usage of windows registry as a storage place for information. Continuing from the first article about sudoku.  There we have designed the application and put a lot of user int…
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.

726 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question