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