2014,2,17在局域网传输文件时所遇到的问题

在局域网传输文件时所遇到的问题 在编写一些局域网应用软件时,有时需要在局域网的计算机间复制数据。如果我们将应用程序设计为网络应用程序,未免设计的有些复杂。Windows

系统提

供了一个外壳函数SHFileOperation能够实现局域网间的文件复制。该函数语法如下:

int SHFileOperation(LPSHFILEOPSTRUCT lpFileOp);

其中,lpFileOp参数是一个SHFILEOPSTRUCT结构指针,该结构定义如下: typedef struct _SHFILEOPSTRUCT {

HWND hwnd; //在文件操作过程中显示的对话框的句柄

UINT wFunc; //对文件进行的操作,FO_COPY表示复制文件,FO_DELETE表示删除文件,FO_MOVE表示移动文件,FO_RENAME表示重命名文件

LPCWSTR pFrom; //操作的源文件

LPCWSTR pTo; //目标文件

FILEOP_FLAGS fFlags; //文件操作标识

BOOL fAnyOperationsAborted; //暂未被使用

LPVOID hNameMappings; //暂未被使用

LPCWSTR lpszProgressTitle; //对话框标题

} SHFILEOPSTRUCT, *LPSHFILEOPSTRUCT;

下面我们通过一个实例来介绍局域网文件的复制。效果如图1所示。

图1 局域网文件复制

(1)创建一个基于对话框的工程,向对话框中添加静态文本、编辑框和按钮控件,效果如图2所示。

图2 对话框设计

(2)处理“复制文件”按钮的单击事件,将网络文件复制到本地磁盘。 void CNetworkFileDlg::OnCopy()

{

CString strnetwork,strlocal;

GetDlgItem(IDC_EDNETWORK)->GetWindowText(strnetwork); //获取编辑框文本

GetDlgItem(IDC_EDLOCAL)->GetWindowText(strlocal);

if(strnetwork.IsEmpty()) //验证信息是否为空

{

AfxMessageBox("请输入网络文件夹路径");

return;

}

if(strlocal.IsEmpty())

{

AfxMessageBox("请输入本地文件夹路径");

return;

}

if(strnetwork.Left(2)!="\\")

{

AfxMessageBox("路径首部应是\\");

return;

}

char fromname[80]="";

char toname[80]="";

strcpy(fromname,strnetwork);

strcpy(toname,strlocal);

strcat(fromname,"");

strcat(toname,"");

SHFILEOPSTRUCT lpFilestru; //定义一个SHFILEOPSTRUCT结构

lpFilestru.hwnd=GetSafeHwnd(); //设置窗口句柄

lpFilestru.wFunc=FO_COPY; //设置文件操作类型为复制文件操作

lpFilestru.pFrom=fromname; //设置源文件

lpFilestru.pTo=toname; //设置目标文件

lpFilestru.fFlags=FOF_ALLOWUNDO; //设置操作标识,允许取消复制操作

lpFilestru.fAnyOperationsAborted=FALSE;

BOOL bcopy=SHFileOperation(&lpFilestru); //开始复制文件

if(bcopy==0) //文件复制操作是否成功

{

if(lpFilestru.fAnyOperationsAborted==TRUE)

AfxMessageBox("复制被取消");

else

AfxMessageBox("复制成功");

}

else

{

AfxMessageBox("复制失败");

}

}

(3)运行程序,效果如图3所示。

图3 运行结果

注意红色所标出来的部分这是一体的,经鉴别例子中这应该是C语言中的用法 而VC++的用法列有不同:如下

//局域网将文件传到服务器 CString strnetwork,strlocal; GetDlgItem(IDC_EDNETWORK)->GetWindowText(strnetwork); GetDlgItem(IDC_EDLOCAL)->GetWindowText(strlocal); char fromname[80]="\0";

char toname[80]="\0"; USES_CONVERSION; //T2A将CString型转换为char型必须用 strcpy_s(fromname,T2A(strnetwork));//T2A将CString型转换为char型 strcpy_s(toname,T2A(strlocal)); strcat_s(fromname,"\0"); strcat_s(toname,"\0"); SHFILEOPSTRUCTA lpFilestru; //不同之处与C中的 lpFilestru.hwnd=GetSafeHwnd(); lpFilestru.wFunc=FO_COPY; lpFilestru.pFrom=toname; lpFilestru.pTo=fromname; //lpFilestru.pFrom=(LPCWSTR)(A2CW((LPCSTR)toname)); //lpFilestru.pTo=(LPCWSTR)(A2CW((LPCSTR)fromname)); lpFilestru.fFlags=FOF_ALLOWUNDO; lpFilestru.fAnyOperationsAborted=FALSE; BOOL bcopy=SHFileOperationA(&lpFilestru);//与C中的不同之处在于函数 /*BOOL bcopy=SHFileOperation(&lpFilestru);*/ if(bcopy==0) { if(lpFilestru.fAnyOperationsAborted==TRUE) AfxMessageBox(_T("复制被取消")); else AfxMessageBox(_T("复制成功")); } else { AfxMessageBox(_T("复制失败")); }

