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
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
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 ?
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 ;)
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:
Here is the code again
better way is to create an edit multiline and write in it.
Then,no need of scroll.It is done by DefWindowProc
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 (http://masm32.com/board/index.php?topic=94.0).
Many thanks to both of you.
Yes I want to learn - So I keep on trying.
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....
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.
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).
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.
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.
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
Grande Michael. Feliz natal à vc tb :)
Bom ver que temos mais brasileiros no Fórum :)
Guga,
feliz natal e um ano 2016 com muita alegria.
Onde mora vc ?
Alem..
Digamos - sou 'teuto-baiano'.
23 anos no Arraial D'Ajuda e ha 2 anos de volta no pais dos loucos.
Ate ja
(sem acentos - teclado alemao)
Oi michael, pra sua família tb.
Estou em sampa. Não conheço Arraial D' ajuda. Da bahia conheci salvador, feira de santana, sauipe, farol. Nem me fala, aqui no Brasil está um pandemônio, ainda mais com esse lixo de governo. A situação aqui está terrível.
bem-vindo ao Fórum :)
Grande abraço
Feliz Natal a vc e sua familia.