Solved

flickering image

Posted on 1998-11-02
5
696 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering 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

Introduction: Ownerdraw of the grid button.  A singleton class implentation and usage. Continuing from the fifth article about sudoku.   Open the project in visual studio. Go to the class view – CGridButton should be visible as a class.  R…
Introduction: Database storage, where is the exe actually on the disc? Playing a game selected randomly (how to generate random numbers).  Error trapping with try..catch to help the code run even if something goes wrong. Continuing from the seve…
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.
In this video, viewers are given an introduction to using the Windows 10 Snipping Tool, how to quickly locate it when it's needed and also how make it always available with a single click of a mouse button, by pinning it to the Desktop Task Bar. Int…

695 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