概況
函式功能描述:檔案操作,與 Shell 的動作相同.
Delphi
: =====================================
functionCopyDir(const SourceDir,DestDir: string): Boolean;
var
lpFileOp: TSHFileOpStruct;
begin
withlpFileOp do
begin
Wnd := Application.Handle;
wfunc := FO_COPY;
pFrom := pchar(SourceDir);
pTo := pchar(DestDir);
fFlags := FOF_ALLOWUNDO;
hNameMappings := nil;
lpszProgressTitle := nil;
fAnyOperationsAborted := false;
end; Result:= (SHFileOperation(lpFileOp) = 0);end; usesShellApi;//
VC
=============================================
函式原型:
int SHFileOperation( _Inout_ LPSHFILEOPSTRUCT lpFileOp);
需要的庫檔案:
#include <Shlwapi.h>
#pragma comment (lib,"Shlwapi.lib")
參數
lpFileOp : 一個指向SHFILEOPSTRUCT結構的指針
返回值:
返回0成功,
SHFILEOPSTRUCT結構說明
typedef struct _SHFILEOPSTRUCT {
HWND hwnd;
UINT wFunc;
PCZZTSTR pFrom;
PCZZTSTR pTo;
FILEOP_FLAGS fFlags;
BOOL fAnyOperationsAborted;
LPVOID hNameMappings;
PCTSTR lpszProgressTitle;
} SHFILEOPSTRUCT, *LPSHFILEOPSTRUCT;
hwnd; //父視窗句柄, 0為桌面
wFunc; 功能標識
FO_COPY 複製
FO_DELETE 刪除
FO_MOVE 移動
FO_RENAME 重命名
pFrom 源檔案或者源資料夾,(source file)
pTo 目的檔案或資料夾 (destination)
fFlags 控制檔案的標誌位
FOF_ALLOWUNDO 準許撤銷
FOF_CONFIRMMOUSE 沒有被使用,,,
FOF_FILESONLY
通配符的檔案名稱( *.* )只對檔案(不是資料夾)進行操作。
FOF_MULTIDESTFILES
The pTo member specifies multiple destination files (one for each source file in pFrom)
rather than one directory where all source files are to be deposited.
(不知道怎么翻譯過來,大家體驗一下精髓)
FOF_NOCONFIRMATION 不出現任何對話框
FOF_NOCONFIRMMKDIR 創建資料夾的時候不用確認
FOF_NO_CONNECTED_ELEMENTS
Version 5.0適用,,不移動連線檔案(connected files),只移動特定檔案
FOF_NOCOPYSECURITYATTRIBS
Version 4.71適用,,複製移動檔案的時候不複製安全屬性,而是為檔案指定新的安全屬性
FOF_NOERRORUI 如果發生錯誤, 不要 顯示對話框給用戶
FOF_NORECURSEREPARSE 沒有被使用
FOF_NORECURSION 不遞歸目錄
FOF_NO_UI
Windows Vista中,默默的進行操作,不給用戶呈現任何UI。
這相當於FOF_SILENT | FOF_NOCONFIRMATION | FOF_NOERRORUI
|FOF_NOCONFIRMMKDIR 。
FOF_RENAMEONCOLLISION 移動複製的時候如果名字重名,自動分配新名字
FOF_SILENT 不顯示進度條提示框
FOF_SIMPLEPROGRESS 顯示一個進度條,但不顯示單個檔案名稱,
FOF_WANTMAPPINGHANDLE
如果指定了FOF_RENAMEONCOLLISION,說明此時是在重命名,
分配一個名稱映射對象,其中包含他們的舊的和新的名字到hNameMappings成員。
如果不再使用,需要用SHFreeNameMappings釋放。
FOF_WANTNUKEWARNING
當一個檔案被永久刪除的時候,彈出警告框
===================
實例:
BOOL CopyDirFileAPI(CString strSrcPath, CString strDesPath)
{
//拷貝檔案
if (strSrcPath.GetAt(strSrcPath.GetLength()-1) == '\\' || strSrcPath.GetAt(strSrcPath.GetLength()-1) == '/')
{
strSrcPath = strSrcPath.Left(strSrcPath.GetLength()-1);
}
if (strDesPath.GetAt(strDesPath.GetLength()-1) == '\\' || strDesPath.GetAt(strDesPath.GetLength()-1) == '/')
{
strDesPath = strDesPath.Left(strDesPath.GetLength()-1);
}
char szFrom[MAX_PATH] = {0};
char szTo[MAX_PATH] = {0};
strSrcPath = strSrcPath+"\\*.*";
strcpy(szFrom, (LPCTSTR)strSrcPath);
szFrom[strSrcPath.GetLength()+1]="\0";
//strDes=strDes+"\\*.*";
strcpy(szTo,(LPCTSTR)strDesPath);
szTo[strDesPath.GetLength()+1]="\0";
int nOk=2000;
char strTitle[] = "正在拷貝檔案,請稍候..."; //進度條標題
SHFILEOPSTRUCT FileOp;
const char * From = szFrom;
const char * To = szTo;
FileOp.hwnd = this->m_hWnd;
FileOp.wFunc = FO_COPY; //執行檔案拷貝
FileOp.pFrom = From;
FileOp.pTo = To;
FileOp.fFlags = FOF_ALLOWUNDO | FOF_NOCONFIRMATION;
FileOp.hNameMappings = NULL;
FileOp.lpszProgressTitle = strTitle;
nOk = SHFileOperation(&FileOp);
if (FileOp.fAnyOperationsAborted) //防止出現低配置光碟機BUG
{
nOk=1;
}
if (nOk==1)
{
return false;
}
Sleep(200);
return true;
}
vb.
Public Structure SHFILEOPSTRUCT
Dim hwnd As IntPtr
Dim wFunc As Integer
Dim pFrom As String
Dim pTo As String
Dim fFlags As Short
Dim fAnyOperationsAborted As Integer
Dim hNameMappings As IntPtr
Dim lpszProgressTitle As String
End Structure
Public Declare Function SHFileOperation Lib "shell32.dll" Alias "SHFileOperationA" (ByRef lpFileOp As SHFILEOPSTRUCT) As Integer
======================
vb
Type SHFILEOPSTRUCT
hWnd As Long
wFunc As Long
pFrom As String '必須用 pFrom & vbNullChar & vbNullChar
pTo As String '同pFrom
fFlags As Integer
fAnyOperationsAborted As Boolean
hNameMappings As Long
lpszProgressTitle As String
End Type
Public Declare Function SHFileOperation Lib "shell32.dll" Alias "SHFileOperationA" (lpFileOp As SHFILEOPSTRUCT) As Long
=======================
wFunc 可以為:
/FO_MOVE 0x0001 移動檔案
FO_COPY 0x0002 複製檔案
FO_DELETE 0x0003 刪除 檔案,只使用 pFrom
FO_RENAME 0x0004 檔案重命名
fFlags可以為:
FOF_MULTIDESTFILES 0x0001 //pTo 指定了多個目標檔案,而不是單個目錄
FOF_CONFIRMMOUSE 0x0002
FOF_SILENT 0x00044 // 不顯示一個進度對話框
FOF_RENAMEONCOLLISION 0x0008 // 碰到有牴觸的名字時,自動分配前綴
FOF_NOCONFIRMATION 0x0010 // 不對用戶顯示提示
FOF_WANTMAPPINGHANDLE 0x0020 // 填充 hNameMappings 欄位,必須使用 SHFreeNameMappings 釋放
FOF_ALLOWUNDO 0x0040 // 允許撤銷
FOF_FILESONLY 0x0080 // 使用 *.* 時, 只對檔案操作
FOF_SIMPLEPROGRESS 0x0100 // 簡單進度條,意味者不顯示檔案名稱。
FOF_NOCONFIRMMKDIR 0x0200 // 建新目錄時不需要用戶確定
FOF_NOERRORUI 0x0400 // 不顯示出錯用戶界面
FOF_NOCOPYSECURITYATTRIBS 0x0800 // 不複製 NT 檔案的安全屬性
FOF_NORECURSION 0x1000 // 不遞歸目錄
返回值:
函式成功返回 0 ,失敗返回非 0 。
例子:
1. 將 C:\Test.txt 拷貝到 D:\
SHFILEOPSTRUCT lpsh;
ZeroMemory(&lpsh,sizeof(lpsh));
lpsh.hwnd= HWND_DESKTOP;
lpsh.fFlags=FOF_NOCONFIRMATION|FOF_SIMPLEPROGRESS ;
lpsh.wFunc=FO_COPY; // FO_MOVE 則是移動
lpsh.pFrom= "C:\Test.txt";
lpsh.pTo = "D:\";
if( 0 != SHFileOperation(&lpsh))
{AfxMessageBox("複製檔案出錯,請檢查");return ;}
2. 刪除 D:\Test.txt
SHFILEOPSTRUCT lpsh;
ZeroMemory(&lpsh,sizeof(lpsh));
lpsh.hwnd= HWND_DESKTOP;
lpsh.fFlags=FOF_NOCONFIRMATION|FOF_SIMPLEPROGRESS ;
lpsh.wFunc=FO_DELETE;
lpsh.pFrom= "D:\Test.txt";
if( 0 != SHFileOperation(&lpsh))
{AfxMessageBox("刪除檔案出錯,請檢查");return ;}
3.重命名
SHFILEOPSTRUCT lpsh;
ZeroMemory(&lpsh,sizeof(lpsh));
lpsh.hwnd= HWND_DESKTOP;
lpsh.fFlags=FOF_NOCONFIRMATION|FOF_SIMPLEPROGRESS ;
lpsh.wFunc=FO_RENAME;
lpsh.pFrom= "D:\Test.txt";
lpsh.pTo = "D:\Test2.txt";
if( 0 != SHFileOperation(&lpsh))
{AfxMessageBox("重命名檔案出錯!");return ;}
4.VB
Public Declare Function SHFileOperation Lib "shell32.dll" Alias "SHFileOperationA" (lpFileOp As SHFILEOPSTRUCT) As Long
Public Const FO_COPY = &H2
Public Const FOF_ALLOWUNDO = &H40
Public Sub ShellCopyFile(Source As String, Dest As String)
Dim result As Long
Dim fileop As SHFILEOPSTRUCT
With fileop
.hwnd = 0
.wFunc = FO_COPY
.pFrom = Source & vbNullChar & vbNullChar
.pTo = Dest & vbNullChar & vbNullChar
.fFlags = FOF_ALLOWUNDO
End With
result = SHFileOperation(fileop)
If result <> 0 Then
'Msgbox the error that occurred in the API.
MsgBox Err.LastDllError, vbCritical Or vbOKOnly
Else
If fileop.fAnyOperationsAborted <> 0 Then
MsgBox "Operation Failed", vbCritical Or vbOKOnly
End If
End If
End Sub