Deep understanding of wm_erasebkgnd and wm_paint

Source: Internet
Author: User

Deep understanding of wm_erasebkgnd and wm_paint

For a long time, the message wm_paint and wm_erasebkgnd are not very clear. I have found a lot of information from books and the Internet. In general, there are several points:

1. wm_paint is generated first, and wm_erasebkgnd is generated later.

2. After wm_paint is generated, call HDC = beginpaint (hwnd, & PS); if PS. ferase is true, beginpaint will generate the wm_erasebkgnd message

3. The beginpaint function is used to erase the window background.

4. wm_erasebkgnd is used to draw the background

After debugging and analysis, we found that the above statement is incorrect. The following is some test code. Some analysis is attached to the code. Finally, the following points are summarized to explain all the issues related to window repainting in the program.

If there are any errors, you can correct them.

To illustrate the problem, here we will not talk about the wm_ncpaint message (non-customer zone message), but only the wm_erasebkgnd message and the wm_paint message in the customer zone.

// This section of code is taken from the code automatically generated by the vc6 Application Wizard, and some test code lresult callback wndproc (hwnd, uint message, wparam, lparam) {int wmid, wmevent; paintstruct pS; HDC; tchar szhello [max_loadstring]; loadstring (hinst, ids_hello, szhello, max_loadstring); Switch (Message) {Case wm_command: wmid = loword (wparam ); wmevent = hiword (wparam); // parse the menu selections: Switch (wmid) {Case idm_about: dialogbox (hinst, (lpctstr) idd_aboutbox, hwnd, (dlgproc) about ); break; Case idm_exit: destroywindow (hwnd); break; default: Return defwindowproc (hwnd, message, wparam, lparam);} break; Case wm_erasebkgnd: // if the message is processed, the default message processing function will not be called, and the background will not be drawn {static int icount = 0; char ch [max_path]; sprintf (CH, "% d --------- wm_erasebkgnd \ n ", icount); // This function must contain # include <stdio. h> outputdebugstring (CH); // icount ++; break;} case wm_paint: {outputdebugstring ("------------- wm_paint \ n"); HDC = beginpaint (hwnd, & PS); // make the invalid region valid and fill in the PS structure // todo: add any drawing code here... // draw a blue oval, PS. rcpaint stores the customer's rectangle hbrush =: createsolidbrush (RGB (255,);: SelectObject (HDC, hbrush);: ellipse (HDC, PS. rcpaint. left, PS. rcpaint. top, PS. rcpaint. right, PS. rcpaint. bottom);: deleteobject (hbrush); endpaint (hwnd, & PS); break;} case wm_lbuttondown: // call defwindowproc to erase the background of the customer area {HDC; HDC = :: getdc (hwnd); wparam W = (wparam) HDC; lparam L = 0; defwindowproc (hwnd, wm_erasebkgnd, W, L);} break; Case wm_destroy: postquitmessage (0 ); break; default: Return defwindowproc (hwnd, message, wparam, lparam);} return 0 ;}

First, let's talk about some of the phenomena found during the program running:

1. The above code: If the wm_erasebkgnd message is added, nothing will be done in it, as shown below:

Case wm_erasebkgnd:

Break;

When the program is running, if the message wm_erasebkgnd is received, the default message processing function defwindowproc is not executed in the switch-case structure. During the running, the background of the window is no longer displayed, that is, the background is empty.

This indicates that the window background is only drawn by the default message processing function defwindowproc.

(Note: When registering the window class, set the background to white wcex. hbrbackground = (hbrush) (color_window + 1 );)

 

2. The above Code indicates that the window background is null when the program is running because of the wm_erasebkgnd message. However, if the wm_lbuttondown message is added, the default window message processing function is called from it, as shown below:

Case wm_lbuttondown:

{

HDC;

HDC =: getdc (hwnd );

Wparam W = (wparam) HDC; // The variable W is used as the wparam parameter of the wm_erasebkgnd message, saving the device environment handle

Lparam L = 0;

Defwindowproc (hwnd, wm_erasebkgnd, W, L); // call the default message processing function defwindowproc

}

Break;

When running the program, if you click the client area of the window, the background of the window will be displayed! This further demonstrates that the background color of the window is drawn by the default message processing function defwindowproc.

3. The preceding Code adds the wm_erasebkgnd message, so the window background is empty. Although HDC = beginpaint (hwnd, & PS); function is called in the wm_paint message, the window background is still empty, this indicates that the beginpaint function does not erase the background (that is, the background of the window is drawn with the default paint brush ).

The beginpaint function only does two things:

1) make the window invalid region valid, so that Windows will not send the wm_paint message (until the window size changes, so that the window will become invalid again ).

(If the window is always invalid, Windows will continuously send the wm_paint message)

2) Fill in the paintstruct structure. The purpose of filling in this structure is to allow programmers to perform some operations based on the flag value in the PS variable.

4. during debugging, it is found that when the window size is changed or other operations make the window invalid, the wm_erasebkgnd message is always sent before the wm_paint message, and if the wm_erasebkgnd message is generated, the next message of the last wm_erasebkgnd must be a wm_paint message (wm_erasebkgnd may be generated several times in a row ). No other message exists between the message wm_erasebkgnd and the message wm_paint.

Bytes -----------------------------------------------------------------------------------------------------------------------

Below are some summary

1. Erase the window background (that is, draw)

The background color of the window is erased by the default message processing function defwindowproc (that is, this function uses the background brush to erase the window background when registering the window class ).

