Saving Device Contexts
Normally when you call GetDC or BeginPaint, Windows gives you a device context with default values for all the attributes. Any changes you make to the attributes are
lost when the device context is released with the ReleaseDC or EndPaint call. If your program needs to use nondefault device context attributes, you'll have to initialize
the device context every time you obtain a new device context handle:
case WM_PAINT:
hdc = BeginPaint (hwnd, &ps) ;
[initialize device context attributes]
[paint client area of window]
EndPaint (hwnd, &ps) ;
return 0 ;
Although this approach is generally satisfactory, you might prefer that changes you make to the attributes be saved when you release the device context so that they will
be in effect the next time you call GetDC or BeginPaint. You can accomplish this by including the CS_OWNDC flag as part of the window class style when you register the window
class:
wndclass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC ;
Now each window that you create based on this window class will have its own private device context that continues to exist when the window is destroyed. When you use the
CS_OWNDC style, you need to initialize the device context attributes only once, perhaps while processing the WM_CREATE message:
case WM_CREATE:
hdc = GetDC (hwnd) ;
[initialize device context attributes]
ReleaseDC (hwnd, hdc) ;
The attributes continue to be valid until you change them.
The CS_OWNDC style affects only the device contexts retrieved from GetDC and BeginPaint and not device contexts obtained from the other functions (such as GetWindowDC). Employing
CS_OWNDC was once discouraged because it required some memory overhead; nowadays it can improve performance in some graphics-intensive Windows NT applications. Even if you use CS_OWNDC,
you should still release the device context handle before exiting the window procedure.
In some cases you might want to change certain device context attributes, do some painting using the changed attributes, and then revert to the original device context. To simplify
this process, you save the state of a device context by calling
idSaved = SaveDC (hdc) ;
Now you can change some attributes. When you want to return to the device context as it existed before the SaveDC call, you use
RestoreDC (hdc, idSaved) ;
You can call SaveDC any number of times before you call RestoreDC.
Most programmers use SaveDC and RestoreDC in a different manner, however, much like PUSH and POP instructions in assembly language. When you call SaveDC, you don't need to save the return value:
SaveDC (hdc) ;
You can then change some attributes and call SaveDC again. To restore the device context to a saved state, call
RestoreDC (hdc, -1) ;
This restores the device context to the state saved by the most recent SaveDC function.
Normally when you call GetDC or BeginPaint, Windows gives you a device context with default values for all the attributes. Any changes you make to the attributes are
lost when the device context is released with the ReleaseDC or EndPaint call. If your program needs to use nondefault device context attributes, you'll have to initialize
the device context every time you obtain a new device context handle:
case WM_PAINT:
hdc = BeginPaint (hwnd, &ps) ;
[initialize device context attributes]
[paint client area of window]
EndPaint (hwnd, &ps) ;
return 0 ;
Although this approach is generally satisfactory, you might prefer that changes you make to the attributes be saved when you release the device context so that they will
be in effect the next time you call GetDC or BeginPaint. You can accomplish this by including the CS_OWNDC flag as part of the window class style when you register the window
class:
wndclass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC ;
Now each window that you create based on this window class will have its own private device context that continues to exist when the window is destroyed. When you use the
CS_OWNDC style, you need to initialize the device context attributes only once, perhaps while processing the WM_CREATE message:
case WM_CREATE:
hdc = GetDC (hwnd) ;
[initialize device context attributes]
ReleaseDC (hwnd, hdc) ;
The attributes continue to be valid until you change them.
The CS_OWNDC style affects only the device contexts retrieved from GetDC and BeginPaint and not device contexts obtained from the other functions (such as GetWindowDC). Employing
CS_OWNDC was once discouraged because it required some memory overhead; nowadays it can improve performance in some graphics-intensive Windows NT applications. Even if you use CS_OWNDC,
you should still release the device context handle before exiting the window procedure.
In some cases you might want to change certain device context attributes, do some painting using the changed attributes, and then revert to the original device context. To simplify
this process, you save the state of a device context by calling
idSaved = SaveDC (hdc) ;
Now you can change some attributes. When you want to return to the device context as it existed before the SaveDC call, you use
RestoreDC (hdc, idSaved) ;
You can call SaveDC any number of times before you call RestoreDC.
Most programmers use SaveDC and RestoreDC in a different manner, however, much like PUSH and POP instructions in assembly language. When you call SaveDC, you don't need to save the return value:
SaveDC (hdc) ;
You can then change some attributes and call SaveDC again. To restore the device context to a saved state, call
RestoreDC (hdc, -1) ;
This restores the device context to the state saved by the most recent SaveDC function.