Liberty Basic is develeopped by Carl Gundel
Original Newsletter compiled by Alyce Watson
Translation to HTML: Raymond Roumeas

The Liberty Basic Newsletter - Issue #78

AUG 2000

© 2000, Side by Side Software

http://alyce.50megs.com/sss/

All Rights Reserved

In this issue:


"Whether one has natural talent or not, any learning period requires the willingness to suffer uncertainty and embarrassment."

        - Gail Sheehy
SIMULATING A 32-BIT LOOK

Many of the newer applications seem to be using smaller, more tightly spaced controls, and smaller fonts.  This may happen because programs are more complex and offer far more choices; therefore more controls must fit onto a window, or toolbar.  There are some things we can do with our Liberty BASIC programs to make their look more consitent with these newer applications.  Here are some suggestions.

Keep controls small, and uniform in size.  Space them in functional groups, with like functions together, and having a slight separation between control goups.  If it is necessary to have multiple radiobutton groups on the same window, you must use a groupbox.  If not, try to avoid the groupbox.  It has no unique extension, so commands cannot be sent to the groupbox to change its size or location, and it cannot accept a font
command, leaving it with the fixedsys font.

Regular pushbuttons are created with the BUTTON command, and the width and height parameters are optional.  Liberty BASIC will size a button for you so that it holds the text for its caption.  Don't omit the width and height parameters!  It looks much better to have buttons conform in size to one another, and this isn't possible unless the programmer (not Liberty BASIC) chooses the size.  It is also difficult to place buttons on the window, without knowing the width.  Try this little example in Liberty BASIC:

button #1.1, "This is a button",[loop],UL,10,10
button #1.2, "This is another",[loop],UL,50,10
open "Huh?" for window as #1
[loop]
input a$

Okay, it is a rather obvious example, but it something like this could happen, if you do not specify width and height parameters.  In the next example, a font command is sent to a button.  It doesn't automatically resize, so the caption might get lost on the button, or hang off the edges!

button #1.1, "This is a button",[loop],UL,10,10
button #1.2, "This is another",[loop],UL,150,10
open "Huh?" for window as #1
print #1.1, "!font ms_sanserif 20"
print #1.2, "!font ms_sanserif 8"
[loop]
input a$

And here is a similar example, with width and height specified:

button #1.1, "This is a button",[loop],UL,10,10,100,20
button #1.2, "This is another",[loop],UL,150,10,100,20
open "Huh?" for window as #1
print #1.1, "!font ms_sanserif 10"
print #1.2, "!font ms_sanserif 10"
[loop]
input a$

The following group of buttons is each 50 pixels wide and 16 pixels high.

button #2.red,   "Red",  [red],  UL, 2,2,50,16
button #2.green, "Green",[green],UL,52,2,50,16
button #2.blue,  "Blue", [blue], UL,102,2,50,16

Most controls accept font commands.  For an updated look, keep fonts small. Windows menus now use MS SanSerif in a small size (in my experience!) Using this font on your own controls (buttons, radiobuttons and so on) will give your application a more up-to-date appearance.

COLOR

Liberty BASIC's 16 colors are the original set of colors used when monitors moved from black and white to color.  They are not necessarily attractive, are they?  All colors but lightgray are combinations of RGB values 0, 128, and 255.

white                           255     255     255
black                             0       0       0
darkgray                        128     128     128
red                             255       0       0
darkred                         128       0       0
darkgreen                         0     128       0
green                             0     255       0
blue                              0       0     255
darkblue                          0       0     128
yellow                          255     255       0
brown                           128     128       0
pink                            255       0     255
darkpink                        128       0     128
cyan                              0     255     255
darkcyan                          0     128     128
lightgray                       192     192     192
 
In LB1.4x, to avoid using these outdated colors, we must specify colors in our own RGB values.  Only a graphics COLOR command makes this possible.

This affects only the drawing and text color of a graphic window or graphicbox.  To "fill" with an RGB color it is necessary to fill the box with a series of lines in the desired color, or to make the SIZE quite large and draw one, large line through the graphicbox.  To use a "backcolor" that is an RGB color, we must draw a set of objects, each smaller than the last.  For curved objects, such as circles, specify a size of at least 2, to insure a solid coverage.  Here are two examples:

