News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

updating window with text

Started by dedndave, December 30, 2010, 02:11:04 PM

Previous topic - Next topic

dedndave

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 ???

redskull

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
Strange women, lying in ponds, distributing swords, is no basis for a system of government

dedndave

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

redskull

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
Strange women, lying in ponds, distributing swords, is no basis for a system of government

qWord

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.
FPU in a trice: SmplMath
It's that simple!

dedndave

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

dedndave

thanks guys
not just for "code help"
more importantly, this clears up a misconception i had about message "mechanics"/screen updating, as well

redskull

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
Strange women, lying in ponds, distributing swords, is no basis for a system of government

dedndave

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

Vortex

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

dedndave

thanks, Erol   :U
let me digest it