在VC++中的函数这是从Visual studio中考出来的,无误

typedef struct _SHFILEOPSTRUCTA

{

HWND hwnd;

UINT wFunc;

LPCSTR pFrom;

LPCSTR pTo;

FILEOP_FLAGS fFlags;

BOOL fAnyOperationsAborted;

LPVOID hNameMappings;

LPCSTR lpszProgressTitle; // only used if FOF_SIMPLEPROGRESS

} SHFILEOPSTRUCTA, *LPSHFILEOPSTRUCTA;

typedef struct _SHFILEOPSTRUCTW

{

HWND hwnd;

UINT wFunc;

LPCWSTR pFrom;

LPCWSTR pTo;

FILEOP_FLAGS fFlags;

BOOL fAnyOperationsAborted;

LPVOID hNameMappings;

LPCWSTR lpszProgressTitle; // only used if FOF_SIMPLEPROGRESS

} SHFILEOPSTRUCTW, *LPSHFILEOPSTRUCTW;

#ifdef UNICODE

typedef SHFILEOPSTRUCTW SHFILEOPSTRUCT;

typedef LPSHFILEOPSTRUCTW LPSHFILEOPSTRUCT;

#else

typedef SHFILEOPSTRUCTA SHFILEOPSTRUCT;

typedef LPSHFILEOPSTRUCTA LPSHFILEOPSTRUCT;

#endif // UNICODE

SHSTDAPI_(int) SHFileOperationA(LPSHFILEOPSTRUCTA lpFileOp);

SHSTDAPI_(int) SHFileOperationW(LPSHFILEOPSTRUCTW lpFileOp);

#ifdef UNICODE

#define SHFileOperation SHFileOperationW

#else

#define SHFileOperation SHFileOperationA

#endif // !UNICODE

SHSTDAPI_(void) SHFreeNameMappings(HANDLE hNameMappings);

typedef struct _SHNAMEMAPPINGA

{

LPSTR pszOldPath;

LPSTR pszNewPath;

int cchOldPath;

int cchNewPath;

} SHNAMEMAPPINGA, *LPSHNAMEMAPPINGA;

typedef struct _SHNAMEMAPPINGW

{

LPWSTR pszOldPath;

LPWSTR pszNewPath;

int cchOldPath;

int cchNewPath;

} SHNAMEMAPPINGW, *LPSHNAMEMAPPINGW;

#ifdef UNICODE

typedef SHNAMEMAPPINGW SHNAMEMAPPING;

typedef LPSHNAMEMAPPINGW LPSHNAMEMAPPING;

#else

typedef SHNAMEMAPPINGA SHNAMEMAPPING;

typedef LPSHNAMEMAPPINGA LPSHNAMEMAPPING;

#endif // UNICODE

SHFILEOPSTRUCT结构体和实例

CString与LPCWSTR的转化,格式转换

SHFILEOPSTRUCT结构体和实例

分类: Delphi技术讨论组 2007-03-15 16:21 1486人阅读 评论(0) 收藏 举报

delete代码分析delphistring

SHFILEOPSTRUCT结构体的定义如下:

typedef struct _SHFILEOPSTRUCT { // shfos

HWND hwnd; //显示状态信息窗口的句柄,一般设为主窗体的句柄 UINT wFunc; //要执行的操作

LPCSTR pFrom; //源文件或目录

LPCSTR pTo; //目标文件或目录

FILEOP_FLAGS fFlags; //控制文件操作的标志

BOOL fAnyOperationsAborted; //操作是否放弃

LPVOID hNameMappings; //文件名映射对象的句柄,很少用

LPCSTR lpszProgressTitle; //进度条标题,仅在fFlags标志中指定了//FO F_SIMPLEPROGRESS时有效

} SHFILEOPSTRUCT, FAR *LPSHFILEOPSTRUCT;

Delphi用记录TSHFileOpStruct对此结构做了两种封装:ANSI字符和宽字符版本。读者可 从ShellAPI单元的第265行看到如下代码:

_SHFILEOPSTRUCTA = packed record //ANSI版本

Wnd: HWND;

wFunc: UINT;

pFrom: PAnsiChar;

pTo: PAnsiChar;

fFlags: FILEOP_FLAGS;

fAnyOperationsAborted: BOOL;

hNameMappings: Pointer;

lpszProgressTitle: PAnsiChar; { only used if FOF_SIMPLEPROGRESS }

end;

{$EXTERNALSYM _SHFILEOPSTRUCTW}

_SHFILEOPSTRUCTW = packed record //宽字符版本

Wnd: HWND;

wFunc: UINT;

pFrom: PWideChar;

pTo: PWideChar;

fFlags: FILEOP_FLAGS;

fAnyOperationsAborted: BOOL;