'fill with RGB color:
UpperLeftX = 50 : UpperLeftY = 50
WindowWidth = 400 : WindowHeight = 350
 
nomainwin
 
menu #g, &File, "E&xit", [quit]
Open "A Graphics Window" for graphics_nsb_nf as #g
 
print #g, "trapclose [quit]"
print #g, "down"
 
print #g, "size 400; color  250 194 120"
print #g, "line 0 200 400 200"
[loop]
input aVar$
 
[quit]
 close #g : end
 
 
 
 
'circle filled with RGB color:
UpperLeftX = 50 : UpperLeftY = 50 
WindowWidth = 400 : WindowHeight = 350
 
nomainwin
 
menu #g, &File, "E&xit", [quit]
 
Open "A Graphics Window" for graphics_nsb_nf as #g
 
print #g, "trapclose [quit]"
print #g, "down; place 100 100; size 2"
print #g, "color  250 194 120"
 
for i = 50 to 1 step -1
print #g, "circle ";i
next i
 
[loop]
input aVar$
 
[quit]
close #g : end

Liberty BASIC 2 allows us to set colors for a window's background and foreground.  They must be set to one of the LB named colors.  Notice that case matters in the color variables such as, ForegroundColor$ and BackgroundColor$, but not in the color assignments, such as yeLLow or Yellow:

Okay:

ForegroundColor$="yeLLow"
BackgroundColor$="Darkgray"
 
Wrong:
foregroundcolor$="yeLLow"
BACKGROUNDCOLOR$="Darkgray"
 

Colors for controls can also be set:

TextboxColor$="darkcyan"
ListboxColor$="darkpink"
ComboboxColor$="RED"
TexteditorColor$="DARKblue"

Now that we've discussed the method for setting colors in LB2, please consider carefully before making color changes like this.  LB2 colors will default to the user's system color scheme, and in most cases, this will give the most professional (Win95+) look.  Of course, you may change the colors if that is best for your particular application, but keep in mind that you may only choose from those original 16 colors.


A FLOATING TOOLBAR

Windows now provides a floating, dockable toolbar.  This is a toolbar that can be "docked" or affixed to one side or another of the client area of a window, or it can be pulled out to float freely within the client area. Although we could probably simulate the docking feature of a Windows toolbar with Liberty BASIC, it would be fairly complicated.  We can easily simulate a floating toolbar, however.

For the toolbar, simply use a small window:

[makeToolbar] 'setup and open toolbar window
WindowWidth=162 : WindowHeight=50
UpperLeftX=300:UpperLeftY=50
button #2.red,   "Red",  [red],  UL, 2,2,50,16
button #2.green, "Green",[green],UL,52,2,50,16
button #2.blue,  "Blue", [blue], UL,102,2,50,16
open "Toolbar" for dialog_nf as #2

It might take some trial and error to get the sizes and placement correct. This little toolbar has only three buttons, and the toolbar window itself is 162 pixels wide and 50 pixels high.  The buttons are only 50x16.  This is small, but in keeping with the desire to simulate a 32-bit look.  The captions must be in a small font, if they are to fit on the buttons!

'set button fonts:
print #2.red,   "!font ms_sanserif 8"
print #2.green, "!font ms_sanserif 8"
print #2.blue,  "!font ms_sanserif 8"
 

There are two, little tricks that will be necessary to make this example work properly.  The first is to trap the close event of the little toolbar window, so that it doesn't actually close when the user clicks the close button.  We'll be hiding it, instead.  Here is the trapclose command:

print #2, "trapclose [noToolbar]"   'hide window - don't close it

The other trick is to confine the toolbar window within the client area of the program window.  Normally, this window could be dragged by the user into any position on the screen.  We can keep it within the program window's confines by setting its parentage.  Here is the generic code to change the parentage of a window:

calldll #user, "SetParent", _    'a function of user.dll
childHWND as short, _        'this window will be the child
parentHWND as short, _       'this window will be the parent
oldParent as short           'returns the previous parent of the first window

In our example, "h1" is the handle of the program's window, which is to become the parent of the toolbar window.  "h2" is the handle of the toolbar window.

