📄 flicker_free_drawing2.shtml.htm
字号:
<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
<META NAME="Author" CONTENT="Zafir Anjum">
<TITLE>Misc - Flicker free drawing (2)</TITLE>
</HEAD>
<body background="../fancyhome/back.gif" tppabs="http://www.codeguru.com/fancyhome/back.gif" bgcolor="#FFFFFF" link="#B50029" vlink="#8E2323" alink="#FF0000" bgproperties="fixed">
<table WIDTH="100%">
<tr WIDTH="100%">
<td><td>
</tr>
</table>
<CENTER><H3><FONT COLOR="#AOAO99">Flicker free drawing (2)</FONT></H3></CENTER>
<HR>
<P>This class was contributed by <A HREF="mailto:aleitner@usa.net">Andreas Leitner</A>.
<P>This is a small class that makes it easy to create windows that are
updated flicker-free. Once I had to code a window that displayed "hard
to calculate" data. Since I needed to update the contents in constant time
(say every second) I got this ugly flickering on my machine.
<P>There is an article dealing with the same problem on this site (<I>Flicker
free drawing using memory DC by Keith Rule</I>). The main difference
between our approaches is that Keith extends the class CDC and I extended
CWnd. I think both versions have got advantages and disadvantages. <A HREF="#Difference">I
will try to point out the difference at the end of this article.</A>
<P>What I needed was a window that displayed its contents without flickering.
I archieve the flicker free mode with a well known trick: First paint everything
on a bitmap, then copy the bitmap into the the window. Since this aproach
is a bit slower than the common way, I decided that the end-user may decide
wether to use the fast mode (in case that his machine is good enough that
even this mode doesn't flicker), or the flicker-free mode.
<P>The new class is called <FONT COLOR="#000099">CadvWnd</FONT> (based
on <FONT COLOR="#000099">CWnd</FONT>):
<BR>The first 2 attributes that came on my mind were:
<PRE><TT><FONT COLOR="#990000">
void SetFlickerFree(BOOL bFlickerFree);
BOOL IsFlickerFree();
</FONT></TT></PRE>
<P>I think it is rather easy to guess what those functions should do. What
I needed further was a sort of <FONT COLOR="#000099">OnPaint</FONT> function.
But since I will need this function-name for internal use I took an other
function (in fact two again to definitly force a difference between foreground
and background).
<PRE><TT><FONT COLOR="#990000">
爒irtual void InternalRedrawFG(CDC* pDC, CRect rcPaint);
爒irtual void InternalRedrawBG(CDC* pDC, CRect rcPaint);
</FONT></TT></PRE>
<P><FONT COLOR="#000099">InternalRedrawFG</FONT> should be overridded for
foreground drawing and <FONT COLOR="#000099">InternalRedrawBG </FONT>for
the background. Once the bitmap is painted it will be copied into the window
every time it needs to be updated. Of course the window checks messages
like WM_SIZE and recreates and repaints the bitmap. But how does the client
tell the window that the contents has changes and the bitmap needs to be
repainted or even recreated?
<PRE><TT><FONT COLOR="#990000">
void ReCreateBitmap();
void SetContentsChanged(BOOL yes = TRUE);
BOOL IsContentsChanged();
</FONT></TT></PRE>
<P><FONT COLOR="#000099">ReCreateBitmap</FONT> is the direct way to recreate
the bitmap (Mabe you as a client of the class will never need to call this
one:). More often you will have to call <FONT COLOR="#000099">SetContentsChanged(TRUE)</FONT>.
When you do this, the next time the window will be repainted, the bitmap
also will be. Just call this function if the data changes on which the
window contents is based.
<P>This class has even got a few extra features. I thought it is often
the case that you need a special background color so I made also this available
easy (of course you can add a mode for a background picture too). By now
there are two background modes: <FONT COLOR="#000099">BM_DEF_WND_COL</FONT>
and <FONT COLOR="#000099">BM_CUST_COL</FONT>. If you select <FONT COLOR="#000099">SetBackgroundMode(
0, BM_DEF_WND_COL )</FONT> the window will behave like default, but if
you call <FONT COLOR="#000099">SetBackgroundMode( RGB(255,0,0), BM_CUST_COL
)</FONT> the background will be painted red. Here come the function declarations:
<PRE><TT><FONT COLOR="#990000">
const int GetBackgroundMode();
void SetBackgroundMode(COLORREF Color, int Mode = BM_CUST_COL); // To set the std mode just set col black and change the mode value
COLORREF GetBackgroundColor();
</FONT></TT></PRE>
<BR>
<BR> There is also a nice new function that you should override in
your derived class if you have child windows in your window.
<PRE><TT><FONT COLOR="#990000">
virtual BOOL CreateChildren();
</FONT></TT></PRE>
<P>This function will be called in the right moment regardless if you create
this window through subclassing (often used in dialogs) or through a "create"
call (often used if you make it a child of another <FONT COLOR="#000099">CWnd</FONT>
(derived) class).
<BR>
<H4>
What do you need to derive a class from CadvWnd?</H4>
Be sure to include the header of <FONT COLOR="#000099">CadvWnd</FONT> in
your new class and derive it as public from it. A minimal implementation
just needs to override <FONT COLOR="#000099">InternalRedrawFG </FONT>as
shown in the following example.
<PRE><TT><FONT COLOR="#990000">
#include "advWnd.h"
class CMyWnd : public CadcWnd
{
牋
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -