Getting a Device Context Handle: Method One

You use this method when you process WM_PAINT messages. Two functions are involved: BeginPaint and EndPaint. These two functions require the handle to the window (passed to the window procedure as a parameter) and the address of a structure variable of type PAINTSTRUCT. Windows programmers usually name this structure variable ps and define it within the window procedure, like so:

PAINTSTRUCT ps ;

While processing a WM_PAINT message, a Windows function first calls BeginPaint to fill in the fields of the ps structure. The value returned from BeginPaint is the device context handle. This is commonly saved in a variable named hdc. You define this variable in your window procedure like this:

HDC hdc ;

The HDC data type is defined in WINDOWS.H as a HANDLE. The program may then use GDI functions such as TextOut. A call to EndPaint releases the device context handle and validates the window.

Typically, processing of the WM_PAINT message looks like this:

case WM_PAINT :

hdc = BeginPaint (hwnd,&ps) ;

[use GDI functions]

EndPaint (hwnd, &ps) ;

return 0 ;

The window procedure must call BeginPaint and EndPaint as a pair while processing the WM_PAINT message. If a window procedure does not process WM_PAINT messages, then it must pass the WM_PAINT message to DefWindowProc (the default window procedure) located in Windows.

DefWindowProc processes WM_PAINT messages with the following code:

case WM_PAINT :

BeginPaint (hwnd, &ps) ;

EndPaint (hwnd, &ps) ;

return 0 ;

This sequence of BeginPaint and EndPaint with nothing in between simply validates the previously invalid rectangle. But don't do this:

case WM_PAINT :

return 0 ; // WRONG !!!

Windows places a WM_PAINT message in the message queue because part of the client area is invalid. Unless you call BeginPaint and EndPaint (or ValidateRect), Windows will not validate that area. Instead, Windows will send you another WM_PAINT message. And another, and another, and another...