var
Form1: TForm1;
/////////////////////////////////////////////////
hCOMPort:THandle;
DCB:TDCB;
TimeOuts:TCommTimeouts;
Ovr:TOverlapped;
Stat:PComStat;
TStat:TComStat;
ComError,readBytes,Count:Cardinal;
COMPortName:PAnsiChar;
COMPortSpeed:integer;
CloseCOMPort:boolean;
///////////////////////////////////////////////// áëîê ïåðåìåííûõ äëÿ óïðàâëåíèÿ ïåðåäà÷åé
SentPacket,ReadNextPacket:boolean;
///////////////////////////////////////////////// áóôåðû îáìåíà
OutBuffer,InBuffer:array [0..37]of byte;
///////////////////////////////////////////////// èìåíà ôàéëîâ
OutFileName,InFileName,FullOutFileName,FullInFileName,SentFileName:string;
/////////////////////////////////////////////////ôàéëîâûå ïåðåìåííûå
inFile,outFile:File;
inFileIsOpen,outFileIsOpen:Boolean;
Path:string;
/////////////////////////////////////////////////// Ïîòîê èíòåðôåéñà ñ ÑÎÌ-ïîðòîì
///////////////////////////////////////////////////
HeaderIsSent:boolean;
///////////////////////////////////////////////////
implementation
//uses DataCommunicationModule;
{$R *.dfm}
procedure TForm1.OpenPortButtonClick(Sender: TObject);
var
COMPort:DataCommThread;
begin
COMPortName:=PChar(PortNameComboBox.Text);
COMPort:=DataCommThread.Create(True);
COMPort.FreeOnTerminate:=True;
COMPort.Resume;
end;
procedure TForm1.ClosePortButtonClick(Sender: TObject);
begin
CloseCOMPort:=True;
end;
procedure TForm1.SpeedButton1Click(Sender: TObject);
var
counter:integer;
begin
if OpenDialog1.Execute then begin
Path:=ExtractFilePath(OpenDialog1.FileName);
SentFileName:=Copy(OpenDialog1.FileName,Length(Path)+1,Length(OpenDialog1.FileName)-Length(Path)+5);
FullOutFileName:=OpenDialog1.FileName;
OutBuffer[1]:=1;
OutBuffer[2]:=Length(SentFileName)+3;
For counter:=0 to Length(SentFileName) do begin
OutBuffer[counter+3]:=byte(SentFileName[counter]);
end;
ReadNextPacket:=False;
end;
end;
TFileStream в дочернем потоке
при попытке разрушить объект класса TFileStream возникает ошибка -как это обойти?
Заранее благодарен.
конкретнее вопросы задавать надо! телепаты в отпуске!
Давай-ка код в студию.
Код:
вспомогательный поток
Код:
procedure DataCommThread.Execute;
var
counter,PacketCount,fPos,fSize,ReadRes:integer;
CheckSum,Temp:byte;
BufferToFile,BufferFromFile:array[0..31] of byte;
begin
{ Place thread code here }
hCOMPort:=Windows.CreateFile('COM1',GENERIC_READ or GENERIC_WRITE,0,NIL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
if GetCommState(hCOMPort,DCB)then begin
///////////////////////////////////////////////////////
DCB.BaudRate:=CBR_115200;
DCB.Parity:=NOPARITY;
DCB.ByteSize:=8;
DCB.StopBits:=ONESTOPBIT;
TimeOuts.ReadIntervalTimeout:=0;
TimeOuts.ReadTotalTimeoutMultiplier:=0;
TimeOuts.ReadTotalTimeoutConstant:=0;
TimeOuts.WriteTotalTimeoutMultiplier:=0;
TimeOuts.WriteTotalTimeoutConstant:=0;
SetCommState(hCOMPort,DCB);
PurgeComm(hCOMPort,purge_txclear or purge_rxclear);
EscapeCommFunction(hCOMPort,SETDTR);
/////////////////////////////////////////
while not CloseCOMPort do begin
////////////////////////
if OutFileName<>'' then begin
FillChar(BufferFromFile,32,0);
BlockRead(outFile,BufferFromFile,32,ReadRes);
FillChar(OutBuffer,38,0);
if ReadRes>0 then begin
for counter:=0 to ReadRes-1 do begin
OutBuffer[counter+3]:= BufferFromFile[counter];
end;
OutBuffer[2]:=ReadRes+3;
OutBuffer[1]:=2;
end
else begin
OutBuffer[1]:=4;
CloseFile(outFile);
end;
end;
////////////////////////
if SentFileName<>'' then begin
OutFileName:=SentFileName;
AssignFile(outFile,FullOutFileName);
Reset(outFile,1);
SentFileName:=''
end;
////////////////////////
OutBuffer[0]:=$7E;
OutBuffer[37]:=$7E;
//////////////////////
OutBuffer[36]:=0;
for counter:=1 to 35 do begin
OutBuffer[36]:=byte(OutBuffer[36]+OutBuffer[counter]);
end;
////////////////////////////////////////////////////
EscapeCommFunction(hCOMPort,SETRTS);
Windows.WriteFile(hCOMPort,OutBuffer,38,Count,@Ovr);
Sleep(200);
////////////////////////
EscapeCommFunction(hCOMPort,CLRRTS);
Stat:=@TStat;
Sleep(200);
ClearCommError(hCOMPort,ComError,Stat);
if Stat.cbInQue=38 then begin
Windows.ReadFile(hCOMPort,InBuffer,38,readBytes,@Ovr);
if (InBuffer[0]=$7E)and(InBuffer[37]=$7E) then begin
CheckSum:=0;
for counter:=1 to 35 do begin
CheckSum:=byte(CheckSum+InBuffer[counter]);
end;
if CheckSum = InBuffer[36] then begin
//////////////////
case InBuffer[1] of
1:
begin
for counter:=4 to InBuffer[2]do begin
InFileName:=InFileName+Char(InBuffer[counter]);
end;
ReadNextPacket:=True;
FullInFileName:=ExtractFilePath(Application.ExeName)+InFileName;
AssignFile(inFile,FullInFileName);
Rewrite(inFile,1);
end;
2:
begin
FillChar(BufferToFile,32,0);
for counter:=3 to inBuffer[2] do begin
BufferToFile[counter-3]:=InBuffer[counter];
end;
BlockWrite(inFile,BufferToFile,InBuffer[2]-3);
end;
3:
begin
end;
4:
begin
InFileName:='';
CloseFile(inFile);
end;
end;
//////////////////
if (OutBuffer[1]=1)or(OutBuffer[1]=2) then begin
ReadNextPacket:=True;
end;
OutBuffer[35]:=1;
end
else begin
OutBuffer[35]:=0;
end;
end;
end;
end;
/////////////////////////////////////////
end;
CloseHandle(hCOMPort);
end;
var
counter,PacketCount,fPos,fSize,ReadRes:integer;
CheckSum,Temp:byte;
BufferToFile,BufferFromFile:array[0..31] of byte;
begin
{ Place thread code here }
hCOMPort:=Windows.CreateFile('COM1',GENERIC_READ or GENERIC_WRITE,0,NIL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
if GetCommState(hCOMPort,DCB)then begin
///////////////////////////////////////////////////////
DCB.BaudRate:=CBR_115200;
DCB.Parity:=NOPARITY;
DCB.ByteSize:=8;
DCB.StopBits:=ONESTOPBIT;
TimeOuts.ReadIntervalTimeout:=0;
TimeOuts.ReadTotalTimeoutMultiplier:=0;
TimeOuts.ReadTotalTimeoutConstant:=0;
TimeOuts.WriteTotalTimeoutMultiplier:=0;
TimeOuts.WriteTotalTimeoutConstant:=0;
SetCommState(hCOMPort,DCB);
PurgeComm(hCOMPort,purge_txclear or purge_rxclear);
EscapeCommFunction(hCOMPort,SETDTR);
/////////////////////////////////////////
while not CloseCOMPort do begin
////////////////////////
if OutFileName<>'' then begin
FillChar(BufferFromFile,32,0);
BlockRead(outFile,BufferFromFile,32,ReadRes);
FillChar(OutBuffer,38,0);
if ReadRes>0 then begin
for counter:=0 to ReadRes-1 do begin
OutBuffer[counter+3]:= BufferFromFile[counter];
end;
OutBuffer[2]:=ReadRes+3;
OutBuffer[1]:=2;
end
else begin
OutBuffer[1]:=4;
CloseFile(outFile);
end;
end;
////////////////////////
if SentFileName<>'' then begin
OutFileName:=SentFileName;
AssignFile(outFile,FullOutFileName);
Reset(outFile,1);
SentFileName:=''
end;
////////////////////////
OutBuffer[0]:=$7E;
OutBuffer[37]:=$7E;
//////////////////////
OutBuffer[36]:=0;
for counter:=1 to 35 do begin
OutBuffer[36]:=byte(OutBuffer[36]+OutBuffer[counter]);
end;
////////////////////////////////////////////////////
EscapeCommFunction(hCOMPort,SETRTS);
Windows.WriteFile(hCOMPort,OutBuffer,38,Count,@Ovr);
Sleep(200);
////////////////////////
EscapeCommFunction(hCOMPort,CLRRTS);
Stat:=@TStat;
Sleep(200);
ClearCommError(hCOMPort,ComError,Stat);
if Stat.cbInQue=38 then begin
Windows.ReadFile(hCOMPort,InBuffer,38,readBytes,@Ovr);
if (InBuffer[0]=$7E)and(InBuffer[37]=$7E) then begin
CheckSum:=0;
for counter:=1 to 35 do begin
CheckSum:=byte(CheckSum+InBuffer[counter]);
end;
if CheckSum = InBuffer[36] then begin
//////////////////
case InBuffer[1] of
1:
begin
for counter:=4 to InBuffer[2]do begin
InFileName:=InFileName+Char(InBuffer[counter]);
end;
ReadNextPacket:=True;
FullInFileName:=ExtractFilePath(Application.ExeName)+InFileName;
AssignFile(inFile,FullInFileName);
Rewrite(inFile,1);
end;
2:
begin
FillChar(BufferToFile,32,0);
for counter:=3 to inBuffer[2] do begin
BufferToFile[counter-3]:=InBuffer[counter];
end;
BlockWrite(inFile,BufferToFile,InBuffer[2]-3);
end;
3:
begin
end;
4:
begin
InFileName:='';
CloseFile(inFile);
end;
end;
//////////////////
if (OutBuffer[1]=1)or(OutBuffer[1]=2) then begin
ReadNextPacket:=True;
end;
OutBuffer[35]:=1;
end
else begin
OutBuffer[35]:=0;
end;
end;
end;
end;
/////////////////////////////////////////
end;
CloseHandle(hCOMPort);
end;