-----------------------------------------------
                            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.