Liberty Basic is develeopped by Carl Gundel Original Newsletter compiled by Alyce Watson and Brosco Translation to HTML: Raymond Roumeas
In this issue:
Thanks, Doyle. This is a terrific, helpful article!
Contact Doyle: mechani-@sonet.net
In future issues:
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:
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.
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.
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]
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
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!"
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!
Comments, requests or corrections: Hit 'REPLY' now!
mailto:brosc-@orac.net.au
or
mailto:awatso-@mail.wctc.net