Вот необходимая и достаточная выжимка.
Я думаю, всё должно быть понятно.
Код:
type
TForm1 =
private
procedure Connect;
procedure Disconnect;
procedure OnAppIdle(Sender: TObject; var Done: Boolean);
procedure SendBuf(var Buf; const Size: Cardinal);
FPort: THandle;
FDCB: TDCB;
FStat: TComStat;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
FPort := INVALID_HANDLE_VALUE;
Application.OnIdle := OnAppIdle;
...
...
end;
procedure TForm1.Connect;
begin
Disconnect;
FPort := CreateFile('COM1', GENERIC_READ or GENERIC_WRITE, 0, nil ,OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
if FPort <> INVALID_HANDLE_VALUE then begin
SetCommMask(FPort, EV_RXFLAG);
GetCommState(FPort, FDCB);
FDCB.BaudRate := CBR_115200;
FDCB.Parity := NOPARITY;
FDCB.ByteSize := 8;
FDCB.StopBits := OneStopBit;
if not SetCommState(FPort, FDCB) then begin
MessageDlg('Невозможно задать парамерты порта', mtError, [mbOk], 0);
CloseHandle(FPort);
FPort := INVALID_HANDLE_VALUE;
end else begin
PurgeComm(FPort, PURGE_TXABORT or PURGE_RXABORT or PURGE_TXCLEAR or PURGE_RXCLEAR);
end;
end;
end;
Procedure TForm1.Disconnect;
begin
if FPort <> INVALID_HANDLE_VALUE then begin
CloseHandle(FPort);
FPort := INVALID_HANDLE_VALUE;
end;
end;
procedure TForm1.OnAppIdle(Sender: TObject; var Done: Boolean);
var
P: Pointer;
BR: Cardinal;
begin
if FPort <> INVALID_HANDLE_VALUE then begin
ClearCommError(FPort, FErrs, @FStat);
GetMem(P, FStat.cbInQue);
ReadFile(FPort, P^, FStat.cbInQue, BR, nil);
//
//Тут обрабатываем данные в P
//
FreeMem(P);
Done:=False;
end;
end;
procedure TForm1.SendBuf(var Buf; const Size: Cardinal);
var
BW: Cardinal;
begin
if FPort <> INVALID_HANDLE_VALUE then begin
WriteFile(FPort, Buf, Size, BW, nil);
end;
end;
Отправляем данные с пом. SendBuf.
Получаем данные, постоянно опрашивая порт на наличие данных в буфере приёма. Это делает OnAppIdle. В моём примере эта процедура посажена на Application.OnIdle.