----------------------------------------------- DECLARE AND DATA TYPES January 2024 ----------------------------------------------- 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. 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 5. OTHER: For reference only, there is no guarantees. Any questions or suggestions, please send me an email at ccb2000@163.com. |