这样你其实就可以采用一个线程发送就可以了!
下面是采用一个线程和api发送信息,希望对你有用!
unit comm_sendfileunit;
interface
uses
Classes,windows,SysUtils;
type
threadsendfile = class(TThread)
private
fname:string;
hwriteEvent:THandle;
hcomfile: THandle;
protected
procedure Execute;
override;
public
constructor create(sendfilename:string);
function initcom: integer;//初始化
function sendbuffer(buffer: Pchar;
count: integer): boolean;//发送字符
function sendfl: integer;//发送文件
function closecomfile: integer;
end;
implementation
uses wait;
{ Important: Methods and properties of objects in VCL can only be used in a
method called using Synchronize, for example,
Synchronize(UpdateCaption);
and UpdateCaption could look like,
procedure sendfile.UpdateCaption;
begin
Form1.Caption := 'Updated in a thread';
end;
}
{ sendfile }
constructor threadsendfile.create(sendfilename:string);
begin
fname:=sendfilename;
inherited create(false);
end;
function threadsendfile.closecomfile: integer;
begin
CloseHandle(hComFile);
CloseHandle(hwriteEvent);
result:=1;
end;
function threadsendfile.sendfl: integer;
var
buf:array[1..512] of Char;
buffer
Char;
FromF: file;
NumRead,i,len: Integer;
label endlabel;
begin
result:=0;
if initcom >10 then
begin
result:=998;
exit;
end;
buf[1]:=#3;
buf[2]:=#3;
buffer:=PChar(@buf);
sendbuffer(buffer,2);
result:=0;
AssignFile(FromF,fname);
Reset(FromF, 1);
len:=FileSize(FromF);
len:=(len+511) div 512;
waitform.ProgressBar1.Min:=0;
waitform.ProgressBar1.Max:=len;
len:=0;
repeat
begin
fillchar(Buf,sizeof(Buf),#0);
BlockRead(FromF, buf, SizeOf(Buf), NumRead);
buffer:=PChar(@buf);
for i:=1 to 3do
begin
if Terminated then
goto endlabel;
if sendbuffer(buffer,NumRead) then
break;
end;
if i>3 then
begin
result:=1;
//raise ERangeError.Create( '传输失败!' );
break;
end;
//len:=len+NumRead;
waitform.ProgressBar1.Position:=waitform.ProgressBar1.Position+1;
//memo1.Lines.Add('已经发送的字节:'+inttostr(len));
end;
until ((NumRead = 0) or (NumRead<SizeOf(Buf)));
buf[1]:=#4;
buffer:=PChar(@buf);
sendbuffer(buffer,1);
endlabel:
CloseFile(FromF);
closecomfile;
end;
function threadsendfile.initcom: integer;
var
commtimeouts: TCommTimeouts;
dcb: Tdcb;
commprop: TCommProp;
fdwEvtMask: DWORD;
begin
hwriteEvent:= CreateEvent( nil, True, False, nil );
hcomfile:=CreateFile( PChar('com1'),GENERIC_READ or GENERIC_WRITE,
0,nil,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
//if hcomfile = INVALID_HANDLE_VALUE then
// raise ERangeError.Create( 'Error opening serial port' );
if hcomfile = INVALID_HANDLE_VALUE then
begin
result:=998;
exit;
end;
if GetFileType( hcomfile ) <> FILE_TYPE_CHAR then
begin
CloseHandle( hcomfile );
raise ERangeError.Create( 'File handle is not a comm handle ' );
end;
GetCommState( hcomfile, dcb );
//SetCommMask( hcomfile, EV_RXCHAR);
SetCommMask( hcomfile,EV_TXEMPTY);
SetupComm( hcomfile, 4096, 4096 );
PurgeComm( hcomfile, PURGE_TXABORT or PURGE_RXABORT or PURGE_TXCLEAR or PURGE_RXCLEAR ) ;
//填写超时
commtimeouts.ReadIntervalTimeout :=0;
commtimeouts.ReadTotalTimeoutMultiplier :=0;
commtimeouts.ReadTotalTimeoutConstant :=0;
commtimeouts.WriteTotalTimeoutMultiplier :=100;
commtimeouts.WriteTotalTimeoutConstant :=0;
SetCommTimeouts( hcomfile, commtimeouts );
{dcb.fAbortOnError := False;
NOT VALID}
dcb.DCBlength:=sizeof( DCB );
//dcb.BaudRate := CBR_115200;
dcb.BaudRate := CBR_57600;
dcb.Flags := dcb.Flags or 1;
// Enable fBinary
dcb.Flags := dcb.Flags or 2;
// 进行校验
//DCB.wReserved1:=65;
//DCB.wReserved:=0;
//dcb.Flags := dcb.Flags or $10;
//dcb.Flags := dcb.Flags or $1000;
{dcb.XonLim :=10;
dcb.XoffLim :=10;
dcb.XonChar :=#0;
dcb.XoffChar :=#0;}
dcb.ByteSize :=8;
dcb.Parity := EVENPARITY;
dcb.StopBits :=ONESTOPBIT;
SetCommState( hcomfile, dcb );
EscapeCommFunction(hcomfile, SETDTR );
//closehandle(hcomfile);
//hcomfile:=CreateFile( PChar('com1'),GENERIC_READ or GENERIC_WRITE,
//0,nil,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
sleep(100);
result:=0;
end;
function threadsendfile.sendbuffer(buffer: Pchar;
count: integer): boolean;
var
sendbuf
char;
sendbool:boolean;
truewr,dwLastError,dwErrors
WORD;
i:integer;
dwModemStat,dwritek,StartWriting
WORD;
ctsbool:boolean;
modd:integer;
sendcount:integer;
begin
result:=false;
sendbuf:=buffer;
sendcount:=count;
dwModemStat:=0;
GetCommModemStatus(hcomfile,dwModemStat);
if(MS_CTS_ON= dwModemStat and MS_CTS_ON) then
ctsbool:=true
else
ctsbool:=false;
i:=0;
while (not(ctsbool) and (i<30))do
begin
if Terminated then
exit;
sleep(10);
GetCommModemStatus(hcomfile,dwModemStat);
if(MS_CTS_ON= dwModemStat and MS_CTS_ON) then
ctsbool:=true;
i:=i+1;
end;
if i>=30 then
begin
exit;
end;
dwritek:=0;
StartWriting:=0;
i:=0;
sendbool:=WriteFile( hComFile,sendbuf^,sendcount,dwritek,nil);
sleep(50);
if not(sendbool) then
begin
dwLastError := GetLastError;
if dwLastError <> ERROR_IO_PENDING then
begin
while (WaitForSingleObject(hwriteEvent,500)=WAIT_TIMEOUT)do
begin
dwLastError := GetLastError;
if(dwLastError <> ERROR_IO_INCOMPLETE) then
begin
ClearCommError(hComFile,dwErrors, nil);
break;
end;
end;
end
else
begin
ClearCommError(hComFile,dwErrors, nil);
end;
end
else
result:=true;
end;
procedure threadsendfile.Execute;
begin
if fileexists(fname) then
if sendfl>10 then
begin
waitform.Label1.Caption:=' 端口已经被占用!';
waitform.ProgressBar1.hide;
waitform.Label1.visible:=true;
exit;
end;
waitform.close;
end;
end.