hNameMappings: Pointer;

lpszProgressTitle: PWideChar; { only used if FOF_SIMPLEPROGRESS }

end;

{$EXTERNALSYM _SHFILEOPSTRUCT}

_SHFILEOPSTRUCT = _SHFILEOPSTRUCTA;

TSHFileOpStructA = _SHFILEOPSTRUCTA;

TSHFileOpStructW = _SHFILEOPSTRUCTW;

TSHFileOpStruct = TSHFileOpStructA;

//默认情况下TSHFileOpStruct为ANSI版本

{$EXTERNALSYM SHFILEOPSTRUCTA}

SHFILEOPSTRUCTA = _SHFILEOPSTRUCTA;

{$EXTERNALSYM SHFILEOPSTRUCTW}

SHFILEOPSTRUCTW = _SHFILEOPSTRUCTW;

{$EXTERNALSYM SHFILEOPSTRUCT}

SHFILEOPSTRUCT = SHFILEOPSTRUCTA;

//默认情况下SHFILEOPSTRUCT为ANSI版本

在ShellAPI单元的第200行对wFunc参数的取值定义了4种操作:

{$EXTERNALSYM FO_MOVE}

FO_MOVE = $0001; //移动操作,从pFrom到pTo

{$EXTERNALSYM FO_COPY}

FO_COPY = $0002; //复制操作,从pFrom到pTo

{$EXTERNALSYM FO_DELETE}

FO_DELETE = $0003; //删除操作,删除pFrom中指定的目录或文件(忽略// pTo参数)

{$EXTERNALSYM FO_RENAME}

FO_RENAME = $0004; //重命名操作,重命名pFrom中指定的目录或文件。 在ShellAPI单元的第210行对fFlags参数定义了如下可能取值:

{$EXTERNALSYM FOF_MULTIDESTFILES}

FOF_MULTIDESTFILES = $0001; //表明pTo 参数是多个文件而不是一个//目 录

{$EXTERNALSYM FOF_CONFIRMMOUSE}

FOF_CONFIRMMOUSE = $0002; //目前没有实现

{$EXTERNALSYM FOF_SILENT}

FOF_SILENT = $0004; //不创建进度条/报告

{$EXTERNALSYM FOF_RENAMEONCOLLISION}

FOF_RENAMEONCOLLISION = $0008; //当目标文件已存在时,将源文件改 //名再复制或移动

{$EXTERNALSYM FOF_NOCONFIRMATION}

FOF_NOCONFIRMATION = $0010; //操作过程中不显示确认信息,相当//于用 户选择了“yes to all”

{$EXTERNALSYM FOF_WANTMAPPINGHANDLE}

FOF_WANTMAPPINGHANDLE = $0020; //填充hNameMappings成员

{$EXTERNALSYM FOF_ALLOWUNDO}

FOF_ALLOWUNDO = $0040; //允许撤销操作

{$EXTERNALSYM FOF_FILESONLY}

FOF_FILESONLY = $0080; //只操作文件

{$EXTERNALSYM FOF_SIMPLEPROGRESS}

FOF_SIMPLEPROGRESS = $0100; //显示进度条对话框但不显示文件名 {$EXTERNALSYM FOF_NOCONFIRMMKDIR}

FOF_NOCONFIRMMKDIR = $0200; //新建目录时不提示确认

{$EXTERNALSYM FOF_NOERRORUI}

FOF_NOERRORUI = $0400; //如果操作出错,不显示用户借口 设计步骤

新建一应用程序,按照图3.1.1所示加入2个TStaticText组件、2个TEdit组件和5个TBut ton组件;TstaticText和TButton组件的Caption属性设置为如图所示,TEdit组件的Tex t属性清空。

在uses中加入FileCtrl,shellapi两单元。SelectDirectory函数用到FileCtrl单元,而 SHFileOperation函数及TSHFileOpStruct记录用到shellapi单元。

代码分析

在第一个“„”按钮的OnClick事件中加入如下代码,用于选择操作的源目录: procedure TForm1.Button4Click(Sender: TObject);

var

Dir: string;

begin

Dir := 'D:';

if SelectDirectory(Dir, [sdAllowCreate, sdPerformCreate, sdPrompt],0) then

//函数执行成功

// sdAllowCreate:允许创建目录

// sdPerformCreate:执行创建目录

// sdPrompt:显示提示信息

edit1.text:= Dir;

end;

在第二个“„”按钮的OnClick事件中加入如下代码,用于选择操作的目标目录: procedure TForm1.Button5Click(Sender: TObject);

var

Dir: string;

begin

Dir := 'D:';

if SelectDirectory(Dir, [sdAllowCreate, sdPerformCreate, sdPrompt],0) then

//解释同上

edit2.text:= Dir;

end;

在“复制”按钮的OnClick事件中加入如下代码,用于执行复制操作:

procedure TForm1.Button1Click(Sender: TObject);

var

OpStruc:TSHFileOpStruct;

