User Tools

Site Tools


This is an old revision of the document!

A PCRE internal error occured. This might be caused by a faulty plugin

=====Scrolling over a large canvas===== //by Richard Russell, September 2007//\\ \\ //**The code in this article requires BBC BASIC for Windows version 5.70a or later.**//\\ \\ Sometimes it may not be possible to display the entirety of your program's User Interface at once in a window of a sensible size, especially when you need the program to run on PCs with a relatively low display resolution. One solution to this is to give the user the ability to scroll the window so that the region of interest is in view.\\ \\ Although there are a number of ad-hoc ways in which this can be achieved, depending on precisely what needs to be displayed, each must be tailored to the particular circumstances and can be quite tricky to implement successfully. This article presents an alternative approach: a general-purpose method which should work for almost any situation.\\ \\ BBC BASIC for Windows' display bitmap is 1920 x 1440 pixels and the code listed in this article is directly applicable to a 'canvas' (over which the user can scroll the output window) up to this size. If this isn't big enough you may be able to increase it using the method described in the [[|Help documentation]] but beware of excessive memory usage.\\ \\ The method will be illustrated by means of a practical example. You should be able to adapt it to your particular requirements fairly easily. Firstly, your program must include (at or near the beginning) some necessary initialisation:\\ \\ CanvasX% = 1920 CanvasY% = 1440 WindowX% = 640 WindowY% = 480 CharX% = 8 CharY% = 16 GWL_STYLE = -16 WM_SIZE = 5 WM_HSCROLL = &114 WM_VSCROLL = &115 DIM Move%(2) ON MOVE Move%()=@msg%,@wparam%,@lparam%:PROCmove(Move%(0),Move%(1),Move%(2)):RETURN SYS "GetWindowLong", @hwnd%, GWL_STYLE TO ws% SYS "SetWindowLong", @hwnd%, GWL_STYLE, ws% OR &300000 VDU 23,22,WindowX%;WindowY%;CharX%,CharY%,16,128 ORIGIN 0,2*(@vdu%!212-CanvasY%) VDU 24,0;0;CanvasX%*2-2;CanvasY%*2-2; VDU 28,0,CanvasY%/CharY%-1,CanvasX%/CharX%-1,0 For the purposes of the example the 'canvas' has here been set to the normal maximum size, 1920 x 1440 pixels, and the output window has been set (initially) to 640 x 480 pixels. **CharX%** and **CharY%** are the width and height, in pixels, of the text characters. In practice you should set **CanvasX%** and **CanvasY%** to whatever dimensions are appropriate for your application. The user can scroll the output window over this range, and can resize the window in the usual ways (e.g. dragging an edge or corner).\\ \\ Once the initialisation is complete you can proceed to display whatever contents of the user interface you wish, up to the full size of the 'canvas'. In this example we will simply display a short piece of text, a BMP image and a pair of diagonal lines:\\ \\ *DISPLAY "C:\Windows\Web\Wallpaper\Bliss.BMP" PRINT "Scroll down to see the picture" LINE 0,0,CanvasX%*2-2,CanvasY%*2-2 LINE 0,CanvasY%*2-2,CanvasX%*2-2,0 Because you will be drawing outside the area occupied by the visible output window you should take note of the article [[/Drawing%20outside%20the%20window|Drawing outside the window]], in particular in respect of the graphics origin. The initialisation code above sets the graphics origin to the bottom-left corner of the canvas, and sets both the graphics viewport (VDU 24) and text viewport (VDU 28) to the full size of the canvas.\\ \\ Now we can enter an 'idle' loop during which the user can scroll the window:\\ \\ REPEAT WAIT 1 UNTIL FALSE END Of course in a practical program it is likely you will want to do something more useful here!\\ \\ Finally, here is the procedure which contains the 'magic' to make all this work:\\ \\ DEF PROCmove(msg%,wp%,lp%) PRIVATE sih{}, siv{} DIM sih{cbSize%, fMask%, nMin%, nMax%, nPage%, nPos%, nTrackPos%} DIM siv{cbSize%, fMask%, nMin%, nMax%, nPage%, nPos%, nTrackPos%} sih.cbSize% = DIM(sih{}) siv.cbSize% = DIM(siv{}) sih.fMask% = 7 siv.fMask% = 7 sih.nMax% = CanvasX% siv.nMax% = CanvasY% CASE msg% OF WHEN WM_SIZE: sih.nPage% = lp% AND &FFFF siv.nPage% = lp% >>> 16 WHEN WM_HSCROLL: CASE wp% AND &FFFF OF WHEN 0: sih.nPos% -= 1 WHEN 1: sih.nPos% += 1 WHEN 2: sih.nPos% -= sih.nPage% WHEN 3: sih.nPos% += sih.nPage% WHEN 5: sih.nPos% = wp% >> 16 ENDCASE WHEN WM_VSCROLL: CASE wp% AND &FFFF OF WHEN 0: siv.nPos% -= 1 WHEN 1: siv.nPos% += 1 WHEN 2: siv.nPos% -= siv.nPage% WHEN 3: siv.nPos% += siv.nPage% WHEN 5: siv.nPos% = wp% >> 16 ENDCASE ENDCASE IF sih.nPos% > sih.nMax%-sih.nPage% sih.nPos% = sih.nMax%-sih.nPage% IF siv.nPos% > siv.nMax%-siv.nPage% siv.nPos% = siv.nMax%-siv.nPage% IF sih.nPos% < sih.nMin% sih.nPos% = sih.nMin% IF siv.nPos% < siv.nMin% siv.nPos% = siv.nMin% SYS "SetScrollInfo", @hwnd%, 0, sih{}, 1 SYS "SetScrollInfo", @hwnd%, 1, siv{}, 1 @ox% = sih.nPos% @oy% = siv.nPos% SYS "InvalidateRect", @hwnd%, 0, 0 *REFRESH ENDPROC Note that the code in this article is not compatible with SPRITELIB.

This website uses cookies for visitor traffic analysis. By using the website, you agree with storing the cookies on your computer.More information
scrolling_20over_20a_20large_20canvas.1522502379.txt.gz · Last modified: 2018/03/31 14:19 by