News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

I do not get the scrolling (I tried hours by now)

Started by clamicun, December 21, 2015, 10:56:33 AM

Previous topic - Next topic

clamicun

include \masm32\include\masm32rt.inc

WinMain  PROTO :DWORD,:DWORD,:DWORD,:DWORD

.data
ps PAINTSTRUCT<>
client RECT<>
wc WNDCLASSEX<>
msg MSG<>

.data?
hIcon     dd ?
hInstance dd ?
main_hwnd  HWND ?
hdc        HDC ?
hFont       dd ?
hBrush      dd ?
hbrBackground dd ?

.const
ClassName    db "CMC",0
AppName      db "TextScoll",0

startstring1 db" Start1",0
teststring1  db "First teststring to be written in window",0
teststring2  db "Second teststring to be written in window",0
teststring3  db "Third teststring to be written in window",0
teststring4  db "Fourth teststring to be written in window",0
teststring5  db "Fifth teststring to be written in window",0
endstring1   db "End1",0

startstring2 db" Start2",0
endstring2   db "End2",0
startstring3 db" Start3",0
endstring3   db "End3",0

.code
start:

INVOKE GetModuleHandle, NULL
mov    hInstance,eax
INVOKE WinMain, hInstance,NULL,0, SW_SHOWDEFAULT
INVOKE ExitProcess,eax

WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD
      mov wc.cbSize,         sizeof WNDCLASSEX
      mov wc.style,          CS_BYTEALIGNWINDOW or CS_VREDRAW
      mov wc.lpfnWndProc,    offset WndProc2
      mov wc.cbClsExtra,     NULL
      mov wc.cbWndExtra,     NULL
      m2m wc.hInstance,      hInstance
      INVOKE CreateSolidBrush, 0
      mov wc.hbrBackground,eax
      mov wc.lpszMenuName,   NULL
      mov wc.lpszClassName,  offset ClassName
      m2m wc.hIcon,          NULL
      INVOKE LoadCursor,NULL,IDC_ARROW
      mov wc.hCursor,        eax
      m2m wc.hIconSm,        NULL
      INVOKE RegisterClassEx, ADDR wc

;---------- [Center the window] ----------
      INVOKE GetSystemMetrics, SM_CXSCREEN
         sub eax, 500
         shr eax, 1
        push eax
      INVOKE GetSystemMetrics, SM_CYSCREEN
         sub eax, 231
         shr eax, 1
         pop ebx

INVOKE  CreateWindowEx, WS_EX_CLIENTEDGE,offset ClassName,ADDR AppName,WS_SIZEBOX OR WS_VSCROLL OR WS_VISIBLE OR WS_BORDER OR WS_SYSMENU OR CS_OWNDC,\
                                       ebx,eax,500,231,NULL,NULL,wc.hInstance,NULL

        mov main_hwnd, eax   
   INVOKE ShowWindow, main_hwnd,SW_SHOWNORMAL
   INVOKE UpdateWindow, main_hwnd

   .WHILE TRUE
   INVOKE GetMessage, ADDR msg,NULL,0,0
   .BREAK .IF (!eax)
   INVOKE TranslateMessage, ADDR msg
   INVOKE DispatchMessage, ADDR msg
   .ENDW
   mov eax,msg.wParam
ret
WinMain endp
;----------------
WndProc2 proc hWnd:HWND, uMsg:UINT, wParam:WPARAM,lParam:LPARAM
LOCAL  scrollInfo:SCROLLINFO,act_Pos:DWORD,safe_edx:DWORD

push hWnd
pop main_hwnd

.if uMsg==WM_DESTROY
INVOKE ExitProcess,NULL

.elseif uMsg==WM_CREATE
mov   scrollInfo.nMax, 20               ;21 lines total
mov   scrollInfo.cbSize, SIZEOF SCROLLINFO
mov   scrollInfo.fMask, SIF_ALL
mov   scrollInfo.nPage, 7               ;7 lines fitinto the window
xor   eax, eax
mov   scrollInfo.nMin, eax
mov   scrollInfo.nPos, eax
INVOKE   SetScrollInfo, main_hwnd, SB_VERT, ADDR scrollInfo, TRUE