FromBuf,ToBuf:Array[0..128] of Char;

begin

FillChar(FromBuf,Sizeof(FromBuf),0);

FillChar(ToBuf,Sizeof(ToBuf),0);

//用0初始化FromBuf和ToBuf数组

StrPCopy(FromBuf,Pchar(Edit1.Text));

StrPCopy(ToBuf,Pchar(Edit2.Text));

//分别在 FromBuf和ToBuf数组中填入操作的源目录及目标目录

//开始填充OpStruc记录

with OpStruc do

begin

Wnd:=Handle;

wFunc:=FO_COPY;

//复制操作

pFrom:=@FromBuf;

pTo:=@ToBuf;

fFlags:=FOF_NOCONFIRMATION or FOF_RENAMEONCOLLISION;

fAnyOperationsAborted:=False;

hNameMappings:=nil;

lpszProgressTitle:=nil;

end;

if SHFileOperation(OpStruc)=0 then

//函数执行成功

MessageBox(Handle,'复制完毕。','复制信息',MB_OK+MB_ICONINFORMATION); end;

在“移动”按钮的OnClick事件中加入如下代码,用于执行移动操作: procedure TForm1.Button2Click(Sender: TObject);

var

OpStruc:TSHFileOpStruct;

FromBuf,ToBuf:Array[0..128] of Char;

begin

FillChar(FromBuf,Sizeof(FromBuf),0);

FillChar(ToBuf,Sizeof(ToBuf),0);

StrPCopy(FromBuf,Pchar(Edit1.Text));

StrPCopy(ToBuf,Pchar(Edit2.Text));

//开始填充OpStruc记录

with OpStruc do

begin

Wnd:=Handle;

wFunc:=FO_MOVE;

//移动操作

pFrom:=@FromBuf;

pTo:=@ToBuf;

fFlags:=FOF_NOCONFIRMATION or FOF_RENAMEONCOLLISION;

fAnyOperationsAborted:=False;

hNameMappings:=nil;

lpszProgressTitle:='正在文件';

end;

if SHFileOperation(OpStruc)=0 then

//执行成功

MessageBox(Handle,'移动完毕。','移动信息',MB_OK+MB_ICONINFORMATION);

end;

在“删除”按钮的OnClick事件中加入如下代码,用于执行删除操作:

procedure TForm1.Button3Click(Sender: TObject);

var

OpStruc:TSHFileOpStruct;

FromBuf:Array[0..128] of Char;

begin

FillChar(FromBuf,Sizeof(FromBuf),0);

StrPCopy(FromBuf,Pchar(Edit1.Text));

//开始填充OpStruc记录

with OpStruc do

begin

Wnd:=Handle;

wFunc:=FO_DELETE;

pFrom:=@FromBuf;

pTo:=nil;

fFlags:=FOF_NOCONFIRMATION;

lpszProgressTitle:='正在删除';

end;

if SHFileOperation(OpStruc)=0 then

//执行成功

MessageBox(Handle,'删除完毕。','删除信息',MB_OK+MB_ICONINFORMATION);

end;

总结

注意:删除时(wFunc参数设为FO_DELETE)如果想将文件或目录放到回收站(fFlags参 数设置为FOF_ALLOWUNDO)则应该给出文件的绝对路径名,否则可能无法恢复。对于多个 文件的操作,文件名之间要以#0)字符分隔,整个字符串以两个# 0 结束。

在局域网传输文件时所遇到的问题 在编写一些局域网应用软件时,有时需要在局域网的计算机间复制数据。如果我们将应用程序设计为网络应用程序,未免设计的有些复杂。Windows

系统提

供了一个外壳函数SHFileOperation能够实现局域网间的文件复制。该函数语法如下:

int SHFileOperation(LPSHFILEOPSTRUCT lpFileOp);

其中,lpFileOp参数是一个SHFILEOPSTRUCT结构指针,该结构定义如下: typedef struct _SHFILEOPSTRUCT {

HWND hwnd; //在文件操作过程中显示的对话框的句柄

UINT wFunc; //对文件进行的操作,FO_COPY表示复制文件,FO_DELETE表示删除文件,FO_MOVE表示移动文件,FO_RENAME表示重命名文件

LPCWSTR pFrom; //操作的源文件

LPCWSTR pTo; //目标文件

FILEOP_FLAGS fFlags; //文件操作标识

BOOL fAnyOperationsAborted; //暂未被使用

LPVOID hNameMappings; //暂未被使用

LPCWSTR lpszProgressTitle; //对话框标题

} SHFILEOPSTRUCT, *LPSHFILEOPSTRUCT;

下面我们通过一个实例来介绍局域网文件的复制。效果如图1所示。

图1 局域网文件复制

(1)创建一个基于对话框的工程,向对话框中添加静态文本、编辑框和按钮控件,效果如图2所示。

图2 对话框设计

(2)处理“复制文件”按钮的单击事件,将网络文件复制到本地磁盘。 void CNetworkFileDlg::OnCopy()

