直接呼叫 DeleteFile 或 RemoveDirectory 會永久刪除檔案,無法還原。Windows Shell 提供 SHFileOperation 配合 FOF_ALLOWUNDO 旗標,可將檔案/目錄移至資源回收筒,保留使用者還原機會。本文提供最精簡的 C++Builder 實作代碼。
#include // 需連結 shell32.lib
void MoveToRecycleBin(const char* path)
{
SHFILEOPSTRUCT OpStruct = {0};
char from[MAX_PATH] = {0};
// 雙重 null 結尾:SHFileOperation 要求 pFrom 以兩個 '\0' 結尾
strncpy(from, path, MAX_PATH - 2);
OpStruct.hwnd = Application->Handle; // 父視窗,用於進度對話框
OpStruct.wFunc = FO_DELETE; // 操作類型:刪除
OpStruct.pFrom = from; // 來源路徑(雙 null 結尾)
OpStruct.pTo = NULL; // 刪除操作不需目標
OpStruct.fFlags = FOF_ALLOWUNDO | // 移至資源回收筒
FOF_NOCONFIRMATION | // 不顯示確認對話框
FOF_SILENT; // 不顯示進度 UI(可選)
OpStruct.hNameMappings = NULL;
OpStruct.lpszProgressTitle = NULL;
int result = SHFileOperation(&OpStruct);
if (result != 0)
{
// 非零表示失敗或使用者取消
ShowMessage("移至資源回收筒失敗,錯誤碼: " + IntToStr(result));
}
}
SHFILEOPSTRUCT.pFrom 與 pTo 必須以兩個連續的 null 字元結尾(即緩衝區最後兩個位元組為 0)。這允許一次指定多個路徑,路徑間以單一 null 分隔,末尾雙 null 結束。上例中 char from[MAX_PATH] = {0} 初始化全零,strncpy 複製路徑後,緩衝區自然保留雙 null 結尾。
| 旗標 | 效果 |
|---|---|
| FOF_ALLOWUNDO | 移至資源回收筒(非永久刪除) |
| FOF_NOCONFIRMATION | 不顯示「確定要刪除嗎?」對話框 |
| FOF_SILENT | 不顯示進度對話框(靜默操作) |
| FOF_NOERRORUI | 發生錯誤時不顯示錯誤對話框 |
| FOF_WANTNUKEWARNING | 永久刪除時顯示警告(配合無 FOF_ALLOWUNDO) |
void MoveMultipleToRecycleBin(const std::vector& paths)
{
// 計算所需緩衝區大小:每個路徑 + 1 null,最後 + 1 null
size_t total = 1; // 結尾雙 null 的第一個
for (auto& p : paths) total += p.Length() + 1;
std::vector buffer(total, 0);
char* ptr = buffer.data();
for (auto& p : paths)
{
strcpy(ptr, p.c_str());
ptr += p.Length() + 1;
}
// 結尾已自動為雙 null(vector 初始化為 0)
SHFILEOPSTRUCT op = {0};
op.hwnd = Application->Handle;
op.wFunc = FO_DELETE;
op.pFrom = buffer.data();
op.fFlags = FOF_ALLOWUNDO | FOF_NOCONFIRMATION;
SHFileOperation(&op);
}
SHFileOperation 為同步阻塞呼叫。大量檔案操作會凍結 UI。解決方案:
TThread)呼叫。IFileOperation (Vista+) 介面,較複雜但支援非同步與進度事件。| 現象 | 原因 | 解決 |
|---|---|---|
| 檔案直接消失,不在回收筒 | 未設定 FOF_ALLOWUNDO | 加入 FOF_ALLOWUNDO 旗標 |
| 彈出確認對話框 | 未設定 FOF_NOCONFIRMATION | 加入 FOF_NOCONFIRMATION |
| SHFileOperation 返回非零 | 路徑不存在、權限不足、檔案被鎖定 | 檢查 GetLastError 或 OpStruct.fAnyOperationsAborted |
| 網路磁碟機檔案不進回收筒 | 網路磁碟機預設不支援回收筒 | 需在伺服器端啟用資源回收筒功能 |
現代應用建議使用 COM 介面 IFileOperation,支援非同步、進度對話框自訂、UAC 提權等進階功能。但 SHFileOperation 仍被廣泛支援且代碼極簡,適合快速原型與舊版相容專案。
善用 SHFileOperation + FOF_ALLOWUNDO,讓你的刪除操作更符合使用者直覺,減少誤刪風險。