转videohome() 发的一篇代码给你参考下unit USerCommu;interface uses Classes,Windows,SysUtils; type TSerCommuMethod = procedure(iLen:CardInal;pData:string) of object; type TSerCommu = class(TThread) private FData:string; FdwLen:DWORD; FPort:Integer; FBaud:Integer; FParity:char; FOnComm:TSerCommuMethod; FCommuHandle:THandle; FDataBits:BYTE; FStopBits:BYTE; FActive :Boolean; procedure Send(const pData:string); procedure SetStatus(const bStatus:Boolean); procedure DataSend; protected procedure Execute; override; public constructor Create; property OnComm:TSerCommuMethod read FOnComm write FOnComm; property Port:Integer read FPort write FPort; property Baudrate:Integer read FBaud write FBaud; property Parity:Char read FParity write FParity; property DataBits:BYTE read FDataBits write FDataBits; property StopBits:BYTE read FStopBits write FStopBits; property Active :Boolean read FActive write SetStatus; property Data:string write Send; end; implementationconstructor TSerCommu.Create; begin Inherited Create(true); FPort := 1; FBaud := 9600; FParity := 'N'; FOnComm := nil; FCommuHandle := INVALID_HANDLE_VALUE; FDataBits := 8; FStopBits :=1 ; FActive := false; end;procedure TSerCommu.DataSend; begin FOnComm(FdwLen,FData); end;procedure TSerCommu.Execute; var dwErrorMask:DWORD; ComStat:TCOMSTAT; pData:PCHAR; begin FreeOnTerminate := true; while not Terminated do begin if ClearCommError(FCommuHandle,dwErrorMask,addr(ComStat)) then begin if ComStat.cbInQue>0 then begin pData := AllocMem(ComStat.cbInQue); if ReadFile(FCommuHandle,pData^,ComStat.cbInQue,FdwLen,nil) then begin FData := pData; Synchronize(DataSend); end; FreeMem(pData); end; end else if FCommuHandle = INVALID_HANDLE_VALUE then Suspend; Sleep(10); end; end; procedure TSerCommu.Send(const pData:string); var dwSendLen:DWORD; p:PCHAR; begin if FCommuHandle <>INVALID_HANDLE_VALUE then begin p := PCHAR(pData); WriteFile (FCommuHandle,p^,Length(pData),dwSendLen,nil); end; end; procedure TSerCommu.SetStatus(const bStatus: Boolean); var szDCB,szPort:string; DCB:TDCB; dwErrorMask:DWORD; begin if bStatus = true then begin if FActive = true then exit; if (FPort<1) or (FPort>10) then{Windows can open com1~com10} begin Assert(false,'无效的端口号'+IntToStr(FPort)); exit; end; szPort := 'COM' + IntToStr(FPort); FCommuHandle := CreateFile(PCHAR(szPort), GENERIC_READ or GENERIC_WRITE, 0,nil,OPEN_EXISTING,0,0); if FCommuHandle = INVALID_HANDLE_VALUE then exit; SetupComm(FCommuHandle,1024,1024); GetCommState(FCommuHandle,DCB); szDCB := IntToStr(FBaud)+','+ FParity+',8,1'; if not BuildCommDCB(PCHAR(szDCB),DCB) then begin CloseHandle(FCommuHandle); exit; end; if not SetCommState(FCommuHandle,DCB)then begin CloseHandle(FCommuHandle); exit; end; PurgeComm(FCommuHandle,PURGE_RXCLEAR or PURGE_TXCLEAR); Resume; FActive := true; end else if FActive then begin self.DoTerminate; CloseHandle(FCommuHandle); FCommuHandle := INVALID_HANDLE_VALUE; FActive := false; end; end; end.
uses
Classes,Windows,SysUtils;
type TSerCommuMethod = procedure(iLen:CardInal;pData:string) of object;
type
TSerCommu = class(TThread)
private
FData:string;
FdwLen:DWORD;
FPort:Integer;
FBaud:Integer;
FParity:char;
FOnComm:TSerCommuMethod;
FCommuHandle:THandle;
FDataBits:BYTE;
FStopBits:BYTE;
FActive :Boolean;
procedure Send(const pData:string);
procedure SetStatus(const bStatus:Boolean);
procedure DataSend;
protected
procedure Execute; override;
public
constructor Create;
property OnComm:TSerCommuMethod read FOnComm write FOnComm;
property Port:Integer read FPort write FPort;
property Baudrate:Integer read FBaud write FBaud;
property Parity:Char read FParity write FParity;
property DataBits:BYTE read FDataBits write FDataBits;
property StopBits:BYTE read FStopBits write FStopBits;
property Active :Boolean read FActive write SetStatus;
property Data:string write Send;
end;
implementationconstructor TSerCommu.Create;
begin
Inherited Create(true);
FPort := 1;
FBaud := 9600;
FParity := 'N';
FOnComm := nil;
FCommuHandle := INVALID_HANDLE_VALUE;
FDataBits := 8;
FStopBits :=1 ;
FActive := false;
end;procedure TSerCommu.DataSend;
begin
FOnComm(FdwLen,FData);
end;procedure TSerCommu.Execute;
var
dwErrorMask:DWORD;
ComStat:TCOMSTAT;
pData:PCHAR;
begin
FreeOnTerminate := true;
while not Terminated do
begin
if ClearCommError(FCommuHandle,dwErrorMask,addr(ComStat)) then
begin
if ComStat.cbInQue>0 then
begin
pData := AllocMem(ComStat.cbInQue);
if ReadFile(FCommuHandle,pData^,ComStat.cbInQue,FdwLen,nil) then
begin
FData := pData;
Synchronize(DataSend);
end;
FreeMem(pData);
end;
end
else if FCommuHandle = INVALID_HANDLE_VALUE then
Suspend;
Sleep(10);
end;
end;
procedure TSerCommu.Send(const pData:string);
var
dwSendLen:DWORD;
p:PCHAR;
begin
if FCommuHandle <>INVALID_HANDLE_VALUE then
begin
p := PCHAR(pData);
WriteFile (FCommuHandle,p^,Length(pData),dwSendLen,nil);
end;
end;
procedure TSerCommu.SetStatus(const bStatus: Boolean);
var
szDCB,szPort:string;
DCB:TDCB;
dwErrorMask:DWORD;
begin
if bStatus = true then
begin
if FActive = true then
exit;
if (FPort<1) or (FPort>10) then{Windows can open com1~com10}
begin
Assert(false,'无效的端口号'+IntToStr(FPort));
exit;
end;
szPort := 'COM' + IntToStr(FPort); FCommuHandle := CreateFile(PCHAR(szPort),
GENERIC_READ or GENERIC_WRITE,
0,nil,OPEN_EXISTING,0,0);
if FCommuHandle = INVALID_HANDLE_VALUE then
exit;
SetupComm(FCommuHandle,1024,1024);
GetCommState(FCommuHandle,DCB);
szDCB := IntToStr(FBaud)+','+ FParity+',8,1'; if not BuildCommDCB(PCHAR(szDCB),DCB) then
begin
CloseHandle(FCommuHandle);
exit;
end;
if not SetCommState(FCommuHandle,DCB)then
begin
CloseHandle(FCommuHandle);
exit;
end;
PurgeComm(FCommuHandle,PURGE_RXCLEAR or PURGE_TXCLEAR);
Resume;
FActive := true;
end
else if FActive then
begin
self.DoTerminate;
CloseHandle(FCommuHandle);
FCommuHandle := INVALID_HANDLE_VALUE;
FActive := false;
end;
end;
end.