Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Graphics flicker.

37 views
Skip to first unread message

Matthew Stanfield

unread,
Aug 21, 1998, 3:00:00 AM8/21/98
to
Hi there,

I am using DrawText to display a time (updated every second) but it
regularly flickers as it's being updated - a flash of white just before
incrementing the time.

At the moment the following method is called every time the time needs to
be updated:

RedrawWindow(songTimeRect, NULL, RDW_INVALIDATE | RDW_UPDATENOW |
RDW_ERASE);

[songTimeRect is the rectangle that it's written in.]

I tried to stop the flickering by noting the current time and, instead of
calling RedrawWindow, writing over the current time in the background color
and then writing the new time as normal. But this did not provide a
significant improvement.

How can I get rid of the annoying flicker.

Thanks,

..matthew

--


##### # ### ---------------------------------------------+
##### ### ##### Matthew Stanfield |
##### ##### ##### mailto:Matthew....@Dial.Pipex.Com |
##### ####### ### ---------------------------------------------+

Chris Hough

unread,
Aug 21, 1998, 3:00:00 AM8/21/98
to

You need to see the Knowledge Base article "Flicker-Free Displays Using
an Off-Screen DC". This technique fixed my flickering perfectly.
Chris Hough

John Goodwin

unread,
Aug 21, 1998, 3:00:00 AM8/21/98
to Matthew Stanfield
Matthew,

Check to see if you have a background color defined in
your window class.

Probably: <window class>.hbrBackground =
(HBRUSH)GetStockObject(WHITE_BRUSH) ;

If you have this defined, the white background will get redrawn every time the
window
gets redrawn.

Substitute "NULL" for background color:

<window class>.hbrBackground = NULL ;

This is assuming that you are replacing the background with some
other graphic. Color or otherwise. If not this will not help.
I had a similar problem and this fixed it.

Another good idea for flicker free graphics is too create an offscreen
device context (CreateCompatibleDC) and do the drawing in memory,
then blit the contents into the window. This is a standard graphics method,
you can find lots of article referring to this technique.

John

John Goodwin

unread,
Aug 21, 1998, 3:00:00 AM8/21/98
to Matthew Stanfield

Emerick Rogul

unread,
Aug 21, 1998, 3:00:00 AM8/21/98
to
Matthew Stanfield writes:

: Hi there,


: I am using DrawText to display a time (updated every second) but it
: regularly flickers as it's being updated - a flash of white just before
: incrementing the time.

: At the moment the following method is called every time the time needs to
: be updated:

: RedrawWindow(songTimeRect, NULL, RDW_INVALIDATE | RDW_UPDATENOW |
: RDW_ERASE);

: [songTimeRect is the rectangle that it's written in.]

: I tried to stop the flickering by noting the current time and, instead of
: calling RedrawWindow, writing over the current time in the background color
: and then writing the new time as normal. But this did not provide a
: significant improvement.

: How can I get rid of the annoying flicker.

I can't provide a _ton_ of detail because I've never really had to do
this, but I believe the common technique is to draw into an in-memory
device context and then BitBlt that image onto the display (as opposed
to drawing directly to the display, the BitBlt method is significantly
faster). The Petzold or Richter books may provide some details on this.

-Emerick
--
--------------------------------------------------------------------------
"this is now, this is here, this is me, this is what i wanted you to see,
that was then, was that, that is gone, that is what i wanted you to feel"
--- Emerick Rogul <eme...@cs.bu.edu> --------- 'so fast, so numb', r.e.m.

Thomas Knorst

unread,
Aug 21, 1998, 3:00:00 AM8/21/98
to
Someone else noted using a NULL background brush for the window
- which will work.

But it is much simpler to override OnEraseBkgnd as so:

BOOL CMyView::OnEraseBkgnd(CDC* pDC)
{
return TRUE; // Avoid Flicker
}

Also, using the offscreen memory bitmap seems unneeded in your situation,
but you may want to retry drawing the background and the text. Currently a
white rectangle is redrawn by the window (as its background) each time,
which
causes the flash.

Regards,
Thomas Knorst t...@tcksoft.com
TCK Software, makers of VForm Grid/Forms MFC Control

PS.......
If you want to try - here is code to use an offscreen bitmap (it sounds more
complex than it is):

void CMyView::OnDraw(CDC* pDC)
{
CDC dc;
CDC* pDrawDC = pDC;
CBitmap bitmap;
CBitmap* pOldBitmap;


// only paint the rect that needs repainting
CRect rectClip, rectClient, rect;
pDC->GetClipBox(rectClip);
GetClientRect(&rectClient);
rect = rectClip;
DocToClient(rect);

if (!pDC->IsPrinting())
{
// draw to offscreen bitmap for fast looking repaints
if (dc.CreateCompatibleDC(pDC))
{
if (bitmap.CreateCompatibleBitmap(pDC, rect.Width(), rect.Height()))
{
OnPrepareDC(&dc, NULL);
pDrawDC = &dc;
// offset origin more because bitmap is just piece of the whole
drawing
dc.OffsetViewportOrg(-rect.left, -rect.top);
pOldBitmap = dc.SelectObject(&bitmap);
dc.SetBrushOrg(rect.left % 8, rect.top % 8);
// might as well clip to the same rectangle
dc.IntersectClipRect(rectClip);
}
}
}

----- DRAW TO pDrawDC -----


if (pDrawDC != pDC)
{
pDC->SetViewportOrg(0, 0);
pDC->SetWindowOrg(0,0);
pDC->SetMapMode(MM_TEXT);
dc.SetViewportOrg(0, 0);
dc.SetWindowOrg(0,0);
dc.SetMapMode(MM_TEXT);
pDC->BitBlt(rect.left, rect.top, rect.Width(), rect.Height(),
&dc, 0, 0, SRCCOPY);
dc.SelectObject(pOldBitmap);
}
}


Matthew Stanfield wrote in message <35DDAF93...@Dial.Pipex.com>...


>Hi there,
>
>I am using DrawText to display a time (updated every second) but it
>regularly flickers as it's being updated - a flash of white just before
>incrementing the time.
>
>At the moment the following method is called every time the time needs to
>be updated:
>
>RedrawWindow(songTimeRect, NULL, RDW_INVALIDATE | RDW_UPDATENOW |
>RDW_ERASE);
>
>[songTimeRect is the rectangle that it's written in.]
>
>I tried to stop the flickering by noting the current time and, instead of
>calling RedrawWindow, writing over the current time in the background color
>and then writing the new time as normal. But this did not provide a
>significant improvement.
>
>How can I get rid of the annoying flicker.
>

Dale M. Nurden

unread,
Aug 25, 1998, 3:00:00 AM8/25/98
to
On Fri, 21 Aug 1998 18:34:11 +0100, Matthew Stanfield
<Matthew....@Dial.Pipex.com> wrote:

>I am using DrawText to display a time (updated every second) but it
>regularly flickers as it's being updated - a flash of white just before
>incrementing the time.
>
>At the moment the following method is called every time the time needs to
>be updated:
>
>RedrawWindow(songTimeRect, NULL, RDW_INVALIDATE | RDW_UPDATENOW |
>RDW_ERASE);
>
>[songTimeRect is the rectangle that it's written in.]
>
>I tried to stop the flickering by noting the current time and, instead of
>calling RedrawWindow, writing over the current time in the background color
>and then writing the new time as normal. But this did not provide a
>significant improvement.

The flicker is probably caused by windows first erasing the background
by filling the whole rectangle with the background colour, and then
painting the your text over it.

If the clock is in its own window, you can give its window class a
NULL background brush, which means Windows doesn't erase the
background (you have to erase it yourself). If you can't modify the
window class, you can intercept WM_ERASEBKGND and erase the background
to your background colour (or not at all) without passing the message
on to DefWindowProc(). Doing this will stop the whole clock window
from flickering, but you might still see the text itself flicker
occasionally (because you are still filling the rectangle then
painting over it). Perhaps a combination of intercepting WM_ERASEBKGND
and your method of drawing the text with the background colour will
work.

I believe the most common solution to flicker problems (but more
complicated), is to create the entire window as a bitmap in memory,
and then copy the whole bitmap onto the display in one go with
BitBlt(). I've never needed to actually code something like this
(yet), but I believe it goes something like using CreateCompatibleDC()
to create a memory DC that you can paint onto, selecting a
suitably-sized bitmap into it, painting, then BitBlt()'ing from your
memory DC onto your window DC.

-Dale
---
Dale M. Nurden __|__ Highway Radio, 101.5FM
| What boots up must go down
dalen-rcis.co.za | http://users.iafrica.com/d/da/dalen
dalen-iafrica.com | For Email, use '@' in place of '-'.

Your market research is wrong! I am not interested in your product.
Don't add me to your mailing list and don't ask me to "reply to
remove myself". Just leave me alone.

0 new messages