使用SHFileOperation()
,您可以使用FOF_SILENT
標誌,以防止標準進程對話框被顯示。
但是,一旦開始運行,就沒有可用於可編程地中止SHFileOperation()
的選項。爲此,請改爲使用CopyFileEx()
或CopyFile2()
。
兩個功能允許您以兩種不同的方式中止副本:
無論哪種方式,這兩種功能不會自動顯示Windows自帶的進度對話框,但您使用IProgressDialog
接口可以display it manually。或者,您可以改爲顯示自己的自定義對話框。
處理多個文件時,在每個單獨文件上顯示/隱藏進度對話框的用戶體驗不是很好。它在操作系統上被浪費在創建和銷燬對話框上。潛在的閃爍對於用戶直觀地查看並不有趣。在需要時應該顯示對話框一次,然後保持可見並更新,直到完成最後一個文件。
嘗試這樣:
var
// this is redundant since IProgressDialog has its own
// Cancel button, this is just an example to demonstrate
// cancellation in code...
CancelClicked: BOOL = FALSE;
function MyCopyProgressCallback(TotalFileSize, TotalBytesTransferred, StreamSize, StreamBytesTransferred: LARGE_INTEGER; dwStreamNumber: DWORD; dwCallbackReason: DWORD; hSourceFile, hDestinationFile: THandle; lpData: Pointer): DWORD; stdcall;
var
msg: WideString;
begin
msg := WideFormat('Transferred %d of %d bytes', [TotalBytesTransferred.QuadPart, TotalFileSize.QuadPart]);
IProgressDialog(lpData).SetLine(2, PWideChar(msg), False, PPointer(nil)^);
if IProgressDialog(lpData).HasUserCancelled then
Result := PROGRESS_CANCEL
else
Result := PROGRESS_CONTINUE;
end;
...
var
FileFrom: string;
FileTo: string;
I: Integer;
ProgressDialog: IProgressDialog;
begin
...
CancelClicked := FALSE;
OleCheck(CoCreateInstance(CLSID_ProgressDialog, nil, CLSCTX_INPROC_SERVER, IProgressDialog, ProgressDialog));
try
ProgressDialog.SetTitle('Processing files');
ProgressDialog.SetCancelMsg('Canceling, please wait...', PPointer(nil)^);
ProgressDialog.SetProgress(0, TheStringList.Count);
ProgressDialog.StartProgressDialog(frmMain.Handle, nil, PROGDLG_MODAL or PROGDLG_AUTOTIME or PROGDLG_NOMINIMIZE, PPointer(nil)^);
ProgressDialog.Timer(PDTIMER_RESET, PPointer(nil)^);
for I := 0 to TheStringList.Count-1 do
begin
FileFrom := ...;
FileTo := ...;
ProgressDialog.SetLine(1, PWideChar(WideString(FileFrom)), True, PPointer(nil)^);
ProgressDialog.SetLine(2, '', False, PPointer(nil)^);
if ProgressDialog.HasUserCancelled then
Break;
...
if not CopyFileEx(PChar(FileFrom), PChar(FileTo), @MyCopyProgressCallback, Pointer(ProgressDialog), @CancelClicked, 0) then
begin
if GetLastError = ERROR_REQUEST_ABORTED then
Break;
// something else happened during the copy, so
// you can decide whether to stop the loop here
// or just move on to the next file...
end;
...
ProgressDialog.SetProgress(I+1, TheStringList.Count);
end;
finally
ProgressDialog.StopProgressDialog;
ProgressDialog := nil;
end;
...
end;
或者,您可以使用IFileOperation
接口來代替。這使您可以:
對於小文件使用FOF_SILENT,所有標誌在文檔中都有解釋。 –
歡迎來到Stack Overflow。你已經證明你知道文檔的位置。你讀過了嗎?你看到了關於'fof_Silent'的部分,對吧?你試過了嗎?你還有什麼問題?請[編輯]你的問題來澄清。 –
@Rob Kennedy:謝謝,我想知道我是否應該有更多,比如「FOF_FILESONLY」和/或「FOF_NOCONFIRMATION」和/或「FOF_NOERRORUI」和/或等等。只是假設(默認)沒有標誌和我需要定義的內容。 – user3272241