The problem arises. In OnEraseBkgnd, if you do not call the original default ONERASEBKGND, only redraw the background will not blink. And in OnPaint, because it implicitly calls the OnEraseBkgnd, And you're not dealing with the ONERASEBKGND function, which is related to the window's default background brush. The default ONERASEBKGND action uses the window's default background to brush the new background (usually white brush), And then you re-paint your background to cause the screen to blink. Another problem is that ONERASEBKGND is not always called. If you call invalidate, the argument is true, and BeginPaint is implicitly called in OnPaint. wm_ ERASEBKGND the message, and if the argument is false, the background is not re-brushed.
So the solution is three and a half:
1. Implement with ONERASEBKGND, do not call the original OnEraseBkgnd function.
2. Implemented with OnPaint, while overloading OnEraseBkgnd, which is returned directly.
3. Implement with OnPaint, set the background brush to empty when creating the window
4. Implemented with OnPaint, but requires invalidate (FALSE) when refreshing
The function. (However, in this case, the refresh caused by the window overlay is still going to flash a
Under, so not a thorough solution)
It's all quite simple.
------------------------------------------------------
The drawing of any window component in MFC is placed in these two member function
OnEraseBkgnd () is used to draw a basemap and OnPaint () is used to draw the main object.
For example, a button is gray and there's text on it.
What OnEraseBkgnd () does is to paint the button gray.
And what OnPaint () does is to draw words.
Since these two member function are used to draw components
So why divide OnPaint () and OnEraseBkgnd ()?
In fact, OnPaint () and onerasebkgnd () characteristics are poor
1. ONERASEBKGND () The requirement is that the quick in-process drawing program is best not to take too much time between
Because every time the window component has any small changes, it will call OnEraseBkgnd immediately.
2. OnPaint () is called only when the program is idle
3. OnEraseBkgnd () is called before OnPaint ()
So OnPaint () may call OnEraseBkgnd () several times before being called once
If we are a person who is working on a graphical user interface
We often need to set a beautiful picture as our dialog basemap.
Putting the program code of the drawing in the OnPaint () may often encounter some problems
Let's say drag a window on top of the dialog we're doing.
The dialog will turn gray until the action stops.
This is because the program will call ONERASEBKGND () every time a redraw is required.
OnEraseBkgnd () painted the dialog gray
The program calls OnPaint only after the action is stopped () and then the basemap we're going to paint is pasted up.
The way to solve this problem is to rewrite OnEraseBkgnd () into a function that does not work.
As shown below
BOOL cmydlg::onerasebkgnd (cdc* PDC)
{
return TRUE;
}
The above would have been called CDIALOG::ONERASEBKGND () but if we don't call,
The program will not draw a gray background.
It is good practice to move the drawing program directly from OnPaint () to OnEraseBkgnd () to do
As shown below
M_bmpbkgnd is a CBitmap object and has already loaded our basemap in advance
The size of the basemap is the same size as our window client
BOOL cmydlg::onerasebkgnd (cdc* PDC)
{
CRect RC;
GetUpdateRect (&RC);
CDC SRCDC;
Srcdc.createcompatibledc (PDC);
Srcdc.selectobject (M_BMPBKGND);
Pdc->bitblt (RC.LEFT,RC.TOP,RC. GetWidth (),
Rc. GetHeight (), &srcdc,rc.left,rc.top,srccopy);
return TRUE;
}
It is especially important to note that getting a redraw size is using getupdaterect () instead of GetClientRect ()
If you use GetClientRect (), repaint the place where it should not be redrawn.
[00008]-[2015-08-21]-[00]-[windows Programming---ONERASEBKGND () OnPaint () DrawItem () Drawing processing]