By Christopher Charabaruk <firstname.lastname@example.org>
Everyone knows that you can't end a QB program with an errorlevel. Everyone knows that you can't use long file names in QuickBasic. Yeah, and everyone knows that the moon is really made of blue cheese. In other words, you can use errorlevels and long file names - there's just some tricks involved. In this article, I will show you how to pull off these amazing stunts, and I'm throwing in a few others, too. Bon appitit!
Errorlevels are nifty things. You can use them in your programs to let users know if there's a problem (using ON ERROR and exiting using ERR), or making programs that exit to run other programs and then return by batch file (like the Arachne browser for Dos). To be able to use errorlevels, you will need to use a library. I'm sure that you won't be able to run your program in the IDE if you're using errorlevels, but if you find a way, don't hesitate to tell me.
Start up QB and open your program. Now, right by the top, add the line
DECLARE SUB ExitWithErrorLevel ALIAS "_exit" (BYVAL Level%)
to be able to use errorlevels. You should all be aquainted with DECLARE SUB, but what are ALIAS and BYVAL, you might ask? Well, ALIAS means that when you call ExitWithErrorLevel, you're actually calling the _exit routine in the library. If you've made a library in C with overloaded functions, then ALIAS is what you use so that people using the library in QB can still use the overloaded functions (by giving each copy of the function a different name).
BYVAL passes the value of a variable, instead of a reference to the variable, to a function. That way, the function is unable to change the contents of the variable. Usually, when you call a SUB or FUNCTION, the variables passed are passed by reference (similar to passing a pointer, but still way different). That way, the SUB or FUNCTION has the ability to change the contents of the variable. Passing by value, means that the actual value of the variable is passed, so that the SUB or FUNCTION cannot change the value of the variable.
So, getting back to using errorlevels... To exit and pass an error code, use code like this:
Level% = 3 ' use any error level here ExitWithErrorLevel (Level%)
For reasons that elude me, you must put the errorlevel in a variable before calling ExitWithErrorLevel. I believe that it has something to do with BYVAL. Now, for some practical examples of using errorlevels. This first one lets you exit with an errorcode whenever the program has an error which cannot be trapped.
ON ERROR GOTO TrapError ' Code goes here TrapError: Level% = ERR SELECT CASE Level% ' Error traps go here CASE ELSE PRINT "ERROR: Fatal untrapped error " + Level% ExitWithErrorLevel(Level%) END SELECT
The second example is for use in a batch file. It checks if the errorlevel is 128, and if so, pipes the dir output into a file called tempfile.tmp and goes to label runagain (not included).
if errorlevel 128 goto getdir goto end getdir: del tempfile.tmp dir >> tempfile.tmp goto runagain end: echo .
So now you can use errorlevels in your programs! Thanks to Robert Fortune <email@example.com> for helping me work this all out.
Using long file names in QB means that you have to use the MbLfn library by Hans Lunsing <firstname.lastname@example.org>. Don't worry, this library is very easy to use. It even includes an example file (so I won't be showing examples here). It's included as mblfn.zip in the downloadable edition of this issue.
To begin using long file names in your program, include the mblfn.bi file, and call the EnableLfn% function. If the library can use long file names, this function returns TRUE, but if it doesn't, FALSE will be returned. Keep in mind those are constants, not strings. To terminate long file name service, call DisableLfn. It's called automatically at the end of your program, so you shouldn't have to worry about it.
If EnableLfn% did return TRUE, that means that the QB commands CHDIR, MKDIR, and RMDIR will support long file names without any problems. However, with OPEN, BLOAD, and BSAVE, long file names will be capitalized and truncated. As we all know, that's a bad thing, so the library includes the Lfn$ function. Just pass the long file name to Lfn$ function, and have it return the DOS filename to those three troublemakers. And you can even use Lfn$ with short file names, and when long file names aren't supported!
Some other QB commands don't support long file names, and so there are other routines to replace them. There are even extras (like long file name versions of CURDIR$ and DIR$ from PDS and VBDOS, and stuff replacing MS-DOS' ATTRIB.EXE). This chart shows the originals, and their long file name counterparts:
|CURDIR$||LfnCurDir$||returns current path for drive drive$ (if drive$ not specified, current drive)|
|returns filenames matching filespec$ (wildcards allowed)|
|n/a||LfnGetAttrib%||for getting file attributes|
|n/a||LfnSetAttrib||for setting file attributes|
You should all know how to use FILES, KILL, and NAME, and using their replacements is almost the same. The remainder of MbLfn I won't explain, there's just too much for a beginner's primer on QB with Lfn. Read the MbLfn manual for all the other details and everything.
Finally, if errors occur, you must check for yourself by using DOSErr or DOSErrTest. They both return the DOS error code (see Appendix A of the MbLfn manual), but DOSErrTest resets it to zero afterwards. It would be nice if MbLfn would just do errors in a way that lets you handle them like any normal ones in QB, but because of oversights in Redmond when making QB, only libraries actually written in QB can do that.
Now that you can use long file names, get rid of wierd unreadable file names in your games, utilities, and libraries!
Some people just don't like having to install the QB programs they download in a certain place. But if you know how to code, you can make it so that your programs can exist in any directory. Still, there's times that you should know what directory your program is in, and occasionally, even the program's name. By using the greatest of DOS interrupts, that's all a piece of cake.
The pathname.bas file included in the downloadable edition of this issue, written by Christy Gemmell (e-mail unknown), is all you need. Regardless of it saying VBDOS, pathname.bas will also work for QB and PDS without any modification. The PathName$ function in the file accepts one string variable, which is where the function places the filename of the program calling the function, and returns the path of that program.
Now, that wasn't so painful, was it? Well, don't figure on that being the end of tips, tricks, or code snippets! Issue #9 will see the return of QB Tricks and Tips to QB Cult Magazine! So send in your fasthacks, your workarounds, and anything else that's small and really useful to the whole community. Remember, we're here for the QB coders, by the QB coders.