{

CString strnetwork,strlocal;

GetDlgItem(IDC_EDNETWORK)->GetWindowText(strnetwork); //获取编辑框文本

GetDlgItem(IDC_EDLOCAL)->GetWindowText(strlocal);

if(strnetwork.IsEmpty()) //验证信息是否为空

{

AfxMessageBox("请输入网络文件夹路径");

return;

}

if(strlocal.IsEmpty())

{

AfxMessageBox("请输入本地文件夹路径");

return;

}

if(strnetwork.Left(2)!="\\")

{

AfxMessageBox("路径首部应是\\");

return;

}

char fromname[80]="";

char toname[80]="";

strcpy(fromname,strnetwork);

strcpy(toname,strlocal);

strcat(fromname,"");

strcat(toname,"");

SHFILEOPSTRUCT lpFilestru; //定义一个SHFILEOPSTRUCT结构

lpFilestru.hwnd=GetSafeHwnd(); //设置窗口句柄

lpFilestru.wFunc=FO_COPY; //设置文件操作类型为复制文件操作

lpFilestru.pFrom=fromname; //设置源文件

lpFilestru.pTo=toname; //设置目标文件

lpFilestru.fFlags=FOF_ALLOWUNDO; //设置操作标识,允许取消复制操作

lpFilestru.fAnyOperationsAborted=FALSE;

BOOL bcopy=SHFileOperation(&lpFilestru); //开始复制文件

if(bcopy==0) //文件复制操作是否成功

{

if(lpFilestru.fAnyOperationsAborted==TRUE)

AfxMessageBox("复制被取消");

else

AfxMessageBox("复制成功");

}

else

{

AfxMessageBox("复制失败");

}

}

(3)运行程序,效果如图3所示。

图3 运行结果

注意红色所标出来的部分这是一体的,经鉴别例子中这应该是C语言中的用法 而VC++的用法列有不同:如下

//局域网将文件传到服务器 CString strnetwork,strlocal; GetDlgItem(IDC_EDNETWORK)->GetWindowText(strnetwork); GetDlgItem(IDC_EDLOCAL)->GetWindowText(strlocal); char fromname[80]="\0";

char toname[80]="\0"; USES_CONVERSION; //T2A将CString型转换为char型必须用 strcpy_s(fromname,T2A(strnetwork));//T2A将CString型转换为char型 strcpy_s(toname,T2A(strlocal)); strcat_s(fromname,"\0"); strcat_s(toname,"\0"); SHFILEOPSTRUCTA lpFilestru; //不同之处与C中的 lpFilestru.hwnd=GetSafeHwnd(); lpFilestru.wFunc=FO_COPY; lpFilestru.pFrom=toname; lpFilestru.pTo=fromname; //lpFilestru.pFrom=(LPCWSTR)(A2CW((LPCSTR)toname)); //lpFilestru.pTo=(LPCWSTR)(A2CW((LPCSTR)fromname)); lpFilestru.fFlags=FOF_ALLOWUNDO; lpFilestru.fAnyOperationsAborted=FALSE; BOOL bcopy=SHFileOperationA(&lpFilestru);//与C中的不同之处在于函数 /*BOOL bcopy=SHFileOperation(&lpFilestru);*/ if(bcopy==0) { if(lpFilestru.fAnyOperationsAborted==TRUE) AfxMessageBox(_T("复制被取消")); else AfxMessageBox(_T("复制成功")); } else { AfxMessageBox(_T("复制失败")); }

在VC++中的函数这是从Visual studio中考出来的,无误

typedef struct _SHFILEOPSTRUCTA

{

HWND hwnd;

UINT wFunc;

LPCSTR pFrom;

LPCSTR pTo;

FILEOP_FLAGS fFlags;

BOOL fAnyOperationsAborted;

LPVOID hNameMappings;

LPCSTR lpszProgressTitle; // only used if FOF_SIMPLEPROGRESS

} SHFILEOPSTRUCTA, *LPSHFILEOPSTRUCTA;

typedef struct _SHFILEOPSTRUCTW

{

HWND hwnd;

UINT wFunc;

LPCWSTR pFrom;

LPCWSTR pTo;

FILEOP_FLAGS fFlags;

BOOL fAnyOperationsAborted;

LPVOID hNameMappings;

LPCWSTR lpszProgressTitle; // only used if FOF_SIMPLEPROGRESS

} SHFILEOPSTRUCTW, *LPSHFILEOPSTRUCTW;

#ifdef UNICODE

typedef SHFILEOPSTRUCTW SHFILEOPSTRUCT;

typedef LPSHFILEOPSTRUCTW LPSHFILEOPSTRUCT;

#else

typedef SHFILEOPSTRUCTA SHFILEOPSTRUCT;

typedef LPSHFILEOPSTRUCTA LPSHFILEOPSTRUCT;

#endif // UNICODE

