unit UntClt;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ComCtrls, IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient,
StdCtrls, UntGlb, IdGlobal, ExtCtrls, ImgList, jpeg, WinSock, IdIPWatch;
type
TForm1 = class(TForm)
stat1: TStatusBar;
img1: TImage;
lbl1: TLabel;
btn1: TButton;
chk1: TCheckBox;
edt1: TEdit;
btn2: TButton;
btn3: TButton;
btn4: TButton;
btn5: TButton;
grp1: TGroupBox;
lst1: TListBox;
idtcpclnt1: TIdTCPClient;
BalloonHint1: TBalloonHint;
il1: TImageList;
dlgOpen1: TOpenDialog;
ProgressBar1: TProgressBar;
btnCancle: TButton;
IdIPWatch1: TIdIPWatch;
procedure btn1Click(Sender: TObject);
procedure chk1Click(Sender: TObject);
procedure idtcpclnt1Disconnected(Sender: TObject);
procedure btn2Click(Sender: TObject);
procedure idtcpclnt1Connected(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure btn5Click(Sender: TObject);
procedure btn3Click(Sender: TObject);
procedure btn4Click(Sender: TObject);
procedure WMMOVE(var msg: TMessage); message WM_MOVE;
procedure WMUSERMSG(var msg: TMessage); message WM_USERMSG;
procedure ShowProgressBar(Visible: Boolean);
procedure btnCancleClick(Sender: TObject);
private
{ Private declarations }
ComputerName: string;
public
{ Public declarations }
UserBreakAll: Boolean;
end;
TFileThread = class(TThread)
private
// CB: TDataPack;
protected
procedure Execute; override;
end;
TMonitorThread = class(TThread)
protected
procedure Execute; override;
end;
var
Form1: TForm1;
FileThread: TFileThread;
MonitorThread: TMonitorThread;
AllowDisconnectedEvent: Boolean = False;
function SendARP(Destip, scrip: DWORD; pmacaddr: PDWORD;
VAR phyAddrlen: DWORD): DWORD; stdcall; external 'iphlpapi.dll';
implementation
{$R *.dfm}
function GetMacFromIP(IP: AnsiString): AnsiString;
type
Tinfo = array [0 .. 7] of Byte;
var
dwTargetIP: DWORD;
dwMacAddress: array [0 .. 1] of DWORD;
dwMacLen: DWORD;
dwResult: DWORD;
X: Tinfo;
stemp: AnsiString;
iloop: integer;
begin
dwTargetIP := Inet_Addr(PAnsiChar(IP));
dwMacLen := 6;
dwResult := SendARP(dwTargetIP, 0, @dwMacAddress[0], dwMacLen);
case dwResult of
NO_ERROR:
begin
// ShowMessage('查到');
X := Tinfo(dwMacAddress);
for iloop := 0 to 5 do
begin
stemp := stemp + inttohex(X[iloop], 2);
end;
Result := stemp;
end;
ERROR_BAD_NET_NAME:
Result := '目标IPv4地址无法送达(Windows Vista 及以后版本错误)';
ERROR_BUFFER_OVERFLOW:
Result := 'PhyAddrLen参数小于6(Windows Vista 及以后版本错误)';
ERROR_GEN_FAILURE:
Result := '目标IPv4地址无法送达(Windows Server 2003及之前版本错误)';
ERROR_INVALID_PARAMETER:
Result := 'pMacAddr或PhyAddrLen参数是一个NULL指针(Windows Server 2003及之前版本错误)';
ERROR_INVALID_USER_BUFFER:
Result := 'PhyAddrLen参数为零(Windows Server 2003及之前版本错误)';
// ERROR_NOT_FOUND:Result :='非INADDR_ANY的IP地址(IPv4地址为0.0.0.0)(Windows Vista 错误)';
ERROR_NOT_SUPPORTED:
Result := '本机操作系统不支持该函数';
else
Result := '未知';
end;
end;
function GetWindowsVersionString: AnsiString;
var
VI: TOSVersionInfoA;
begin
VI.dwOSVersionInfoSize := SizeOf(TOSVersionInfoA);
if GetVersionExA(VI) then
with VI do
Result := Trim(Format('%d.%d build %d %s', [dwMajorVersion,
dwMinorVersion, dwBuildNumber, szCSDVersion]))
else
Result := '';
end;
function GetWindowsVersion: String; // 读取操作系统版本
var
AWin32Version: Extended;
os: string;
begin
os := 'Windows ';
AWin32Version := StrtoFloat(Format('%d.%d', [Win32MajorVersion,
Win32MinorVersion]));
if Win32Platform = VER_PLATFORM_WIN32s then
Result := os + '32'
else if Win32Platform = VER_PLATFORM_WIN32_WINDOWS then
begin
if AWin32Version = 4.0 then
Result := os + '95'
else if AWin32Version = 4.1 then
Result := os + '98'
else if AWin32Version = 4.9 then
Result := os + 'Me'
else
Result := os + '9x'
end
else if Win32Platform = VER_PLATFORM_WIN32_NT then
begin
if AWin32Version = 3.51 then
Result := os + 'NT 3.51'
else if AWin32Version = 4.0 then
Result := os + 'NT 4.0'
else if AWin32Version = 5.0 then
Result := os + '2000'
else if AWin32Version = 5.1 then
Result := os + 'XP'
else if AWin32Version = 5.2 then
Result := os + '2003'
else if AWin32Version = 6.0 then
Result := os + 'Vista'
else if AWin32Version = 6.1 then
Result := os + '7'
else
Result := os;
end
else
Result := os + '??';
Result := Result + ' ' + GetWindowsVersionString;
end;
procedure TForm1.btn1Click(Sender: TObject);
begin
close;
end;
procedure TForm1.btn2Click(Sender: TObject);
var
i: integer;
begin
if dlgOpen1.Execute(Handle) then
begin
for i := 0 to dlgOpen1.Files.Count - 1 do
lst1.Items.add(dlgOpen1.Files[i]);
end;
grp1.Caption := GroupText + Format(FileListString, [lst1.Count]);
end;
procedure TForm1.btn3Click(Sender: TObject);
begin
lst1.Clear;
grp1.Caption := GroupText + Format(FileListString, [0]);
end;
procedure TForm1.btn4Click(Sender: TObject);
begin
lst1.DeleteSelected;
grp1.Caption := GroupText + Format(FileListString, [lst1.Count]);
end;
procedure TForm1.btn5Click(Sender: TObject);
var
DlgText: string;
begin
if idtcpclnt1.Connected then
begin
if lst1.Count > 0 then
begin
DlgText := Format(DlgSendFileText, [lst1.Count]);
if Application.MessageBox(PChar(DlgText), '发送提示',
MB_OKCANCEL + MB_ICONQUESTION) = IDOK then
begin
ShowProgressBar(True);
FileThread := TFileThread.Create(True);
FileThread.FreeOnTerminate := True;
FileThread.Start;
end;
end
else
ShowMessage(DlgSelectFile);
end
else
ShowMessage(DlgNoConnected);
end;
procedure TForm1.btnCancleClick(Sender: TObject);
begin
UserBreakAll := True;
end;
procedure TForm1.chk1Click(Sender: TObject);
begin
idtcpclnt1.Host := edt1.Text;
if chk1.Checked then
begin
try
Application.ProcessMessages;
idtcpclnt1.Connect;
AllowDisconnectedEvent := True;
stat1.Panels[1].Text := StaConnected;
except
ShowMessage(DlgConnectFailed);
end;
end
else
begin
AllowDisconnectedEvent := False;
idtcpclnt1.Disconnect;
end;
chk1.Checked := idtcpclnt1.Connected;
end;
procedure TForm1.FormCreate(Sender: TObject);
var
n: Cardinal;
Name: array [0 .. MAX_COMPUTERNAME_LENGTH] of Char;
begin
n := MAX_COMPUTERNAME_LENGTH + 1;
GetComputerName(name, n);
ComputerName := string(Name);
MonitorThread := TMonitorThread.Create(True);
MonitorThread.FreeOnTerminate := True;
MonitorThread.Start;
end;
procedure TForm1.idtcpclnt1Connected(Sender: TObject);
var
bbuf: TIdBytes;
buf: TDataPack;
begin
bbuf := nil;
FillChar(buf, SizeOf(buf), '');
buf.Command := cmdSetName;
StrPCopy(buf.ClientInfo.ClientName ,ComputerName);
StrPCopy(buf.ClientInfo.ClientOS,GetWindowsVersion);
StrPCopy(buf.ClientInfo.ClientACTIP ,GetMacFromIP(IdIPWatch1.LocalIP));
bbuf := RawToBytes(buf, SizeOf(buf));
idtcpclnt1.IOHandler.Write(bbuf);
end;
procedure TForm1.idtcpclnt1Disconnected(Sender: TObject);
begin
stat1.Panels[1].Text := StaDisconnected;
chk1.Checked := False;
end;
procedure TForm1.ShowProgressBar(Visible: Boolean);
begin
ProgressBar1.Visible := Visible;
btnCancle.Visible := Visible;
end;
procedure TForm1.WMMOVE(var msg: TMessage);
begin
// inherited;
// if Assigned(frmProgress) then
// frmProgress.Position := poMainFormCenter;
end;
procedure TForm1.WMUSERMSG(var msg: TMessage);
begin
case msg.WParam of
1:
ShowMessage(Format(DlgFileSendOk, [msg.LParam]));
2:
stat1.Panels[1].Text := string(PChar(msg.LParam));
3:
ProgressBar1.Position := msg.LParam;
4:
ProgressBar1.Max := msg.LParam;
5:
idtcpclnt1.OnDisconnected(Self);
6:
ShowMessage(DlgExcept);
7:
ShowProgressBar(False);
end;
end;
{ TFileThread }
procedure TFileThread.Execute;
var
FileName: string;
buf: TDataPack;
bbuf: TIdBytes;
i, j, SendTimes, RemainLen, h, FileLen, SentFilesNum,
ClientReadedBytes: integer;
begin
try
Form1.UserBreakAll := False;
SentFilesNum := 0;
for i := 0 to Form1.lst1.Count - 1 do
begin
if Form1.UserBreakAll then
Break;
FileName := Form1.lst1.Items[i];
// frmProgress.lbl1.Caption := FileName;
// frmProgress.pb1.Position := 0;
PostMessage(Form1.Handle, WM_USERMSG, 2, integer(PChar(FileName)));
PostMessage(Form1.Handle, WM_USERMSG, 3, 0);
h := FileOpen(FileName, fmOpenRead);
if h > 0 then
begin
try
FileLen := GetFileSize(h, nil);
SendTimes := FileLen div SEND_BUF;
RemainLen := FileLen mod SEND_BUF;
// frmProgress.pb1.Max := FileLen;
PostMessage(Form1.Handle, WM_USERMSG, 4, FileLen);
FillChar(buf.ClientInfo, SizeOf(buf.ClientInfo), '');
buf.Command := cmdSendFile;
StrPCopy(buf.FileName,ExtractFileName(FileName));
buf.FileSize := FileLen;
buf.Flags := 0; // 新建
for j := 1 to SendTimes do
begin
if Form1.UserBreakAll then
Break;
if not Form1.idtcpclnt1.Connected then
Break;
ClientReadedBytes := FileRead(h, buf.FileData, SEND_BUF);
buf.ReadBytes := ClientReadedBytes;
bbuf := nil;
bbuf := RawToBytes(buf, SizeOf(buf));
Form1.idtcpclnt1.IOHandler.Write(bbuf);
buf.Flags := 1; // 续传
// frmProgress.pb1.Position := j * SEND_BUF;
PostMessage(Form1.Handle, WM_USERMSG, 3, j * SEND_BUF);
end;
if RemainLen > 0 then
begin
if not Form1.idtcpclnt1.Connected then
Break;
ClientReadedBytes := FileRead(h, buf.FileData, RemainLen);
buf.ReadBytes := ClientReadedBytes;
bbuf := nil;
bbuf := RawToBytes(buf, SizeOf(buf));
Form1.idtcpclnt1.IOHandler.Write(bbuf);
PostMessage(Form1.Handle, WM_USERMSG, 3, FileLen);
end;
finally
FileClose(h);
end;
if (not Form1.UserBreakAll) then
inc(SentFilesNum);
end;
end;
PostMessage(Form1.Handle, WM_USERMSG, 7, 0);
PostMessage(Form1.Handle, WM_USERMSG, 1, SentFilesNum);
if Form1.idtcpclnt1.Connected and Form1.UserBreakAll then
begin
bbuf := nil;
buf.Command := cmdUserbreak;
bbuf := RawToBytes(buf, SizeOf(buf));
Form1.idtcpclnt1.IOHandler.Write(bbuf);
end;
except
PostMessage(Form1.Handle, WM_USERMSG, 7, 0);
PostMessage(Form1.Handle, WM_USERMSG, 6, 0);
AllowDisconnectedEvent := False;
Form1.idtcpclnt1.Disconnect;
Terminate;
end;
end;
{ TMonitorThread }
procedure TMonitorThread.Execute;
begin
while not Terminated do
begin
if not Form1.idtcpclnt1.Connected then
if AllowDisconnectedEvent then
begin
AllowDisconnectedEvent := False;
PostMessage(Form1.Handle, WM_USERMSG, 5, 0);
end;
Sleep(100);
end;
end;
end.
请发表评论