Refreshing with WM_PAINT

One of the weaknesses of windraw1 is that a drawn image can become broken. If you cover a part of the circle with another window and then move that window away you are left with a partial circle. Windows expects you to redraw that portion and it signals you by posting a WM_PAINT message. [ Back to Win32 ASM Page ]

WM_PAINT BeginPaint and EndPaint

The WM_PAINT message is sent when the client area of a window requires repainting. One such case is when portions of the client area are "uncovered" by closing moving or resizing an overlapping window. Because the display DC does not hold the image that is supposed to be there the uncovered portion must be redrawn by the application.
    When handling WM_PAINT always call both BeginPaint and EndPaint even if you don't do any graphics. These functions handle the special needs of the WM_PAINT message. If you don't handle this message DefWindowProc will call these functions for you.
    BeginPaint returns a DC handle and EndPaint releases it. So it's not necessary to call GetDC and ReleaseDC.

An example program

The example program windraw2.asm draws a circle in the client area of the "main" window and maintains it. Most of the code is the same as windraw1.asm so we show only what is different.

Message dispatch

We respond to WM_PAINT instead of WM_LBUTTONDOWN.
; The window procedure...where messages for one class of windows
;   are processed.
;
; Parameters are hWnd
message
wParam
lParam.
;   hWnd is the window receiving this message.
;   message is the message ID.
;   wParam and lParam depend on the message ID.
;
; Must preserve EBX
ESI
and EDI.
;
extrn   DefWindowProc:near
PostQuitMessage:near

.code
WndProc:
mov     eax
[esp+4+4]   ; message ID
cmp     eax
WM_DESTROY  ; about to start window destruction
je      on_destroy
cmp     eax
WM_PAINT    ; paint command
je      on_paint
jmp     DefWindowProc   ; delegate other message processing

Painting

The old mouse button handler now becomes the new WM_PAINT handler.  Because of the message we must use BeginPaint and EndPaint. We define a PAINTSTRUCT that's needed by these two functions.
    Now when the window is uncovered it will be restored. It will also restore after a resizing of the window.
; Process WM_PAINT.  Some window area needs repainting.
;
; wParam is ???.
; lParam is ???.
;
; Return zero if processed.
;
; Must preserve EBX
ESI
and EDI.
;
.data
align   4
wndDC   dd 0            ; DC handle (hDC) of window client area

ps      PAINTSTRUCT     <>      ; this would normally be on the stack

.code

extrn BeginPaint:near
EndPaint:near
extrn Ellipse:near

on_paint:
mov     eax
[esp+4+0]           ; hWnd
push    offset ps               ; lpPaint
push    eax
call    BeginPaint
mov     [wndDC]
eax             ; hDC for window

push    large 150               ; y
lower right
push    large 150               ; x
push    large 50                ; y
upper left
push    large 50                ; x
push    [wndDC]                 ; hDC
call    Ellipse

mov     eax
[esp+4+0]           ; hWnd
push    offset ps               ; lpPaint
push    eax
call    EndPaint

xor     eax
eax
ret     16