SHSTDAPI_(int) SHFileOperationA(LPSHFILEOPSTRUCTA lpFileOp);

SHSTDAPI_(int) SHFileOperationW(LPSHFILEOPSTRUCTW lpFileOp);

#ifdef UNICODE

#define SHFileOperation SHFileOperationW

#else

#define SHFileOperation SHFileOperationA

#endif // !UNICODE

SHSTDAPI_(void) SHFreeNameMappings(HANDLE hNameMappings);

typedef struct _SHNAMEMAPPINGA

{

LPSTR pszOldPath;

LPSTR pszNewPath;

int cchOldPath;

int cchNewPath;

} SHNAMEMAPPINGA, *LPSHNAMEMAPPINGA;

typedef struct _SHNAMEMAPPINGW

{

LPWSTR pszOldPath;

LPWSTR pszNewPath;

int cchOldPath;

int cchNewPath;

} SHNAMEMAPPINGW, *LPSHNAMEMAPPINGW;

#ifdef UNICODE

typedef SHNAMEMAPPINGW SHNAMEMAPPING;

typedef LPSHNAMEMAPPINGW LPSHNAMEMAPPING;

#else

typedef SHNAMEMAPPINGA SHNAMEMAPPING;

typedef LPSHNAMEMAPPINGA LPSHNAMEMAPPING;

#endif // UNICODE

SHFILEOPSTRUCT结构体和实例

CString与LPCWSTR的转化,格式转换

SHFILEOPSTRUCT结构体和实例

分类: Delphi技术讨论组 2007-03-15 16:21 1486人阅读 评论(0) 收藏 举报

delete代码分析delphistring

SHFILEOPSTRUCT结构体的定义如下:

typedef struct _SHFILEOPSTRUCT { // shfos

HWND hwnd; //显示状态信息窗口的句柄,一般设为主窗体的句柄 UINT wFunc; //要执行的操作

LPCSTR pFrom; //源文件或目录

LPCSTR pTo; //目标文件或目录

FILEOP_FLAGS fFlags; //控制文件操作的标志

BOOL fAnyOperationsAborted; //操作是否放弃

LPVOID hNameMappings; //文件名映射对象的句柄,很少用

LPCSTR lpszProgressTitle; //进度条标题,仅在fFlags标志中指定了//FO F_SIMPLEPROGRESS时有效

} SHFILEOPSTRUCT, FAR *LPSHFILEOPSTRUCT;

Delphi用记录TSHFileOpStruct对此结构做了两种封装:ANSI字符和宽字符版本。读者可 从ShellAPI单元的第265行看到如下代码:

_SHFILEOPSTRUCTA = packed record //ANSI版本

Wnd: HWND;

wFunc: UINT;

pFrom: PAnsiChar;

pTo: PAnsiChar;

fFlags: FILEOP_FLAGS;

fAnyOperationsAborted: BOOL;

hNameMappings: Pointer;

lpszProgressTitle: PAnsiChar; { only used if FOF_SIMPLEPROGRESS }

end;

{$EXTERNALSYM _SHFILEOPSTRUCTW}

_SHFILEOPSTRUCTW = packed record //宽字符版本

Wnd: HWND;

wFunc: UINT;

pFrom: PWideChar;

pTo: PWideChar;

fFlags: FILEOP_FLAGS;

fAnyOperationsAborted: BOOL;

hNameMappings: Pointer;

lpszProgressTitle: PWideChar; { only used if FOF_SIMPLEPROGRESS }

end;

{$EXTERNALSYM _SHFILEOPSTRUCT}

_SHFILEOPSTRUCT = _SHFILEOPSTRUCTA;

TSHFileOpStructA = _SHFILEOPSTRUCTA;

TSHFileOpStructW = _SHFILEOPSTRUCTW;

TSHFileOpStruct = TSHFileOpStructA;

//默认情况下TSHFileOpStruct为ANSI版本

{$EXTERNALSYM SHFILEOPSTRUCTA}

SHFILEOPSTRUCTA = _SHFILEOPSTRUCTA;

{$EXTERNALSYM SHFILEOPSTRUCTW}

SHFILEOPSTRUCTW = _SHFILEOPSTRUCTW;

{$EXTERNALSYM SHFILEOPSTRUCT}

SHFILEOPSTRUCT = SHFILEOPSTRUCTA;

//默认情况下SHFILEOPSTRUCT为ANSI版本

在ShellAPI单元的第200行对wFunc参数的取值定义了4种操作:

{$EXTERNALSYM FO_MOVE}

FO_MOVE = $0001; //移动操作,从pFrom到pTo

{$EXTERNALSYM FO_COPY}

FO_COPY = $0002; //复制操作,从pFrom到pTo

{$EXTERNALSYM FO_DELETE}

FO_DELETE = $0003; //删除操作,删除pFrom中指定的目录或文件(忽略// pTo参数)

{$EXTERNALSYM FO_RENAME}

