-----------------------------------------------
DECLARE AND DATA TYPES
January 2026
-----------------------------------------------
CCB
1. THE DECLARE STATEMENT SYNTAX (from dv_foxhelp9.chm):
DECLARE [cFunctionType] FunctionName IN LibraryName [AS AliasName]
[cParamType1 [@] ParamName1, cParamType2 [@] ParamName2, ...]
cFunctionType
Indicates the data type of the return value from the shared library, if any.
If the function does not return a value, omit cFunctionType.
cFunctionType can assume the following values:
SHORT 16-bit integer
INTEGER 32-bit integer
SINGLE 32-bit floating point
DOUBLE 64-bit floating point
LONG 32-bit long integer
STRING Character string
OBJECT IDispatch object type
2. REFERENCE CODE:
Usually, VFP Advanced (x64) supports all above function types same as VFP 9.0.
When we pass a structure data as string to the Windows API function,
we MUST pass the 64-bit structure data instead of the 32-bit structure data.
For example,
BOOL ShellExecuteEx(
_Inout_ SHELLEXECUTEINFO *pExecInfo
);
When we pass the SHELLEXECUTEINFO structure data to ShellExecuteEx,
we MUST pass the 64-bit SHELLEXECUTEINFO structure data.
The 32-bit SHELLEXECUTEINFO structure:
typedef struct _SHELLEXECUTEINFO {
DWORD cbSize; // 0x00, cbSize = 0x3C
ULONG fMask; // 0x04
HWND hwnd; // 0x08
LPCTSTR lpVerb; // 0x0C
LPCTSTR lpFile; // 0x10
LPCTSTR lpParameters; // 0x14
LPCTSTR lpDirectory; // 0x18
int nShow; // 0x1C
HINSTANCE hInstApp; // 0x20
LPVOID lpIDList; // 0x24
LPCTSTR lpClass; // 0x28
HKEY hkeyClass; // 0x2C
DWORD dwHotKey; // 0x30
HANDLE hIcon; // 0x34
HANDLE hProcess; // 0x38
} SHELLEXECUTEINFO, *LPSHELLEXECUTEINFO;
The size of 32-bit SHELLEXECUTEINFO structure data is 0x3C bytes.
The 64-bit SHELLEXECUTEINFO structure:
typedef struct _SHELLEXECUTEINFO {
DWORD cbSize; // 0x00, cbSize = 0x70
ULONG fMask; // 0x04
HWND hwnd; // 0x08
LPCTSTR lpVerb; // 0x10
LPCTSTR lpFile; // 0x18
LPCTSTR lpParameters; // 0x20
LPCTSTR lpDirectory; // 0x28
int nShow; // 0x30
DWORD padding1; // 0x34
HINSTANCE hInstApp; // 0x38
LPVOID lpIDList; // 0x40
LPCTSTR lpClass; // 0x48
HKEY hkeyClass; // 0x50
DWORD dwHotKey; // 0x58
DWORD padding2; // 0x5C
HANDLE hIcon; // 0x60
HANDLE hProcess; // 0x68
} SHELLEXECUTEINFO, *LPSHELLEXECUTEINFO;
The size of 64-bit SHELLEXECUTEINFO structure data is 0x70 bytes.
If we want the same code can run in VFP Advanced (x64) and VFP 9.0,
we can use the system variable _WIN64 to do it.
The system variable _WIN64 always returns true (.T.) in VFP Advanced 64-bit version.
For example,
PRIVATE m.q_execinfo
IF TYPE("_win64")="L".AND._win64=.T.
m.q_execinfo=;
fval2str(m.q_execinfo_cbsize,4)+;
fval2str(m.q_execinfo_fmask,4)+;
fval2str(m.q_execinfo_hwnd,8)+;
fval2str(m.q_execinfo_lpverb,8)+;
fval2str(m.q_execinfo_lpfile,8)+;
fval2str(m.q_execinfo_lpparameters,8)+;
fval2str(m.q_execinfo_lpdirectory,8)+;
fval2str(m.q_execinfo_nshow,4)+;
fval2str(0,4)+;
fval2str(m.q_execinfo_hinstapp,8)+;
fval2str(m.q_execinfo_lpidlist,8)+;
fval2str(m.q_execinfo_lpclass,8)+;
fval2str(m.q_execinfo_hkeyclass,8)+;
fval2str(m.q_execinfo_dwhotkey,4)+;
fval2str(0,4)+;
fval2str(m.q_execinfo_hicon,8)+;
fval2str(m.q_execinfo_hprocess,8)
ELSE
m.q_execinfo=;
fval2str(m.q_execinfo_cbsize,4)+;
fval2str(m.q_execinfo_fmask,4)+;
fval2str(m.q_execinfo_hwnd,4)+;
fval2str(m.q_execinfo_lpverb,4)+;
fval2str(m.q_execinfo_lpfile,4)+;
fval2str(m.q_execinfo_lpparameters,4)+;
fval2str(m.q_execinfo_lpdirectory,4)+;
fval2str(m.q_execinfo_nshow,4)+;
fval2str(m.q_execinfo_hinstapp,4)+;
fval2str(m.q_execinfo_lpidlist,4)+;
fval2str(m.q_execinfo_lpclass,4)+;
fval2str(m.q_execinfo_hkeyclass,4)+;
fval2str(m.q_execinfo_dwhotkey,4)+;
fval2str(m.q_execinfo_hicon,4)+;
fval2str(m.q_execinfo_hprocess,4)
ENDIF
=shellexecuteex(@m.q_execinfo)
In the header file, we can use the function SYS(17) instead of the system variable _WIN64.
For example,
* MSXML DOM parser
#IF SYS(17) = "X64"
#define MSXML_PARSER "MSXML2.DOMDocument.6.0"
#ELSE
#define MSXML_PARSER "MSXML2.DOMDocument.4.0"
#ENDIF
3. THE INTEGER AND LONG DATA TYPES:
In VFP 9.0 (and before), there is no difference for the INTEGER data type and the LONG data type, they are 32-bit integer.
In VFP Advanced (x64), for the HANDLE data type and the size_t data type, recommend to use the LONG data type instead of the INTEGER data type.
For example,
BOOL WINAPI OpenProcessToken(
_In_ HANDLE ProcessHandle,
_In_ DWORD DesiredAccess,
_Out_ PHANDLE TokenHandle
);
Sometimes the following code can not run fine in VFP Advanced (x64):
DECLARE INTEGER OpenProcessToken IN win32api ;
INTEGER ProcessHandle,;
INTEGER DesiredAccess,;
INTEGER @TokenHandle
Recommend to use the following code:
DECLARE INTEGER OpenProcessToken IN win32api ;
LONG ProcessHandle,;
INTEGER DesiredAccess,;
LONG @TokenHandle
4. THE DECLARE COMMAND ON HIGH ADDRESS SPACE:
Some DLLs such as NTDLL.DLL will be loaded on high address space on windows 10 or later,
so some Windows API functions such as GetModuleHandle("NTDLL.DLL") and GetProcAddress(hmodule_ntdll,"RtlGetVersion") return a high address.
In VFP Advanced (x64), we can call all Windows API functions on high address space (between 0x100000000 (4 GB) and 0x7FFFFFFFFFFFFh (2048 TB)).
In VFP Advanced (x64), we can pass some parameters on high address space (between 0x100000000 (4 GB) and 0x7FFFFFFFFFFFFh (2048 TB))
and/or large integers (between 0x100000000 (4 GB) and 0x7FFFFFFFFFFFFh (2048 TB)) to the following Windows API functions:
* KERNEL32.DLL
DECLARE LONG "GetProcAddress" IN WIN32API ;
LONG hModule,; && high address space
STRING lpProcName
DECLARE LONG "VirtualAlloc" IN WIN32API ;
LONG lpAddress,; && high address space
LONG dwSize,; && large integer
INTEGER flAllocationType,;
INTEGER flProtect
DECLARE LONG "VirtualAllocEx" IN WIN32API ;
LONG hProcess,;
LONG lpAddress,; && high address space
LONG dwSize,; && large integer
INTEGER flAllocationType,;
INTEGER flProtect
DECLARE INTEGER "VirtualFree" IN WIN32API ;
LONG lpAddress,; && high address space
LONG dwSize,; && large integer
INTEGER dwFreeType
DECLARE INTEGER "VirtualFreeEx" IN WIN32API ;
LONG hProcess,;
LONG lpAddress,; && high address space
LONG dwSize,; && large integer
INTEGER dwFreeType
DECLARE INTEGER "VirtualLock" IN WIN32API ;
LONG lpAddress,; && high address space
LONG dwSize && large integer
DECLARE INTEGER "VirtualUnlock" IN WIN32API ;
LONG lpAddress,; && high address space
LONG dwSize && large integer
DECLARE LONG "VirtualQuery" IN WIN32API ;
LONG lpAddress,; && high address space
INTEGER lpBuffer,;
INTEGER dwLength
DECLARE LONG "VirtualQueryEx" IN WIN32API ;
LONG hProcess,;
LONG lpAddress,; && high address space
INTEGER lpBuffer,;
INTEGER dwLength
DECLARE INTEGER "VirtualProtect" IN WIN32API ;
LONG lpAddress,; && high address space
LONG dwSize,; && large integer
INTEGER flNewProtect,;
INTEGER @lpflOldProtect
DECLARE INTEGER "VirtualProtectEx" IN WIN32API ;
LONG hProcess,;
LONG lpAddress,; && high address space
LONG dwSize,; && large integer
INTEGER flNewProtect,;
INTEGER @lpflOldProtect
DECLARE INTEGER "ReadProcessMemory" IN WIN32API ;
LONG hProcess,;
LONG lpAddress,; && high address space
STRING @lpBuffer,;
INTEGER nSize,;
INTEGER @lpNumberOfBytesRead
DECLARE INTEGER "WriteProcessMemory" IN WIN32API ;
LONG hProcess,;
LONG lpAddress,; && high address space
STRING lpBuffer,;
INTEGER nSize,;
INTEGER @lpNumberOfBytesRead
DECLARE INTEGER "UnhandledExceptionFilter" IN WIN32API ;
LONG ExceptionInfo && high address space
* PSAPI.DLL
DECLARE INTEGER "GetModuleInformation" IN "PSAPI.DLL" ;
LONG hProcess,;
LONG hModule,; && high address space
STRING @lpmodinfo,;
INTEGER cb
* NTDLL.DLL
DECLARE INTEGER "NtAllocateVirtualMemory" IN "NTDLL.DLL" ;
LONG ProcessHandle,;
LONG BaseAddress,; && high address space
INTEGER ZeroBits,;
LONG RegionSize,; && large integer
INTEGER AllocationType,;
INTEGER Protect
DECLARE INTEGER "NtFreeVirtualMemory" IN "NTDLL.DLL" ;
LONG ProcessHandle,;
LONG BaseAddress,; && high address space
LONG RegionSize,; && large integer
INTEGER FreeType
DECLARE INTEGER "NtLockVirtualMemory" IN "NTDLL.DLL" ;
LONG ProcessHandle,;
LONG BaseAddress,; && high address space
LONG RegionSize,; && large integer
INTEGER MapType
DECLARE INTEGER "NtUnlockVirtualMemory" IN "NTDLL.DLL" ;
LONG ProcessHandle,;
LONG BaseAddress,; && high address space
LONG RegionSize,; && large integer
INTEGER MapType
DECLARE INTEGER "NtQueryVirtualMemory" IN "NTDLL.DLL" ;
LONG ProcessHandle,;
LONG BaseAddress,; && high address space
INTEGER MemoryInformationClass,;
STRING @MemoryInformation,;
INTEGER MemoryInformationLength,;
INTEGER @ReturnLength
DECLARE INTEGER "NtReadVirtualMemory" IN "NTDLL.DLL" ;
LONG ProcessHandle,;
LONG BaseAddress,; && high address space
STRING @Buffer,;
INTEGER BufferSize,;
INTEGER @NumberOfBytesRead
DECLARE INTEGER "NtWriteVirtualMemory" IN "NTDLL.DLL" ;
LONG ProcessHandle,;
LONG BaseAddress,; && high address space
STRING Buffer,;
INTEGER BufferSize,;
INTEGER @NumberOfBytesRead
5. REFERENCE WEBSITES:
For the HANDLE data type, usually it starts with the character H, for example, HANDLE, HBITMAP, HBRUSH.
Please refer to:
1, Windows Data Types.
http://msdn.microsoft.com/en-us/library/windows/desktop/aa383751(v=vs.85).aspx
6. OTHER:
For reference only, there is no guarantees.
Any questions or suggestions, please send me an email at ccb2000@163.com.
|