📄 fileandclientinfoctrlunit.pas
字号:
procedure TFileAndInfoCtrlForm.ShellListViewDragDrop(Sender,
Source: TObject; X, Y: Integer);
var
TargetItem, SourceItem : TListItem;
tmpStr : string;
i : longint;
FileName : string;
begin
try
//下载文件
if (Source = ListViewFile) then
begin
if (Pos(':', ShellComboBox.Path) <> 0) and (ClientSocket <> 0) then
begin
for i := 0 to ListViewFile.Items.Count - 1 do
begin
//暂时不实现传输文件夹的功能
if (ListViewFile.Items[i].Selected) and (ListViewFile.Items[i].SubItems[0] <> '文件夹') and
(ListViewFile.Items[i].SubItems[0] <> '文件')then
begin
SourceItem := ListViewFile.Items[i];
TargetItem := ListViewTransmitList.Items.Add;
TargetItem.ImageIndex := 1;
//将不包括文件路径信息的文件名加入列表
TargetItem.SubItems.Add(ListViewFile.Items[i].Caption);
//加入远程主机IP
TargetItem.SubItems.Add(MainClientSocketIP_IO^.ExternalIPaddressString);
//将远程文件名加入列表
if SourceItem.SubItems[0] = '文件夹' then
begin
tmpStr := SourceItem.SubItems[3];
if tmpStr[Length(tmpStr)] <> '\' then tmpStr := tmpStr + '\';
TargetItem.SubItems.Add(tmpStr);
end
else
TargetItem.SubItems.Add(SourceItem.SubItems[3]);
//将本地文件夹加入列表
TargetItem.SubItems.Add(ShellComboBox.Path);
//添加主socket
TargetItem.SubItems.Add(IntToStr(ClientSocket));
end;
end;
StatusBarMsg.Panels[1].Text := '传输队列:' + IntTostr(ListViewTransmitList.Items.Count);
try
//发送接收文件命令,
PageControl1.Enabled := False;
//-------发送列表里面的倒数第一个文件------
if (ClientSocket <> 0) then
begin
//定位到列表的最后一个
i := ListViewTransmitList.Items.Count - 1;
//得到源文件
FileName := ListViewTransmitList.Items[i].SubItems.Strings[2];
//得到目标文件
tmpStr := ListViewTransmitList.Items[i].SubItems.Strings[3];
if tmpStr[Length(tmpStr)] <> '\' then tmpStr := tmpStr + '\';
//得到目标文件名(包含路径)
tmpStr := tmpStr + ListViewTransmitList.Items[i].SubItems.Strings[0];
if FileExists(tmpStr) then
begin
if MessageBoxEx(Self.Handle, '文件已存在,是否进行覆盖?选“是”覆盖,“否”继传',
'文件已存在', MB_YESNO or MB_ICONQUESTION or MB_APPLMODAL, $0804) = IDYES then
begin
CMDHeader.ExdSource := 0;
RecvFileStream := TFileStream.Create(tmpStr, fmOpenReadWrite);
end
else
begin
CMDHeader.ExdSource := GetFileSize(tmpStr);
RecvFileStream := TFileStream.Create(tmpStr, fmOpenReadWrite);
//文件流指针下移
RecvFileStream.Seek(CMDHeader.ExdSource, soFromBeginning);
end;
end
else
begin
CMDHeader.ExdSource := 0;
RecvFileStream := TFileStream.Create(tmpStr, fmCreate);
end;
CMDHeader.Order := SendFile;
//显示进度条
FileProgressBar.Position := 0;
FileProgressBar.Visible := True;
//发送命令,并将文件名和继传点传递过去
SetCmdSignByte(ClientSocket, CMDHeader, False, FileName);
end;
except
end;
end;
end;
except
showmessage('拖拽出错');
end;
end;
//结束拖拽,接受文件上传
procedure TFileAndInfoCtrlForm.ListViewFileDragDrop(Sender,
Source: TObject; X, Y: Integer);
var
TargetItem : TListItem;
tmpStr : string;
i : longint;
begin
//上传文件
if (Source = ShellListView) and (RCBTreeList.Text <> '我的电脑') and
(ClientSocket <> 0) then
begin
EnterCriticalSection(ListAccessSemaphore);
for i := 0 to ShellListView.Items.Count - 1 do
begin
if ShellListView.Items[i].Selected then
begin
tmpStr := ShellListView.Folders[i].PathName;
//先不传输文件夹,等以后实现之
if DirectoryExists(tmpStr) then Continue;
TargetItem := ListViewTransmitList.Items.Add;
TargetItem.ImageIndex := 0;
//将不包括文件路径信息的文件名加入列表
TargetItem.SubItems.Add(ShellListView.Folders[i].PathName);
//加入远程主机IP
TargetItem.SubItems.Add(MainClientSocketIP_IO^.ExternalIPaddressString);
//将远程文件夹加入列表
TargetItem.SubItems.Add(RCBTreeList.Text);
//将本地带有路径信息的文件名加入列表
TargetItem.SubItems.Add(tmpStr);
//添加主socket
TargetItem.SubItems.Add(IntToStr(ClientSocket));
end;
end;
StatusBarMsg.Panels[1].Text := '传输队列:' + IntTostr(ListViewTransmitList.Items.Count);
LeaveCriticalSection(ListAccessSemaphore);
end;
end;
//接受一个文件下载完成的消息
procedure TFileAndInfoCtrlForm.ReceiveNotifyFileOkMsg(var Message: TMessage);
var
tmpStr : string;
i : longint;
FileName : string;
begin
if ListViewTransmitList.Items.Count > 0 then
ListViewTransmitList.Items.Delete(ListViewTransmitList.Items.Count - 1);
StatusBarMsg.Panels[1].Text := '传输队列:' + IntTostr(ListViewTransmitList.Items.Count);
StatusBarMsg.Panels[0].Text := '下载速度:';
//反馈ok
SetEvent(MsgDealDataOkNotifyEvent);
//检查列表里面是否还有文件
if ListViewTransmitList.Items.Count > 0 then
begin
i := ListViewTransmitList.Items.Count - 1;
//上传文件
if ListViewTransmitList.Items[i].ImageIndex = 0 then
begin
end
//下载文件
else
begin
if (ClientSocket <> 0) then
begin
//得到源文件
FileName := ListViewTransmitList.Items[i].SubItems.Strings[2];
//得到目标文件
tmpStr := ListViewTransmitList.Items[i].SubItems.Strings[3];
if tmpStr[Length(tmpStr)] <> '\' then tmpStr := tmpStr + '\';
//得到目标文件名(包含路径)
tmpStr := tmpStr + ListViewTransmitList.Items[i].SubItems.Strings[0];
if FileExists(tmpStr) then
begin
if MessageBoxEx(Self.Handle, '文件已存在,是否进行覆盖?选“是”覆盖,“否”继传',
'文件已存在', MB_YESNO or MB_ICONQUESTION or MB_APPLMODAL, $0804) = IDYES then
begin
CMDHeader.ExdSource := 0;
RecvFileStream := TFileStream.Create(tmpStr, fmOpenReadWrite);
end
else
begin
CMDHeader.ExdSource := GetFileSize(tmpStr);
RecvFileStream := TFileStream.Create(tmpStr, fmOpenReadWrite);
//文件流指针下移
RecvFileStream.Seek(CMDHeader.ExdSource, soFromBeginning);
end;
end
else
begin
CMDHeader.ExdSource := 0;
RecvFileStream := TFileStream.Create(tmpStr, fmCreate);
end;
CMDHeader.Order := SendFile;
//显示进度条
FileProgressBar.Position := 0;
FileProgressBar.Visible := True;
//发送命令,并将文件名和继传点传递过去
SetCmdSignByte(ClientSocket, CMDHeader, False, FileName);
end;
end;
end
else
begin
PageControl1.Enabled := True;
end;
end;
//接收更新进度条消息
procedure TFileAndInfoCtrlForm.ReceiveNotifyFileProcMsg(var Message: TMessage);
var
CurrenrSize : DWORD;
CurrenrTime : DWORD;
CurrentPackageSize : WORD;
Percent : Byte;
begin
//得到时间间隔
CurrenrTime := GetTickCount - TransmitTime;
//得到大小
CurrenrSize := MakeLong(Message.LParam, Message.WParam);
//得到本次传输的大小
CurrentPackageSize := CurrenrSize - CurrenrTransmitFileSize;
//每秒显示一次
if CurrenrTime >= 1000 then
begin
StatusBarMsg.Panels[0].Text := Format('下载速度:%fK/S', [(CurrentPackageSize / 1024 / CurrenrTime) * 1000]);
//更新目前的已传输的文件大小
CurrenrTransmitFileSize := CurrenrSize;
TransmitTime := GetTickCount;
end;
if TransmitFileSize <> 0 then
begin
//一定要这样写,如果先*100,则就会超出边界,出错的
FileProgressBar.Position := Round(CurrenrSize / TransmitFileSize * 100);
end
else
FileProgressBar.Position := 0;
if FileProgressBar.Position = 100 then
begin
TransmitTime := 0;
TransmitFileSize := 0;
CurrenrTransmitFileSize := 0;
FileProgressBar.Visible := False;
end;
end;
//接收设置进度条的大小
procedure TFileAndInfoCtrlForm.ReceiveNotifySetProBarMsg(var Message: TMessage);
begin
TransmitFileSize := MakeLong(Message.LParam, Message.WParam);
TransmitTime := GetTickCount;
//反馈ok
SetEvent(MsgDealDataOkNotifyEvent);
end;
(*------------------------------以下是文件管理部分------------------------------*)
//获得系统的图标,并赋值给ListViewFile
procedure TFileAndInfoCtrlForm.SetListViewImageList;
var
ImageList: THandle;
SHFileInfo: TSHFileInfo;
begin
ZeroMemory(@SHFileInfo,sizeof(TSHFileInfo));
ImageList := HIMAGELIST(SHGetFileInfo('.', 0, SHFileInfo, SizeOf(SHFileInfo),
SHGFI_LARGEICON or SHGFI_SYSICONINDEX));
if ImageList <> 0 then
ListView_SetImageList(ListViewFile.Handle, ImageList, LVSIL_NORMAL);
ImageList := HIMAGELIST(SHGetFileInfo('.', 0, SHFileInfo, SizeOf(SHFileInfo),
SHGFI_SMALLICON or SHGFI_SYSICONINDEX));
if ImageList <> 0 then
ListView_SetImageList(ListViewFile.Handle, ImageList, LVSIL_SMALL);
end;
//将文件时间格式转化为日期时间格式
Function FileTimeToDateTime(FileTime : TFileTime) : TDateTime;
var
LocalTime : TFileTime;
SystemTime : TSystemTime;
begin
Result := EncodeDate(1900, 1, 1);
if FileTimeToLocalFileTime(FileTime, LocalTime) then
if FileTimeToSystemTime(LocalTime, SystemTime) then
Result := SystemTimeToDateTime(SystemTime);
end;
//根据xml描述文件,将文件信息加入listview,等等信息中
procedure TFileAndInfoCtrlForm.XML2List(const ListType : Byte; out FileCount : DWORD);
var
jNode : IXMLNode;
procedure ProcessNode(Node : IXMLNode);
var
ListItem : TListItem;
FreeSpace, TotalSpace : int64;
fFreeSpace, fTotalSpace : Double;
strHi, strLow : string;
SHFileInfo : TSHFileInfo;
ItemIDList : TItemIDList;
mypItemIDList : pItemIDList;
FileTime : TFileTime;
i : integer;
IsAdded : Boolean;
tmpTtr : string;
const
CSIDL_COMMON_DOCUMENTS = $2E;
CSIDL_CDBURN_AREA = $3B;
begin
if Node = nil then Exit;
case ListType of
1:
begin
//加入listview里面
ListItem := ListViewFile.Items.Add;
//文件名
tmpTtr := Node.Attributes['text'];
for i := 1 to Length(tmpTtr) do
if tmpTtr[i] = '?' then tmpTtr[i] := '&';
Listitem.Caption := tmpTtr;
if not Boolean(StrToInt(Node.Attributes['IsDirectory'])) then
begin
ZeroMemory(@SHFileInfo, sizeof(TSHFileInfo));
SHGetFileInfo(PChar(Listitem.Caption), 0, SHFileInfo, sizeof(TSHFileInfo),
//关键就是SHGFI_USEFILEATTRIBUTES,允许不存在的文件获取图标
SHGFI_USEFILEATTRIBUTES or SHGFI_ICON or SHGFI_SYSICONINDEX or SHGFI_TYPENAME);
//文件图标
ListItem.ImageIndex := SHFileInfo.iIcon;
//文件类型
ListItem.SubItems.Add(SHFileInfo.szTypeName);
//大小
strHi := Node.Attributes['FleSizeH'];
strLow := Node.Attributes['FleSizeL'];
FreeSpace := StrToInt('$' + strHi) shl 8 + StrToInt('$' + strLow);
fFreeSpace := FreeSpace / 1024;
Listitem.SubItems.Add(Format('%f KB', [fFreeSpace]));
end
else
begin
//文件图标
mypItemIDList := @ItemIDList;
SHGetSpecialFolderLocation(Self.Handle, CSIDL_COMMON_DOCUMENTS, mypItemIDList);
ZeroMemory(@SHFileInfo, sizeof(TSHFileInfo));
SHGetFileInfo(PChar(mypItemIDList), 0, SHFileInfo, sizeof(TSHFileInfo),
shgfi_sysiconindex or shgfi_icon or shgfi_smallicon or shgfi_pidl);
//文件图标
ListItem.ImageIndex := SHFileInfo.iIcon;
//文件类型
ListItem.SubItems.Add('文件夹');
Listitem.SubItems.Add('');
end;
//最后访问时间
strHi := Node.Attributes['FileLastWriteTimeH'];
strLow := Node.Attributes['FileLastWriteTimeL'];
FileTime.dwHighDateTime := StrToInt('$' + strHi);
FileTime.dwLowDateTime := StrToInt('$' + strLow);
Listitem.SubItems.Add(FormatDateTime('yyyy/mm/dd hh:nn', FileTimeToDateTime(FileTime)));
//全路径
tmpTtr := Node.Attributes['FileName'];
for i := 1 to Length(tmpTtr) do
if tmpTtr[i] = '?' then tmpTtr[i] := '&';
Listitem.SubItems.Add(tmpTtr);
//增加文件计数
Inc(FileCount);
end;
2:
begin
//加入listview里面
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -