Wm_paint
WM_PAINT is an important message in the Windows Window System, and the application works by processing the message to make the drawing work on the window.
Wm_ncpaint
The system sends the message to the program when it needs to be redrawn outside the client area of the window, such as the window title bar, menu bar, and so on. The message is sent by default to the DefWindowProc function for default processing because the client area of the standard window is part of the window required. The program can intercept the message to implement custom drawing for other parts of the window.
Wm_erasebkgnd
The WM_ERASEBKGND message is sent when the window background must being erased (for example, when a window is resized). The message is sent to prepare an invalidated portion of a window for painting.
First, WM_PAINT News
Sends a WM_PAINT message to the program when the system draws the window. After receiving the WM_PAINT message, the program calls the BeginPaint function to get the current device context for the drawing operation, and then releases the device context using EndPaint after the drawing is complete.
1. When does the system send WM_PAINT messages?
The system sends WM_PAINT messages at various times: when a window is first created, when the window is resized, when the window is moved from behind another window, when the window is maximized or minimized, and so on, the actions are managed by the system, and the application simply receives the message passively. Draw operations in the message handler, and most of the time the application needs to be able to actively trigger the drawing operations in the window, such as when the data of the window display changes, this is usually done by the invalidaterect and INVALIDATERGN functions. InvalidateRect and INVALIDATERGN Add the specified area to the window's update region, and the system automatically generates a WM_PAINT message if the window's update zone is not empty when there is no other message for the application's message queue.
Why is the system not sending WM_PAINT messages when calling invalidate? Why do I have to wait until the app message queue is empty to send WM_PAINT messages? This is because the system treats the drawing operations in the window as a low-priority operation, so as to be pushed backwards as much as possible. However, this also helps to improve the efficiency of drawing: Two WM_PAINT messages between the InvalidateRect and Invaliatergn to invalidate the area will be added up, and then in a WM_PAINT message is updated once, It not only avoids updating the same area multiple times, but also optimizes the app's update operations.
such as this through InvalidateRect and invalidatergn to invalidate the window area, depending on the system at the right time to send the WM_PAINT message mechanism is actually an asynchronous way of working, that is, in the invalid window area and send Wm_ There is a delay between the paint messages;
Sometimes this delay is not what we want, and of course we can use SendMessage to send a WM_PAINT message after invalidating the window area to force immediate redrawing.
Annotations:
SendMessage will block until the message being sent is processed and returned, but the processing time of the WM_PAINT message is not user-controllable: "GetMessage returns the WM_PAINT message when there is no Other messages in the application ' s message queue, and DispatchMessage sends the message to the appropriate window procedu Re. "(MSDN), that is, after you call SendMessage, this method will need to wait for how long to return is not controllable. So MSDN does not recommend that users send WM_PAINT messages directly: "The WM_PAINT message is generated by the system and should not being sent by an application"
But instead of using Windows GDI to provide us with more convenient and powerful functions:
UpdateWindow and RedrawWindow. UpdateWindow checks the window's update region to send the WM_PAINT message when it is not empty;
RedrawWindow gives us more control: whether to redraw non-client areas and backgrounds, whether to always send WM_PAINT messages regardless of whether the update region is empty or not.
WM_PAINT trigger mechanism
If WM_PAINT is not produced by InvalidateRect or INVALIDATERGN, send Wm_erasebkgnd first, then WM_PAINT
If the WM_PAINT is produced by InvalidateRect or INVALIDATERGN, the WM_PAINT is sent first,
Then BeginPaint () then decides whether to send the WM_ERASEBKGND message according to the Invalidate's berase parameter (redrawing the background)
When WM_PAINT is not generated by invalidaterect, that is, by maximizing, minimizing, and so forth, or by moving (sometimes only generating WM_ERASEBKGND messages) The system sends WM_ERASEBKGND messages before sending WM_PAINT messages.
When WM_PAINT is generated by InvalidateRect (), the WM_PAINT message (async) is sent first, and if InvalidateRect berase checks to the update area for True,beginpaint to remove the background, a WM is sent to the window _ERASEBKGND message
Second, WM_ERASEBKGND News
Parameters
WParam
Handle to the device context.
LParam
This parameter was not used.
Return Value
An application should return nonzero if it erases the background; Otherwise, it should return zero.
That is, the WM_ERASEBKGND message redraws the background, it should return a value other than 0, otherwise 0 is returned;
Remarks
The DefWindowProc function erases the background by using the class background brush specified by the Hbrbackground member of the WNDCLASS structure. If Hbrbackground is NULL, the application should process the WM_ERASEBKGND message and erase the background.
An application should return nonzero in response to WM_ERASEBKGND if it processes the message and erases the background; This indicates, no further erasing is required. If the application returns zero, the window would remain marked for erasing. (Typically, this indicates, the Ferase member of the PAINTSTRUCT structure would be TRUE.)
Add:
DefWindowProc (hWnd, message, WParam, LParam) handles the WM_ERASEBKGND message by default when the background is cleared with the following paint brush
Wcex.hbrbackground = (hbrush) (color_window+1);
Third, Wm_ncpaint News
The Wm_ncpaint message is sent to a window when its frame must be painted.
A window receives this message through its WindowProc function.
LRESULT CALLBACK WindowProc (
HWND hwnd,//Handle to Window
UINT umsg,//Wm_ncpaint
WPARAM WPARAM,//Handle to update region (HRGN)
LPARAM LPARAM//Not used
);
Parameters
WParam
Handle to the update region of the window. The update is clipped to the window frame. When WParam was 1, the entire window frame needs to be updated.
LParam
This parameter was not used.
Return Values
An application returns the zero if it processes this message.
Remarks
The DefWindowProc function paints the window frame.
An application can intercept the Wm_ncpaint message and paint its own custom window frame. The clipping region for a window was always rectangular, even if the shape of the frame is altered.
The WParam value can passed to GetDCEx as in the following example.
Case Wm_ncpaint:
{
HDC hdc;
HDC = GetDCEx (hwnd, (HRGN) WParam, dcx_window| DCX_INTERSECTRGN);
Paint into this DC
ReleaseDC (hwnd, HDC);
}
Iv. Paintstruct Structural Body
The PAINTSTRUCT structure contains information for a application. This information can is used to paint the client area of a window owned by that application.
typedef struct TAGPAINTSTRUCT {
HDC hdc;
BOOL ferase;
RECT Rcpaint;
BOOL Frestore;
BOOL fincupdate;
BYTE rgbreserved[32];
} paintstruct, *ppaintstruct;
Members
hDC
Handle to the display DC to is used for painting.
Ferase
Specifies whether the background must be erased. This value is nonzero if the application should erase the background. The application is responsible for erasing the background if a Windows class is created without a background brush. For more information, see the description of the Hbrbackground member of the WNDCLASS structure.
Rcpaint
Specifies a RECT structure that specifies the upper left and lower right corners of the rectangle in which the painting is requested, in device units relative to the upper-left corner of the client area.
V. Related functions
1) BeginPaint
The BeginPaint function prepares the specified window for painting and fills a paintstruct structure with information abou t the painting.
HDC BeginPaint (
HWND hwnd,//Handle to Window
Lppaintstruct lppaint//Paint information
);
Parameters
hwnd
[In] Handle to the window to be repainted.
Lppaint
[out] Pointer to the PAINTSTRUCT structure that would receive painting information.
Return Values
If The function succeeds, the return value is the handle-a display device context for the specified window.
If The function fails, the return value is NULL, indicating that no display device context is available.
Windows nt/2000/xp:to Get extended error information, call GetLastError.
Remarks
The BeginPaint function automatically sets the clipping region of the device context to exclude any area outside the Updat E region. The update region was set by the InvalidateRect or InvalidateRgn function and by the system after sizing, moving, creating, Scrolling, or any other operation this affects the client area. If the update is marked for erasing, BeginPaint sends a WM_ERASEBKGND message to the window.
An application should not call BeginPaint except in response to a WM_PAINT message. Each call to BeginPaint must has a corresponding call to the EndPaint function.
If the caret is in the area to being painted, BeginPaint automatically hides the caret to prevent it from being erased.
If the window ' s class has a background brush, BeginPaint uses that brush to erase the background of the update region BEFO Re returning.
BeginPaint
BeginPaint and WM_PAINT messages are closely related. What if you try not to write beginpaint in the WM_PAINT processing function?
The program will achieve a staggering CPU usage as it enters a dead loop, and you will find that the program is always processing one WM_PAINT message after another. This is because, under normal circumstances, when an app receives a WM_PAINT message, the window's update region is non-empty (if it's empty, you don't need to send a WM_PAINT message), and BeginPaint's role is to set the update to empty. This way, if you do not call BeginPaint, the window's update region is not empty, as mentioned earlier, the system will always send WM_PAINT messages.
BeginPaint and WM_ERASEBKGND messages are also related. When the window's update region is marked as needing to erase the background, BeginPaint sends a WM_ERASEBKGND message to redraw the background, and in its return message there is a flag indicating whether the window background has been redrawn. When we use InvalidateRect and invalidatergn to add the specified area to the update region, you can set whether the region needs to be erased, so that the next beginpaint knows whether to send the WM_ Erasebkgnd the news.
If WM_ERASEBKGND is processed, the True,beginpaint token ps.ferase false is returned,
If the WM_ERASEBKGND message is processed, the False,beginpaint token ps.ferase is returned as true.
It is also important to note that BeginPaint can only be used in WM_PAINT processing functions.
2) InvalidateRect
InvalidateRect only increases the redraw area and takes effect the next time WM_PAINT, the parameter true in the InvalidateRect function indicates that the system will overwrite the selected area with a background color before you draw it, the default background color is white, You can change the background color by setting a brush.
InvalidateRect (hwnd,&rect,true); sends a WM_PAINT message to the HWnd form, forcing the client area to redraw, rect is the area you specify to refresh, the customer area outside this area is not redrawn, This prevents a partial change in the customer area, which causes the entire customer area to redraw and cause flicker, and if the last parameter is true, the WM_ERASEBKGND message is also sent to the form, causing the background to redraw and, of course, before the customer area is redrawn.
(3) UpdateWindow
UpdateWindow only sends a WM_PAINT message to the form, and GetUpdateRect (Hwnd,null,true) sees if there is no customer area to draw before sending it, and if not, WM_PAINT is not sent. If you want to flush an invalid zone immediately, you can call UpdateWindow after calling InvalidateRect, and if any part of the client area is not valid, UpdateWindow will cause Windows to use WM_ The paint message invokes the window procedure (does not call the window procedure if the entire client area is valid). This WM_PAINT message does not enter the message queue and is called directly by Windows to the window procedure. When the window procedure finishes flushing and exits immediately, Windows controls the return to the statement after the UpdateWindow call in the program. (Windows Programming version 5th P98)
4) EndPaint
The EndPaint function marks the end of painting in the specified window. This function was required for each of the BeginPaint function, but only after painting was complete.
BOOL EndPaint (
HWND hwnd,//Handle to Window
CONST paintstruct *lppaint//Paint data
);
Parameters
HWnd
[In] Handle to the window and has been repainted.
Lppaint
[In] Pointer to a PAINTSTRUCT structure this contains the painting information retrieved by BeginPaint.
Return Values
The return value is always nonzero.
Remarks
If the caret is hidden by BeginPaint, EndPaint restores the caret to the screen.
Http://www.cppblog.com/aaxron/archive/2011/04/15/144284.html
Window drawing about the message finishing wm_paint, Wm_ncpaint, WM_ERASEBKGND