..Painting and Drawing

Category: Graphics - GDI

Date: 02-16-2022

Return to Index


 
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 toand 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 windowIn such cases, neither
window receives a WM_PAINT message.
 
'Display Devices  ==========================================================
The system supplies a commonclassparentor 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 functionIn 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 windowor 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


created by gbSnippets
http://www.garybeene.com/sw/gbsnippets.htm