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 #42 - JUN 99

"Knowledge is a gift we receive from others." - Michael T. Rankin

In this issue:

  1. Programmer's Spotlight on Doyle Whisenant.
  2. Doyle Whisenant, in his own words.
  3. Practical Uses for API's in Liberty BASIC by Doyle Whisenant

Thanks, Doyle. This is a terrific, helpful article!

Contact Doyle: mechani-@sonet.net

In future issues:


Programmer's Spotlight on Doyle Whisenant

If you have read the LB message boards or mailing lists, then you are already acquainted with Doyle. He's the one who is always willing to help out, answer questions, and make interesting comments. He's also the one who ALWAYS says, "Thanks!" Brosco and Alyce want to take this opportunity to say to Doyle, "THANK YOU ! ! ! !"

If you have surfed around the LB websites, then you also know Doyle as "The API Guy." His website, MeKanixx Designs, has all of the API calls that have been translated into LB, with explanations and sample programs. There are plenty of other goodies there, too, (including Doyle's update to FreeForm) so drop by soon at:

http://mechanic.webjump.com


Doyle Whisenant in his own words:

I have been married for 23 years and have 3 wonderful girls. Two are married and the youngest is almost out of school. My main interests are electronics and programming. I have been interested in programming of some type for 20+ years. In obtaining an Associates Degree in Electronics, I learned some machine programming on Motorola's microcontroller uc6809 (anyone remember the Heath Hero robots?) and some ladder logic as used on Allan Bradley and GE PLC's (Programmable Logic Controllers, a type of industrial computer). I had a little assembly programming thrown in for good measure.

I started programming in Basic 15-20 years ago. I have programmed basic in the following dialects: TI99-4A, Commodore 64, Commodore Vic 20, Timex Sinclair, IBM (Basica), GwBasic, Qbasic, and now Liberty Basic.

Of all of these different basic's, Liberty Basic has got to be my favorite. Carl Gundel has done a wonderful job making Liberty Basic so easy and fun to use.


Practical uses for API's in Liberty Basic by Doyle Whisenant, (c)1999

Carl Gundel did a wonderful job when he created Liberty Basic. If you have a chance, look at a Windows program written in C; hundreds, sometimes thousands, of lines of code to do even the simplest functions which are a snap in Liberty Basic. Liberty Basic hides most of these lines of code from the programmer by handling the gory details for you. Even so, sometimes the programmer needs to use an API function that is not included in Liberty Basic.

Carl has made it possible to call almost all of the API functions which Windows provides for your use.

Example #1: GetVersion

When writing an application in Liberty Basic, the programmer doesn't know if the user is running Windows 3.1/3.11 or Windows 95/98. For most applications this is unimportant. It makes no difference in how the program runs for the user.

Sometimes though, the program uses API or DLL calls which only function correctly on a 32 bit system. In a professional program it would be better for the programmer to check for the version of Windows that is on the user's computer and write the program accordingly.

For instance if the user is running Windows 3.1, textbox height minimum is 24 pixels. If the programmer creates a GUI (Graphical User Interface) that has a smaller textbox height for aesthetic reasons and uses a height smaller than 24 pixels, it won't run under Windows 3.1. I have seen this several times in programs written by people on the mailing lists. Sometimes I have downloaded a *.tkn file in which the programmer has used a height of less than 24 pixels for the textbox height. Some great programs I'm sure - but users running Windows 3.1 will not be able to use them.

How do I write a program and still make sure that both Windows 3.1 and Windows 95/98 users can run the program without problems? Consider the following code:

'top of program
open "Kernel.dll" for dll as #Kernel
calldll #Kernel, "GetVersion", result as long
close #Kernel
 
'calculate the version of Windows running on the users system
ver = result and hexdec("&HFFFF")
Lowbyte$ = Str$(ver And hexdec("&HFF"))
Highbyte$ = Trim$(Str$((ver And hexdec("&HFF00")) / 256))
win.version$ = Lowbyte$ + "." + Highbyte$
 
if val(win.version$) > 3.1 then
gosub [doWin95Setup]
else
gosub [doWin31Setup]
end if
'the rest of the program code goes here
 
open "My Wonderful Program" for graphics as #1
etc., etc,
 
Later in the program:
 
[doWin95Setup]
'do GUI setup for Win95/98 here
TEXTBOX #main.tb, xpos, ypos, 100, 20
'other Win95 specific control code here
return
 
[doWin31Setup]
'do GUI setup for Win31 here
TEXTBOX #main.tb, xpos, ypos, 100, 24
'other Win31 specific code here
return

Of course this means more work for the programmer, doing two different GUI designs is not going to be easy but this would be a more professional program. This is only one example of how you can cater to the users and their version of Windows. I'm sure that you can think of many more occasions where knowing the Windows version can improve your code.

If the programmer wants to really make sure his or her program will run for everyone, then he/she should consider doing something like the following at the start of the program:

dw = DisplayWidth
dh = DisplayHeight
 
if dw > 640 and dh > 480 then goto [checkFor800] '800x600 or larger
'do 640x480 display setup
'set up different fonts, etc
goto [start]
end if
 
[checkFor800]
if dw > 800 and dh > 600 then 'must be larger so do 1024x768
'do 1024x768 display setup
else 'nope got to be 800x600
'do 800x600 display setup
end if
 
[start]

Example #2: SetWindowText

This call uses the SetWindowText API call to change the titlebar of your window to reflect the file name, add your program version info, etc. Liberty Basic now has the new command - TitleBar - which will do the same thing but it only works for the main window. If you want to change the caption on any other window type you must use this call to do so. Thanks to Tom Record because his code is where I picked up this little gem.

Please note that the "GetParent" handle is required only for graphic and text windows. The call won't work for dialog and window type windows. For the latter two window types, use the normal hwnd (hg below) handle for the call to work.

open "" for graphics as #graphics
'use GetParent for win handle for graphics, text types
hg = hwnd(#graphics)
open "USER" for dll as #user
CallDLL #user, "GetParent", _
hg AS word, _ 'handle of graphics window
hParent AS word 'return is handle of Parent window
 
calldll #user, "SetWindowText", _
hParent as word, _ 'use Parent window handle here only for
graphics, text types
"Title was changed!" as ptr, _ 'use normal window handle for
dialog, window types
result as void
close #user

Example #3: GetModuleHandle

Have you ever wanted to run another program such as notepad using code from your Liberty Basic application? This is easy, just use "run notepad.exe". You probably need to know when the user has finished using notepad in order for your program to continue. How do you accomplish this?

Well the designers of the Windows API thought of this and included the call "GetModuleHandle". Note how easy it is to tell if notepad is running. Of course you may have to supply the full path to the application that is being checked.

'result=0 when the file is closed
'result>0 when the file is open
 
open "kernel.dll" for dll as #kernel
 
calldll #kernel, "GetModuleHandle", _
"notepad.exe" as ptr, _
result as short
 
close #kernel
If result=0 then print "File is not open"
if result>0 then print "File is open already!"

Example #4: ShellExecute

What do you do when you want to run a file on the user's computer but you don't have the faintest clue of the path to the user's application? Also, maybe the user has a different program to use for that particular file type. Since there are literally dozens of applications that can run the same file types, how do you know what application the user has associated with the file type you want to run?

The following call takes care of opening your file on the user's system no matter what application the user has associated with the particular file type. An example is shown below that uses a bmp file opened in the user's associated application.

lpszOp$ = "open" + chr$(0) 'Open or Print
lpszFile$ = "carl.bmp" + chr$(0) 'file name
lpszParams$="" + chr$(0) 'used only for *.exe type files
lpszDir$ = "c:\lb14w\" + chr$(0) 'your application file folder
 
open "shell" for dll as #shell
calldll #shell, "ShellExecute", _
hDeskTop as word, _ ' the hwnd of the parent form.
lpszOp$ as ptr,_ ' open or print
lpszFile$ as ptr,_ ' file to open or print
lpszParams$ as ptr, _ ' no parameters
lpszDir$ as ptr, _ ' default directory
_SW_SHOWNORMAL as short, _ ' API parameters i.e. _SW_SHOWNORMAL,
result as word ' _SW_HIDE or _SW_SHOWMINNOACTIVE etc
close #shell

Below is a list of the values that you can specify in the Shellexecute call above. They are listed in the correct liberty Basic format.

Value Meaning

_SW_HIDE Hides the window and activates another window.

_SW_MAXIMIZE Maximizes the specified window.

_SW_MINIMIZE Minimizes the specified window and activates the next top-level window in the Z order.

_SW_RESTORE Activates and displays the window. If the window is minimized or maximized, Windows restores it to its original size and position. An application should specify this flag when restoring a minimized window.

_SW_SHOW Activates the window and displays it in its current size and position.

_SW_SHOWDEFAULT Sets the show state based on the SW_ flag specified in the STARTUPINFO structure passed to the CreateProcess function by the program that started the application. An application should call ShowWindow with this flag to set the initial show state of its main window.

_SW_SHOWMAXIMIZED Activates the window and displays it as a maximized window.

_SW_SHOWMINIMIZED Activates the window and displays it as a minimized window.

_SW_SHOWMINNOACTIVE Displays the window as a minimized window.

The active window remains active.

_SW_SHOWNA Displays the window in its current state. The active window remains active.

_SW_SHOWNOACTIVATE Displays a window in its most recent size and position. The active window remains active.

_SW_SHOWNORMAL Activates and displays a window. If the window is minimized or maximized, Windows restores it to its original size and position. An application should specify this flag when displaying the window for the first time.

Well that's about all for now. What other API calls would you like to see in the newsletter? I certainly am not the best qualified to write about this subject but if there is enough interest, I might be persuaded to give it a try.

Thanks for reading!


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