在Windows的shellapi文件中定義了一個名為SHFileOperation()的外殼函數,它可以用來實現各種文件操作,例如文件的拷貝、刪除和移動等,該函數使用起來非常簡單,它只有一個指向SHFILEOPSTRUCT結構的參數。使用SHFileOperation()函數時只要填寫該專用結構--SHFILEOPSTRUCT,告訴Windows執行什么樣的操作,以及其它重要信息就行了。SHFileOperation()的特別之處在於它是一個高級外殼函數,不同於低級文件處理。當調用SHFileOperation操作文件時,相應的外殼拷貝處理器(如果有的話)被調用。如在刪除某個文件時,SHFileOperation會將刪除的文件放到Recycle Bin中。
SHFileOperation()函數原型為:WINSHELLAPI int WINAPI SHFileOperation(LPSHFILESTRUCT lpFileOp);
LPSHFILESTRUCT結構格式如下:
Typedef struct _shFILEOPSTRUCT
{
HWND hWnd; //消息發送的窗口句柄;
UINT wFunc; //操作類型
LPCSTR pFrom; //源文件以及路徑
LPCSTR pTo; //目標文件以及路徑
FILEOP_FLAGS fFlags; //操作選擇位
LPVOID hNameMapping; //文件映射
LPCSTR lpszProgressTitle; //文件操作進度窗口標題
}SHFILEOPSTRUCT,FAR* LPSHFILEOPSTRUCT;
在這個結構中,hWnd是指向發送消息的窗口句柄,pFrom與pTo是進行文件操作的源文件名和目標文件名,它包含文件的路徑,對應單個文件的路徑字符串,或對於多個文件,必須以NULL作為字符串的結尾或文件路徑名之間的間隔,否則在程序運行的時候會發生錯誤。另外,pFrom和pTo都支持通配符*和?,這大大方便了開發人員的使用。例如,源文件或目錄有兩個,則應是:char pFrom[]="d:/Test1/0d:/Text.txt/0",它表示對要D:盤Test1目錄下的所有文件和D:盤上的Text.txt文件進行操作。字符串中的""是C語言中的''的轉義符,'/0'則是NULL。wFunc 是結構中的一個非常重要的成員,它代表着函數將要進行的操作類型,它的取值為如下:
·FO_COPY: 拷貝文件pFrom到pTo 的指定位置。
·FO_RENAME: 將pFrom的文件名更名為pTo的文件名。
·FO_MOVE: 將pFrom的文件移動到pTo的地方。
·FO_DELETE: 刪除pFrom指定的文件。
使用該函數進行文件拷貝、移動或刪除時,如果需要的時間很長,則程序會自動在進行的過程中出現一個無模式的對話框(Windows操作系統提供的文件操作對話框),用來顯示執行的進度和執行的時間,以及正在拷貝、移動或刪除的文件名,此時結構中的成員lpszProgressTitle顯示此對話框的標題。fFlags是在進行文件操作時的過程和狀態控制標識。它主要有如下一些標識,也可以是其組合:
·FOF_FILESONLY:執行通配符,只執行文件;
·FOF_ALLOWUNDO:保存UNDO信息,以便在回收站中恢復文件;
·FOF_NOCONFIRMATION:在出現目標文件已存在的時候,如果不設置此項,則它會出現確認是否覆蓋的對話框,設置此項則自動確認,進行覆蓋,不出現對話框。
·FOF_NOERRORUI:設置此項后,當文件處理過程中出現錯誤時,不出現錯誤提示,否則會進行錯誤提示。
·FOF_RENAMEONCOLLISION:當已存在文件名時,對其進行更換文提示。
·FOF_SILENT:不顯示進度對話框。
·FOF_WANTMAPPINGHANDLE:要求SHFileOperation()函數返回正處於操作狀態的實際文件列表,文件列表名柄保存在hNameMappings成員中。
·SHFILEOPSTRUCT結構還包含一個SHNAMEMAPPING結構的數組,此數組保存由SHELL計算的每個處於操作狀態的文件的新舊路徑。
同時也有一個重要的應用就是:
在進行文件操作時,可以使用CFile類中的Remove()函數來刪除一個文件,但是這樣的操作將永久性的刪除該文件,不能在必要的時候再恢復該文件,解決這個問題的唯一方法就是把文件送到Windows系統中的回收站(Recycle Bin)里面,而不是簡單的永久性刪除它,這樣用戶就可以在必要的時候恢復這個文件。用這個函數實現編程來實現Windows回收站的文件存取操作。
在使用該函數刪除文件時必須設置SHFILEOPSTRUCT結構中的神秘FOF_ALLOWUNDO標志,這樣才能將待刪除的文件拷到Recycle Bin,從而使用戶可以撤銷刪除操作。需要注意的是,如果pFrom設置為某個文件名,用FO_DELETE標志刪除這個文件並不會將它移到Recycle Bin,甚至設置FOF_ALLOWUNDO標志也不行,在這里你必須使用全路徑名,這樣SHFileOperation才會將刪除的文件移到Recycle Bin。
代碼如下:
void CFileOperationView::OnFileDelete()
{
int nOk;
char strSrc[]="d:/Vb/0";//源文件路徑;
char strDst[]="d:/Vb1/0";//目標文件路徑;
char strTitle[]="文件拷貝"; //文件刪除進度對話框標題
SHFILEOPSTRUCT FileOp;//定義SHFILEOPSTRUCT結構對象;
FileOp.hwnd=this->m_hWnd;
FileOp.wFunc=FO_DELETE; //執行文件刪除操作;
FileOp.pFrom=strSrc;
FileOp.pTo=strDst;
FileOp.fFlags=FOF_ALLOWUNDO;//此標志使刪除文件備份到Windows回收站
FileOp.hNameMappings=NULL;
FileOp.lpszProgressTitle=strTitle;
//開始刪除文件
nOk=SHFileOperation(&FileOp);
if(nOk)
TRACE("There is an error: %d/n",nOk);
else
TRACE("SHFileOperation finished successfully/n");
}
fFlags成員標志間的關系
標志 |
抑制的對話框 |
相關性與優先級 |
FOF_MULTIDESTFILES |
無 |
無 |
FOF_FILESONLY |
無 |
無 |
FOF_SILENT |
如果設置,進度對話框不顯示。 |
優先於FOF_SIMPLEPROGRESS標志。 |
FOF_SIMPLEPROGRESS |
無 |
為FOF_SILENT標志所抑制。 |
FOF_RENAMEONCOLLISION |
如果設置了這個標志,當被移動或拷貝的文件與已存在文件同名時置換對話框不會出現。 |
名字沖突時,如果FOF_NOCONFIRMATION標志設置,則操作繼續。 如果二者都設置了,則它優先於FOF_NOCONFIRMATION。即,文件以給定的新名字復制,而不是覆蓋。 |
FOF_NOCONFIRMATION |
如果設置,確認對話框在任何情況下都不出現。 |
名字沖突時,引起文件覆蓋,除非設置了FOF_RENAMEONCOLLISION標志。 |
FOF_NOCONFIRMMKDIR |
抑制請求建立新文件夾的對話框 |
缺省目錄作為嚴重錯誤產生一個錯誤消息框。 建立目錄的確認對話框作為錯誤消息框是否顯示依賴於FOF_NOERRORUI的設置。 |
FOF_NOERRORUI |
抑制所有錯誤消息框。 |
優先於前一個標志。如果設置,則,缺省目錄引起不被處理的異常,並且返回錯誤碼。 |
刪除文件
文件刪除是一個簡單的操作,它僅僅影響到輸入緩沖pFrom,而pTo緩沖被忽略。與文件復制一樣,操作的詳細情況依賴於標志的設置。相關的標志是:
標志 |
值 |
描述 |
FOF_SILENT |
0x0004 |
這個操作不回饋給用戶,就是說,不顯示進度對話框。相關的消息框仍然顯示。 |
FOF_NOCONFIRMATION |
0x0010 |
這個標志使函數對任何遇到的消息框都自動回答Yes。 |
FOF_ALLOWUNDO |
0x0040 |
如果設置,這個標志強迫函數移動被刪除的文件到‘回收站’中。否則,文件將被物理地從磁盤上刪除。 |
FOF_FILESONLY |
0x0080 |
設置這個標志導致函數僅僅刪除文件,跳過目錄項。它僅僅應用於指定通配符的情況。 |
FOF_SIMPLEPROGRESS |
0x0100 |
這導致簡化用戶界面。使之只有動畫而不報告被刪除的文件名。代之的是顯示lpszProgressTitle成員中指定的文字。(Win7實際中貌似不可用) |
FOF_NOERRORUI |
0x0400 |
如果設置了這個標志,任何發生的錯誤都不能使消息框顯示,而是程序中返回錯誤碼。 |
這里出現的標志最要緊的是FOF_ALLOWUNDO,它決定文件是否一次就全部刪除,或存儲到‘回收站’中等候可能的恢復。如果FOF_ALLOWUNDO被設置,文件則被移動到回收站,並且這個操作可以被Undo(盡管可以手動Undo)。Undo特征僅在刪除下可用,在拷貝與移動中沒有等價的操作。
SHFileOperation()函數的返回值
MSDN資料中說明,SHFileOperation()在成功時返回0,失敗時返回非0值。顯然這是真的,但並不是最有用的解釋。重復測試這個函數,可以確信它有非常多的終止方式。事實上,我們經常在系統錯誤的提示中運行,在有些地方這個函數只是簡單地返回從更靠近文件系統的其它程序中獲得的返回碼。下面列表給出了SHFileOperation()返回的最通常的部分錯誤。
錯誤碼 |
描述 |
2 |
如果你試圖重命名多重文件,這個消息就會出現。描述是相當直接的:系統不能找到指定的文件。 |
7 |
在詢問是否想要置換給定文件時,你回答了‘取消’,函數就返回這個錯誤碼。它的描述也是相當的不明確—存儲控制塊被銷毀。 |
115 |
在試圖重命名文件到不同的文件夾時,發生這個文件系統錯。重命名文件只是改變文件名,而不能改變文件夾。 |
117 |
一個IOCTL錯(輸入/輸出控制),在目的路徑中有錯誤時或取消了新目錄的建立時,這個錯誤發生了。 |
123 |
你正在試圖重命名一個文件,然而你給出的名字是一個已經存在的文件。它也有一個無用的描述:文件名,目錄名,或卷標號的語法是不正確的。 |
1026
|
在試圖移動或拷貝一個不存在的文件時,出現這個文件系統錯。一般地,它提示了,源緩沖中的某些東西應該修改一下。這個錯誤碼彈出一個的錯誤框,你可以通過設置FOF_NOERRORUI標志抑制它的顯示。 |
原文:https://www.cnblogs.com/arsblog/p/5016553.html