When to draw? When the window function receives the wm_erasebkgnd message, the defwindowproc function uses the wm_erasebkgnd parameter to draw the window background.

(Note: When the wm_erasebkgnd message is generated, some of the windows must be invalid)

 

2. Invalid Window:

When a vertex of the window is dragged to change the size of the window, the window is restored from the minimum to the maximum, a part of the window is hidden and re-displayed by other windows, the movewindow function is called to change the size of the window, and the window is moved when a portion outside the desktop is dragged back to re-display, the window becomes invalid. The invalid region is the entire customer zone. Therefore, the default window processing function defwindowproc erased the entire customer zone. (Note: drag the title bar of the window to move the window. As long as the window is not moved out of the screen, no messages are generated)

When the window is invalid, Windows will send the wm_erasebkgnd and wm_paint messages to the window, and the wm_erasebkgnd will be sent once or several times first, followed by wm_paint. exception: the call of the invalidaterect function will invalidate the window and generate the wm_erasebkgnd message and the wm_paint message. Whether wm_erasebkgnd is generated depends on the berase parameter.

Void invalidaterect (

Lpcrect lprect,

Bool berase = true );

When the berase parameter is true, wm_erasebkgnd messages are generated. If the berase parameter is false, wm_erasebkgnd messages are not generated.

 

3. Message Processing Process. When the window is invalid, the wm_erasebkgnd message is sent several times ----------- and then the wm_paint message is sent. There is no other message between wm_erasebkgnd and wm_paint.

The message wm_erasebkgnd must be followed by wm_paint.

1) wm_erasebkgnd message processing:

In the above Code, if wm_erasebkgnd is not added, the default message processing function defwindowproc will be called. In this case, defwindowproc will erase the window background (that is, draw the background) and PS. the value of ferase is false. If the wm_erasebkgnd message is added, defwindowproc will not be called, the window background cannot be erased, and PS. ferase will be true.

2) wm_paint Processing

If the HDC = beginpaint (hwnd, & PS); function is called in this message, this function only performs two tasks: Filling the PS structure and making the window effective again. In addition, the defwindowproc function also makes the window valid.

PS. ferase;

This parameter is related to the return value of Window Function wndproc:

If the window function wndproc returns true, PS. ferase is false when the wm_paint message is generated, indicating that the background is erased by the system.

When the window function wndproc returns false, PS. ferase is true when the wm_paint message is generated, indicating that the background is not erased.

Imagine that when the wm_erasebkgnd message is added to the Code above and true is returned directly (this indicates that the system has drawn the window background), PS. ferase is false.

Case wm_erasebkgnd:

Return true; // The Window Function wndproc returns true;

Note that the returned real or false information only allows programmers to see ps. ferase and make their own code. It has nothing to do with the display of the window, that is, the background.

Some people say that when ps. ferase = true, the beginpaint function will send a wm_erasebkgnd message. In fact, beginpaint does not send a wm_erasebkgnd message.

 

4. Draw your own background or system background.

What if a programmer does not want to erase the background and wants to draw the background himself? The method is to add your own drawing code in wm_erasebkgnd message processing.

For wm_erasebkgnd messages, the wparam parameter stores the device environment Used for plotting, and lparam is not used.

In the sample code above, when the wm_erasebkgnd message is added, the defwindowproc function will not be called in switch --- case to draw the background. At this time, the programmer can add the drawing code, and in the MFC-based program, it is like this to process the self-painting code:

Bool ccedlg: onerasebkgnd (CDC * PDC) // This function is the message processing function of wm_erasebkgnd.

{

// Todo: add your message handler code here and/or call default

// Add the self-painting code

...

Return true; // return true, which indicates the return value of the window function. This allows programmers to process the wm_paint message (if needed ). The following default processing will not be called when the result is returned.

// The following calls the system's default message processing function defwindowproc to draw the background by default.

Return cdialog: onerasebkgnd (PDC); // do not execute the automatically generated function

}

When this function is executed, the user is prompted to draw the background. If the user does not draw the background, return cdialog: onerasebkgnd (PDC); call the default window handler function to erase the background.

 

Bool ccedlg: onerasebkgnd (CDC * PDC) {// todo: add your message handler code here and/or call default // Add the self-painted background code cbitmap m_bitmap; bitmap m_bminfo; m_bitmap.loadbitmap (idb_bitmap1); m_bitmap.getobject (sizeof (m_bminfo), & m_bminfo); CDC memdc; memdc. createcompatibledc (PDC); memdc. selectObject (& m_bitmap); getclientrect (m_rect); PDC-> stretchblt (0, 0, m_rect.width (), m_rect.height (), & memdc, 0, 0, m_bminfo.bmwid Th, m_bminfo.bmheight, srccopy); // memory copy function. Draw background memdc. deletedc (); Return true; // return true, representing the return value of the window function. This allows programmers to process the wm_paint message (if needed ). The following default message processing function defwindowproc will not be called when the result is returned here. // The following will call the default message processing function defwindowproc of the system to draw the background by default. Return cdialog: onerasebkgnd (PDC); // do not execute the automatically generated function}

5. Another meaning of wm_erasebkgnd message and wm_paint message: Background Color and foreground color

The wm_erasebkgnd message is used to notify the system or programmer to draw the background color.

The wm_paint message is used to notify programmers to draw foreground colors. For example, in wm_paint, The textout function is called to output text.

 

Article from: http://blog.csdn.net/sdeeds/article/details/6859530

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.