This is not a tutorial for using API calls! If you want some "how to" information, please refer to these articles in previous issues:
The beginner's guide to API and DLL calls, by Brad Moore - issue #101
Translating 32-bit Visual BASIC API Calls, by Alyce Watson - issue #102
There are some very good reasons to use API calls in your programs. There are also some good reasons to avoid them!
When NOT to use API's
If you can do something using native Liberty BASIC commands, then there is no reason to use API calls. There is a greater possibility of program crashes when you use API calls to do things, so stick with native commands whenever possible.
Don't use API calls if you are not sure what you are doing. You can cause your program to crash and you can even cause your system to become unstable. If you want to use API calls, either use code routines that are tried and true, or do some studying first to make sure you are getting it right.
Liberty BASIC handles quite a lot of the Windows API for you. There are an enormous number of API functions; so many that it would be impossible to include them all as native commands. Even if it were possible, it would add far too much complexity to the language. One of the most charming and useful features of Liberty BASIC is its gentle learning curve and ease of use.
There are some things you simply cannot do with native commands. That's when you turn to the API for help. One such thing involves the groupbox. It doesn't have a command set that allows it to be moved, or to have its caption changed. You can get its handle, though, and use API calls to do these things. In fact, if you look in the LB Helpfile Groupbox topic, you will see the API commands in a sample program!
Having access to the Windows API allows us to do many things that are not available in native commands, or it allows us to do them in a more specialized way. For instance, we can run an external application using the LB "run" command. We can include a filename parameter so that the other application opens with that file loaded, and we can set the "show window" state of the other application. If we use an API call, we can cause the user's default application for the file type in the filename parameter. We can also set the "show window" state, but we can also tell the application to "open" or "print" the file, as desired.
Here is a small demo that causes Notepad to open with a specified file loaded, and to be maximized:
RUN "NOTEPAD NEWFOR302.TXT", SHOWMAXIMIZED
The API version adds some functionality. You can choose to have the file printed or opened. There are some other options as well. Native LB only allows "open." You are also running the user's default text editor, rather than Notepad. With native LB, you must know the name of the application you want to run, and if it isn't in the Windows path, you must include the full path to the executable. The API version of the code above:
lpszOp$ = "open" 'could be "print" lpszFile$ = DefaultDir$ + "/NEWFOR302.TXT" lpszDir$ = DefaultDir$ lpszParams$="" showFlag = _SW_MAXIMIZE CallDLL #shell32, "ShellExecuteA",hWnd As long,_ lpszOp$ As ptr,lpszFile$ As ptr,_ lpszParams$ As ptr,lpszDir$ As ptr,_ showFlag As long, result As long
Note that this is not an API tutorial. These code snippets are presented "as is" for the purpose of illustration only.
Some things you cannot do natively, but can do with API calls:
Here are a few examples of useful API calls.
'relocate and resize: calldll #user32, "MoveWindow", _ hWnd as long, _ 'window or control handle xOrg as long, _ 'new upper left x position yOrg as long, _ 'new upper left y position width as long, _ 'new width height as long, _ 'new height 1 as boolean, _ '1 = repaint window now result as boolean 'nonzero (true) if successful 'set new caption: calldll #user, "SetWindowTextA",_ hWnd as long,_ 'handle of window or control NewText$ as ptr,_ 'new text string result as void 'no return 'enable/disable CallDLL #user32, "EnableWindow",_ hWnd As Long,_ 'handle of window or control enable As Boolean,_ 'Enable=1 Disable=0 result As Boolean
For more on adding functions via the API, see these articles:
The Need for Speed
Liberty BASIC is fast enough for most purposes, especially on today's fast computers. If you need to do a lot of complex calculations quickly, then Liberty BASIC may not provide enough speed. Here is one example:
I wrote some pixel routines in native Liberty BASIC. They read the color values of pixels and changed this values according to different algorithms to produce a variety of visual effects, such as grayscale, blurring, colorizing, etc. In some cases, for each pixel, that pixel and several of its neighbors needed to be read and evaluated before a new value could be set. The routines worked just fine, but some of them took several seconds on a small bitmap, and much longer on a large bitmap. The same routines written in C were accomplished in a fraction of a second. The Liberty BASIC version was fun to play with, but for a real world application, it was too slow. Placing the pixel routines in a DLL written in C gave us the best of both worlds... the speed of C for the computations, and the ease of programming with Liberty BASIC for the GUI.
Any routines that require quite a lot of math processing are candidates for inclusion in a DLL, rather than native LB implementation.
The pixel routines are contained in the DLL reviewed here:
Sometimes the implementation of a particular function is so complex that it is too difficult for the average hobby programmer (like me!) to understand. Even if the programmer understands a complex routine, it may be easy to introduce errors as the routine is implemented in different programs and under different conditions. In this case, a DLL with tested routines allows us to call a function with one line of code, making it much simpler to use and reducing the chance of errors.
One example of this "simplifying" use of API calls can be found in Dennis McKinney's toolbar DLL. We can produce Windows toolbars using Liberty BASIC API calls, but it requires a lot of code. It is much easier to do it if we use the DLL.
Another example is sprites. Prior to LB2, sprites were not a part of native Liberty BASIC. We could do them with a series of API calls, and I did just that. I also published two tutorials that detailed the use of API calls for sprites. Nobody used them! Some people told me that it was just too complicated. I put the routines into a DLL, which made it possible to simplify their use and gave the added bonus of a speed boost. Several people published games and programs that used the sprite DLL. Of course, now sprites are part of native Liberty BASIC, and Carl has made them even easier to use!
This issue includes a demo that places a sprite in a graphicbox. It is a shortcut method and far simpler than the actual method used in Liberty BASIC for sprites, but even so, it will give you some idea of the complexity involved.
Using Third-Party DLL's
Most of the API calls we make are to Windows DLL's that are part of the operating system. Sometimes, though, we find DLL's written by another programmer that we want to use. Some of these DLL's provide database functions, some allow internet access, some do image loading or processing, some provide specialized controls... the list goes on and on.
For some examples, see the following articles: