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 ???
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
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
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
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.
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
thanks guys
not just for "code help"
more importantly, this clears up a misconception i had about message "mechanics"/screen updating, as well
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
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
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
thanks, Erol :U
let me digest it