Edison
Edison

Reputation: 31

How can I call cancel while copying file? (using copy file ex function with copy progress routine callback function)

I'd created one cancel button to stop the file copy. What should I call in Copy Progress Routine in order to cancel the file copy.

DWORD CALLBACK CopyProgressRoutine(LARGE_INTEGER TotalFileSize, 
LARGE_INTEGER TotalBytesTransferred, LARGE_INTEGER StreamSize, 
LARGE_INTEGER StreamBytesTransferred, DWORD dwStreamNumber, DWORD 
dwCallbackReason, HANDLE hSourceFile, HANDLE hDestinationFile, LPVOID 
lpData)
{   
HWND hWndDlg = (HWND)lpData;
static HWND hwndIDC_PROGRESS1;
hwndIDC_PROGRESS1 = GetDlgItem(hWndDlg, IDC_PROGRESS_DATA_OF_RETRIEVING);

DOUBLE Percentage = ((DOUBLE)TotalBytesTransferred.QuadPart / 
    (DOUBLE)TotalFileSize.QuadPart) * 100;

switch (dwCallbackReason)
{
    case CALLBACK_CHUNK_FINISHED:
    break;

    case CALLBACK_STREAM_SWITCH:
    if (cancel_Copy_File!=false) // cancel_copy_file is still undefined
        {
            return PROGRESS_CANCEL;
        }
    break;
}
return PROGRESS_CONTINUE;

Upvotes: 0

Views: 368

Answers (2)

Daniel Sęk
Daniel Sęk

Reputation: 2769

You react only on CALLBACK_STREAM_SWITCH which in most cases you will get only once. CopyFileEx copies file in chunks and after each chunk calls callback with reson == CALLBACK_CHUNK_FINISHED. In reality you don't need to differentiate between this cases and handle both with same code.

DWORD CALLBACK CopyProgressRoutine(LARGE_INTEGER TotalFileSize, 
    LARGE_INTEGER TotalBytesTransferred, LARGE_INTEGER StreamSize, 
    LARGE_INTEGER StreamBytesTransferred, DWORD dwStreamNumber, DWORD 
    dwCallbackReason, HANDLE hSourceFile, HANDLE hDestinationFile, LPVOID 
    lpData)
{   
    HWND hWndDlg = (HWND)lpData;
    static HWND hwndIDC_PROGRESS1;
    hwndIDC_PROGRESS1 = GetDlgItem(hWndDlg, IDC_PROGRESS_DATA_OF_RETRIEVING);

    DOUBLE Percentage = ((DOUBLE)TotalBytesTransferred.QuadPart / 
        (DOUBLE)TotalFileSize.QuadPart) * 100;

    /* If you copy on GUI thread, you need to pump messages with
       while ( PeekMessage( ... ) ) { ... }
    */

    return cancel_Copy_File ? PROGRESS_CANCEL : PROGRESS_CONTINUE;
}

Upvotes: 2

Alex F
Alex F

Reputation: 43321

Yoy need to return PROGRESS_CANCEL from CopyProgressRoutine, as described here: LPPROGRESS_ROUTINE callback function https://learn.microsoft.com/en-us/windows/desktop/api/winbase/nc-winbase-lpprogress_routine

Return Value:

PROGRESS_CANCEL Cancel the copy operation and delete the destination file.

PROGRESS_CONTINUE Continue the copy operation.

See the full list in MSDN article.

Upvotes: 2

Related Questions