CFile::Remove 永久刪除檔案,無法復原。使用者習慣從回收站還原誤刪檔案,專業應用應尊重此行為模式。
int SHFileOperation(LPSHFILEOPSTRUCT lpFileOp);
單一結構體參數控制所有行為,支援複製、移動、重命名、刪除,並自動顯示系統標準進度對話框。
| 欄位 | 型別 | 說明 |
|---|---|---|
| hwnd | HWND | 擁有者視窗句柄,進度對話框置中用 |
| wFunc | UINT | 操作類型:FO_COPY/FO_MOVE/FO_RENAME/FO_DELETE |
| pFrom | LPCSTR | 來源路徑,多檔案以 \0 分隔,結尾雙 \0\0 |
| pTo | LPCSTR | 目標路徑 (移動/複製/重命名用),刪除時可為 NULL |
| fFlags | FILEOP_FLAGS | 行為旗標組合 (見下表) |
| lpszProgressTitle | LPCSTR | 進度對話框標題 |
| 旗標 | 作用 |
|---|---|
| FOF_ALLOWUNDO | 刪除至回收站 (核心旗標) |
| FOF_NOCONFIRMATION | 覆蓋/刪除不彈出確認對話框 |
| FOF_SILENT | 不顯示進度對話框 |
| FOF_NOERRORUI | 錯誤時不顯示 UI |
| FOF_RENAMEONCOLLISION | 名稱衝突自動重命名 |
| FOF_FILESONLY | 通配符僅匹配檔案,不含目錄 |
| FOF_WANTMAPPINGHANDLE | 回傳實際操作檔案對應清單 |
void CMyView::OnFileDeleteToRecycle() {
SHFILEOPSTRUCT fos = {0};
fos.hwnd = m_hWnd;
fos.wFunc = FO_DELETE;
// 來源路徑:雙 \0 結尾
TCHAR szFrom[MAX_PATH * 2] = _T("D:\\TestFolder\0\0");
fos.pFrom = szFrom;
fos.pTo = NULL; // 刪除不需目標
fos.fFlags = FOF_ALLOWUNDO | FOF_NOCONFIRMATION | FOF_SILENT;
fos.lpszProgressTitle = _T("正在刪除...");
int nResult = SHFileOperation(&fos);
if (nResult != 0) {
TRACE(_T("SHFileOperation 失敗,錯誤碼: %d\n"), nResult);
// 常見錯誤:DE_CANCELLED (使用者取消)、DE_INCOMPLETE (路徑無效)
} else if (fos.fAnyOperationsAborted) {
TRACE(_T("操作被使用者中斷\n"));
} else {
TRACE(_T("已移至回收站\n"));
}
}
_T("C:\\Test.txt\0\0")_T("C:\\A.txt\0C:\\B.txt\0\0")_T("C:\\Folder\0\0") (會連同內容一起刪除)_T("C:\\Logs\\*.log\0\0")fos.fFlags |= FOF_WANTMAPPINGHANDLE;
// 執行後...
if (fos.hNameMappings) {
SHNAMEMAPPING* pMap = (SHNAMEMAPPING*)fos.hNameMappings;
for (int i = 0; i < pMap->cItems; ++i) {
TRACE(_T("原路徑: %s -> 新路徑: %s\n"), pMap->pszOldPath, pMap->pszNewPath);
}
SHFreeNameMappings(fos.hNameMappings); // 必須釋放
}
| 場景 | 建議 |
|---|---|
| 使用者手動刪除文檔/圖片 | 必須用 FO_DELETE + FOF_ALLOWUNDO |
| 快取/臨時檔案清理 | 可用 CFile::Remove 或 SHFileOperation + FOF_NOCONFIRMATION + FOF_SILENT |
| 大量檔案批次刪除 | SHFileOperation 效能較好,自動處理長路徑、權限、進度 UI |
| 網路磁碟機刪除 | 視伺服器支援,可能無回收站功能,需測試 |
| 需永久刪除 (安全清除) | 不可用此 API,需多次覆寫資料或呼叫 SHFileOperation 後再清空回收站 |
SHFileOperation 是 Windows Shell 級檔案操作 API,單一呼叫即可實現「移至回收站」且完美整合系統 UI、權限、長路徑、網路路徑。記住 pFrom 雙 \0 結尾 與 FOF_ALLOWUNDO 兩大關鍵,即可為使用者提供專業、安全的刪除體驗。