FO_RENAME = $0004; //重命名操作,重命名pFrom中指定的目录或文件。 在ShellAPI单元的第210行对fFlags参数定义了如下可能取值:

{$EXTERNALSYM FOF_MULTIDESTFILES}

FOF_MULTIDESTFILES = $0001; //表明pTo 参数是多个文件而不是一个//目 录

{$EXTERNALSYM FOF_CONFIRMMOUSE}

FOF_CONFIRMMOUSE = $0002; //目前没有实现

{$EXTERNALSYM FOF_SILENT}

FOF_SILENT = $0004; //不创建进度条/报告

{$EXTERNALSYM FOF_RENAMEONCOLLISION}

FOF_RENAMEONCOLLISION = $0008; //当目标文件已存在时,将源文件改 //名再复制或移动

{$EXTERNALSYM FOF_NOCONFIRMATION}

FOF_NOCONFIRMATION = $0010; //操作过程中不显示确认信息,相当//于用 户选择了“yes to all”

{$EXTERNALSYM FOF_WANTMAPPINGHANDLE}

FOF_WANTMAPPINGHANDLE = $0020; //填充hNameMappings成员

{$EXTERNALSYM FOF_ALLOWUNDO}

FOF_ALLOWUNDO = $0040; //允许撤销操作

{$EXTERNALSYM FOF_FILESONLY}

FOF_FILESONLY = $0080; //只操作文件

{$EXTERNALSYM FOF_SIMPLEPROGRESS}

FOF_SIMPLEPROGRESS = $0100; //显示进度条对话框但不显示文件名 {$EXTERNALSYM FOF_NOCONFIRMMKDIR}

FOF_NOCONFIRMMKDIR = $0200; //新建目录时不提示确认

{$EXTERNALSYM FOF_NOERRORUI}

FOF_NOERRORUI = $0400; //如果操作出错,不显示用户借口 设计步骤

新建一应用程序,按照图3.1.1所示加入2个TStaticText组件、2个TEdit组件和5个TBut ton组件;TstaticText和TButton组件的Caption属性设置为如图所示,TEdit组件的Tex t属性清空。

在uses中加入FileCtrl,shellapi两单元。SelectDirectory函数用到FileCtrl单元,而 SHFileOperation函数及TSHFileOpStruct记录用到shellapi单元。

代码分析

在第一个“„”按钮的OnClick事件中加入如下代码,用于选择操作的源目录: procedure TForm1.Button4Click(Sender: TObject);

var

Dir: string;

begin

Dir := 'D:';

if SelectDirectory(Dir, [sdAllowCreate, sdPerformCreate, sdPrompt],0) then

//函数执行成功

// sdAllowCreate:允许创建目录

// sdPerformCreate:执行创建目录

// sdPrompt:显示提示信息

edit1.text:= Dir;

end;

在第二个“„”按钮的OnClick事件中加入如下代码,用于选择操作的目标目录: procedure TForm1.Button5Click(Sender: TObject);

var

Dir: string;

begin

Dir := 'D:';

if SelectDirectory(Dir, [sdAllowCreate, sdPerformCreate, sdPrompt],0) then

//解释同上

edit2.text:= Dir;

end;

在“复制”按钮的OnClick事件中加入如下代码,用于执行复制操作:

procedure TForm1.Button1Click(Sender: TObject);

var

OpStruc:TSHFileOpStruct;

FromBuf,ToBuf:Array[0..128] of Char;

begin

FillChar(FromBuf,Sizeof(FromBuf),0);

FillChar(ToBuf,Sizeof(ToBuf),0);

//用0初始化FromBuf和ToBuf数组

StrPCopy(FromBuf,Pchar(Edit1.Text));

StrPCopy(ToBuf,Pchar(Edit2.Text));

//分别在 FromBuf和ToBuf数组中填入操作的源目录及目标目录

//开始填充OpStruc记录

with OpStruc do

begin

Wnd:=Handle;

wFunc:=FO_COPY;

//复制操作

pFrom:=@FromBuf;

pTo:=@ToBuf;

fFlags:=FOF_NOCONFIRMATION or FOF_RENAMEONCOLLISION;

fAnyOperationsAborted:=False;

hNameMappings:=nil;

lpszProgressTitle:=nil;

end;

if SHFileOperation(OpStruc)=0 then

//函数执行成功

MessageBox(Handle,'复制完毕。','复制信息',MB_OK+MB_ICONINFORMATION); end;

在“移动”按钮的OnClick事件中加入如下代码,用于执行移动操作: procedure TForm1.Button2Click(Sender: TObject);

var

OpStruc:TSHFileOpStruct;

FromBuf,ToBuf:Array[0..128] of Char;

begin

FillChar(FromBuf,Sizeof(FromBuf),0);

FillChar(ToBuf,Sizeof(ToBuf),0);

StrPCopy(FromBuf,Pchar(Edit1.Text));

StrPCopy(ToBuf,Pchar(Edit2.Text));

