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

The Liberty Basic Newsletter - Issue #51 - OCT 99

© 1999, Cliff Bros and Alyce Watson All Rights Reserved

In this issue:

  1. Liberty BASIC Message Boxes
  2. Message Box Tutorial - by Larry Dunham
  3. Borland Message Boxes


Liberty BASIC Message Boxes

Liberty BASIC has two built-in message boxes, that are very easy to use; NOTICE and CONFIRM.

NOTICE is used when you need to give the user a small amount of information, such as error messages, or copyright information.

The notice command displays a dialog box containing the string expression you desire, and an OK button which the user activates by clicking with the mouse after the message is read. Pressing ENTER also closes the notice dialog box.

The basic form for NOTICE generates a message box containing an exclamation icon, the text string you place in the command, and a titlebar caption that says "Notice." Here is the format:

notice "This program (c) Side by Side Software, 1999"

The other form for NOTICE generates a message box that also contains the exclamation icon and the text string you place in the command. Additionally, it contains the caption on the titlebar which you specify. You specify a caption by placing it as the first part of the string expression, then including the ascii character for a carriage return, which is chr$(13) then specifying the text string for the actual message. You must place the chr$(13) outside of the double quote marks that enclose the caption string and the message string. This is done by concatenating (adding together) the strings using a simple plus (+) sign. Format:

notice "Error!" + chr$(13) + "Number too large!"

Any additional carriage returns will force carriage returns (line breaks) into the message itself. You might want to do this so that line breaks occur at logical breaks in the message contents. For instance:

notice "Hello!" _
+ chr$(13) + "Side by Side Software" _
+ chr$(13) + "Brosco - brosc-@orac.net.au" _
+ chr$(13) + "Alyce - awatso-@wctc.net"

CONFIRM is used when you need to get a yes/no decision from the user. The format for the command includes the text string for the message that will be displayed on the dialog box, then a semicolon (;) and a receiver variable, which will be filled with the response corresponding to the button pushed by the user.

CONFIRM "Do you wish to save your work?"; answer$

The CONFIRM message box contains two buttons, "Yes" and "No." If the user clicks on the "Yes" button, the receiver variable will contain the string "yes" This button is also activated if the user presses the ENTER key on the keyboard. If the user clicks on the "No" button, the receiver variable will contain the string "no" You cannot change the caption on the titlebar of a CONFIRM message box. It will always be "Please Confirm."

Usage:

 
[quit]
' confirm that the user wants to quit:
CONFIRM "Are you sure you want to QUIT?"; answer$
if answer$ = "no" then [inputLoop]
 
close #main : end


Although Liberty BASIC Message boxes are easy to use, they do not allow as many options as Windows message boxes created with API calls. Larry Dunham has written a comprehensive tutorial on the use of Windows message boxes. Thanks Larry, for a great article! This one should be of interest to everybody.


Message Box Tutorial

by Larry Dunham - mailto:ldunham50-@aol.com

Copyright © 1999 Dunham Business Systems

 

One of the things I strive for in writing Liberty Basic programs is to keep the user interface as standard as I can, so that the user has as little "figuring out" to do as possible.

Perhaps one of the most common user actions is responding to a message box. You could create new message boxes from scratch for each message that the user needs to respond to, but Windows already has this feature built into it, so why re-invent the wheel? Using the Windows message box function not only saves the programmer a lot of custom coding, it gives a more polished, professional look to the user interface.

Calling Windows message boxes from your application requires setting just four components:

When the box appears, the user clicks a button and a "RESULT" is returned that tells your program which button was clicked. In turn, the "RESULT" can be tied to [branch] labels in your program to perform an action corresponding to the user response.

Let us say we want to notify the user that a file has been updated successfully. Here is code we might use:

'*************** BEGIN PROGRAM ******************
'IF YOU WISH TO COPY THIS CODE INTO YOUR PROGRAM,
'COPY ONLY THE SNIPPET PART -- OTHER LINES ARE
'INCLUDED SOLELY TO MAKE THIS A COMPLETE EXECUTABLE
'CODE SAMPLE...
 
nomainwin
OPEN "My Program" for window as #main
 
