再加送50(合计100)大洋,继续求教API shfileoperation 用法(50分)

  • 主题发起人 主题发起人 canna
  • 开始时间 开始时间
C

canna

Unregistered / Unconfirmed
GUEST, unregistred user!
各位高手:
上次提出的问题,尚未得到解决。不惜加码50大洋,连同上次的
酬金,能解此疑团者,即刻送上100大洋。
曾给本人指出方向者为3h,但随即消失。真是高人不露相。在此
也征求3h的email,以便登门求教。
原问题为:
使用shfileoperation(),其参数pfrom设置以'd:/tmp/customer.db'
形式,正常。而以directorylistbox1+'/'+filelistbox1.items[mi]
形式赋值,则出现无法打开文件错误。这可能是c与delphi字符串的区别
造成的,如何解决。

 
我想我找到了正确答案:
关键在于:M$的文档说对于多个文件,每个文件名必须被#)字符分隔,而整个字符串
必须用两个#0结束。
所以我用以下例程就成功了: :-))

procedure TForm1.Button1Click(Sender: TObject);
var
shfo :TSHFileOpStruct;
from :string;
pstr :array [0..MAX_PATH-1] of char;
begin
FillChar(pstr,MAX_PATH,#0); //一定要加这句话哟!!
from := FileListbox1.FileName //我仅仅用一个文件测试了一下,你的
//程序原理是一样的
strpcopy(pstr,from); // !!!!
with shfo do
begin
wnd := Handle;
wFunc := FO_COPY;
pfrom := pstr;
pto := 'd:/temp';
fFlags := FOF_ALLOWUNDO or FOF_RENAMEONCOLLISION;
end;
if ShFileOperation(shfo) <> 0 then
ShowMessage('Failed')
else
ShowMessage('ok');
end;
 
上面输错了:
M$的文档说对于多个文件,各个文件名之间必须以#0字符分隔,而整个字符串必须用两个#0结束。
 
From变量与Delphi的保留字重复,易于产生二义性。
 
柳五公子:
你的方法可以实现copy,但出现大量的错误“无法复制文件:
文件系统错误(1026)”。看来还不完善,请仔细校验。
等你的消息,我就把银子给你送来。
 
; fFlags := FOF_ALLOWUNDO or FOF_FILESONLY or FOF_NOCONFIRMATION
end;
if ShFileOperation(shfo) <> 0 thencanna:
我按照你的要求用两种方法改了一下程序,你再试试:

//方法一:各文件单独拷贝
procedure TForm1.Button2Click(Sender: TObject);
var
shfo :TSHFileOpStruct;
s :string;
pstr :array [0..MAX_PATH-1] of char;
mi :integer;
begin
with shfo do
begin
wnd := Handle;
wFunc := FO_COPY;
pto := 'd:/temp';
fFlags := FOF_ALLOWUNDO or FOF_FILESONLY or FOF_NOCONFIRMATION
end;
for mi:=0 to FileListbox1.items.Count-1 do
begin
FillChar(pstr,MAX_PATH,#0);
s := FileListbox1.items[mi]
strpcopy(pstr,s);
shfo.pFrom := pstr;
if ShFileOperation(shfo) <> 0 then
begin
ShowMessage('Copy file '+s+' Failed!')
Exit;
end;
end;
ShowMessage('Copy files Ok !');
end;

//方法二:文件批处理拷贝 (推荐)
procedure TForm1.Button3Click(Sender: TObject);
const
MAX_LEN :2048; //2k
var
shfo :TSHFileOpStruct;
pstr :array [0..MAX_LEN-1] of char;
pt :pchar;
s :string;
i :integer;
begin
FillChar(pstr,MAX_LEN,#0);
pt := pstr;
for i:=0 to FileListbox1.items.Count-1 do
begin
s := filelistbox1.Items;
Strpcopy(pt,s);
pt := pt+ length(s)+1;
end;

with shfo do
begin
wnd := Handle;
wFunc := FO_COPY;
pfrom := pstr;
pto := 'd:/temp';

ShowMessage('Failed')
else
ShowMessage('ok');

end;

还有fFlags,你要按照自己想要的设置!
 
怎么贴过去的程序的后面那块掉了一段,:-(,重贴一下:

//方法二:文件批处理拷贝 (推荐)
procedure TForm1.Button3Click(Sender: TObject);
const
MAX_LEN = 2048; //2k
var
shfo :TSHFileOpStruct;
pstr :array [0..MAX_LEN-1] of char;
pt :pchar;
s :string;
i :integer;
begin
FillChar(pstr,MAX_LEN,#0);
pt := pstr;
for i:=0 to FileListbox1.items.Count-1 do
begin
s := filelistbox1.Items;
Strpcopy(pt,s);
pt := pt+ length(s)+1;
end;
with shfo do
begin
wnd := Handle;
wFunc := FO_COPY;
pfrom := pstr;
pto := 'd:/temp';
fFlags := FOF_ALLOWUNDO or FOF_FILESONLY or FOF_NOCONFIRMATION or FOF_SIMPLEPROGRESS;
end;
if ShFileOperation(shfo) <> 0 then
ShowMessage('Failed')
else
ShowMessage('ok');
end;
 
柳五公子,你好:
你推荐的方法二较好。仍有小问题。
我设计该程序的目的是,定时进行网络数据库文件备份。其中关键的
一点是能copy共享文件,这是使用ShFileOperation的原因。
经你的指点,程序如下。尚存问题是,启动该程序,第一次copy
共享文件(近100个网络数据库文件)时,出现“共享冲突”错误,
当成功copy其他路径下未共享的文件后,再copy原共享文件时,
则可成功copy。请再校验。

procedure Tdatmove.BitBtn1Click(Sender: TObject);
const max_len=2048;
var shfo:TShFileOpstruct;
pstr:array [0..max_len-1] of char;
pt: pchar;
s: string;
i: integer;
begin
fillchar(pstr,max_len,#0);
pt:=pstr;
for i:=0 to filelistbox1.items.count-1 do
begin
s:=filelistbox1.items;
strpcopy(pt,s);
pt:=pt+length(s)+1;
end;
with shfo do
begin
wnd:=handle;
wfunc:=fo_copy;
pfrom:=pstr;
pTo:=pchar(directorylistbox2.directory);
fFlags:=fof_allowundo or fof_simpleprogress;
end;
if ShFileOperation(shfo)<>0 then showmessage('操作失败');
end;
 
canna:
我考虑了一下你说的现象,据我估计是因为数据库正在操作的原因--此时文件
属性已经被设为OF_SHARE_EXCLUSIVE(禁止其他进程读写)--你可以用第一种方法找
到到底是哪个文件正在操作。因而导致“共享冲突”错误,与程序倒没什么关系,但
程序还是有些问题,因为是网络共享文件,所以fFlags里不应包含fof_allowundo,
我又改了一下,如果还有什么问题,你再告诉我:

procedure TForm1.Button3Click(Sender: TObject);
const
MAX_LEN = 2048; //2k
var
shfo :TSHFileOpStruct;
pstr :array [0..MAX_LEN-1] of char;
pstr2:array [0..MAX_LEN-1] of char;
pt :pchar;
s :string;
i :integer;
begin
FillChar(pstr,MAX_LEN,#0);
FillChar(pstr2,MAX_LEN,#0);
strpcopy(pstr2,directorylistbox2.directory);
pt := pstr;
for i:=0 to FileListbox1.items.Count-1 do
begin
s := filelistbox1.Items;
Strpcopy(pt,s);
pt := pt+ length(s)+1;
end;
with shfo do
begin
wnd:=handle;
wfunc:=fo_copy;
pfrom:=pstr;
pTo:=pstr2;
fFlags:= fof_simpleprogress;
lpszProgressTitle := PAnsiChar('网络数据库文件备份中...');
end;
if ShFileOperation(shfo)<>0 then
showmessage('操作失败')
else
ShowMessage('Ok');
end;
 
柳五公子,你好:
按你新的提示改动后,“共享冲突”错误仍未解决。win9x能够对
共享文件进行copy,这是我使用ShFileOperation的原因和关键,我想
是某个变量或参数设置不当,程序中可以设法避免。请再研究。
 
这个页面害的我收了半个小时(老是超时),所以下次讨论我们就换到你的前面那
个问题里面去,好吗?
因为我的程序在发给你之前都测试过了,但我没有发现你说的那个问题,所以
我提供一些方法,你试一下,看看问题究竟出在什么地方:
1、把网络数据库文件所在目录映射为网络驱动器(你可能就是这么做的)
2、选个数据库不在操作的时间,分别试一下程序1,2。确定一下是数据库操作的原
因,还是程序的原因导致你说的问题。
3、如果仍有问题,用程序1找到是那个文件,再手动拷一下试试。
因为我想不出程序里还会有什么问题?
 
柳五公子,你好:
问题依然存在,也可能是其他原因引致。先把银子给你送来,如找到
解决办法,还望及时告知。email:everdove@163.net

 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
D
回复
0
查看
1K
DelphiTeacher的专栏
D
D
回复
0
查看
1K
DelphiTeacher的专栏
D
D
回复
0
查看
2K
DelphiTeacher的专栏
D
后退
顶部