在 Windows 程式設計中,直接呼叫 DeleteFile 或 RemoveDirectory 會永久刪除檔案,無法進入資源回收筒。若要提供使用者熟悉的「刪除到資源回收筒」功能 (支援復原),必須使用 Shell API SHFileOperation 並設定 FOF_ALLOWUNDO 旗標。本文提供 C++ Builder 完整範例程式碼。
SHFileOperation 接收一個 SHFILEOPSTRUCT 結構體,控制檔案操作類型 (複製、移動、重命名、刪除)、來源/目標路徑、UI 行為旗標等。
| 成員 | 用途 | 本範例設定 |
|---|---|---|
hwnd | 父視窗控制碼,用於顯示進度/錯誤對話框 | Handle (表單控制碼) |
wFunc | 操作類型 | FO_DELETE (刪除) |
pFrom | 來源路徑雙重 NULL 結尾字串 | "C:\\temp\0\0" |
pTo | 目標路徑 (刪除操作設 NULL) | NULL |
fFlags | 行為旗標組合 | FOF_ALLOWUNDO (進入資源回收筒) |
hNameMappings | 重命名對應結構 (刪除不需) | NULL |
lpszProgressTitle | 進度對話框標題 | NULL (使用預設) |
#include <shellapi.h> // 必須包含
void DeleteToRecycleBin(const AnsiString& path) {
SHFILEOPSTRUCT OpStruct = {0};
// 來源路徑必須雙重 NULL 結尾
// 使用 AnsiString 確保緩衝區足夠大並自動管理記憶體
AnsiString src = path + "\0\0";
OpStruct.hwnd = Application->Handle; // 或 Form->Handle
OpStruct.wFunc = FO_DELETE;
OpStruct.pFrom = src.c_str();
OpStruct.pTo = NULL;
OpStruct.fFlags = FOF_ALLOWUNDO | FOF_NOCONFIRMATION | FOF_SILENT; // 可加靜默旗標
OpStruct.hNameMappings = NULL;
OpStruct.lpszProgressTitle = NULL;
int result = SHFileOperation(&OpStruct);
if (result != 0) {
// 處理錯誤,result 為錯誤碼 (參考 MSDN)
ShowMessage("刪除失敗,錯誤碼: " + IntToStr(result));
}
// OpStruct.fAnyOperationsAborted 可檢查使用者是否取消
}
// 使用範例
void __fastcall TForm1::Button1Click(TObject *Sender) {
DeleteToRecycleBin("C:\\temp"); // 刪除資料夾及其內容
// DeleteToRecycleBin("C:\\test.txt"); // 刪除單一檔案
}
pFrom 和 pTo 必須以兩個 NULL 字元結尾 (如 "C:\\dir\0\0" 或 "C:\\file1\0C:\\file2\0\0")。AnsiString 透過 + "\0\0" 簡單實現此要求。pFrom 可包含多個路徑,以單一 \0 分隔,最終以雙重 \0\0 結尾。FOF_ALLOWUNDO:核心旗標,送入資源回收筒而非永久刪除。FOF_NOCONFIRMATION:不顯示確認對話框。FOF_SILENT:不顯示進度對話框 (配合 NOCONFIRMATION 完全靜默)。FOF_NOERRORUI:不顯示錯誤 UI。SHFileOperation 受限於 MAX_PATH (260 字元)。處理長路徑需使用 \\?\ 前綴或改用 IFileOperation 介面 (Vista+)。對於新專案,微軟推薦使用 COM 介面 IFileOperation,它支援長路徑、非同步操作、更豐富的進度回呼,且不需處理雙重 NULL 字串。但 SHFileOperation 仍廣泛用於舊專案維護及 XP 相容場景。
SHFileOperation 配合 FOF_ALLOWUNDO 是 C++ Builder 實現「刪除到資源回收筒」最直接、相容性最好的方法。掌握結構體填寫細節 (特別是雙重 NULL 字串),即可可靠地提供使用者預期的刪除體驗。