The MASM Forum Archive 2004 to 2012

General Forums => The Campus => Topic started by: dedndave on December 30, 2010, 02:11:04 PM

Title: updating window with text
Post by: dedndave on December 30, 2010, 02:11:04 PM
i have code that goes something like this (the basics are shown)...
        .DATA

Group1  db 'Some Text',13,10,13,10
Group2  db 0,'ome More Text',13,10,13,10
Group3  db 0,'till More Text',13,10,0

        .CODE

;....

        call    CreateWin            ;RegisterClassEx, CreateWindowEx, ShowWindow

;--------------------------------------------------

;simulate text generation (see notes below)


;--------------------------------------------------

;message loop

        INVOKE  UpdateWindow,hWnd
        call    MessageLoop          ;GetMessage, TranslateMessage, DispatchMessage

;terminate

        INVOKE  ExitProcess,eax

;....

;WndProc WM_PAINT handler code

        INVOKE  BeginPaint,hwnd,offset PaintStrc
        mov     hDc,eax
        INVOKE  GetClientRect,hwnd,offset PaintRect
        INVOKE  SelectObject,hDc,hFont
        INVOKE  SetTextColor,hDc,TColor1
        INVOKE  SetBkMode,hDc,TRANSPARENT
        INVOKE  DrawText,hDc,offset Group1,-1,offset PaintRect,NULL
        INVOKE  EndPaint,hwnd,offset PaintStrc
        xor     eax,eax
        ret

to simulate text generation and display update, i tried this...
;--------------------------------------------------

;simulate text generation 1

        INVOKE  UpdateWindow,hWnd
        INVOKE  Sleep,1000
        mov byte ptr Group2,'S'
        INVOKE  UpdateWindow,hWnd
        INVOKE  Sleep,1000
        mov byte ptr Group3,'S'

;--------------------------------------------------

the first line of text appears as expected, but the other 2 lines only show up if i minimize/restore or otherwise force the window to update
just for the fun of it, i even tried this...
;--------------------------------------------------

;simulate text generation 2

        INVOKE  WndProc,hWnd,WM_PAINT,NULL,NULL
        INVOKE  Sleep,1000
        mov byte ptr Group2,'S'
        INVOKE  WndProc,hWnd,WM_PAINT,NULL,NULL
        INVOKE  Sleep,1000
        mov byte ptr Group3,'S'

;--------------------------------------------------

the results are the same

at any rate, UpdateWindow does not behave the way i thought it should
maybe the problem is in my WM_PAINT handler
any ideas ???
Title: Re: updating window with text
Post by: redskull on December 30, 2010, 02:37:28 PM
It's my understanding that paint messages only get sent if repaininting needs to be done; since you are not actually changing the contents of the screen itself, painting is unecessary until you move/change the window.

-r
Title: Re: updating window with text
Post by: dedndave on December 30, 2010, 02:49:07 PM
thanks Red
well - i do change the string with each step in the simulation code

however, maybe what i need to do is to get the message loop going
then, update the text after dispatch
probably "the right way" to do it, anyways - lol
i thought this would work, though
Title: Re: updating window with text
Post by: redskull on December 30, 2010, 02:55:57 PM
Quote from: dedndave on December 30, 2010, 02:49:07 PM
well - i do change the string with each step in the simulation code

Changing the string in memory had nothing to do with the contents displayed on the screen; WM_PAINT really only gets generated when you move/resize/uncover the display itself.  UpdateWindow() is smart enough to know that if no painting is necessary, not to do anything.  Simiarly, BeginPaint() uses the "dirty" area too.  Try InvalidateRect() to specifically set the entire region to need repainting.

-r
Title: Re: updating window with text
Post by: qWord on December 30, 2010, 03:00:37 PM
It is also recommendable to use a back buffer, that is copied to screen while handling WM_PAINT. This avoids senseless redrawing of the whole client area and, as an side effect, it prevented/reduce flickering  :bg.
Title: Re: updating window with text
Post by: dedndave on December 30, 2010, 03:10:52 PM
InvalidateRect - that's what i need
thanks again, Red   :U

qWord
i understand that it should not be necessary to update the whole screen
and that may be something i attack next, too   :U
i am new to this stuff, and taking it one step at a time
i have the text in a buffer
actually - in the end, it will probably be in a heap block or something
i might set the rectangle and use single-line mode in DrawText to get the job done
i guess each line of text will need to be null-terminated, too
Title: Re: updating window with text
Post by: dedndave on December 30, 2010, 03:26:56 PM
thanks guys
not just for "code help"
more importantly, this clears up a misconception i had about message "mechanics"/screen updating, as well
Title: Re: updating window with text
Post by: redskull on December 30, 2010, 03:27:07 PM
Officially, BeginPaint() only lets you draw in whatever subsection of the window is actually dirty.  You are supposed to use GetUpdateRect() to make sure there is something to paint, and otherwise do nothing to save the cycles.  I think most programmers just say "screw it", invalidate the entire region, and redraw the entire screen for simplicity's sake.  But, like qWord said, that's wasteful.

-r
Title: Re: updating window with text
Post by: dedndave on December 30, 2010, 03:29:36 PM
well - in this particular app, it is a little bit of text - speed isn't really that big of an issue
but, it is more important for me to grasp how it works and to learn the right way of doing things for future apps

if i was going to write a text editor or something, i'd want it right   :P
Title: Re: updating window with text
Post by: Vortex on December 30, 2010, 06:31:40 PM
Hi Dave,

Here is an example for you :



include DlgBox.inc

.data

DlgBox  db 'DLGBOX',0
TextMsg db '      This is a scrolling text message ',0
CharPos dd 0

.data?

hBrush    dd ?

.code

start:

    invoke  GetModuleHandle,0
    invoke  DialogBoxParam,eax,ADDR DlgBox,0,ADDR DlgProc,0
    invoke  ExitProcess,eax

DlgProc PROC hWnd:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM

LOCAL hdc:HDC
LOCAL ps:PAINTSTRUCT
LOCAL rc:RECT

    .IF uMsg==WM_INITDIALOG

        invoke    SetTimer,hWnd,ID_TIMER,300,ADDR TimerProc

    .ELSEIF uMsg==WM_CTLCOLORDLG

        invoke CreateSolidBrush,White
        mov       hBrush,eax
        ret

    .ELSEIF uMsg==WM_CLOSE

        invoke    EndDialog,hWnd,0

    .ELSEIF uMsg==WM_PAINT

        invoke    BeginPaint,hWnd, ADDR ps
        mov       hdc,eax
        invoke    GetClientRect,hWnd,ADDR rc
        mov       rc.left,100
        mov       edx,OFFSET TextMsg
        add       edx,CharPos
        mov       ecx,39
        sub       ecx,CharPos
        invoke    DrawText,hdc,edx,ecx,ADDR rc,0
        invoke    EndPaint,hWnd,ADDR ps

    .ELSE

        xor eax,eax
        ret

    .ENDIF

    mov    eax,1
    ret

DlgProc ENDP

TimerProc PROC hWnd:HWND,uMsg:UINT,idEvent:UINT,dwTime:DWORD

    cmp     CharPos,38
    jne     @f
    invoke  KillTimer,hWnd,ID_TIMER
    ret
@@:
    inc     CharPos
    invoke  InvalidateRect,hWnd,0,TRUE
    ret

TimerProc ENDP

END start
Title: Re: updating window with text
Post by: dedndave on December 31, 2010, 12:17:03 AM
thanks, Erol   :U
let me digest it