Mega Code Archive

 
Categories / Delphi / Examples
 

Apiparams

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