Date: 02-16-2022
Return to Index
created by gbSnippets
Windows manages all output to the screen. Apps write to
windows by writing on a device context.
Drawing in a window is usually done in WM_Paint, but can
be done at any time by the application.
'WM_Paint =================================================
System determine update needed - sends WM_Paint
App can mark window for updating - causes WM_Paint to be sent
- UpdateWindow() causes WM_Paint to be sent
- RedrawWindow() causes WM_Paint to be sent
App can also update window immediately
WM_Paint - lParam/wParam are not used
WM_Paint - should not be sent by an application
WM_Paint - if client area must be painted
WM_NCPaint - if non-client area must be painted
WM_EraseBkGnd - if window background must be erased
If GetUpdateRect() = 0, should not call BeginPaint/EndPaint
BeginPaint() - use in WM_Paint
GetDC() - use outside WM_Paint
Most applications rely on the default window function, DefWindowProc,
to draw this area and therefore pass the WM_NCPAINT message to this
function.
Local PS as PaintStruct
BeginPaint(hDlg,PS) 'validates update region, hides caret, returns hDC
EndPaint(hDlg,PS) 'restore caret
Type PAINTSTRUCT
hDC As Dword 'handle to the display DC to be used for painting.
fErase As Long 'whether the background must be erased. nonzero to erase.
rcPaint As RECT 'RECT structure. area to paint, given as upper/left and lower/right in device coordinates
fRestore As Long 'reserved
fIncUpdate As Long 'reserved
rgbReserved(0 To 31) As Byte 'reserved
End Type
Invalidate/Validate regiion
InvalidateRect - does not generate WM_Paint
InvalidateRgn - does not generate WM_Paint
ValidateRect
ValidateRgn
GetUpdateRect
GetUpdateRgn
drawing in WM_Paint is asynchronous
to draw synchronously (send WM_Paint immediately):
- UpdateWindow() causes WM_Paint to be sent
- RedrawWindow() causes WM_Paint to be sent
'Draw Without WM_Paint =====================================================
While it is recommended that an app draw within WM_Paint, for
imm
GetDC(hWnd)
ReleaseDC(hWnd,hDC)
'Background ================================================================
wParam = DC
lParm = not used
WM_EraseBkGnd gives an app the opportunity to paint the
background. The app can choose not to, and simply pass the
message to DefWindowProc
If app does the painting, return Function = 1 : Exit Function
'Minimized Window ==========================================================
Window class usually defines the icon to show when app is minimized.
If no class icon is defined, WM_EraseBkGnd is sent, followed by WM_Paint
'Resize Window =============================================================
On resize, the system invalidates only the newly exposed portion of the window.get
To force the system to invalidate the entire client area of the window when a
vertical, horizontal, or both vertical and horizontal change is made, an
application must specify the CS_VREDRAW or CS_HREDRAW style
Eventually, WM_Paint is sent
'NonClient Area ============================================================
WM_NCPaint - when nonclient areas must be update
WM_NCActivate - when window becomes active/inactive
GetWindowDC - NC area included in hDC
'Child Window Update Region ================================================
Window Styles
WS_Child
WS_ChildWindow
WS_ClipChildren
WS_ClipSiblings
An application cannot generate a WM_PAINT message for the parent window by
invalidating the child window. Similarly, an application cannot generate a
WM_PAINT message for the child by invalidating a portion of the 's
client area that lies entirely under the child window. In such cases, neither
window receives a WM_PAINT message.
'Display Devices ==========================================================
The system supplies a common, class, parent, or private device context to a
window based on the type of display device context specified in that 's
class style. The system supplies a window device context only when the
application explicitly requests one for example, by calling the GetWindowDC
or GetDCEx function. In all cases, an application can use the WindowFromDC
function to determine which window a display DC currently represents.
'Window Update Lock
LockWindowUpdate hWnd (%Null to unlock)
applies to windows and all of its child windows
'WM_Paint ================================================================
Idea is to consolidate your drawin in this part of the window procedure
'Drawing in Client Area ==================================================
Type PAINTSTRUCT
hDC As Dword 'handle to the display DC to be used for painting.
fErase As Long 'whether the background must be erased. nonzero to erase.
rcPaint As RECT 'RECT structure. area to paint, given as upper/left and lower/right in device coordinates
fRestore As Long 'reserved
fIncUpdate As Long 'reserved
rgbReserved(0 To 31) As Byte 'reserved
End Type
Local PS AS PaintConstruct
These work in the CLIENT area!
BeginPaint(hWnd,PS)
TextOut(hdc, 0, 0, "Hello, Windows!", 15)
EndPaint(hWnd,PS)
When window is first created, WM_Paint is sent immediately
'Redrawing the Entire Client Area ========================================
To force the system to invalidate the entire client area of the window when a
vertical, horizontal, or both vertical and horizontal change is made, an
application must specify the CS_VREDRAW or CS_HREDRAW style
'Redrawing in the Update Region
If you choose, you can get the Update Region and draw only in that
to improve performance
Also, use RectVisible to determine if the item to draw is in
the clipping region (thus in the update region)
'Invalidating the Client Area =============================================
These indirectly generate WM_Paint:
InvalidateRect(hWnd, lpRect, bErase)
InvalidateRgn(hWn, hRgn, bErase)
'Drawing a Minimized Window
You can draw your own minimized window, or have the system do it for you.
If you set the class icon to NULL, you draw the minimized window in WM_Paint
Case %WM_Paint
If Iconic(hDlg)
...
End If
'Drawing a Custom Window Background
Case %WM_EraseBkgnd
hdc = wParam;
GetClientRect(hwnd, &c)
SetMapMode(hdc, MM_ANISOTROPIC)
SetWindowExtEx(hdc, 100, 100, NULL)
SetViewportExtEx(hdc, rc.right, rc.bottom, NULL)
FillRect(hdc, &rc, hbrWhite)
'Using the GetDC Function
Use GetDC to carry out drawing instantly, rather than in WM_Paint
'gbs_00949
'Date: 03-10-2012
http://www.garybeene.com/sw/gbsnippets.htm