Painting and Drawing

Category: Graphics - GDI

Date: 02-16-2022

Return to Index


 
'If an action affects the content of a window, the OS marks the affected portion
'of the window as ready For updating and, at the next opportunity, sends a WM_PAINT
'message to the window procedure of the window.
 
'If an action requires immediate feedback, the application can draw while the
'action takes place, without waiting for WM_PAINT.
 
'To draw in a window, the application must first retrieve a handle to a display
'device context for the window.
 
'Ideally, an application carries out most of its drawing operations during the
'processing of WM_PAINT messages. In this case, the application retrieves a
'display device context by calling the BeginPaint function.
 
'If an application draws at any other time, it calls the GetDC or GetDCEx
'function to retrieve the display DC.
 
 
'Drawing With WM_Paint =======================================================================
'To draw in a window using a WM_PAINT message, an application first retrieves
'a handle to a display device context for the window by calling BeginPaint.
 
'When the drawing actions are completed, the application calls EndPaint to
'release the display device context for use by other applications.
 
 
'Drawing Without WM_Paint ====================================================================
'To draw in a window without using a WM_PAINT message, the application uses
'the GetDC or GetDCEx function to retrieve a display device context for the window.
 
'When the application has finished drawing, it calls the ReleaseDC function to
'release the display device context for use by other applications.
 
'When drawing without using a WM_PAINT message, the application usually does not
'invalidate the window.
 
 
'WM_Paint - More Details =====================================================================
'The system sends this message to a window procedure when changes to the window
'have altered the content of the client area. The system sends the message only
'if there are no other messages in the application message queue.
 
'To start drawing operations, call BeginPaint to get the display device context
'for the client area.
 
'After completing the drawing operations, call the EndPaint Function to release
'the display device context.
 
 
'BeginPaint directs the OS to prepares the device context for the specified window.
'A clipping is set, equal to the intersection of the portion of the window that needs
'updating and the portion that is visible to the user. Only those portions of the
'window that have changed are redrawn. Attempts to draw outside this region are
'clipped and do not appear on the screen.
 
'Before BeginPaint returns a DC, the OS may also send WM_NCPAINT AND WM_ERASEBKGND
'messages. These messages direct the application to draw the nonclient area and
'and window background. Most apps ignore the WM_NCPAINT message but often use the
'WM_ERASEBKGND to fill the window with colors or patterns before drawing operations
'begin.
 
'If a window belongs to a Window Class having a class background brush, the
'DefWindowProc function draws the window background automatically.
 
'BeginPaint fills a PAINTSTRUCT structure with information such as the dimensions
'of the portion of the window to be updated and a flag indicating whether the window
'background has been drawn. The application can use this information to optimize
'drawing. For example, it can use the dimensions of the update region, specified by
'the rcPaint member, to limit drawing to only those portions of the window that need
'updating. If an application has very simple output, it can ignore the update region
'and draw in the entire window, relying On the system to discard (clip) any unneeded
'output. Because the system clips drawing that extends outside the clipping region,
'only drawing that is in the update region is Visible.
 
'BeginPaint sets the update region of a window to NULL. This clears the region,
'preventing it from generating subsequent WM_PAINT messages. If an application
'processes a WM_PAINT message but does not call BeginPaint or otherwise clear
'the update region, the application continues to receive WM_PAINT messages as
'long as the region is not empty. In all cases, an application must clear the
'update region before returning from the WM_PAINT message.
 
'After the application finishes drawing, it should call EndPaint. For most windows,
'EndPaint releases the display device context, making it available to other windows.
'EndPaint also shows the caret, if it was previously hidden by BeginPaint. BeginPaint
'hides the caret to prevent drawing operations from corrupting it.
 
 
'Region Validataion/Invalidation =============================================================
'Windows will invalidate a portions of a window (region) as needed, such as when
'one window moves over another. Windows will also validate a region as part of an
'EndPaint function.
 
'Or, an application may choose to invalidate a region, update the region, and then
'then validate the region. This is usually done when an immediate screen update
'is desired.
 
'The location of the current update region can be acquired using these API
'  - GetUpdateRect    - smallest rectangle (logical coordainte)
'  - GetUpdateRgn     - update region
'These are useful in determining where to carry out a drawing operation (limiting
'drawing actions to within the update region to improve speed).
 
'BeginPaint also retrieves the dimensions of the smallest rectangle enclosing the
'current update region, copying the dimensions to the rcPaint Member in the
'PAINTSTRUCT structure.
 
'Because BeginPaint validates the update region, any call to GetUpdateRect or
'GetUpdateRgn immediately after a call to BeginPaint returns an empty update region.
 
'To manually invalidate a portion of a window and set the update region, use these API:
'  - InvalidateRect
'  - InvalidateRgn
'These add the specified rectangle/regiion (client coordinates) to the update region,
'combining the rectangle or region with anything the system or the application may
'have previously added to the update region.
 
'These DO NOT generate WM_PAINT messages. Instead, the system accumulates the changes
'made by these functions and its own changes, then processes all changes at once.
 
'The corresponding API to validate a portion of a window are
'  - ValidateRect
'  - ValidateRgn
'These validate a portion of the window by removing a specified rectangle Or region
'from the update region. These functions are typically used when the Window has
'updated a specific part of the screen in the update region before receiving the
'WM_PAINT message.
 
'Synchronous Drawing =======================================================================
'The Windows messaging system introduces some delays between the time a region is
'invalidated and when a WM_PAINT message is sent.
 
'To immediately update a region, use these API:
'  - UpdateWindow
'  - RedrawWindow
'Both immediately send a WM_PAINT message but RedrawWindow provides greater control
'over how to draw the window.
 
 
'Compilable Example:  (Jose Includes)
#Compiler PBWin 9, PBWin 10
#Compile EXE
#Dim All
%Unicode=1
#Include "win32api.inc"
Global hDlg As DWord
 
Function PBMain () As Long
   Dialog New Pixels, 0, "Draw on Dialog",,, 250,200, %WS_OverlappedWindow To hDlg
   Dialog Show Modal hDlg, Call DlgProc
End Function
 
CallBack Function DlgProc() As Long
   Local PS As PaintStruct, hDC As DWord
   Select Case CB.Msg
      Case %WM_Paint
         hDC = BeginPaint(hDlg, PS)        'get handle to DC
         Ellipse hDC, 20,20,80,80          'circle
         Rectangle hDC, 100,100,200,150    'rectangle
         TextOut hDC, 100,30, " test ", 6  'text
         EndPaint hDlg, PS                 'release handle to DC
         CPrint "wm_paint"                 'display each time WM_PAINT received
   End Select
End Function
 
Sub CPrint (SOut As String)
   Static hConsole As Long, cWritten As Long, iCount As Long
   Incr iCount : SOut = SOut + Str$(iCount)
   If hConsole = 0 Then AllocConsole: hConsole = GetStdHandle(-11&)
   WriteConsole hConsole, ByCopy sOut + $CrLfLen(sOut) + 2, cWritten, ByVal 0&
End Sub
 
'gbs_00493
'Date: 03-10-2012


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