Dang … I made my own little example to prove the REAL worked.
Note this is only for a LARGE_INTEGER passed by Value, that I think would be rare,
and not passed by address P LARGE_INTEGER e.g. see GetDiskFreeSpaceExA()
!CopyFileEx with Callback test by Carl Barnes - Copyright 2022 - Released under the MIT License
PROGRAM
LARGE_INTEGER_In EQUATE(REAL) !64 bit INT passed by value Prototype as REAL
MAP
TestCopy PROCEDURE()
CopyFileEx_PPROGRESS PROCEDURE( | !DWORD WINAPI *LPPROGRESS_ROUTINE(
LARGE_INTEGER_In R_TotalFileSize , | !_In_ LARGE_INTEGER TotalFileSize
LARGE_INTEGER_In R_TotalBytesTransferred , | !_In_ LARGE_INTEGER TotalBytesTransferred
LARGE_INTEGER_In R_StreamSize , | !_In_ LARGE_INTEGER StreamSize
LARGE_INTEGER_In R_StreamBytesTransferred , | !_In_ LARGE_INTEGER StreamBytesTransferred
UNSIGNED dwStreamNumber , | !_In_ DWORD dwStreamNumber
UNSIGNED dwCallbackReason , | !_In_ DWORD dwCallbackReason
SIGNED hSourceFile , | !_In_ HANDLE hSourceFile
SIGNED hDestinationFile , | !_In_ HANDLE hDestinationFile
<UNSIGNED lpData> | !_In_opt_ LPVOID lpData
),UNSIGNED,PASCAL
MODULE('api')
OutputDebugString(*CSTRING cMsg),PASCAL,DLL(1),RAW,NAME('OutputDebugStringA')
GetLastError(),LONG,PASCAL,DLL(1)
CopyFileEx PROCEDURE( | !BOOL WINAPI CopyFileExA(
*CSTRING lpExistingFileName , | !_In_ LPCSTR lpExistingFileName
*CSTRING lpNewFileName , | !_In_ LPCSTR lpNewFileName
LONG lpProgressRoutine=0 , | !_In_opt_ LPPROGRESS_ROUTINE lpProgressRoutine Address(CallBack)
UNSIGNED lpData=0 , | !_In_opt_ LPVOID lpData
<*BOOL pbCancel> , | !_Inout_opt_ LPBOOL pbCancel
UNSIGNED dwCopyFlags | !_In_ DWORD dwCopyFlags
),BOOL ,RAW,PASCAL,DLL(1),PROC,name('CopyFileExA') !If the function succeeds, the return value is nonzero.
END !Module API
END
!https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-copyfileexa
COPY_FILE_FAIL_IF_EXISTS EQUATE(00000001h) !The copy operation fails immediately if the target file already exists.
COPY_FILE_NO_BUFFERING EQUATE(00001000h) !The copy operation is performed using unbuffered I/O, bypassing system I/O cache resources. Recommended for very large file transfers.
PROGRESS_CANCEL EQUATE(1) !Cancel the copy operation and delete the destination file.
PROGRESS_CONTINUE EQUATE(0) !Continue the copy operation.
PROGRESS_QUIET EQUATE(3) !Continue the copy operation, but stop invoking CopyProgressRoutine to report progress.
PROGRESS_STOP EQUATE(2) !Stop the copy operation. It can be restarted at a later time.
CODE
TestCopy()
TestCopy PROCEDURE()
ExistingFileName CSTRING('XXX.txt')
NewFileName CSTRING('XXX_Copy.txt')
ProgressRoutine LONG
lpData LONG
boolCancel BOOL
CopyFlags LONG
RetCopy BOOL
CODE
IF ~EXISTS(ExistingFileName) THEN COPY('CopyFileExTest.clw',ExistingFileName).
IF ~EXISTS(ExistingFileName) THEN
Message('You need to make a file to test copy named: ' & ExistingFileName, 'CopyFileEx Test File')
RETURN
END
REMOVE(NewFileName)
lpData=8312022
ProgressRoutine = ADDRESS( CopyFileEx_PPROGRESS )
RetCopy = CopyFileEx( |
ExistingFileName , | ! *CSTRING lpExistingFileName , | !_In_ LPCSTR lpExistingFileName
NewFileName , | ! *CSTRING lpNewFileName , | !_In_ LPCSTR lpNewFileName
ProgressRoutine , | ! LONG lpProgressRoutine=0 , | !_In_opt_ LPPROGRESS_ROUTINE lpProgressRoutine Address(CallBack)
lpData , | ! UNSIGNED lpData=0 , | !_In_opt_ LPVOID lpData
boolCancel , | ! <*BOOL pbCancel> , | !_Inout_opt_ LPBOOL pbCancel
CopyFlags ) ! UNSIGNED dwCopyFlags | !_In_ DWORD dwCopyFlags
Message('CopyFileEx return='& RetCopy & CHOOSE(~RetCopy,' FAILED',' Success!') & |
' <9>LastError='& GetLastError() &|
'||Copy From: <9>'& ExistingFileName & |
'|Copy To: <9>'& NewFileName & |
'','CopyFileEx Test')
RETURN
!=================
! https://docs.microsoft.com/en-us/windows/win32/api/winbase/nc-winbase-lpprogress_routine
CopyFileEx_PPROGRESS PROCEDURE( | !DWORD WINAPI *LPPROGRESS_ROUTINE(
LARGE_INTEGER_In R_TotalFileSize , | !_In_ LARGE_INTEGER TotalFileSize
LARGE_INTEGER_In R_TotalBytesTransferred , | !_In_ LARGE_INTEGER TotalBytesTransferred
LARGE_INTEGER_In R_StreamSize , | !_In_ LARGE_INTEGER StreamSize
LARGE_INTEGER_In R_StreamBytesTransferred , | !_In_ LARGE_INTEGER StreamBytesTransferred
UNSIGNED dwStreamNumber , | !_In_ DWORD dwStreamNumber
UNSIGNED dwCallbackReason , | !_In_ DWORD dwCallbackReason
SIGNED hSourceFile , | !_In_ HANDLE hSourceFile
SIGNED hDestinationFile , | !_In_ HANDLE hDestinationFile
<UNSIGNED lpData> ) !_In_opt_ LPVOID lpData ) !,UNSIGNED ,RAW,PASCAL
!Note: LARGE_INTEGER_In EQUATE(REAL) !64 bit INT passed by value Prototype as REAL
TotalFileSize LIKE(INT64),OVER(R_TotalFileSize) !Passed REAL but its really 64 bit INT
TotalBytesTransferred LIKE(INT64),OVER(R_TotalBytesTransferred)
StreamSize LIKE(INT64),OVER(R_StreamSize)
StreamBytesTransferred LIKE(INT64),OVER(R_StreamBytesTransferred)
ReturnProgress LONG
CODE
CASE Message('In callback lpData=' & lpData & |
'||TotalFileSize = ' & TotalFileSize.lo & |
' <9>TotalBytesTransferred = '& TotalBytesTransferred.lo & |
'|StreamSize = ' & StreamSize.lo & |
' <9>StreamBytesTransferred = ' & StreamBytesTransferred.lo & |
'||dwStreamNumber = ' & dwStreamNumber & |
'|dwCallbackReason = '& dwCallbackReason & |
'|hSourceFile = '& hSourceFile & |
' <9>hDestinationFile = '& hDestinationFile & |
'','CopyFileEx_PPROGRESS',ICON:Copy,'Continue|Quite|Cancel Copy')
OF 1 ; ReturnProgress = PROGRESS_CONTINUE
OF 2 ; ReturnProgress = PROGRESS_QUIET
OF 3 ; ReturnProgress = PROGRESS_CANCEL
END
RETURN ReturnProgress
CopyFileExTestProject.zip (2.5 KB)