TRANSLATING WINDOWS API (C) SYNTAX TO A DELPI-ACCEPTABLE SYNTAX
[See end of file for brief description of some C types and their Delphi equivalents]
[Gap in the market...
'It's been our experience that components that encapsulate or expidite the
usage of awkward API routines, or a series of them, generally sell well.
Of course, for most shareware components, there are usually several
freeware ones that work equally well.'... -from Delphi programmer's chat
line]
In order to use Windows Application Programmer's Interface functions from Delphi
code it's usually necessary to make sense of the parameters for a particular
function, as detailed in the Win32.hlp file, and then write a Delphi version of
the function such that the parameters are of the appropriate types. Confusion
can often arise due to the fact that the definitions for the C variable types
reside in C header files not easily acessible to the Delphi programmer, and the
Win32.hlp file doesn't give any information about them at all.
For example, if we want to know the line number of a character (or the carat)
in a Memo, we can use the EM_LINEFROMCHAR message. Win32.hlp says this:
EM_LINEFROMCHAR
wParam = (WPARAM) ich; // character index
lParam = 0; // not used; must be zero
'An application sends an EM_LINEFROMCHAR message to retrieve the index of the line that
contains the specified character index in a multiline edit control'. (Or -1 for the
carat). But what's a wParam, or an LParam? In Delphi, we write this as follows:
var
lineNumber: LongInt;
begin
lineNumber := SendMessage(MyMemo.Handle, EM_LINEFROMCHAR, -1, 0);
end;
Note that in order to use the Delphi SendMessage function to 'wrap up' this kind of
API call (that involves sendning or receiving a Windows message) we must include
'Messages' in the enclosing module's 'uses' clause.
Another example. 'The GetWindowsDirectory function retrieves the path of the Windows
directory'.
UINT GetWindowsDirectory(
LPTSTR lpBuffer, // address of buffer for Windows directory
UINT uSize // size of directory buffer
);
But what exactly is the type of the lpBuffer variable? Win32.hlp won't tell you what
the LPTSTR type is. In Delphi, do we use GetWindowsDirectory with a first parameter of
a PChar, or the address of the first index of a string perhaps? No, it's an array we
need:
var
winDirName: String;
dirName: array[0..dirNameLen] of Char;
begin
GetWindowsDirectory(dirName, 100);
winDirName := String(dirName);
end;
The next example is less obvious still: say we want to use the EM_CHARFROMPOS message
to retrieve the index of the nearest character to a user's mouse-click in a Memo. We can
use the built-in Delphi OnMouseDown event handler for the Memo, so that we have the X and
Y positions for the mouse click on a plate. But to use EM_CHARFROMPOS we need to put both
the X and the Y value into the ONE 'lParam' type parameter such that the X value is the
low-order word of lParam, and the X value is the high-order word of lParam. So we need
to 'bundle' X and Y together into one LongInt varaiable. We can do this as follows:
var
bundledXY, charIndex: LongInt;
clickPoint: TPoint;
lineNumber: LongInt;
begin
clickPoint.X := X;
clickPoint.Y := Y;
bundledXY := LongInt(@clickPoint);
charIndex := SendMessage(Editor.Handle, EM_CHARFROMPOS, 0, bundledXY);
lineNumber := SendMessage(Editor.Handle, EM_LINEFROMCHAR, charIndex, 0);
end;
I spent a long time scouring Win32.hlp before I found a way to get the character
position of the beginning and end of selected text in a RichEdit:
procedure GetCaratPos;
var
startPos, endPos: LongInt;
begin
SendMessage(Editor.Handle, EM_GETSEL, LongInt(@startPos), LongInt(@endPos));
end;
****************************************************************************************************************
a C++ int is identical to a Delphi Integer. Other types, such as strings, are either identical, or very similar. For instance, a C++ char * (LPSTR) is identical to a Delphi PChar. Furthermore, a Delphi string is fully compatible with a char *, and the C++Builder AnsiString type is designed to be compatible with, and to mimic, a Delphi string. This parallel structure continues throughout the two languages, and includes complex types such as structures (records) and arrays. (What C++ calls a union, Delphi calls a variable record.)
DATA TYPES USED IN OBJECT PASCAL (32-BIT PROGRAMS).
Data Type Size in Bytes Possible Range of Values
ShortInt 1 -128 to 127
Byte 1 0 to 255
Char 1 0 to 255 (same as Byte)
WideChar 2 0 to 65,535 (same as Word)
SmallInt 2 -32,768 to 32,767
Word 2 0 to 65,535
LongInt 4 -2,147,483,648 to 2,147,483,647
Int64 8 -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807
Integer 4 Same as LongInt
Cardinal 4 0 to 2,147,483,647
Single 4 1.5 ¥ 10-45 to 3.4 ¥ 1038
Double 8 5.0 ¥ 10-324 to 1.7 ¥ 10308
Real 8 5.0 ¥ 10-324 to 1.7 ¥ 10308 (same as Double)
Extended 10 3.4 ¥ 10-4932 to 1.1 ¥ 104932
Comp 8 -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807
Currency 8 -922,337,203,685,477.5808 to 922,337,203,685,477.5807
Boolean 1 True or False
Variant 16 Varies
Note: an Integer is the same as a LongInt.
DATA TYPES USED IN C/C++
Data Type Size (bytes) Format Range
unsigned char 1 ordinal 0 to 255
[signed] char 1 two's-complement integer -128 to 127
unsigned short 2 ordinal 0 to 65535
[signed] short 2 two's-complement integer -32768 to 32767
unsigned int 4 ordinal 0 to 2 ttpo 32 -1
[signed] int 4 two's-complement integer -2 ttpo 31 to 2 ttpo 31-1
[signed] long int 4 two's-complement integer -2 ttpo 31 to 2 ttpo 31-1
unsigned long int 4 ordinal 0 to 2 ttpo 32-1
[signed] long long [int] 8 two's-complement integer -2 ttpo 63 to 2 ttpo 63-1
unsigned long long [int] 8 ordinal 0 to 2 ttpo 64-1
float 4 IEEE single-precision fltg-pt 10 ttpo -37 to 10 ttpo 38 (1)
double 8 IEEE double-precision fltg-pt 10 ttpo -307 to 10 ttpo 308 (1)
long double 8 IEEE double-precision fltg-pt 10 ttpo -307 to 10 ttpo 308 (1)
bit field(2) (unsigned) 1 to 32 bits ordinal 0 to 2size-1, where size is the number of bits in the bit field
bit field(2) (signed value) 1 to 32 bits two's complement integer -2size-1 to 2size-1-1, where size is the number of bits in the bit field
pointer 4 address 0 to 232-1
enum 4 two's complement integer -2 ttpo 31 to 2 ttpo 31-1
BRIEF DESCRIPTION OF SOME C TYPES AND THEIR DELPHI EQUIVALENTS
C Delphi
lParam LongInt
wParam LongInt
LPTSTR array (which will actually be a pointer to an array in Delphi)
UINT Integer (that must be zero or greater than zero)
HRESULT LongInt