Date: 02-16-2022
Return to Index
created by gbSnippets
'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 + $CrLf, Len(sOut) + 2, cWritten, ByVal 0&
End Sub
'gbs_00493
'Date: 03-10-2012
http://www.garybeene.com/sw/gbsnippets.htm