Command EXTERN Foundation
Executes a function in a non-Xbase++ DLL.
[STATIC] EXTERN [<CallingConvention>] [<Type>] ;
<FunctionName>( [[@] <Parameter> AS <Type>, ...] ) ;
IN <Library> [NAME <AliasName>]
Key word | Description |
---|---|
CDECL | C calling convention |
STDCALL *) | Standard for the Windows 32bit API |
|
Key word | Description | Corresponding C/SDK types (examples) |
---|---|---|
BOOL8 | 8 bit boolean | bool |
BOOL | 32 bit boolean | BOOL |
SHORT | 16 bit integer | SHORT, short int |
USHORT | Unsigned 16 bit integer | USHORT, unsigned short |
INTEGER | 32 bit integer | int |
LONG | 32 bit integer | INT32 |
UINTEGER | Unsigned 32 bit integer | DWORD, LPDWORD, LPARAM, PVOID, HANDLE, HWND, UINT, ULONG |
INTEGER64 | 64 bit integer | INT64 |
UINTEGER64 | Unsigned 64 bit integer | UINT64, ULONG64, DWORD64 |
SINGLE | 32 bit floating point | FLOAT32, float |
DOUBLE | 64 bit floating point | FLOAT64 |
STRING | Character string | LPSTR, PSZ, char, char* |
IDISPATCH | COM/ActiveX object (IDispatch) | IDispatch* |
Key word | Description | Corresponding C/SDK types (examples) |
---|---|---|
BOOL8 | 8 bit boolean | bool |
BOOL | 32 bit boolean | BOOL |
SHORT | 16 bit integer | SHORT, short int |
USHORT | Unsigned 16 bit integer | USHORT, unsigned short |
INTEGER | 32 bit integer | int |
LONG | 32 bit integer | INT32 |
UINTEGER | Unsigned 32 bit integer | DWORD, LPDWORD, LPARAM, PVOID, HANDLE, HWND, UINT, ULONG |
INTEGER64 | 64 bit integer | INT64 |
UINTEGER64 | Unsigned 64 bit integer | UINT64, ULONG64, DWORD64 |
SINGLE | 32 bit floating point | FLOAT32, float |
DOUBLE | 64 bit floating point | FLOAT64 |
STRING | Character string | LPSTR, PSZ, char, char* |
IDISPATCH | COM/ActiveX object (IDispatch) | IDispatch* |
CALLBACK | Callback function | WNDENUMPROC, DLGPROC |
ACALLBACK | Asynchronous callback function | WNDPROC, HOOKPROC |
XPPVALUE | An arbitrary Xbase++ value | (not applicable) |
STRUCTURE | Memory structure | RECT, PROCESS_INFORMATION, typedef struct |
The EXTERN command is used for calling functions in non-Xbase++ DLLs. The command allows the utilization of functions within an Xbase++ application which are not known by the linker at the time when the EXE file is created. This includes operating system APIs as well as functions contained in 3rd party DLLs.
The command creates an Xbase++ wrapper function which has the same name as the function contained in the DLL file. This allows the DLL function to be called on the Xbase++ language level using a symbolic identifier. Because the EXTERN command creates a new function, it must appear outside of any existing function bodies.
When the Xbase++ function is called in a program, it first loads the DLL and then executes the DLL function of the same name. If parameters are declared in the EXTERN command, the Xbase++ function passes the received arguments to the DLL function. All parameters that are declared with a preceeding reference operator (@) are passed by reference to the DLL function. When the DLL function finishes, the DLL is unloaded and the Xbase++ function returns the return value of the DLL function.
// The example uses a Window API functions for reading the
// title of the application window.
#include "dll.ch"
// Declare Win32 API for getting the title of an OS-level
// window. Note the reference (out) parameter <cTxt>.
// int WINAPI GetWindowText( HWND hWnd, LPTSTR lpString, int nMaxCount );
EXTERN LONG GetWindowText( nHWND AS LONG, @cTxt AS STRING, nCnt AS LONG ) IN WIN32API
/// <summary>
/// The application's main procedure
/// </summary>
PROCEDURE Main()
LOCAL cTitle := Space( 255 )
GetWindowText( SetAppWindow():getHWND(), @cTitle, 255 )
? "Window Title: " + cTitle
WAIT
RETURN
// The example uses Windows API functions for reading the
// titles of the windows currently visible on the desktop.
#include "dll.ch"
// Declare the Win32 API for enumerating existing windows. The API
// expects a callback function in the first, and an application-supplied
// value in the second parameter. The second parameter is passed on to
// the callback function.
// BOOL WINAPI EnumWindows( WNDENUMPROC lpEnumFunc, LPARAM lParam );
EXTERN BOOL EnumWindows( EnumProc AS CALLBACK, aParam AS XPPVALUE ) IN WIN32API
// Declare Win32 APIs for getting the visible state and the caption
// of an OS-level window. Note the reference (out) parameter <cTxt>
// BOOL WINAPI IsWindowVisible( HWND hWnd );
EXTERN BOOL IsWindowVisible( nHWND AS LONG ) IN WIN32API
// int WINAPI GetWindowText( HWND hWnd, LPTSTR lpString, int nMaxCount );
EXTERN LONG GetWindowText( nHWND AS LONG, @cTxt AS STRING, nCnt AS LONG ) IN WIN32API
/// <summary>
/// The application's main procedure
/// </summary>
PROCEDURE Main()
LOCAL aWins
DevPos( 2,5 )
DevOut( "Visible Windows:" )
//
// Get an array with the titles of the visible windows and display
// them on the screen
//
aWins := ListWindowHandles()
AChoice( 5,5,MaxRow()-5,MaxCol()-5, aWins )
RETURN
/// <summary>
/// Get the windows which are currently open on the desktop. Return
/// is an array with the window titles.
/// </summary>
FUNCTION ListWindowHandles()
LOCAL oCallback
LOCAL aRet := {}
//
// Create a callback object for the callback function expected by
// the EnumWindows() Win32 API. This is a standard Xbase++ function
// which is called implicitly by the API.
//
oCallback := DLLCallBack():new( "EnumWindowProc",, DLL_TYPE_UINT32, DLL_TYPE_XPPVALUE )
EnumWindows( oCallback, aRet )
RETURN aRet
/// <summary>
/// Xbase++ callback function to be executed by the EnumWindows()
/// Win32 API.
/// </summary>
/// <param name="nHWND">The OS-level window handle</param>
/// <param name="aWins">An array to be filled with window titles</param>
/// <returns>1 to continue enumerating OS-level windows, 0 to cancel</returns>
FUNCTION EnumWindowProc( nHWND, aWins )
LOCAL cTmp := Space( 255 )
// Only visible windows should be listed
IF ! IsWindowVisible(nHWND)
RETURN 1
ENDIF
// Get the window's caption and add it to the title array
IF GetWindowText(nHWND, @cTmp, 255) == 0
RETURN 1
ENDIF
AAdd( aWins, RTrim(cTmp) )
RETURN 1
If you see anything in the documentation that is not correct, does not match your experience with the particular feature or requires further clarification, please use this form to report a documentation issue.