h1=hwnd(#1)
h2=hwnd(#2)
 
'set parentage
open "user.dll" for dll as #user
calldll #user, "SetParent",h2 as short, h1 as short, oldParent as short

Since we will not allow the user to close the toolbar window, we must close it ourselves when the program ends.

[quit]
close #1
close #2
close #user
end
 

We must furnish a way for the user to show or hide the toolbar as he chooses, so we'll include that option in one of the menus:

menu #1, "&File","&Show Toolbar",[toolbar],_
"&Hide Toolbar",[noToolbar],"E&xit",[quit]
 

When the user tries to close the toolbar, we'll capture that action and hide the toolbar from view.  It requires only a simple call to ShowWindow, including the toolbar window handle and the constant for hiding a window, _SW_HIDE:

[noToolbar]
calldll #user, "ShowWindow",_
h2 as word,_
_SW_HIDE as ushort,_
result As word
 
    goto [loop]

The value for the _SW_HIDE constant is actually 0, so 0 can be used as a parameter instead, if you choose.  See Newsletter #57 for more on Windows constants.

[noToolbar]
calldll #user, "ShowWindow",_
h2 as word,_
0 as ushort,_
result As word
    goto [loop]
 

If the user has minimized the toolbar window, it does not minimize to the taskbar as a regular window would.  It actually minimizes within the client area of its parent and it may no longer be visible, since it might hide under other controls while in the minimized state.  If the user has "closed" the toolbar, it is not closed, but hidden.  When the user wants to show the toolbar, we need to check to see whether it has been minimized by the user or "closed" (hidden).  If it has been minimized, a call to IsIconic will yield a result that is nonzero.  If the window has not been minimized, the return from IsIconic is 0:

 
[toolbar] 'show toolbar
calldll #user, "IsIconic",_
h2 AS short,_
RESULT AS short
 
IF RESULT > 0 THEN gosub [IsMinimized] ELSE gosub [NotMinimized]

If the window has been minimized, a call to ShowWindow, with the Show Window flag of _SW_RESTORE will restore the window for viewing:

[IsMinimized]
' If the window is minimized we use this DLL call to bring it back up.
calldll #user,"ShowWindow",_
h2 AS word,_
_SW_RESTORE AS ushort,_
result As word
RETURN

The value for _SW_RESTORE is 9, so that can be used instead:

calldll #user,"ShowWindow",_
h2 AS word,_
9 AS ushort,_
result As word
RETURN
 

If the window was not minimized, then it can be activated with a very simple call to BringWindowToTop:

[NotMinimized]
' If the window is not minimized then this DLL call
' will bring it into view.
calldll #user, "BringWindowToTop",_
    h2 AS word,_
    re AS void
    RETURN

Once the window has either been restored, or brought to the top, it can be shown with a call to ShowWindow, this time with the constant _SW_SHOW:

calldll #user, "ShowWindow",_
        h2 as word,_
        _SW_SHOW as ushort,_
        result As word
        goto [loop]

The value for _SW_SHOW is 5, so that can be used instead:

calldll #user, "ShowWindow",_
        h2 as word,_
        5 as ushort,_
        result As word
        goto [loop]

Okay, that's it.  We now have a floating toolbar that is contained within the client area of the program window, and which the user can hide or show as desired.  All choices offered on the toolbar must also be offered in some other place; usually on a menu.


POPUP MENU

If the window is of type Graphics, or if it contains a graphicbox, a right mouse click can be trapped.  This allows us to show a popup menu in LB2. The graphics window, or graphicbox must have the input focus for this to work, and we need to tell it where to branch when the right mouse button is clicked:

[loop]
print #1.g, "setfocus;when rightButtonDown [popMenu]"
input r$

In LB2, it is quite easy to implement a popup menu.  It will appear at the current mouse location.  Popupmenu syntax:

popupmenu "&Firt Item",[firstBranch],"&Second Item",[secondBranch],_
        ..... "&Last Item",[lastBranch]

As you can see, it is very similar to a regular menu command, but it does not include a menu name as the first parameter, as does a menu command that places a menu on a window.  Here is the popup menu for our demo:

[popMenu]
popupmenu "&Red",[red],"&Green",[green],"&Blue",[blue],_
"&Show Toolbar",[toolbar],"&Hide Toolbar",[noToolbar]
goto [loop]
 

WARNING

Remember that a semicolon is used to separate graphics commands, so that multiple commands can be placed in one print statement:

print #1.g, "down; color yellow; fill black"

There is an exception to this, however.  If graphic text is contained in a print command, all semicolons following the graphic text marker, (either \ or |) will be considered part of the text.  Do not string any other commands after graphic text.  Look at this:

print #1.g, "\Hello; fill green"

The graphicbox will display the following:

Hello; fill green

The graphicbox will NOT be filled with green!

From our demo:

print #1.g, "\Right Click for Menu!" 'can have no further commands on this line
print #1.g, "flush" 'cannot put this on previous line!
 

Here is the full code for the floating toolbar demo:

' The important parts of this code courtesy of
' Michael Rankin and Brent Thorn
' This code is placed in the public domain
' by Alyce Watson awatson@wctc.net
[init]
open "user.dll" for dll as #user
WindowWidth = 600 : WindowHeight = 400
UpperLeftX=50:UpperLeftY=20
 
nomainwin
 
menu #1, "&File","&Show Toolbar",[toolbar],_
"&Hide Toolbar",[noToolbar],"E&xit",[quit]
 
    menu #1, "&Color","&Red",[red],"&Green",[green],"&Blue",[blue]
graphicbox #1.g, -1,-1,800,200
 
    open "Floating Toolbar Demo" for window_nf as #1
h1=hwnd(#1)
print #1, "trapclose [quit]"
print #1.g, "Down;place 20 50;font MS_SANSERIF 8 20"
print #1.g, "\Right Click for Menu!" 'can have no further commands on this line
print #1.g, "flush" 'cannot put this on previous line!
 
gosub [makeToolbar]
[loop]
 
    print #1.g, "setfocus;when rightButtonDown [popMenu]"
 
input r$
 
[quit]
 
close #1:close #user
close #2
end
[popMenu]
        popupmenu "&Red",[red],"&Green",[green],"&Blue",[blue],_
"&Show Toolbar",[toolbar],"&Hide Toolbar",[noToolbar]
    goto [loop]
 
 
[toolbar] 'show toolbar
calldll #user, "IsIconic",_
h2 AS short,_
RESULT AS short
 
IF RESULT > 0 THEN gosub [IsMinimized] ELSE gosub [NotMinimized]
 
calldll #user, "ShowWindow",_
h2 as word,_
_SW_SHOW as ushort,_
result As word
 
        goto [loop]
 
[noToolbar]
    calldll #user, "ShowWindow",_
h2 as word,_
_SW_HIDE as ushort,_
result As word
   
    goto [loop]
 
 
[IsMinimized]
    ' If the window is minimized we use this DLL call to bring it back up.     calldll #user,"ShowWindow",_
h2 AS word,_
_SW_RESTORE AS ushort,_
result As word
 
RETURN
 
[NotMinimized]
' If the window is not minimized then this DLL call
' will bring it into view.
 
    calldll #user, "BringWindowToTop",_
h2 AS word,_
re AS void
    RETURN
 
 
[makeToolbar] 'setup and open toolbar window
WindowWidth=162 : WindowHeight=50
UpperLeftX=300:UpperLeftY=50
button #2.red,   "Red",  [red],  UL, 2,2,50,16
button #2.green, "Green",[green],UL,52,2,50,16
button #2.blue,  "Blue", [blue], UL,102,2,50,16
 
open "Toolbar" for dialog_nf as #2
 
print #2, "trapclose [noToolbar]"   'hide window - don't close it
h2=hwnd(#2)
 
'set button fonts:
 
print #2.red,   "!font ms_sanserif 8"
print #2.green, "!font ms_sanserif 8"
print #2.blue,  "!font ms_sanserif 8"
 
'set parentage
 
calldll #user, "SetParent",h2 as short, h1 as short,oldParent as short
 
RETURN
 
[red]
print #1.g, "cls;down;fill red;flush"
goto [loop]
 
[green]
print #1.g, "cls;down;fill green;flush"
goto [loop]
 
[blue]
print #1.g, "cls;down;fill blue;flush"
goto [loop]
   
 

Comments, requests or corrections: Hit 'REPLY' now! Dean Hodgson -- mailto:Hodgson.Dean@saugov.sa.gov.au Alyce Watson -- mailto:awatson@wctc.net