📄 win32com.pas
字号:
(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*)
procedure TWin32Obj.Com_StopThread;
begin
EndThreads := true;
ThreadsInitted := false;
if DoTxEvent <> nil then DoTxEvent^.SignalEvent;
if TxThread <> nil then TxThread^.CloseThread;
if RxThread <> nil then RxThread^.CloseThread;
if TxClosedEvent <> nil then
if NOT TxClosedEvent^.WaitForEvent(1000) then
TxThread^.TerminateThread(0);
if RxClosedEvent <> nil then
if NOT RxClosedEvent^.WaitForEvent(1000) then
RxThread^.TerminateThread(0);
if TxThread <> nil then Dispose(TxThread, Done);
if RxThread <> nil then Dispose(RxThread, Done);
if DoTxEvent <> nil then Dispose(DoTxEvent, Done);
if RxClosedEvent <> nil then Dispose(RxClosedEvent, Done);
if TxClosedEvent <> nil then Dispose(TxClosedEvent, Done);
if CriticalTx <> nil then Dispose(CriticalTx, Done);
if CriticalRx <> nil then Dispose(CriticalRx, Done);
if InBuffer <> nil then Dispose(InBuffer, Done);
if OutBuffer <> nil then Dispose(OutBuffer, Done);
if RecvEvent <> nil then Dispose(RecvEvent, Done);
if ReadEvent <> nil then Dispose(ReadEvent, Done);
if WriteEvent <> nil then Dispose(WriteEvent, Done);
Com_InitVars;
end; { proc. Com_StopThread }
(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*)
procedure TWin32Obj.Com_InitDelayTimes;
var CommTimeOut: TCommTimeouts;
RC : Longint;
begin
FillChar(CommTimeOut, SizeOf(TCommTimeOuts), 00);
CommTimeOut.ReadIntervalTimeout := MAXDWORD;
if NOT SetCommTimeOuts(SaveHandle, CommTimeOut) then
begin
RC := GetLastError;
{ ErrorStr := 'Error setting communications timeout: #'+IntToStr(RC) + ' / ' + SysErrorMessage(rc)); }
end; { if }
end; { proc. InitDelayTimes }
(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*)
function TWin32Obj.Com_GetHandle: Longint;
begin
Result := SaveHandle;
end; { func. Com_GetHandle }
(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*)
procedure TWin32Obj.Com_OpenQuick(Handle: Longint);
var LastError: Longint;
begin
SaveHandle := Handle;
InitHandle := Handle;
FillChar(ReadOl, SizeOf(ReadOl), 00);
FillChar(WriteOl, SizeOf(WriteOl), 00);
Com_InitDelayTimes;
if NOT SetupComm(Com_GetHandle, 1024, 1024) then
begin
LastError := GetLastError;
{ ErrorStr := 'Error setting up communications buffer: #'+IntToStr(LastError) + ' / '+SysErrorMessage(LastError); }
end; { if }
InitFailed := NOT Com_StartThread;
Com_SetLine(-1, 'N', 8, 1);
end; { proc. TWin32Obj.Com_OpenQuick }
(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*)
function TWin32Obj.Com_OpenKeep(Comport: Byte): Boolean;
var TempSave : THandle;
Security : TSECURITYATTRIBUTES;
LastError : Longint;
begin
InitPortNr := Comport;
FillChar(ReadOl, SizeOf(ReadOl), 00);
FillChar(WriteOl, SizeOf(WriteOl), 00);
FillChar(Security, SizeOf(TSECURITYATTRIBUTES), 0);
Security.nLength := SizeOf(TSECURITYATTRIBUTES);
Security.lpSecurityDescriptor := nil;
Security.bInheritHandle := true;
TempSave := CreateFile(PChar('\\.\COM' + IntToStr(ComPort)),
GENERIC_READ or GENERIC_WRITE,
0,
@Security, { No Security }
OPEN_EXISTING, { Creation action }
FILE_ATTRIBUTE_NORMAL or FILE_FLAG_OVERLAPPED,
0); { No template }
LastError := GetLastError;
if LastError <> 0 then
ErrorStr := 'Unable to open communications port';
SaveHandle := TempSave;
Result := (TempSave <> INVALID_HANDLE_VALUE);
if Result then { Make sure that "CharAvail" isn't going to wait }
begin
Com_InitDelayTimes;
end; { if }
if NOT SetupComm(Com_GetHandle, 1024, 1024) then
begin
LastError := GetLastError;
{ ErrorStr := 'Error setting up communications buffer: #'+IntToStr(LastError) + ' / '+SysErrorMessage(LastError); }
end; { if }
InitFailed := NOT Com_StartThread;
end; { func. Com_OpenKeep }
(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*)
function TWin32Obj.Com_Open(Comport: Byte; BaudRate: Longint; DataBits: Byte;
Parity: Char; StopBits: Byte): Boolean;
begin
Com_Open := Com_OpenKeep(Comport);
Com_SetLine(Baudrate, Parity, DataBits, StopBits);
end; { func. TWin32Obj.Com_OpenCom }
(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*)
procedure TWin32Obj.Com_SetLine(BpsRate: longint; Parity: Char; DataBits, Stopbits: Byte);
var DCB : TDCB;
BPSID : Longint;
begin
if BpsRate = 11520 then
BpsRate := 115200;
GetCommState(Com_GetHandle, DCB);
if NOT (Parity in ['N', 'E', 'O', 'M']) then Parity := 'N';
if BpsRate >= 0 then dcb.BaudRate := BpsRate;
dcb.StopBits := ONESTOPBIT;
Case Parity of
'N' : dcb.Parity := NOPARITY;
'E' : dcb.Parity := EVENPARITY;
'O' : dcb.Parity := ODDPARITY;
'M' : dcb.Parity := MARKPARITY;
end; { case }
if StopBits = 1 then
dcb.StopBits := ONESTOPBIT;
dcb.ByteSize := DataBits;
dcb.Flags := dcb.Flags OR dcb_Binary or Dcb_DtrControlEnable;
if not SetCommState (Com_GetHandle, DCB) then
begin
BPSId := GetLastError;
{ ErrorStr := 'Error setting up communications parameters: #'+IntToStr(BpsId) + ' / '+SysErrorMessage(BpsId); }
end; { if }
end; { proc. TWin32Obj.Com_SetLine }
(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*)
procedure TWin32Obj.Com_Close;
begin
if DontClose then EXIT;
if Com_GetHandle <> INVALID_HANDLE_VALUE then
begin
Com_StopThread;
CloseHandle(Com_GetHandle);
SaveHandle := INVALID_HANDLE_VALUE;
end;
end; { func. TWin32Obj.Com_CloseCom }
(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*)
function TWin32Obj.Com_SendChar(C: Char): Boolean;
var Written: Longint;
begin
Com_SendBlock(C, SizeOf(C), Written);
Com_SendChar := (Written = SizeOf(c));
end; { proc. TWin32Obj.Com_SendChar }
(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*)
function TWin32Obj.Com_GetChar: Char;
var Reads: Longint;
begin
Com_ReadBlock(Result, SizeOf(Result), Reads);
end; { func. TWin32Obj.Com_GetChar }
(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*)
procedure TWin32Obj.Com_SendBlock(var Block; BlockLen: Longint; var Written: Longint);
begin
if OutBuffer^.BufRoom < BlockLen then
repeat
{$IFDEF WIN32}
Sleep(1);
{$ENDIF}
{$IFDEF OS2}
DosSleep(1);
{$ENDIF}
until (OutBuffer^.BufRoom >= BlockLen) OR (NOT Com_Carrier);
CriticalTx^.EnterExclusive;
Written := OutBuffer^.Put(Block, BlockLen);
CriticalTx^.LeaveExclusive;
DoTxEvent^.SignalEvent;
end; { proc. TWin32Obj.Com_SendBlock }
(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*)
procedure TWin32Obj.Com_ReadBlock(var Block; BlockLen: Longint; var Reads: Longint);
begin
if InBuffer^.BufUsed < BlockLen then
begin
repeat
Sleep(1);
until (InBuffer^.BufUsed >= BlockLen) OR (NOT Com_Carrier);
end; { if }
CriticalRx^.EnterExclusive;
Reads := InBuffer^.Get(Block, BlockLen, true);
CriticalRx^.LeaveExclusive;
end; { proc. TWin32Obj.Com_ReadBlock }
(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*)
function TWin32Obj.Com_CharAvail: Boolean;
begin
Result := (InBuffer^.BufUsed > 0);
end; { func. TWin32Obj.Com_CharAvail }
(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*)
function TWin32Obj.Com_Carrier: Boolean;
var Status: DWORD;
begin
GetCommModemStatus(Com_GetHandle,
Status);
Result := (Status AND MS_RLSD_ON) <> 00;
end; { func. TWin32Obj.Com_Carrier }
(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*)
procedure TWin32Obj.Com_GetModemStatus(var LineStatus, ModemStatus: Byte);
var Data: DWORD;
begin
GetCommModemStatus(Com_GetHandle, Data);
ModemStatus := ModemStatus and $0F;
ModemStatus := ModemStatus or Byte(Data);
end; { proc. TWin32Obj.Com_GetModemStatus }
(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*)
procedure TWin32Obj.Com_SetDtr(State: Boolean);
begin
if State then
EscapeCommFunction(Com_GetHandle, SETDTR)
else EscapeCommFunction(Com_GetHandle, CLRDTR);
end; { proc. TWin32Obj.Com_SetDtr }
(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*)
function TWin32Obj.Com_GetBpsRate: Longint;
var DCB : TDCB;
BPSID : Longint;
begin
GetCommState(Com_GetHandle, DCB);
Com_GetBpsRate := dcb.Baudrate;
end; { func. TWin32Obj.Com_GetBpsRate }
(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*)
procedure TWin32Obj.Com_GetBufferStatus(var InFree, OutFree, InUsed, OutUsed: Longint);
begin
InFree := InBuffer^.BufRoom;
OutFree := OutBuffer^.BufRoom;
InUsed := InBuffer^.BufUsed;
OutUsed := OutBuffer^.BufUsed;
end; { proc. TWin32Obj.Com_GetBufferStatus }
(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*)
procedure TWin32Obj.Com_PurgeInBuffer;
begin
CriticalRx^.EnterExclusive;
InBuffer^.Clear;
PurgeComm(Com_GetHandle, PURGE_RXCLEAR);
CriticalRx^.LeaveExclusive;
end; { proc. TWin32Obj.Com_PurgeInBuffer }
(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*)
procedure TWin32Obj.Com_PurgeOutBuffer;
begin
CriticalTx^.EnterExclusive;
OutBuffer^.Clear;
PurgeComm(Com_GetHandle, PURGE_TXCLEAR);
CriticalTx^.LeaveExclusive;
end; { proc. TWin32Obj.Com_PurgeInBuffer }
(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*)
function TWin32Obj.Com_ReadyToSend(BlockLen: Longint): Boolean;
begin
Result := OutBuffer^.BufRoom >= BlockLen;
end; { func. ReadyToSend }
(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*)
procedure TWin32Obj.Com_PauseCom(CloseCom: Boolean);
begin
if CloseCom then Com_Close
else Com_StopThread;
end; { proc. Com_PauseCom }
(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*)
procedure TWin32Obj.Com_ResumeCom(OpenCom: Boolean);
begin
if OpenCom then
begin
if InitPortNr <> -1 then Com_OpenKeep(InitPortNr)
else Com_OpenQuick(InitHandle);
end
else InitFailed := NOT Com_StartThread;
end; { proc. Com_ResumeCom }
(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*)
procedure TWin32Obj.Com_SetFlow(SoftTX, SoftRX, Hard: Boolean);
var DCB : TDCB;
BPSID : Longint;
begin
GetCommState(Com_GetHandle, DCB);
if Hard then
dcb.Flags := dcb.Flags OR dcb_OutxCtsFlow OR dcb_RtsControlHandshake;
if SoftTX then
dcb.Flags := dcb.Flags OR dcb_OutX;
if SoftRX then
dcb.Flags := dcb.Flags OR dcb_InX;
if not SetCommState (Com_GetHandle, DCB) then
begin
BPSId := GetLastError;
{ ErrorStr := 'Error setting up communications parameters: #'+IntToStr(BpsId) + ' / '+SysErrorMessage(BpsId); }
end; { if }
end; { proc. Com_SetFlow }
(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*)
procedure TWin32Obj.Com_SetDataProc(ReadPtr, WritePtr: Pointer);
begin
ReadProcPtr := ReadPtr;
WriteProcPtr := WritePtr;
end; { proc. Com_SetDataProc }
(*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-+-*-*)
end. { unit WIN32COM }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -