CALL32nt.pas: Library for Delphi/TPW/BPW to call 32 bit
functions in Windows NT or Windows 95
Adapted to Pascal by Christian Ghisler, CIS: 100332,1175
from CALL32.DLL, a DLL for Visual Basic written and placed
in the Public Domain by Peter Golde.
This unit is placed in the public domain.
Please feel free to redistribute as you wish.
No guarantees are made as to its suitability or
usefulness, and no support can be provided.
CALL32NT.PAS is a Unit that can be used for calling
routines in 32-bit DLLs on the Microsoft(R) Windows NT(TM)
and/or Windows 95(TM) operating system. It cannot be used
on Windows(TM) 3.1, Win32s(TM), or other operating systems.
Using it, a Delphi, Turbo or Borland Pascal program, running
in the Win16 subsystem, can declare and call functions in any
32-bit DLL (including, but not limited to, the system
DLLs).
Directories in ZIP file (unzip with pkunzip -d):
root:
call32nt.pas the unit to call 32 bit functions from
Delphi/TPW/BPW
delphi: sample source of a Delphi program calling 32-bit code
(exe not incuded)
tpw-bpw: sample source and exe of a TPW/BPW wincrt program
calling 32-bit code
longname: some 32-bit functions which use long filenames,
ready to be called
----------------
CALL32nt.pas: Library for Delphi/TPW/BPW to call 32 bit functions
in Windows NT or Windows 95
Adapted to Pascal by Christian Ghisler
from CALL32.DLL, a DLL for Visual Basic
written and placed in the Public Domain by Peter Golde
This unit is placed in the public domain.
Please feel free to redistribute as you wish.
No guarantees are made as to its suitability or
usefulness, and no support can be provided.
To call a function in a 32-bit DLL, follow these steps:
1. Declare the function you wish to call. Declare it
in the ordinary fashion, with the following exceptions:
> Declare it as a function variable
> Add an additional argument at the end, of type Longint:
For example, if you are calling the function: (C code)
GetWindowText(HWND hwnd, LPSTR lpsz, int cch)
declare it as follows (remember that ints and all handles
are 32 bits, so use a Longint):
var GetWindowText:function(hwnd:Longint;lpsz:PChar;
cch:longint;id:Longint):Longint;
2. Each function needs an identifier to distinguish the
function from other called functions. Declare this
identifier in a var block.
For the above example:
var id_GetWindowText:longint;
3. In the initialization section of your application, set the
address of the called function to the address of Call32:
@GetWindowtext:=@Call32;
4. Also in the initialization section of your application,
declare the actual library and name of the function you
want to call with the Declare32 function. Pass it the name
of the function (CASE SENSITIVE!!!), the library name, and
a string describing the argument types.
Each letter in the string declares the type of one argument,
and should be either "i" for a 32-bit integer or handle
type, "p" for any pointer type, or "w" for an HWND parameter
to which you want to pass a 16-bit HWND and have it be
automatically converted to a 32-bit HWND. Save the return
value of Declare32 in a global variable to pass as the last
parameter to the function you declared earlier. So, in
continuing the example, you would call:
id_GetWindowText:=Declare32('GetWindowText','user32','wpi');
(As a side note, this more properly would be declared as
'GetWindowTextA', since this is the real exported name.
However, Declare32 will automatically add an 'A' to the
end of a function name if necessary.)
To call the function, you would call:
cbCopy:=GetWindowText(hwnd, sz, cb, id_GetWindowText);
It is important to use the correct data types when calling
DLL functions. There are two important points to pay
attention to when using CALL32NT.PAS.
First, only 32-bit integers can be passed to a DLL
procedure. Since virtually all 32-bit functions take int,
UINT, LONG, DWORD, or HANDLE parameters, which are all 32
bits, this is not a major restriction. However, you must
remember to always declare function arguments as Longint,
not Integer.
Second, 16-bit handles and 32-bit handles are not
interchangeable. For example, a 16-bit bitmap handle that
you get from calling a 16-bit DLL or from the Delphi/TPW
environment cannot be passed to a 32-bit function
expecting a bitmap handle. Similarly, a 32-bit handle
obtained from a 32-bit function cannot be passed to a 16-
bit DLL. The only exception is window handles (HWND). If
you declare a function parameter with the "w" letter in
the argument description string passed to Declare32, the
corresponding parameter will be automatically converted
from a 16-bit HWND to a 32-bit HWND when the call is made.
You must still declare the argument as a LONG. This is
convenient, for example, when passing the value returned
by the "handle" property of a form/control to a 32-bit DLL
function. Only windows created by your application can be
translated.
The following is a summary of data types:
C data type Type specified in Declare Character for Declare32
int, UINT Longint i
LONG, DWORD Longint i
HANDLE Longint i
WORD, short not supported
HWND Longint w
(i for no 16->32
translation)
LPSTR PChar p
LPLONG, LPDWORD,
LPUINT, int FAR * VAR x:Longint p
LPWORD VAR x:Word p
Note on Declare32 function names: Declare32 will
automatically try three different names for the function
name you pass in. First, it uses the exact name you pass
in. If it doesn't find that function name, it converts the
name to the stdcall decorated name convention by adding an
underscore at the beginning and adding "@nn" at the end,
where "nn" is the number of bytes of arguments. If it
doesn't find that name, it adds an "A" to the end of the
original name to try the Win32(R) ANSI function calling
convention.
If there occurs an error in Declare32, the returned id will
be less than 0. Also, the variable Call32NTError will be set,
so you only have to check one variable to check that all went
well. You can use this variable to distinguish between Windows
3.1 and Windows NT/95: if Call32NTError is false, you can use
the declared 32-bit functions, otherwise you must use 16-bit
replacement functions.
This allows you to write programs which work in both 16 and 32
bit environments.
If you have to pass a record containing a pointer, you must use
the function GetVDMPointer32W to create a 0:32 pointer from
your 16:16 pointer.
This unit is, like the original DLL, in the public domain.
Feel free to redistribute as you wish. No guarantees are
made as to its suitability or usefulness, and no support
is provided. Please send bug reports to my CIS address
100332,1175.
CALL32NT requires the Microsoft Windows NT operating system
or Windows 95 Preview or later to perform its task. The program
will also run in Win 3.1, but of course the functions will not
work.
|