ResizeHandler

= ResizeHandler = toc First, Brent Thorn wanted to me say it again, clearly and for all: (done that). // but for now it works, and allows to do some otherwise impossible things in JB. (tsh73) //
 * This behavior is undocumented. It could be removed in any future release of JB.**

Original post
Thread started on: 19.04.2005 at 00:43:38 This is a demo, originally RESIZE.BAS, included with Liberty BASIC, rewritten to work with Just BASIC. Since JB lacks a LOCATE command for controls (an exception being a GRAPHICBOX), one has to resort to an undocumented behavior of JB and LB.
 * ResizeHandler**
 * Brent Thorn**:

The fact is that when one declares a control statement in JB or LB, the language stores this as a sort of subroutine that it executes when a REFRESH is issued to the parent window.

By declaring controls using variables in the location and size parameters, one gains the ability to move and resize controls in a rather intuitive way. One simply assigns new values to these variables and REFRESHes the window. The code has a VB property look and feel, if one names the variables with this sort of "dot" notation.

Just one caveat exists. The variables must have scope inside any routine that REFRESHes. This means that if control statements are executed inside a SUB or FUNCTION, the variables must be declared as GLOBAL, otherwise the program will crash at a REFRESH.

code format="lb" 'resize.bas 'Rewritten for Just BASIC, by Brent D. Thorn, 4/2005 'This is an example of a program which resizes several 'controls in a window depending on how the user changes 'the size of the window.

nomainwin WindowWidth = 550 WindowHeight = 410

resizer.lbox1.Width = 256: resizer.lbox1.Height = 186 listbox #resizer.lbox1, array$, [lbox1DClick], 0, 0, resizer.lbox1.Width, resizer.lbox1.Height resizer.lbox2.Left = 257: resizer.lbox2.Width = 284: resizer.lbox2.Height = 164 listbox #resizer.lbox2, array$, [lbox2DClick], resizer.lbox2.Left, 0, resizer.lbox2.Width, resizer.lbox2.Height resizer.cbox3.Left = 257: resizer.cbox3.Top = 164: resizer.cbox3.Width = 283 combobox #resizer.cbox3, array$, [cbox3DoubleClick], resizer.cbox3.Left, resizer.cbox3.Top, resizer.cbox3.Width, 150 resizer.tedit4.Top = 186: resizer.tedit4.Width = 540: resizer.tedit4.Height = 195 texteditor #resizer.tedit4, 1, resizer.tedit4.Top, resizer.tedit4.Width, resizer.tedit4.Height open "Resizing example" for window as #resizer print #resizer, "trapclose [quit]" print #resizer, "resizehandler [resized]"

[loop] wait goto [loop]

[resized] wWid = WindowWidth wHig = WindowHeight upperVert = int(256/550*wWid) 'upper middle vertical edge midHoriz = int(186/410*wHig) 'middle horizontal edge urWid = upperVert - wWid resizer.lbox1.Width = upperVert resizer.lbox1.Height = int(186/410*wHig) resizer.lbox2.Left = upperVert resizer.lbox2.Width = wWid-upperVert resizer.lbox2.Height = int(186/410*wHig)-23 resizer.cbox3.Left = upperVert resizer.cbox3.Top = midHoriz-23 resizer.cbox3.Width = wWid - upperVert resizer.tedit4.Top = midHoriz resizer.tedit4.Width = wWid resizer.tedit4.Height = wHig-midHoriz print #resizer, "refresh" goto [loop]

[quit] 'quit the program

close #resizer end code

Following explanations
The variables used in a control statement are not really important. You can reuse variables if, for example, two or more controls will always have the same width or height.
 * Brent Thorn**:

The use of plain variables is not a limitation. You can use calculations in the position or size parameters. However, doing so can greatly complicate the code and, in my experience with the method, can introduce subtle problems. It is also not a good idea to use **WindowWidth** or **WindowHeight** in calculations, because the meaning of these changes from window creation to resize handler.

> //It is also not a good idea to use WindowWidth or WindowHeight in calculations, because the meaning of these changes from window creation to resize handler. // from the LB help file: > //After the resize-handler has been activated, the new dimensions of the window workspace are contained in the variables WindowWidth and WindowHeight. // (just tested - it is so in JB)
 * tsh73**:

So, then we open window, WindowWidth and WindowHeight are size of window (with border and title-bar and may be menu). After resize-handler, only client area (without border, menu or title-bar). If you bear it in mind (and measure border, title-bar and menu), you can indeed "use WindowWidth or WindowHeight in calculations"

And to measure them, you can go to adjusting width, height of a window tip: code format="lb" 'example of resize handler with accounting for window border/title size nomainwin 'get space taken by borders gosub [getSlack] 'set your desired window zise WindowWidth = 550 WindowHeight = 410 'calculate clent size clentWidth = WindowWidth - slackX clentHeight = WindowHeight - slackY 'use clent size to position controls staticText1W=144: staticText1H=55 statictext #main.statictext1, _ "This static text stays with lower right corner then resized", _ clentWidth-staticText1W, clentHeight-staticText1H, staticText1W, staticText1H

open "Please resize me" for window as #main print #main, "trapclose [quit.main]"

print #main, "font ms_sans_serif 10" 'init resize handler #main, "Resizehandler [rh]"

wait

[quit.main] Close #main END

[rh] 'in the resize handler, we should update variables our controls placed with 'in the resize handler, WindowWidth, WindowHeight is actually client size clentWidth = WindowWidth clentHeight = WindowHeight 'and refresh window #main "refresh" wait

[getSlack] WindowWidth=200:WindowHeight=200 open "" for graphics_nsb as #t:#t,"home;posxy x y":close#t slackX=WindowWidth-2*x:slackY=WindowHeight-2*y return

code

Trouble with several events
It might not be obvious if your resize code works instantly, but actually resizing fires several event. It makes sence to handle only last one (of your resize code is heavy - text wrapping for example - your program will get laggish.) Adding a timer saves a day. code format="lb" 'problem: resize generates several events "as it go".

open "resize test" for window as #main wait
 * 1) main, "trapclose [quit]"
 * 2) main, "Resizehandler [rh]"

[rh] print time$("ms"), WindowWidth, WindowHeight #main "refresh" wait

[quit] timer 0 close #main end code

code format="lb" 'problem: resize generates several events "as it go". 'But responding to resize might involve long computation. 'How we get only last event?

open "resize test" for window as #main wait
 * 1) main, "trapclose [quit]"
 * 2) main, "Resizehandler [rh]"

[rh] timer 100, [clickTimer] wait

[clickTimer] 'now we have only last event on resize timer 0 print time$("ms"), WindowWidth, WindowHeight #main "refresh" wait

[quit] timer 0 close #main end code