'*************** BEGIN SNIPPET ******************
Open "user" for dll as #user
h=hwnd(#main)
wtype = _MB_ICONASTERISK or _MB_OK
message$ = "The file has been updated."
title$ = "Operation Successful"
sound = _MB_ICONASTERISK
calldll #user, "MessageBeep", _
sound as word, _
result as void
calldll #user, "Messagebox", _
h as word, _
message$ as ptr, _
title$ as ptr, _
wtype as word, _
RESULT as short
if RESULT=1 then close #user
'**************** END SNIPPET *****************
 
close #main
'**************** END PROGRAM *******************

 

-- SETTING UP THE WINDOW --

In the example above, there is a line that reads:

wtype = _MB_ICONASTERISK or _MB_OK

This designates a box with the "Information" icon and an "OK" button. There are six different types of message boxes that can be called, and four different icons that can be used. These are selected by simply inserting the proper designation in the "wtype" line, using the format

wtype = <icon type> or <box type>

The icons to choose from are:

_MB_ICONASTERISK (can access same icon with _MB_ICONINFORMATION) (lower case "i" )

_MB_ICONEXCLAMATION (exclamation point)

_MB_ICONHAND (can access same icon with_MB_ICONSTOP) (stop sign [Win3.1] or circle with X [Win95/98])

_MB_ICONQUESTION (question mark)

The box type designations (describing the buttons to appear) are:

_MB_OK

_MB_OKCANCEL

_MB_YESNO

_MB_YESNOCANCEL

_MB_RETRYCANCEL

_MB_ABORTRETRYIGNORE

 

-- SOUNDING OFF --

The sound played as the message box appears is also selectable. In your Windows Control Panel, sounds (.wav files) can be designated to play in the event of certain occurences. The message box routine can access five different Windows-defined sounds, and selects the sound with the line:

sound = <sound type>

The choices are:

sound = _MB_ICONASTERISK (Plays .wav file for Windows Asterisk event)
sound = _MB_ICONEXCLAMATION (Plays .wav file for Windows Exclamation event)
sound = _MB_ICONQUESTION (Plays .wav file for Windows Question event)
sound = _MB_ICONHAND (Plays .wav file for Windows Critical Stop event)
sound = _MB_OK (Plays .wav file for Windows default sound)

Typically you would select the sound matching the icon you chose in the wtype line, but for a simple OK box you might choose _MB_OK.

In the above example, "h" is set equal to the handle of the window or dialog box controlling the action. If you opened the window as #main, then hwnd(#main) is the Windows internal designation for that window. Likewise, if you opened the window or dialog box as #comm, then you would set h equal to hwnd(#comm). When calling a message box from a dialog box, use the handle of the dialog box in the hwnd() parameter--do not use the handle of a control contained in that dialog box.

 

The string "message$" contains the main text of the message box, while "title$" contains the words that are to appear in the message box's title bar.

-- GETTING RESULTS --

OK--you've commanded Windows to create your message box, it sat on the screen, big as life, and the user clicked a button--now what? Once a button was clicked, the variable "RESULT" was invested with a value indicating which button was clicked. The possible values held by RESULT are below:

If OK was clicked, RESULT will always equal 1

If Cancel was clicked, RESULT will always equal 2

If Abort was clicked, RESULT will always equal 3

If Retry was clicked, RESULT will always equal 4

If Ignore was clicked, RESULT will always equal 5

If Yes was clicked, RESULT will always equal 6

If No was clicked, RESULT will always equal 7

From there it becomes a simple matter to direct the program flow to a branch label based on the value of RESULT. The last line of the snippet above is:

 if RESULT=1 then close #user

This message handler can be used for directing program flow with a simple addendum, like so:

if RESULT=1 then close #user : goto [branchlabel]

Let's say we have tax program with a YES/NO/CANCEL routine that says "Calculating Federal Tax....Calculate State Tax also?" The message handlers could read:

if RESULT=6 then close #user : phrase$="Fed / State taxes.": goto [showresult]
if RESULT=7 then close #user : phrase$="Federal taxes only.": goto
[showresult]
if RESULT=2 then close #user : phrase$="Calculation Cancelled.": goto
[showresult]

A complete routine might be:

 
'*************** BEGIN PROGRAM ******************
'IF YOU WISH TO COPY THIS CODE INTO YOUR PROGRAM,
'COPY ONLY THE SNIPPET PART -- OTHER LINES ARE
'INCLUDED SOLELY TO MAKE THIS A COMPLETE EXECUTABLE
'CODE SAMPLE...
 
nomainwin
OPEN "My Program" for window as #main
 
'*************** BEGIN SNIPPET ******************
Open "user" for dll as #user
h=hwnd(#main)
wtype = _MB_ICONQUESTION or _MB_YESNOCANCEL
message$ = "Calculating Federal Tax....Calculate State Tax also?"
title$ = "Tax Calculation"
sound = _MB_ICONQUESTION
calldll #user, "MessageBeep", _
sound as word, _
result as void
calldll #user, "Messagebox", _
h as word, _
message$ as ptr, _
title$ as ptr, _
wtype as word, _
RESULT as short
if RESULT=6 then close #user : phrase$="Fed / State taxes.": goto [showresult]
if RESULT=7 then close #user : phrase$="Federal taxes only.": goto
[showresult]
if RESULT=2 then close #user : phrase$="Calculation Cancelled.": goto
[showresult]
'**************** END SNIPPET *****************
 
[showresult]
Open "user" for dll as #user
h=hwnd(#main)
wtype = _MB_ICONASTERISK or _MB_OK
message$ = phrase$
title$ = "Result"
sound = _MB_OK
calldll #user, "MessageBeep", _
sound as word, _
result as void
calldll #user, "Messagebox", _
h as word, _
message$ as ptr, _
title$ as ptr, _
wtype as word, _
RESULT as short
if RESULT=1 then close #user
 
close #main
end
 
'**************** END PROGRAM *******************

--- A LA MODAL ---

Here's another little tidbit that might come in handy sometime. Windows message boxes have one of three possible modal states. A modal message (or dialog) box is one that requires the box be acknowledged before continuing; it disables something until you do. By default, Windows message boxes are Application Modal--that is, you can switch to other Windows programs or open new ones, but you cannot continue in the application which called the message box until you click one of the buttons.

A message box can also be Task Modal, which is just like Application Modal in that it does not affect other Windows programs, it only disables access to the calling function.

The Task Modal box, however, can be used without a window handle to attach it to. That is, it can be called from applications or libraries which do not themselves have window handles, and thus the hwnd parameter is NULL. (editor's note: NULL is passed as 0 in Liberty BASIC API calls.)

The third modal state is System Modal. A message box so defined actually suspends access to ALL Windows functions until the box is acknowledged. When a System Modal message box appears, you won't be able to switch to another application, minimize or resize a window, or even access the Win 95 start button. For this reason, System Modal message boxes should be reserved for urgent error messages affecting the integrity of the system, like running out of memory.

Defining them is simple. If you want a message box to be Application Modal, do nothing except call the message box as demonstrated above. The other two types are created by "OR-ing" the parameter with the "wtype" line in the DLL call, like so:

wtype = _MB_ICONASTERISK or _MB_OK or _MB_SYSTEMMODAL

The modal state parameters are:

_MB_APPLMODAL (If you feel you must define it--it's the default anyway)

_MB_TASKMODAL

_MB_SYSTEMMODAL

Calling the _MB_SYSTEMMODAL parameter with a _MB_ICONHAND type box is a last-resort usage since Windows will always force such a message box to be displayed, no matter how low memory resources are. The message and title strings for these special message boxes should be hard-coded, and not reside in a resource file, since the attempt to load them may fail if system resources are low. Also, the message text will be limited to three lines, and will not wordwrap, so you will need to insert carriage returns in the message string where line breaks are desired. (editor's note: Liberty BASIC does not make use of resource files.)

-- HOT BUTTONS --

Finally, there's a little matter of default buttons. The default button in a message box is the one that "presses itself" when you press the <ENTER> key. You'll recognize it visually by a dotted line around the button label. Unless otherwise defined, The first button in a box is always the default. In a YES/NO box, it's the YES button --in ABORT/RETRY/IGNORE, it's the ABORT button.

It may be however, that the function of the message box makes the first button undesirable as a default, in case <Enter> was inadvertantly pressed. (Consider a message box reading "Are you certain you wish to format your hard drive?" Would you want "Yes" to execute if you accidently bumped the <Enter> key?)

To set a default button, the parameters are:

_MB_DEFBUTTON1 (First button - Default setting if no parameter specified)

_MB_DEFBUTTON2 (Second button)

_MB_DEFBUTTON3 (Third button)

just "OR" the parameter on the "wtype", as in:

 wtype = _MB_ICONQUESTION or _MB_YESNOCANCEL or _MB_DEFBUTTON2

(Sets second button as default)

In any message box containing a Cancel button, the <Esc> key always executes the Cancel function, no matter which button is set as the default.

In coding these boxes, rather than having umpteen message box calls, you may wish to set each of the different box types you plan to use as subroutines, and call them as you need them, just changing the title and message text strings before calling them.

Hopefully, this little introduction to Windows message boxes will help you add a more professional touch to your user interfaces--have fun!

Larry Dunham

Dunham Business Systems


Borland Message Boxes

Borland has a message box that we may use, just as we may use the Windows message boxes. Most systems already have a copy of the Borland DLL that accomplishes this. We will include it with the newsletter for those who do not have it. Place it in the same directory as the program that will utilize it, or place it in your Windows\System directory. It functions exactly as the Windows message boxes that Larry has described. It has a different look, and that is the only reason to use the Borland DLL message boxes. They are more colorful.

open "Test" for window as #main
h=hwnd(#main)
wtype = _MB_ICONEXCLAMATION or _MB_YESNOCANCEL or _MB_DEFBUTTON2
message$ = "This looks different!"
title$ = "A Borland Message Box"
 
playwave "augah.wav", async
 
open "bwcc.dll" for dll as #bwcc
calldll #bwcc, "bwccMessageBox", _
h as word, _
message$ as ptr, _
title$ as ptr, _
wtype as word, _
RESULT as short
close #bwcc
close #main

The RESULT codes are the same as the Windows message box results, as listed above. You must still use the Windows MessageBeep function to play a sound. You may instead play a wav that you have included with your program files. Play it asynchronously, so that the message box will appear immediately. A wav played synchronously will halt program execution until it if finished. Augah.wav is also included in the attached ZIP file.


Newsletter compiled and edited by: Brosco and Alyce.

Comments, requests or corrections: Hit 'REPLY' now!

mailto:brosc-@orac.net.au or mailto:awatso-@mail.wctc.net