好不容易才找到一个N年前些的控件,给你参考参考,分可不能少 :)unit SNCOMM;interfaceuses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;type TSNCOMM = class(TComponent) private { Private declarations } FPortName: String; FComHandle: THandle; protected { Protected declarations } public { Public declarations } constructor Create(AOwner: TComponent); override; destructor Destroy; override; function Connect(ComPort: Byte; bps: Cardinal): Boolean; procedure Disconnect; function Read(var Buff; Bytes: Cardinal): Cardinal; function Write(var Buff; Bytes: Cardinal): Cardinal; function ReadByte(var B: Byte): Boolean; function SendByte(B: Byte): Boolean; function WriteByte(B: Byte): Boolean; procedure Clear; function BytesNeedRead: Cardinal; function Connected: Boolean; procedure FlushBuffers(Rx,Tx: Boolean); property PortName: String read FPortName; published { Published declarations } end;procedure Register;implementationprocedure Register; begin RegisterComponents('Standard', [TSNCOMM]); end;{ TSNCOMM }function TSNCOMM.BytesNeedRead: Cardinal; var err: Cardinal; cs: TCOMSTAT; begin Result := 0; if not Connected then Exit; if not ClearCommError(FComHandle,err,@cs) then Exit; Result := cs.cbInQue; end;procedure TSNCOMM.Clear; begin if not Connected then Exit; PurgeComm(FComHandle,PURGE_TXABORT or PURGE_RXABORT or PURGE_TXCLEAR or PURGE_RXCLEAR); end;function TSNCOMM.Connect(ComPort: Byte; bps: Cardinal): Boolean; var dcb: TDCB; tos: TCOMMTIMEOUTS; n: Cardinal; begin Result := False; if Connected then Exit; case bps of 110: n := CBR_110; 300: n := CBR_300; 600: n := CBR_600; 1200: n := CBR_1200; 2400: n := CBR_2400; 4800: n := CBR_4800; 9600: n := CBR_9600; 14400: n := CBR_14400; 19200: n := CBR_19200; 38400: n := CBR_38400; 56000: n := CBR_56000; 57600: n := CBR_57600; 115200: n := CBR_115200; 128000: n := CBR_128000; 256000: n := CBR_256000; else Exit; end; FPortName := Format('COM%d',[ComPort]); FComHandle := CreateFile( PChar(FPortName), GENERIC_READ or GENERIC_WRITE, 0, // Not shared nil, // No security attributes OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL or FILE_FLAG_OVERLAPPED, 0 // No template ) ; if Connected then begin FillChar( dcb, SizeOf(dcb), 0 ); dcb.DCBLength := sizeof(dcb); dcb.BaudRate := n; dcb.Flags := 1; { binary mode } dcb.ByteSize := 8; dcb.Parity := 0; dcb.StopBits := 0; tos.ReadIntervalTimeout := 100; tos.ReadTotalTimeoutMultiplier := 100; tos.ReadTotalTimeoutConstant := 1000; tos.WriteTotalTimeoutMultiplier := 100; tos.WriteTotalTimeoutConstant := 1000; Result := True; if SetCommState( FComHandle, dcb ) and PurgeComm( FComHandle, PURGE_TXABORT or PURGE_TXCLEAR or PURGE_RXABORT or PURGE_RXCLEAR ) and SetupComm( FComHandle, 100, 100 ) and SetCommTimeouts( FComHandle, tos ) then Exit; Disconnect; Result := False; end; FPortName := ''; end;function TSNCOMM.Connected: Boolean; begin Result := FComHandle <> INVALID_HANDLE_VALUE; end;constructor TSNCOMM.Create(AOwner: TComponent); begin inherited; FComHandle := INVALID_HANDLE_VALUE; end;destructor TSNCOMM.Destroy; begin Disconnect; inherited; end;procedure TSNCOMM.Disconnect; begin if Connected then begin CloseHandle(FComHandle); FComHandle := INVALID_HANDLE_VALUE; end; end;procedure TSNCOMM.FlushBuffers(Rx, Tx: Boolean); var Flag: Cardinal; begin if not Connected then Exit; Flag := 0; if Rx then Flag := Flag or PURGE_RXABORT or PURGE_RXCLEAR; if Tx then Flag := Flag or PURGE_TXABORT or PURGE_TXCLEAR; if Flag <> 0 then PurgeComm(FComHandle,Flag); end;function TSNCOMM.Read(var Buff; Bytes: Cardinal): Cardinal; var ol: TOVERLAPPED; begin Result := 0; if not Connected then Exit; FillChar(ol,SizeOf(ol),0); if not ReadFile(FComHandle,Buff,Bytes,Result,@ol) then GetOverlappedResult(FComHandle,ol,Result,True); end;function TSNCOMM.ReadByte(var B: Byte): Boolean; begin Result := Read(B,1) = 1; end;function TSNCOMM.SendByte(B: Byte): Boolean; begin Result := Write(B,1) = 1; end;function TSNCOMM.Write(var Buff; Bytes: Cardinal): Cardinal; var ol: TOVERLAPPED; begin Result := 0; if not Connected then Exit; FillChar(ol,SizeOf(ol),0); if not WriteFile(FComHandle,Buff,Bytes,Result,@ol) then GetOverlappedResult(FComHandle,ol,Result,True); end;function TSNCOMM.WriteByte(B: Byte): Boolean; begin Result := Write(B,1) = 1; end;end.
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;type
TSNCOMM = class(TComponent)
private
{ Private declarations }
FPortName: String;
FComHandle: THandle;
protected
{ Protected declarations }
public
{ Public declarations }
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
function Connect(ComPort: Byte; bps: Cardinal): Boolean;
procedure Disconnect;
function Read(var Buff; Bytes: Cardinal): Cardinal;
function Write(var Buff; Bytes: Cardinal): Cardinal;
function ReadByte(var B: Byte): Boolean;
function SendByte(B: Byte): Boolean;
function WriteByte(B: Byte): Boolean;
procedure Clear;
function BytesNeedRead: Cardinal;
function Connected: Boolean;
procedure FlushBuffers(Rx,Tx: Boolean); property PortName: String read FPortName;
published
{ Published declarations }
end;procedure Register;implementationprocedure Register;
begin
RegisterComponents('Standard', [TSNCOMM]);
end;{ TSNCOMM }function TSNCOMM.BytesNeedRead: Cardinal;
var
err: Cardinal;
cs: TCOMSTAT;
begin
Result := 0;
if not Connected then Exit;
if not ClearCommError(FComHandle,err,@cs) then Exit;
Result := cs.cbInQue;
end;procedure TSNCOMM.Clear;
begin
if not Connected then Exit;
PurgeComm(FComHandle,PURGE_TXABORT or PURGE_RXABORT or PURGE_TXCLEAR or PURGE_RXCLEAR);
end;function TSNCOMM.Connect(ComPort: Byte; bps: Cardinal): Boolean;
var
dcb: TDCB;
tos: TCOMMTIMEOUTS;
n: Cardinal;
begin
Result := False;
if Connected then Exit; case bps of
110: n := CBR_110;
300: n := CBR_300;
600: n := CBR_600;
1200: n := CBR_1200;
2400: n := CBR_2400;
4800: n := CBR_4800;
9600: n := CBR_9600;
14400: n := CBR_14400;
19200: n := CBR_19200;
38400: n := CBR_38400;
56000: n := CBR_56000;
57600: n := CBR_57600;
115200: n := CBR_115200;
128000: n := CBR_128000;
256000: n := CBR_256000;
else Exit;
end; FPortName := Format('COM%d',[ComPort]);
FComHandle := CreateFile( PChar(FPortName),
GENERIC_READ or GENERIC_WRITE,
0, // Not shared
nil, // No security attributes
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL or FILE_FLAG_OVERLAPPED,
0 // No template
) ;
if Connected then
begin
FillChar( dcb, SizeOf(dcb), 0 );
dcb.DCBLength := sizeof(dcb);
dcb.BaudRate := n;
dcb.Flags := 1; { binary mode }
dcb.ByteSize := 8;
dcb.Parity := 0;
dcb.StopBits := 0; tos.ReadIntervalTimeout := 100;
tos.ReadTotalTimeoutMultiplier := 100;
tos.ReadTotalTimeoutConstant := 1000;
tos.WriteTotalTimeoutMultiplier := 100;
tos.WriteTotalTimeoutConstant := 1000; Result := True; if SetCommState( FComHandle, dcb )
and PurgeComm( FComHandle, PURGE_TXABORT or PURGE_TXCLEAR or PURGE_RXABORT or PURGE_RXCLEAR )
and SetupComm( FComHandle, 100, 100 )
and SetCommTimeouts( FComHandle, tos )
then Exit; Disconnect;
Result := False;
end; FPortName := '';
end;function TSNCOMM.Connected: Boolean;
begin
Result := FComHandle <> INVALID_HANDLE_VALUE;
end;constructor TSNCOMM.Create(AOwner: TComponent);
begin
inherited;
FComHandle := INVALID_HANDLE_VALUE;
end;destructor TSNCOMM.Destroy;
begin
Disconnect;
inherited;
end;procedure TSNCOMM.Disconnect;
begin
if Connected then
begin
CloseHandle(FComHandle);
FComHandle := INVALID_HANDLE_VALUE;
end;
end;procedure TSNCOMM.FlushBuffers(Rx, Tx: Boolean);
var
Flag: Cardinal;
begin
if not Connected then Exit;
Flag := 0;
if Rx then Flag := Flag or PURGE_RXABORT or PURGE_RXCLEAR;
if Tx then Flag := Flag or PURGE_TXABORT or PURGE_TXCLEAR;
if Flag <> 0 then PurgeComm(FComHandle,Flag);
end;function TSNCOMM.Read(var Buff; Bytes: Cardinal): Cardinal;
var
ol: TOVERLAPPED;
begin
Result := 0;
if not Connected then Exit; FillChar(ol,SizeOf(ol),0);
if not ReadFile(FComHandle,Buff,Bytes,Result,@ol) then
GetOverlappedResult(FComHandle,ol,Result,True);
end;function TSNCOMM.ReadByte(var B: Byte): Boolean;
begin
Result := Read(B,1) = 1;
end;function TSNCOMM.SendByte(B: Byte): Boolean;
begin
Result := Write(B,1) = 1;
end;function TSNCOMM.Write(var Buff; Bytes: Cardinal): Cardinal;
var
ol: TOVERLAPPED;
begin
Result := 0;
if not Connected then Exit; FillChar(ol,SizeOf(ol),0);
if not WriteFile(FComHandle,Buff,Bytes,Result,@ol) then
GetOverlappedResult(FComHandle,ol,Result,True);
end;function TSNCOMM.WriteByte(B: Byte): Boolean;
begin
Result := Write(B,1) = 1;
end;end.
mscomm:微软的东西,ActivX控件,使用简单,在VB中带的,性能一般,由于是ActivX控件,打包时需要注册好多信息,不推荐使用。
spcomm:比较好的vcl,算是比较专业的,解剖了一下,功能比较完善。
TurboPower:公认的专业通讯控件。可以到其站点下载,开放源码了。
我在制作串口通讯软件时三种都用过,最终全部使用TurboPower!所以也推荐大家使用它。
写了个例子,基本的串口通讯都可以实现,可提供参考。
下载地址:http://www.kaer.cn/default.aspx(网站安全性较差,经常当机,如果急用,mail我)
多多指正:[email protected]