Understanding of the OnPaint () and ONERASEBKGND () messages in the Go dialog box

Source: Internet
Author: User


Understanding of OnPaint () and ONERASEBKGND () messages in dialog boxes


A dialog box overrides OnPaint () and OnEraseBkgnd (), performing a Discovery onerasebkgnd () a much larger number of executions than OnPaint ( ), but performing OnPaint () OnEraseBkgnd () must be executed before. in the project with GDI double buffering, draw the background picture of the dialog box, the onerasebkgnd () will appear flashing, placed in the OnPaint () will not blink.



This problem is related to the understanding of these two message functions: Specific information has been found for reference.






Personal Understanding:



The return Cdialogex::onerasebkgnd (PDC) of OnEraseBkgnd () is the erase background, and if you do not want to erase the background, you can return the bytes to true.






OnPaint () Trigger condition:



1. Move the window (MoveWindow ()), when the window is obscured by other windows, the window is minimized, and then open.



2. You want to update an area yourself to send invalidate or invalidrect, plus UpdateWindow () can also be triggered.



Note: in OnPaint () it is not possible to execute the statement that triggers the WM_PAINT again, otherwise it will die loop.






Here's what others understand: excerpt from HTTP://HI.BAIDU.COM/YANG_QI168/ITEM/A648BEC135BF1EC8EE183BCC





WM_PAINT is a message that occurs every time a window is redrawn.
OnPaint is the response function to this message.
MFC Cwnd::onpaint not do anything, just throw it to the system processing.

One:
Perform the OnEraseBkgnd first, erase the background (if you want to draw the control, this function directly return true, so that the background is not erased, not flash)


The difference and connection between ONERASEBKGND and OnPaint

In OnEraseBkgnd, if you do not call the original default ONERASEBKGND only redraw the background there will be no flicker. And in OnPaint, because it implicitly calls the OnEraseBkgnd, and you don't handle ONERASEBKGND functions, This is related to the window's default background brush. The default ONERASEBKGND action uses the window's default background to brush the new background (normally a white brush), and then you re-draw the background yourself causing the screen to blink.

OnEraseBkgnd is not always called. If you call invalidate when the argument is true, then the WM_ERASEBKGND message is generated when BeginPaint is implicitly called in OnPaint, and if the argument is false, The background is not re-brushed.

void Invalidate (BOOL bErase = TRUE); The function is to invalidate the entire window client area. Invalid client area of window means redrawing is required, the background in the redraw area is redrawn or erased if the parameter berase is true, otherwise the background will remain unchanged. The window does not redraw immediately after calling functions such as invalidate, because the WM_PAINT message has a low priority, and it needs to be processed after other messages in the message queue have been sent out.

OnPaint calls the BeginPaint function to automatically set the clipping area of the display device content and exclude any area update areas outside of the update area. If the update area is marked as erasable, BeginPaint sends a WM_ERASEBKGND message to the window. The response function of the WM_ERASEBKGND message is both ONERASEBKGND ()

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,However, it is required to refresh with invalidate (FALSE)
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 graphics of any window element in MFC are placed in these two member function
OnEraseBkgnd () is used to draw the Basemap and OnPaint () is used to draw the main object
For example, a button is gray with text on it.
What OnEraseBkgnd () does is to make the button gray.
And what OnPaint () is doing is painting the words.


Since these two member function are used to draw components
So why divide OnPaint () and OnEraseBkgnd ()?
The fact that the OnPaint () and onerasebkgnd () characteristics are poor
1. The requirement of ONERASEBKGND () is that the fast in-plane graphics program is best not too time consuming
Because every moment the window element has any minor changes, it will call OnEraseBkgnd ()
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 doing a graphical user interface
We often need to set a picture as our dialog background.
Putting the drawing code in the OnPaint () may often come across some problems
Dragging a window, for example, keeps moving on top of the dialog we do.
The dialog will turn gray until the action stops.
This is because every time you need to redraw the program will call ONERASEBKGND ()
OnEraseBkgnd () painted the dialog gray
The program calls OnPaint only after the action is stopped () and then the background we're going to paint is taped up.

The poor solution to 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 won't draw a gray background.

Q: How to Overload the OnEraseBkgnd () function in a dialog-based program

A: This is a message Wm_erasebkwnd
In the Class wizard
Select ClassInfo Page
The option in MessageFilter is set in window to see the message.

It is better to move the graphics program directly from OnPaint () to OnEraseBkgnd ().
As shown below

M_bmpbkgnd is a CBitmap object and has already been loaded into 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 important to note that getting the redraw size is using getupdaterect () instead of GetClientRect ()
If you use GetClientRect (), you will redraw the place where you don't have to redraw the painting.



Understanding of the OnPaint () and ONERASEBKGND () messages in the Go dialog box


Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.