;This seems to be ok. - 7 clicks down and the 2window should be there - 7 more for the 3 window 

.elseif uMsg==WM_PAINT

INVOKE BeginPaint,main_hwnd,offset ps
mov hdc,eax

call Write_Content              ;Writes the text into the window
INVOKE EndPaint,main_hwnd, ADDR ps
INVOKE DeleteObject,hFont
INVOKE DeleteObject,hdc
;---===end PAINT

.elseif uMsg==WM_VSCROLL
       
        mov   scrollInfo.cbSize, SIZEOF SCROLLINFO
        mov   scrollInfo.fMask, SIF_ALL
   INVOKE   GetScrollInfo, main_hwnd, SB_VERT, ADDR scrollInfo
   mov   eax, scrollInfo.nPos
   mov   act_Pos, eax                       ;- Actual position

; See which scroll action requested:
   mov   edx, scrollInfo.nPos      ;used below
   mov   ax, WORD PTR wParam
   cmp   ax, SB_LINEDOWN
   je   do_scrolldown
   cmp   ax, SB_LINEUP
   je   do_scrollup
   cmp   ax, SB_PAGEUP
   je   do_scrollpup
   cmp   ax, SB_PAGEDOWN
   je   do_scrollpdown
   cmp   ax, SB_THUMBTRACK
   je   do_thumb
   jmp   defWinProc

do_thumb:
   mov   edx, scrollInfo.nTrackPos
   jmp    SHORT do_scrolljob

do_scrollpdown:
   add   edx, scrollInfo.nPage
   jmp    SHORT do_scrolljob

do_scrollpup:
   SUB   edx, scrollInfo.nPage
   jmp    SHORT do_scrolljob   

do_scrollup:
   dec   edx
   jmp    SHORT do_scrolljob

do_scrolldown:
INC   edx

do_scrolljob:
   mov   scrollInfo.nPos, edx             
        mov     safe_edx,edx                  ;New Position of scrollbar
   mov   scrollInfo.fMask, SIF_POS      
   INVOKE   SetScrollInfo, main_hwnd, SB_VERT, ADDR scrollInfo, TRUE
   INVOKE   GetScrollInfo, main_hwnd, SB_VERT, ADDR scrollInfo

;Compare new position and actual position
   mov   eax, act_Pos
   mov   edx, scrollInfo.nPos
   cmp   eax, edx
   je   no_scrolljob

;Scroll window if edx and eax are unequal
   mov   scrollInfo.nPos, edx
   mov   scrollInfo.fMask, SIF_POS      ;Change pos. only
   INVOKE   SetScrollInfo,main_hwnd,SB_VERT,ADDR scrollInfo,TRUE

mov eax, act_Pos          ;Org Position of scrollbar
sub eax,safe_edx          ;Minus New Position of scrollbar
mov ebx,26                ;Lineheight   
mul ebx

;INVOKE   GetClientRect, main_hwnd, offset client   ;??

INVOKE ScrollWindow,main_hwnd, 0, eax,NULL,NULL                     ;This scrolls line by line,moves the scrollbar, but scrolls wrongly
;INVOKE ScrollWindow,main_hwnd, 0, eax,offset client,NULL            ;This does nothing , moves scrollbar
;INVOKE ScrollWindow,main_hwnd, 0, eax,NULL,offset client            ;This does nothing , moves scrollbar
;INVOKE ScrollWindow,main_hwnd, 0, eax,offset client,offset client   ;This does nothing , moves scrollbar

;INVOKE ScrollWindowEx,main_hwnd, 0, eax,NULL,NULL,NULL,NULL,SW_SMOOTHSCROLL          ;Strange result - the content disappears 
;INVOKE ScrollWindowEx,main_hwnd, 0, eax,offset client,NULL,NULL,NULL,SW_SMOOTHSCROLL  ;"
;INVOKE ScrollWindowEx,main_hwnd, 0, eax,offset client,NULL,offset client,NULL,SW_SMOOTHSCROLL  ;"
;INVOKE ScrollWindowEx,main_hwnd, 0, eax,offset client,offset client,offset client,NULL,SW_SMOOTHSCROLL  ;"

;INVOKE   InvalidateRect,main_hwnd, NULL, FALSE    ;Here and GetClientRect is probably the catch ??
INVOKE UpdateWindow,main_hwnd

no_scrolljob:
   xor   eax, eax
   ret

.endif
;--------------

defWinProc:
INVOKE DefWindowProc,main_hwnd,uMsg,wParam,lParam
   
ret
WndProc2 endp
;====================================-------------------
Write_Content proc

INVOKE CreateFont,25,0,0,0,400,0,0,0,ANSI_CHARSET,\
OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,\
DEFAULT_QUALITY,DEFAULT_PITCH, NULL
mov    hFont,eax
INVOKE SelectObject,hdc, hFont

RGB    255,255,255
INVOKE SetTextColor,hdc,eax
RGB    0,0,0
INVOKE SetBkColor,hdc,eax

INVOKE GetClientRect,main_hwnd,offset client
mov client.bottom,26

;start 1
INVOKE lstrlen,offset startstring1
INVOKE DrawText,hdc,offset startstring1,eax,offset client,DT_CENTER

;1 line
add client.top,26
add client.bottom,26
INVOKE lstrlen,offset teststring1
INVOKE DrawText,hdc,offset teststring1,eax,offset client,DT_CENTER

;2 line
add client.top,26
add client.bottom,26
INVOKE lstrlen,offset teststring2
INVOKE DrawText,hdc,offset teststring2,eax,offset client,DT_CENTER

;3 line
add client.top,26
add client.bottom,26
INVOKE lstrlen,offset teststring3
INVOKE DrawText,hdc,offset teststring3,eax,offset client,DT_CENTER

;4 line
add client.top,26
add client.bottom,26
INVOKE lstrlen,offset teststring4
INVOKE DrawText,hdc,offset teststring4,eax,offset client,DT_CENTER

;5 line
add client.top,26
add client.bottom,26
INVOKE lstrlen,offset teststring5
INVOKE DrawText,hdc,offset teststring5,eax,offset client,DT_CENTER

;end 1
add client.top,26
add client.bottom,26
INVOKE lstrlen,offset endstring1
INVOKE DrawText,hdc,offset endstring1,eax,offset client,DT_CENTER
;---------

;start 2
add client.top,26
add client.bottom,26
INVOKE lstrlen,offset startstring2
INVOKE DrawText,hdc,offset startstring2,eax,offset client,DT_CENTER

;1 line
add client.top,26
add client.bottom,26
INVOKE lstrlen,offset teststring1
INVOKE DrawText,hdc,offset teststring1,eax,offset client,DT_CENTER

;2 line
add client.top,26
add client.bottom,26
INVOKE lstrlen,offset teststring2
INVOKE DrawText,hdc,offset teststring2,eax,offset client,DT_CENTER

;3 line
add client.top,26
add client.bottom,26
INVOKE lstrlen,offset teststring3
INVOKE DrawText,hdc,offset teststring3,eax,offset client,DT_CENTER

;4 line
add client.top,26
add client.bottom,26
INVOKE lstrlen,offset teststring4
INVOKE DrawText,hdc,offset teststring4,eax,offset client,DT_CENTER

;5 line
add client.top,26
add client.bottom,26
INVOKE lstrlen,offset teststring5
INVOKE DrawText,hdc,offset teststring5,eax,offset client,DT_CENTER

;end 2
add client.top,26
add client.bottom,26
INVOKE lstrlen,offset endstring2
INVOKE DrawText,hdc,offset endstring2,eax,offset client,DT_CENTER

;---------

;start 3
add client.top,26
add client.bottom,26
INVOKE lstrlen,offset startstring3
INVOKE DrawText,hdc,offset startstring3,eax,offset client,DT_CENTER

;1 line
add client.top,26
add client.bottom,26
INVOKE lstrlen,offset teststring1
INVOKE DrawText,hdc,offset teststring1,eax,offset client,DT_CENTER

;2 line
add client.top,26
add client.bottom,26
INVOKE lstrlen,offset teststring2
INVOKE DrawText,hdc,offset teststring2,eax,offset client,DT_CENTER

;3 line
add client.top,26
add client.bottom,26
INVOKE lstrlen,offset teststring3
INVOKE DrawText,hdc,offset teststring3,eax,offset client,DT_CENTER

;4 line
add client.top,26
add client.bottom,26
INVOKE lstrlen,offset teststring4
INVOKE DrawText,hdc,offset teststring4,eax,offset client,DT_CENTER

;5 line
add client.top,26
add client.bottom,26
INVOKE lstrlen,offset teststring5
INVOKE DrawText,hdc,offset teststring5,eax,offset client,DT_CENTER

;end 3
add client.top,26
add client.bottom,26
INVOKE lstrlen,offset endstring3
INVOKE DrawText,hdc,offset endstring3,eax,offset client,DT_CENTER

ret
Write_Content endp

;===============================;===============================

end start

Grincheux

Quote
INVOKE EndPaint,main_hwnd, ADDR ps
INVOKE DeleteObject,hFont
INVOKE DeleteObject,hdc



QuoteINVOKE DeleteObject,hdc
No need
EndPaint deletes de DC

move

QuoteINVOKE DeleteObject,hFont
Before EndPaint


QuoteWrite_Content proc
INVOKE CreateFont,25,0,0,0,400,0,0,0,ANSI_CHARSET,\
OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,\
DEFAULT_QUALITY,DEFAULT_PITCH, NULL
mov    hFont,eax
INVOKE SelectObject,hdc, hFont
Create the Font into WM_CREATE, here it is created every time the window is painted and the hFont is not deleted
After SelectObject, keeps hFontOld

Quote
INVOKE SelectObject,hDC,hFont
mov hFontOld,eax
.
.
.
INVOKE SelectObject,hDC,hFontOld

clamicun

Yes Thank you,

INVOKE EndPaint,main_hwnd, ADDR ps - kills the DC
INVOKE DeleteObject,hdc   ;no need ok.

;------
Any info on my actual srcolling problem ?

jj2007

Quote from: clamicun on December 21, 2015, 10:08:15 PMAny info on my actual srcolling problem ?

Are you sure you can scroll a DC this way? Normally this is part of the default processing of controls.
Btw using code tags would be nice ;)

clamicun

Hello jj,

of course this scrolls, but absolutely incorrect.
The code I saw here (; yaHXV (yet another Hex File Viewer) - Hexview.asm).Author:  NoCforMe
I think, it does a BeginPaint after the scrolling.

do_scrolljob:
   mov    scrollInfo.nPos, edx             
          mov    scrollInfo.fMask, SIF_POS      
   INVOKE   SetScrollInfo, main_hwnd, SB_VERT, ADDR scrollInfo, TRUE
   INVOKE    GetScrollInfo, main_hwnd, SB_VERT, ADDR scrollInfo

;Compare new position and actual position
   mov    eax, act_Pos
   mov    edx, scrollInfo.nPos
   cmp   eax, edx
   je   no_scrolljob

;Scroll window if edx and eax are unequal
sub eax,edx               ;Minus New Position of scrollbar
mov ebx,26                ;Lineheight    requires GetTextMetrics, but 26 is ok here.
mul ebx

INVOKE ScrollWindow,main_hwnd, 0, eax,NULL,NULL   
INVOKE UpdateWindow,main_hwnd

no_scrolljob:

clamicun


TouEnMasm


better way is to create an edit multiline  and write in it.
Then,no need of scroll.It is done by DefWindowProc
Fa is a musical note to play with CL

jj2007

ScrollWindow scrolls the current content of a window. This won't help much if, in your WM_PAINT handler, you rewrite that content all the time.

I haven't done this stuff for a long time, but if I remember well, you have to do lots of things "by hand" if you draw to a DC. You need to keep info where you are, and based on this info you DrawText from the first visible to the last visible line (see Event Paint in \Masm32\MasmBasic\Res\SimpleGui.asc*) - the top variable defines which is the first line to be drawn).

No ScrollWindow needed, but WM_VSCROLL tells you what the user wants, and you need to adjust your info accordingly. All the painting is your job. Leaving this job to DefWindowProc, as Yves suggests, is a lot easier. But I assume you want to learn it, right?  ;)

*) Just saw that the example didn't work as it should. Minor glitch, fixed with version 21 Dec uploaded right now.

clamicun

Many thanks to both of you.
Yes I want to learn - So I keep on trying.

dedndave

i looked in my code for use of ScrollWindow, to give you an example
i don't really use the function - lol

generally, when i want to scroll....

first, i create my own scroll bars, rather than using the system scroll bars
it's a bit more coding, but easier to customize when you start adding the fine touches

second, rather than using ScrollWindow, i keep track of a scroll position
and, my paint code takes care of what is to be displayed

i am short for time, these days - but i will have a look at your code....

HSE

Hi Clamium!

You are writing all the lines all the time.

You only must to write the number of lines wich summatory have the window height.

You must to write the lines >=  initial scroll position, and < (initial+height). You need font height for calculations.

The client.top of the first line >= initial scroll is 0 (or close to that) every time. Then You increment for the other visible lines.

Regards. 
Equations in Assembly: SmplMath

clamicun

Quote from: jj2007 on December 22, 2015, 01:37:42 AM

ScrollWindow scrolls the current content of a window. This won't help much if, in your WM_PAINT handler, you rewrite that content all the time.


I do not get this.
BeginPaint runs once and writes (DrawText) into the window.
Then hdc  is deleted.
So now the window is a window full of text.(not all visible of course).


hutch--

The usual logic of a window that will scroll its contents is to have a parent windows as the "container" and you have a child window within the parent that is much larger than the parent so that the parent window crops the child window. To scroll the contents of the child window you would normally have scroll bars in the parent window and use the API MoveWindow() to move the child window relative to the parent.

You can scroll an image by having it sitting in its own device context then cropping out parts of it with BitBlt() and copying the cropped part to the client area of a parent window. This assumes that the image is larger than the parent client area.

jj2007

Quote from: clamicun on December 22, 2015, 11:14:56 AM
BeginPaint runs once and writes (DrawText) into the window.
Then hdc  is deleted.
So now the window is a window full of text.(not all visible of course).

Well, no, it's not full of text. It is a bit different:

You are drawing on a canvas, and that canvas called "device context" is limited to the client area of your main window (or your control, in case you are drawing on a control).

Everything higher up or further down is not "invisible", no, it has never been drawn because there is no canvas. This is why you need to define a top line from where you start drawing, and a last line near the lower border.

At the beginning, top = 0:

line 0  <<<<--------- drawn at x:0, y:0
line 1  <<<<--------- drawn at x:0, y:20
line 2


Then you scroll down, and top=40 (for example):
line 40  <<<<--------- drawn at x:0, y:0
line 41  <<<<--------- drawn at x:0, y:20
line 42


MasmBasic\Res\SimpleGui.asc works exactly like this.
Remember that edit controls perform this via a built-in mechanism call DefWindowProc. For a DC, you have to do your own calculations.

clamicun

Jesus no ceu,
have to digest that.
Thanks again very much.

By the way - not all of what you said fits, because my shown code was an "example. In "reality" it is part of my mysql project (since weeks working on that) and there the mainwindow is the largest and the only window to be scrolled (it is supposed to show the 3 last bank statements of an account)  is a child. 

Right now I am testing to get those into a listviewwindow (at least there is no scrollproblem - but others).

Well - I am having a good time.
Feliz natal e um bom ano novo.
Michael