//开始填充OpStruc记录

with OpStruc do

begin

Wnd:=Handle;

wFunc:=FO_MOVE;

//移动操作

pFrom:=@FromBuf;

pTo:=@ToBuf;

fFlags:=FOF_NOCONFIRMATION or FOF_RENAMEONCOLLISION;

fAnyOperationsAborted:=False;

hNameMappings:=nil;

lpszProgressTitle:='正在文件';

end;

if SHFileOperation(OpStruc)=0 then

//执行成功

MessageBox(Handle,'移动完毕。','移动信息',MB_OK+MB_ICONINFORMATION);

end;

在“删除”按钮的OnClick事件中加入如下代码,用于执行删除操作:

procedure TForm1.Button3Click(Sender: TObject);

var

OpStruc:TSHFileOpStruct;

FromBuf:Array[0..128] of Char;

begin

FillChar(FromBuf,Sizeof(FromBuf),0);

StrPCopy(FromBuf,Pchar(Edit1.Text));

//开始填充OpStruc记录

with OpStruc do

begin

Wnd:=Handle;

wFunc:=FO_DELETE;

pFrom:=@FromBuf;

pTo:=nil;

fFlags:=FOF_NOCONFIRMATION;

lpszProgressTitle:='正在删除';

end;

if SHFileOperation(OpStruc)=0 then

//执行成功

MessageBox(Handle,'删除完毕。','删除信息',MB_OK+MB_ICONINFORMATION);

end;

总结

注意:删除时(wFunc参数设为FO_DELETE)如果想将文件或目录放到回收站(fFlags参 数设置为FOF_ALLOWUNDO)则应该给出文件的绝对路径名,否则可能无法恢复。对于多个 文件的操作,文件名之间要以#0)字符分隔,整个字符串以两个# 0 结束。


相关文章

  • 2014年四川省专升本计算机试题1.2
  • 一.单选题 (每小题1分) 1. 微机存储器容量的单位是( ). A.位 B.字节 C.字 D.bit 2. 某单位自行开发的工资管理系统,按计算机应用的类型划分,它属 于( ). A.科学计算 B.辅助设计 C.数据处理 D.实时控制 3 ...查看


  • 2014山西信息技术会考模拟题
  • 1.关于电子邮件的下列说法中,不正确的是 A.只有主题而没有正文内容的邮件也可以成 功发送 B.压缩文件可以作为电子邮件的附件 C.一封电子邮件可以附带多个附件 D.一封电子邮件只能有一个收件人 2. 计算机网络的基本功能是 A.提高计算机 ...查看


  • 2014辽宁省最新公共基础知识试题及答案
  • 1.全球信息网(WWW)的主要传输的通讯协议是____. A.FTP B.HTTP C.HTML D.XMTP 2.在WINDOW中,有两个对系统资源进行管理的程序组,它们是资源管理器和____ A.回收站 B.剪贴板 C.我的电脑 D.我 ...查看


  • 2014辽宁省事业编公共基础知识最新考试试题库(完整版)
  • 1.TCP/IP是一种_____. A .网络操作系统 B.网络协议 C .网络体系结构 D.内存容量大 2.广域网和局域网是按照____来分的. A .网络使用者 B.信息交换方式 C.网络连接距离 D.传输控制规程 3.在Interne ...查看


  • 昆明理工大学 计算机网络基础 期末考点
  • 计算机网络基础 期末复习(修订) 考试时间:2014-06-17(17周 星期二)09:20-11:20 考试地点:中心101 座位号:13 考试题型 1.选择题 60分 共30题 2.简答题 30分 共6题 3.综合题 10分 共1题 ( ...查看


  • 计算机名词解释
  • 一. 名词解释 1. 信息:广义地说,信息就是消息. 2. 信息技术:以微电子为基础,通过通信技术.计算机技术.及控制技术相结合,研究信息的获取.传输.存储 和处理的技术. 3. 基本信息技术:感知与识别技术.通信技术.计算与存储技术.控制 ...查看


  • 2013-2014华工计算机应用基础随堂练习答案
  • 第一章计算机基础知识 1. 计算机能直接识别并执行的语言是______. A. 汇编语言 B.自然语言 C. 机器语言 D.高级语言 答题:C 2. 计算机存储容量的基本单位是_____. A. 赫兹 B. 字节(Byte )C. 位 (b ...查看


  • 银监会专业笔试
  • 2015年的银监会计算机类专业科目笔试的真题.举例如下: [例1]"science"是XML 中一个元素的定义,其中元素的内容是( ). A.title B.style C.italic D.science [例2]SQ ...查看


  • 2014陕西省[公共基础知识]考资料
  • 1.微型计算机中运算器的主要功能是进行____ A.算术运算 B.逻辑运算 C.算术和逻辑运算 D.初等函数运算 2.如果希望在演示过程中终止幻灯片的演示,则随时可按的终止键是_____. A.delete B.ctrl+e C.shift ...查看


热门内容