Using DLLs and
The Windows API
API Wrappers and
Custom Controls
An alternative to diving around in the
API is to look for a custom control that
does what you want to do. Many custom
controls (OCXs or ActiveX controls) are
themselves a wrapper around a particular
bit of the API, which deliver that
functionality to your program in a
VB-style, user-friendly manner.
Having said that, more and more
ActiveX controls go much further than
this, like for example a mapping control.
These can really extend the feature set
of your applications, without requiring
huge programming effort on your behalf. I
can tell you now that there's no
DrawAmerica function call in the API, no
matter how hard you look.
ActiveX Controls and OLE Automation
Servers (collectively ActiveX Components)
actually represent the most useable way
to distribute code in an API-like format
between projects, without having to go to
all the hassle of dropping into a
compiler and writing a true DLL. We cover
them in a little more detail, and discuss
how to create your own, in the next
chapter.
Another approach is to enclose some
API calls into a Visual Basic class
module of your own, which brings the
power of the API into a VB object. We'll
have a look at doing this ourselves later
in this chapter.
Finding and
Using API Calls
We said that Windows has a lot of DLLs
in itsome large, some small.
There's no point in trying to take all
these in at one go, let alone all of the
1000+ calls they contain. The best
strategy for working with the API is to
get to know a few common API calls and
then fan out your knowledge from there.
In this chapter, we'll look at a couple
of API calls, and leave you to find out
more at your own speed. Often magazines
publish these-there are a few listed in
the VB Help file, and there are some very
good reference books available which list
the majority of them.
The Text API
Viewer
Depending on which version of Visual
Basic 5 you've splashed out all your
hard-earned cash on, you may find that it
includes a useful utility to help you
find the correct declarations for API
routines. What the Text API Viewer
doesn't do, however, is give you any real
help as to what the routine does, exactly
what values it expects, and what values
it returns. You'll need to buy a
reference book to learn more.
Still, it can help to get the
declarations correct, and find our the
types and constants it requires. It can
even copy them to the clipboard, so you
can paste them directly into your code.
Some Windows
DLLs
If it helps, think of each API call as
a subroutine or function. Given the
number of API calls that make up Windows,
Microsoft wisely decided to group them
together into four main libraries.
KERNEL32
The main DLL, Kernel32, handles memory
management, multitasking of the programs
that are running, and most other
functions which directly affect how
Windows actually runs.
USER32
Windows management library. Contains
functions which deal with menus, timers,
communications, files and many other
non-display areas of Windows.
GDI32
Graphics Device Interface. Provides
the functions necessary to draw things on
the screen, as well as checking which
areas of forms need to be redrawn.
WINMM
Provides multimedia functions for
dealing with sound, music, real-time
video, sampling and more. This is a
32-bit only DLL. The 16 bit equivalent is
called MMSYSTEM.
You can see these files in your
Windows\System directory. There are also
many other smaller, less frequently used
DLLs which provide specialist services to
applications.
Those listed above are the 32-bit DLL
names. If you have been reading this so
far with the idea that you are going to
support the millions of 16-bit Windows
users out there with your application,
then I'm afraid I have some bad news for
you.In the past, Microsoft have always
released a version of Visual Basic that's
useable on 16-bit Windows platforms, such
as Windows for Workgroups, or Windows
3.1. However, Visual Basic 5 is the first
ever 32-bit-only version of VB, with
Visual Basic 4 being the last incarnation
of a 16-bit development tool from
Microsoft.
Having done our homework, now comes
the fun part. We're going to check out
some common API calls and, along the way,
make sure we know everything we need to
know about using the API in general.
After that, it's up to you to explore
away.
Calling API
Routines
Calling a procedure in the API is
really no different to calling a function
or subroutine that you've written
yourself and added to a module in your
project. For example, if you have this
piece of code:
Public Sub FindText(objDataControl As
Control, sFieldName As String)
' Code to implement function does
here.
End Sub
To invoke the procedure, you could use
this code:
FindText datTitles, "Titles"
Let's apply the same logic to an API
call, which is a subprocedure that isn't
only outside our current module, but also
outside VB.
A Quick Look at Declaring an API Call
Before a DLL routine can be used, it
needs to be declared. Visual Basic needs
to be told:
The name of the subroutine or function
Which DLL file it can be found in
The parameters it expects to receive
The type of value that it can return
if the routine is a function
You still use the word Sub or Function
to start the code off, but it must be
prefixed with the word Declare. Because
we're calling an API function, the code
isn't directly in our VB program after
the declaration, it's off in the DLL we
indicated. Apart from that, the
declaration is the same as for a function
that you wrote yourself.
Once the function is declared, calling
it is straightforward. Let's take a look
at how this works, using a quick example
of an API call.
Try It Out -
Flashing a Window with an API Call
1 Create a new project in Visual
Basic.
2 Draw a timer control on the form and
set the timer Interval property to 10.
This will cause a timer event to occur
every 10 milliseconds.
3 Double-click on the timer control to
display its code window. Then type in
code so that it looks like this:
Private Sub Timer1_Timer()
Dim
nReturnValue As Long
nReturnValue = FlashWindow(Form1.hWnd,
True)
End Sub
4 Now declare the FlashWindow function
in the general declarations section as
follows:
Private Declare Function FlashWindow
Lib "user32" Alias
"FlashWindow" (ByVal hWnd As Long, ByVal bInvert
As Long) As Long
5 Now run the program. When the form
appears, its caption should be flashing.
This is a very simple program, but
flashing the caption of a window using
pure Visual Basic code is extremely
difficult and requires a lot of code-try
it at your own peril!
How It Works -
The API Declaration
The function declaration itself is
fairly straightforward once you
understand its constituent parts. It
helps to have a Windows API reference
manual handy to determine whether the API
call you're about to use is a subroutine
or function, which DLL it's contained in,
and what the parameters to be passed to
it should be.
The word Declare tells Visual Basic
that we're declaring a DLL routine.
Immediately following Declare is the
word Sub or Function, which declares
either a subroutine or a function. Of
course, you can't declare subroutines and
functions indiscriminately.
The Lib keyword tells Visual Basic the
DLL in which the function we want is
contained. In this case, it's the User32
DLL file. Alias tells VB what the actual
name of the function inside the library
is-this could be different for the name
we assign to it before the Lib keyword.
Private Declare Function FlashWindow
Lib "user32" Alias
"FlashWindow" (ByVal hWnd As Long, ByVal bInvert
As Long) As Long
Finally, the parameters which are to
be passed to the function are declared,
along with the type of value that the
function will return.
The parameters we're passing here are:
(ByVal hWnd As Integer, ByVal bInvert
As Integer) As Integer
The first parameter, hWnd, is a handle
that identifies the window we want to
blink. It's important that you understand
the concept of handles in Windows, and
we'll come back to it later. The second
parameter, bInvert, switches the flashing
property on and off. If bInvert is set to
True by the calling statement, then the
bar flashes. To return it to its original
state, you need to call the function
again, with the value False.
In many API routines, the Alias is the
same as the actual routine name, such as
in FlashWindow. In these cases, we can
omit the Alias part altogether, for
example:
Private Declare Function FlashWindow
Lib "user32" (ByVal hWnd As Long, ByVal bInvert
As Long) As Long
However, some have names that are
illegal in VB, such as _lopen, and other
come in different versions-sometimes with
an A or W appended to the name. In
general, it's safer to use the definition
as it is. Some programmers use the Alias
to change the name that the refer to the
routine by, or even to declare two
different versions of a routine which
accept different parameter types-but
we'll steer clear of these techniques for
now.
How It Works -
Calling the API
We called the function in this way:
nReturnValue = FlashWindow(Form1.hWnd,
True)
Once you've declared an API call, it's
used in almost exactly the same way as a
normal call to a Visual Basic function or
subroutine. In the above example, the
FlashWindow call is a call to a function
held in a DLL. Just as with Visual Basic
functions, API functions return values
which must then be stored somewhere. We
store the value that the FlashWindow
function returns in a variable called
nReturnValue.
Again, just as with Visual Basic
functions, you don't have to do anything
with the values returned by API
functions. But you do need to store them
somewhere, even if you intend to ignore
them, by assigning them to a variable.
Almost every API function returns a
numeric error code, which you can use to
see if everything worked correctly.
In fact, ignoring these values is not
only a bit lazy-it can actually be
dangerous if you're using more than one
call in your code. In this
straightforward example, however, it's
fine to just store the return value in a
variable that we never subsequently use.
Using Windows API calls can
potentially crash Windows, if not your
machine. When you come to the more
complex API calls, such as those which
are responsible for allocating vast
amounts of memory and system resources,
woe-betide the programmer who casually
ignores the return code. Since the DLL
functions live outside of your
application they handle all their own
error checking-your only indication that
something might have gone wrong is that
return code. Remember that, and ignore it
at your peril later on!!
Page [<<
PREV] 1
2 3 4
[NEXT
>>]
Back to Tutorials
- Main
|