rwg
New Member
Posts: 49
|
Post by rwg on Apr 8, 2019 22:19:19 GMT -5
i'd like to be able to scroll a graphics window using code.
maybe the dll function ScrollWindowEx might allow this.
my graphics window handle i can get from ......
open "PLOT" for graphics_nsb_nf as #w.g calldll #user32,"GetActiveWindow",_ plot as ulong
i can call the scrolling dll by ..... calldll #user32,"ScrollWindowEx",_
but i'm lost with coding the parameters with the correct syntax microsoft docs show a C++ answer to this but how do i write it in LB
BOOL ScrollWindow( HWND hWnd, int XAmount, int YAmount, const RECT *lpRect, const RECT *lpClipRect );
grateful for any leads. cheers rwg
|
|
|
Post by metro on Apr 9, 2019 5:02:38 GMT -5
|
|
|
Post by Rod on Apr 9, 2019 10:28:02 GMT -5
There will be a set scroll position api call but I have not used it. You would need to get the scroll bar parameters first. You might just draw the relevant section rather than scroll. You can just pretend to be clicking the scrollbar but it is only half a solution. The rest here, docs.microsoft.com/en-us/windows/desktop/controls/wm-hscroll
' Open main window. Open "Demo" For Graphics As #demo #demo "TrapClose [quit]"
hWnd=hwnd(#demo)
' Draw something on it. #demo "Down; Place 8 0;\" For lin = 1 to 50 #demo "\";lin Next #demo "Flush"
cmd = _SB_LINEDOWN 'cmd = _SB_PAGEUP ' fast for n= 1 to 50 gosub [scroll] next
timer 1000,[pause] wait [pause] timer 0
cmd = _SB_LINEUP 'cmd = _SB_PAGEUP 'fast for n= 1 to 50 gosub [scroll] next wait
|
|
rwg
New Member
Posts: 49
|
Post by rwg on Apr 9, 2019 17:59:02 GMT -5
thanks Rod / Metro i'm not experienced with these dll calls. would really like to understand them. i'm sure the calldll #user32,"ScrollWindowEx",_ is what i'm after, as it would appear,from microsoft's parameters, that dx and dy are the amounts that the scrollbars would be moved. viz
int ScrollWindowEx( HWND hWnd, int dx, int dy, const RECT *prcScroll, const RECT *prcClip, HRGN hrgnUpdate, LPRECT prcUpdate, UINT flags ); i just cant work out how to get this into LB, just like the SetActiveWindow, GetActiveWindow functions many thanks
|
|
cundo
Full Member
Muchas Gracias!!
Posts: 146
|
Post by cundo on Apr 9, 2019 18:06:18 GMT -5
My suggestion to you is to "fake it", draw your own scroll buttons, and draw what you see. If it's not on screen, don't draw it. Like in a game.
|
|
|
Post by Rod on Apr 10, 2019 2:54:27 GMT -5
If you just want to move the graphics on display why involve complicated scrollbars, or indeed complicated window scrolling? Just draw the segment of the graphic you need in the location you want it. DRAWBMP should be just about all you need.
This is the code to move the scrollbar. Unfortunately that's all it does, move the scrollbar, the graphics are unchanged. This is the kinda stuff that happens when you step outside the system. API should be a last resort IMHO.
' Open main window. Open "Demo" For Graphics As #demo #demo "TrapClose [quit]"
hWnd=hwnd(#demo)
' Draw something on it. #demo "Down; Place 8 0;\" For lin = 1 to 50 #demo "\";lin Next #demo "Flush"
pos=200
CallDLL #user32, "SetScrollPos", _ hWnd As ULong, _ _SB_VERT As ULong, _ pos As ULong, _ 1 As ULong, _ ret As Long wait
Why don't you tell us a little more about what the task is, I am sure folks will show you at least two other ways to accomplish what you want natively.
|
|
|
Post by tsh73 on Apr 10, 2019 8:53:08 GMT -5
This thing moves graphics BY using scrollbar. Don't ask me how\why it works - I have no idea ' programmed graphic scroll ' kind of (have no idea how it works) ' But! it works for me under Win10 'tsh73 Apr 2019
nomainwin
WindowWidth = 450 WindowHeight = 300
UpperLeftX=int((DisplayWidth-WindowWidth)/2) UpperLeftY=int((DisplayHeight-WindowHeight)/2)
graphicbox #main.gr1, 1, 1, 200, 200 graphicbox #main.gr2, 246, 76, 100, 100 button #main.button3, "Scroll", [button3Click], UL, 238, 11, 122, 25 open "Programming scroll demo" for window as #main print #main.gr1,"down; fill white; flush" print #main.gr2,"down; fill white; flush" print #main, "trapclose [quit.main]"
print #main, "font ms_sans_serif 10"
wait
[quit.main] timer 0 Close #main END
[button3Click] #main.gr1 "place 100 100" for r = 10 to 90 step 20 #main.gr1 "circle ";r next #main.gr1 "flush"
#main.gr2 "place 100 100" for r = 10 to 90 step 20 #main.gr2 "circle ";r next #main.gr2 "flush"
timer 100, [changeScroll] a=0 wait
[changeScroll] a=a+.1 x=50+50*cos(3*a) 'Lissajous curve in 100x100 y=50+50*cos(2*a)
#main.gr2 "horizscrollbar on ";x;" ";x #main.gr2 "vertscrollbar on ";y;" ";y wait
|
|
|
Post by Rod on Apr 10, 2019 9:13:48 GMT -5
Well more simply,
' programmed graphic move,aka scroll
nomainwin
WindowWidth = 450 WindowHeight = 300
UpperLeftX=int((DisplayWidth-WindowWidth)/2) UpperLeftY=int((DisplayHeight-WindowHeight)/2)
graphicbox #main.gr1, 1, 1, 200, 200 graphicbox #main.gr2, 246, 76, 100, 100 button #main.button3, "Scroll", [button3Click], UL, 238, 11, 122, 25 open "Programming scroll demo" for window as #main print #main.gr1,"down; fill white; flush" print #main.gr2,"down; fill white; flush" print #main, "trapclose [quit.main]"
print #main, "font ms_sans_serif 10"
wait
[quit.main] timer 0 Close #main END
[button3Click] #main.gr1 "place 100 100" for r = 10 to 90 step 20 #main.gr1 "circle ";r next #main.gr1 "flush" #main.gr1 "getbmp bmp 0 0 200 200"
timer 100, [changeScroll] a=0 wait
[changeScroll] a=a+.1 x=50*sin(a) y=50*cos(a) #main.gr2 "drawbmp bmp ";x;" ";y
wait
|
|
|
Post by tsh73 on Apr 10, 2019 9:26:14 GMT -5
Not quite. You actually _REDRAW_ whole picture each timer tick.
EDIT
but really there might not be much difference. I was thinking about ability to add to the picture along with scrolling. But pressing button second time produces weird behavior - I see thing scroll but also I got un-scrolling part. How's that?
|
|
|
Post by Rod on Apr 10, 2019 10:22:03 GMT -5
It is just about managing what is on display, this one is better. Main point is we don't need scrollbars to scroll graphics. But until the task in hand is better described we are both guessing.
' programmed graphic move,aka scroll
nomainwin
WindowWidth = 450 WindowHeight = 300
UpperLeftX=int((DisplayWidth-WindowWidth)/2) UpperLeftY=int((DisplayHeight-WindowHeight)/2)
graphicbox #main.gr1, 1, 1, 200, 200 graphicbox #main.gr2, 246, 76, 100, 100 button #main.button3, "Scroll", [button3Click], UL, 238, 11, 122, 25 open "Programming scroll demo" for window as #main print #main.gr1,"down; fill white; flush" print #main.gr2,"down; fill white; flush" print #main, "trapclose [quit.main]"
print #main, "font ms_sans_serif 10"
wait
[quit.main] timer 0 Close #main END
[button3Click] #main.gr2 "cls" #main.gr1 "place 100 100" for r = 10 to 90 step 20 #main.gr1 "circle ";r next #main.gr1 "flush" #main.gr1 "getbmp bmp 0 0 200 200"
timer 100, [changeScroll] a=0 wait
[changeScroll] a=a+.1 x=-50+25*sin(a) y=-50+25*cos(a) #main.gr2 "discard ; drawbmp bmp ";x;" ";y
wait
|
|
|
Post by tsh73 on Apr 10, 2019 12:26:00 GMT -5
I was able to do scrolling AND drawing Thought it flickers like mad on my machine. (and I found that turning scrollbars ON changes "home" position)
' nomainwin
pi=acs(-1) rad=pi/180
graphicbox #main.gr, 50, 50, 200, 200 open "test" for window as #main
#main "trapclose [quit]" #main.gr "down"
'should be on before drawing or "home" gives different point! #main.gr "vertscrollbar on " #main.gr "horizscrollbar on "
#main.gr "home; circle 10" #main.gr "home; circle 30" #main.gr "home; circle 50" #main.gr "home; circle 70"
#main.gr "flush" #main.gr "rule xor"
timer 100, [tick] wait
[quit] timer 0 close #main end
[tick] if a<>0 then 'clear #main.gr "north; turn "; a #main.gr "home; go 100" end if 'scroll x=-10+80*cos(3*a*rad/2) 'offsets by trial and errors y=-10+80*sin(2*a*rad/2) #main.gr "vertscrollbar on ";y;" ";y #main.gr "horizscrollbar on ";x;" ";x
'draw a=a+15 #main.gr "north; turn "; a #main.gr "home; go 100" wait
|
|
|
Post by Rod on Apr 10, 2019 12:43:35 GMT -5
But the scroll bars don't work anymore, I am not sure we are addressing the OP's original problem.
|
|
rwg
New Member
Posts: 49
|
Post by rwg on Apr 11, 2019 18:11:50 GMT -5
thanks everyone for the responses. i'm learning much.
ok Rod, the task at hand .....
1) i'll be entering a series of xy points via prompts from the mainwin. (i know you don't recommend this, but it suits) 2) these xy points are plotted on a graphics window together with identifiers eg point number. 3) the size of the graphics window has been estimated, as the range of xy points is unknown but estimatable. 4) due to this, the first xy point, and indeed following points may not land on the visual part of the graphics display. 5) as i'd like to know how the plot is going, i'd like to see the first point(s) at the middle of the graphics window. 6) manually using the graphics window scrollbars the find the plotted point(s) is often time consuming. 7) i'd rather be able to use a dll to place the plotted point at the centre off the graphics window.
thanks for the resposes cheers rwg
|
|
|
Post by tsh73 on Apr 12, 2019 3:44:49 GMT -5
Hello rwg
I basically wonder why bother with scrollbars etc if you just need two variables for offset by x and by y?
Have a look on this program. It uses "offX" "offY" to scroll (pan) and "scale" to zoom things in or out. Instructions are on top comments.
'zoom and pan 'by tsh73, july 2013 '1. draw smth, denending of offset (offX, offY) and scale '2. scale and pan, programmatically '3. rmb pans '4. lmb zooms (left to right zoom in; righ to left zoom out (try it)) '5. F5 resets zoom/pan to original one
nomainwin open "test zoom & pan" for graphics_nsb_nf as #gr #gr "trapclose [quit]" #gr "down" #gr "home; posxy cx cy"
#gr "when rightButtonDown [rmbDown]" #gr "when rightButtonUp [rmbUp]" #gr "when rightButtonMove [rmbMove]"
#gr "when leftButtonDown [lmbDown]" #gr "when leftButtonUp [lmbUp]" #gr "when leftButtonMove [lmbMove]"
#gr "when characterInput [keyCheck]" #gr "setfocus" offX=0:offY=0 scale = 1
gosub [drawStuff] wait
'------------------------------- [keyCheck] 'print len(Inkey$), asc(Inkey$) if Inkey$=chr$(0)+chr$(_VK_F5) then offX=0:offY=0 scale = 1 gosub [drawStuff] end if wait
'------------------------------- [lmbDown] lmbX=MouseX: lmbY=MouseY oldX=MouseX: oldY=MouseY #gr "rule xor" wait
[lmbUp] lmbX2=MouseX: lmbY2=MouseY dx2 = int((lmbX2-lmbX)/2) if dx2=0 then wait 'not possible to zoom midX=(lmbX2+lmbX)/2 midY=(lmbY2+lmbY)/2 midX.math = (midX-offX)/scale 'old scale midY.math = (midY-offY)/scale
if dx2>0 then 'left to right zoom in scale = scale * cx/dx2 else 'right to left zoom out scale = scale * (-1)*dx2/cx end if 'the math is, after new scale, selection rectangle midpoint should go to window midpoint offX=cx-scale*midX.math offY=cy-scale*midY.math 'x.screen = offX+scale*x '=> x.math = (x.screen-offX)/scale 'print scale, (lmbX2+lmbX)/2, (lmbY2+lmbY)/2, offX, offY #gr "rule over" gosub [drawStuff] wait
[lmbMove] #gr "place ";lmbX;" ";lmbY;"; box ";oldX;" ";oldY oldX=MouseX: oldY=MouseY #gr "place ";lmbX;" ";lmbY;"; box ";oldX;" ";oldY wait
'-------------------------------------- [rmbDown] rmbX=MouseX: rmbY=MouseY oldX=MouseX: oldY=MouseY #gr "rule xor" wait
[rmbUp] offX=offX+MouseX-rmbX offY=offY+MouseY-rmbY #gr "rule over" gosub [drawStuff] wait
[rmbMove] #gr "line ";rmbX;" ";rmbY;" ";oldX;" ";oldY oldX=MouseX: oldY=MouseY #gr "line ";rmbX;" ";rmbY;" ";oldX;" ";oldY wait
'--------------------------------- [drawStuff] 'x.screen = offX+scale*x '=> x.math = (e.screen-offX)/scale '#gr "line ";;" ";;" ";;" "; #gr "cls" 'OX y=cy x0=(0-offX)/scale x1=(2*cx-offX)/scale #gr "line ";0;" ";y;" ";2*cx;" ";y #gr "place ";0;" ";y+25 #gr "\";int(x0) #gr "place ";2*cx-50;" ";y+25 #gr "\";int(x1) for x=10*int(x0/10) to 10*int(x1/10) step 10 xe=offX+scale*x #gr "line ";xe;" ";y-4;" ";xe;" ";y+4 if x mod 50 =0 then #gr "line ";xe;" ";y-7;" ";xe;" ";y+7 end if if x mod 100 =0 then #gr "place ";xe;" ";y-20 #gr "\";x;" " end if next 'OY x=cx y0=(0-offY)/scale y1=(2*cy-offY)/scale #gr "line ";x;" ";0;" ";x;" ";2*cy #gr "place ";x-40;" ";20 #gr "\";int(y0) #gr "place ";x-40;" ";2*cy-5 #gr "\";int(y1) for y=10*int(y0/10) to 10*int(y1/10) step 10 ye=offY+scale*y #gr "line ";x-4;" ";ye;" ";x+4;" ";ye if y mod 50 =0 then #gr "line ";x-7;" ";ye;" ";x+7;" ";ye end if if y mod 100 =0 then #gr "place ";x+10;" ";ye #gr "\";y;" " end if next
'draw smth, denending of offset (offX, offY) and scale 'it really should be as simple as this. Or as complex as you want. randomize .5 #gr "place ";scale*cx+offX;" "; scale*cy+offY
#gr "north" for i = 1 to 20 a=int(rnd(0)*360)-180 r=int(rnd(0)*50) #gr "turn ";a;"; go ";r*scale next
#gr "flush" return
[quit] close #gr end
|
|
|
Post by Rod on Apr 12, 2019 5:17:49 GMT -5
Another alternative is to "scale" the chart to a defined size. No need for scrolling.
nomainwin
'set up some dummy x,y data in a points() array dim points(2,500) for n= 1 to 500 degree=degree+1 if degree>359 then degree=0 y=sin(degree/57.29577951)*300 points(1,n)=n 'x points(2,n)=y 'y next
'specify our charts screen position and size width=400 height=400 x=(DisplayWidth-width)/2 y=(DisplayHeight-height)/2
'specify our charts X data range 'in this example I chart the whole set but could equally chart a subset xstart=0 xend=500
'now call the generic charting function ret=chart(x,y,width,height,xstart,xend) wait
function chart(x,y,w,h,s,e)
' add a margin of 80 pixels to width and height ' and open a graphicbox at the desired x,y location WindowWidth = w+80 WindowHeight = h+80 UpperLeftX = x UpperLeftY = y open "Graph" for graphics_nf_nsb as #1 #1 "down ; trapclose [quit] ; font consolas 8"
' draw a shaded background the chart starts at 40,10 to allow for x and y ' scale values to be printed. For the shading we find y increment in color ' value from 128 to 256 so 128 shades and we find what increment per pixel ' line is required to give us 128 shades of color cx=40 cy=10 incc=0-128/h #1 "place ";cx-1;" ";cy-1;" ;box ";cx+w+2;" ";cy+h+2 for y=h to 1 step -1 #1 "color ";y*incc+256;" ";y*incc+256;" ";y*incc+256 #1 "line ";cx;" ";cy+y;" ";cx+w+1;" ";cy+y next y
' how many points to chart nopoints=e-s
' find scale min and max minx=points(1,s) maxx=points(1,s) miny=points(2,s) maxy=points(2,s) for n= s to e if minx>points(1,n) then minx=points(1,n) if maxx<points(1,n) then maxx=points(1,n) if miny>points(2,n) then miny=points(2,n) if maxy<points(2,n) then maxy=points(2,n) next
'calculate scale increase per pixel line 'write text every 20 pixels 'set mid point as 0,0 initially mx=0 my=0 incx=(maxx-minx)/w incy=(maxy-miny)/h
'now draw the Y scale for y=h to 0 step -20 s$=str$(int(maxy-y*incy)) if left$(s$,1)="-"then s$=right$(s$,len(s$)-1) #1 "color red" else #1 "color black" end if sx=len(s$)*6 'at the mid point draw an axis line if int(maxy-y*incy)>-1 and int(maxy-y*incy)<1 then #1 "place ";cx;" ";cy+y;" ;color yellow ; turn 90 ; go ";w #1 "color black" my=y end if #1 "place ";cx-sx-5;" ";cy+y+5;" ;\";s$ next
'now draw the X scale for x=0 to w step 20 s$=str$(int(minx+x*incx)) if left$(s$,1)="-"then s$=right$(s$,len(s$)-1) #1 "color red" else #1 "color black" end if if int(minx+x*incx)>-1 and int(minx+x*incx)<1 then #1 "place ";cx+x;" ";cy+h;" ;color yellow ; north ; go ";h #1 "color black" mx=x end if for l=1 to len(s$) #1 "place ";cx-8+x+l*6;" ";cy+5+h+l*8;" ;\";mid$(s$,l,1) next next
'chart the actual data #1 "color blue" for n=s to e #1 "set ";cx+mx+points(1,n)/incx;" ";cy+my+points(2,n)/incy next #1 "flush" end function
[quit] close #1 end
|
|