Win32 Drawing WM_PAINT Processing

How to Draw in Windows Using BeginPaint, EndPaint and InvalidateRect

© Guy Lecky-Thompson

A Win32 Drawing Tutorial showing the usual way to process WM_PAINT messages, use BeginPaint and EndPaint, and force updates with InvalidateRect

Introduction

Drawing using the Win32 GDI is very easy once we understand the mechanism. It is also very slow; in other words, not really high performance enough for writing all but the simplest video games. However, the theory is the basis of other, faster, drawing libraries, including GDI+ (GDI plus) which also has the advantage of being able to handle image files, perform advanced image processing, and so on.

The general principle behind drawing (painting) in Win32 applications is:

Most painting - if not all - should be done in the message processing function associated with the WNDCLASS (Window Class).

Processing the WM_PAINT Message

The WM_PAINT message is sent to the application by Windows whenever the client area needs to be updated. For example:

Upon reception of the message, the application should call the GetUpdateRect function to ascertain whether or not there is a region to be updated. If 0 is returned by GetUpdateRect, then the application should not proceed.

The BeginPaint and EndPaint Functions

The application uses BeginPaint and EndPaint to do 2 things:

  1. Get a handle to the client area to paint (HDC hdc);
  2. Tell Windows when we have finished painting.

An empty WM_PAINT processing statement looks like:

case WM_PAINT:
{
PAINTSTRUCT psPaint;
HDC hdc = BeginPaint( hwnd, &psPaint );
// Do painting here
EndPaint (hwnd, &psPaint);
}
return 0;

The hdc variable is the device handle, needed for calling drawing functions (Rectangle, Line, etc.), and the psPaint variable contains information about the situation under which the WM_PAINT message was sent. This includes flags for erasing the background, the update region, and the device context.

Forcing a Repaint of the Client Area

The InvalidateRect function can be used to force a WM_PAINT message to be sent to the window, and this provides an opportunity for it to paint the client area. While a discrete region can be added to the update region, the whole client area can be specified by the following call:

The TRUE in the last parameter indicates that the background area should be erased prior to drawing. This will occur when the application calls BeginPaint. If the application does not call BeginPaint (using GetDC, for example), then the repaint will not occur. Similarly, if the window class was created without a background brush, then the background will also not be erased, no matter what flag is used.

Summary

So, the usual way to repaint the client area of a window is to process the Win32 WM_PAINT message during execution of the message processing function associated with the window. This applies to any windows, not just the main application client area. We can use it to repaint:

However, if we do so, we need to remember that the act of sub-classing and overriding default painting in this way will inevitably cause more work for the programmer. We lose, for instance, some of the automatic processing provided by the main GUI element implementation.


The copyright of the article Win32 Drawing WM_PAINT Processing in Windows Programming is owned by Guy Lecky-Thompson. Permission to republish Win32 Drawing WM_PAINT Processing must be granted by the author in writing.




Post this Article to facebook Add this Article to del.icio.us! Digg this Article furl this Article Add this Article to Reddit Add this Article to Technorati Add this Article to Newsvine Add this Article to Windows Live Add this Article to Yahoo Add this Article to StumbleUpon Add this Article to BlinkLists Add this Article to Spurl Add this Article to Google Add this Article to Ask Add this Article to Squidoo