📄 unidevice_builtin.pas
字号:
if (Success) or (GetLastError = ERROR_IO_PENDING) then
begin
Signaled := WaitForMultipleObjects(EventHandleCount, @EventHandles,
False, Timeout);
Success := (Signaled = WAIT_OBJECT_0)
or (Signaled = WAIT_OBJECT_0 + 1) or (Signaled = WAIT_TIMEOUT);
SetCommMask(FHandle, 0);
end;
if not Success then
raise EComPort.Create(CError_WaitFailed, GetLastError);
Events := IntToEvents(Mask);
finally
CloseHandle(Overlapped.hEvent);
end;
end;
// transmit char ahead of any pending data in ouput buffer
procedure TCustomSerialPort.TransmitChar(Ch: Char);
begin
if not TransmitCommChar(FHandle, Ch) then
raise EComPort.Create(CError_TransmitFailed, GetLastError);
end;
// default actions on port events
procedure TCustomSerialPort.DoBeforeClose;
begin
if Assigned(FOnBeforeClose) then
FOnBeforeClose(Self);
end;
procedure TCustomSerialPort.DoBeforeOpen;
begin
if Assigned(FOnBeforeOpen) then
FOnBeforeOpen(Self);
end;
procedure TCustomSerialPort.DoAfterOpen;
begin
if Assigned(FOnAfterOpen) then
FOnAfterOpen(Self);
end;
procedure TCustomSerialPort.DoAfterClose;
begin
if Assigned(FOnAfterClose) then
FOnAfterClose(Self);
end;
procedure TCustomSerialPort.DoRxChar(Count: Integer);
begin
if Assigned(FOnRxChar) then
FOnRxChar(Self, Count);
end;
procedure TCustomSerialPort.DoRxBuf(const Buffer; Count: Integer);
begin
if Assigned(FOnRxBuf) then
FOnRxBuf(Self, Buffer, Count);
end;
procedure TCustomSerialPort.DoBreak;
begin
if Assigned(FOnBreak) then
FOnBreak(Self);
end;
procedure TCustomSerialPort.DoTxEmpty;
begin
if Assigned(FOnTxEmpty) then FOnTxEmpty(Self);
end;
procedure TCustomSerialPort.DoRing;
begin
if Assigned(FOnRing) then
FOnRing(Self);
end;
procedure TCustomSerialPort.DoCTSChange(OnOff: Boolean);
begin
if Assigned(FOnCTSChange) then
FOnCTSChange(Self, OnOff);
end;
procedure TCustomSerialPort.DoDSRChange(OnOff: Boolean);
begin
if Assigned(FOnDSRChange) then
FOnDSRChange(Self, OnOff);
end;
procedure TCustomSerialPort.DoRLSDChange(OnOff: Boolean);
begin
if Assigned(FOnRLSDChange) then
FOnRLSDChange(Self, OnOff);
end;
procedure TCustomSerialPort.DoError(Errors: TComErrors);
begin
if Assigned(FOnError) then
FOnError(Self, Errors);
end;
procedure TCustomSerialPort.DoRxFlag;
begin
if Assigned(FOnRxFlag) then
FOnRxFlag(Self);
end;
procedure TCustomSerialPort.DoRx80Full;
begin
if Assigned(FOnRx80Full) then
FOnRx80Full(Self);
end;
// set signals to false on close, and to proper value on open,
// because OnXChange events are not called automatically
procedure TCustomSerialPort.CheckSignals(Open: Boolean);
begin
if Open then
begin
CallCTSChange;
CallDSRChange;
CallRLSDChange;
end
else
begin
DoCTSChange(False);
DoDSRChange(False);
DoRLSDChange(False);
end;
end;
// called in response to EV_X events, except CallXClose, CallXOpen
procedure TCustomSerialPort.CallAfterClose;
begin
DoAfterClose;
end;
procedure TCustomSerialPort.CallAfterOpen;
begin
DoAfterOpen;
CheckSignals(True);
end;
procedure TCustomSerialPort.CallBeforeClose;
begin
// shutdown com signals manually
CheckSignals(False);
DoBeforeClose;
end;
procedure TCustomSerialPort.CallBeforeOpen;
begin
DoBeforeOpen;
end;
procedure TCustomSerialPort.CallBreak;
begin
DoBreak;
end;
procedure TCustomSerialPort.CallCTSChange;
var
OnOff: Boolean;
begin
OnOff := csCTS in Signals;
DoCTSChange(OnOff);
end;
procedure TCustomSerialPort.CallDSRChange;
var
OnOff: Boolean;
begin
OnOff := csDSR in Signals;
DoDSRChange(OnOff);
end;
procedure TCustomSerialPort.CallRLSDChange;
var
OnOff: Boolean;
begin
OnOff := csRLSD in Signals;
DoRLSDChange(OnOff);
end;
procedure TCustomSerialPort.CallError;
var
Errors: TComErrors;
begin
Errors := LastErrors;
if Errors <> [] then
DoError(Errors);
end;
procedure TCustomSerialPort.CallRing;
begin
DoRing;
end;
procedure TCustomSerialPort.CallRx80Full;
begin
DoRx80Full;
end;
procedure TCustomSerialPort.CallRxChar;
var
Count: Integer;
// read from input buffer
procedure PerformRead(var P: Pointer);
begin
GetMem(P, Count);
Read(P^, Count);
// call OnRxBuf event
DoRxBuf(P^, Count);
end;
begin
Count := InputCount;
if Count > 0 then
DoRxChar(Count);
end;
procedure TCustomSerialPort.CallRxFlag;
begin
DoRxFlag;
end;
procedure TCustomSerialPort.CallTxEmpty;
begin
DoTxEmpty;
end;
// set connected property, same as Open/Close methods
procedure TCustomSerialPort.SetConnected(const Value: Boolean);
begin
if not ((csDesigning in ComponentState) or (csLoading in ComponentState)) then
begin
if Value <> FConnected then
if Value then
Open
else
Close;
end
else
FConnected := Value;
end;
// set baud rate
procedure TCustomSerialPort.SetBaudRate(const Value: TBaudRate);
begin
if Value <> FBaudRate then
begin
FBaudRate := Value;
// if possible, apply settings
ApplyDCB;
end;
end;
// set custom baud rate
procedure TCustomSerialPort.SetCustomBaudRate(const Value: Integer);
begin
if Value <> FCustomBaudRate then
begin
FCustomBaudRate := Value;
ApplyDCB;
end;
end;
// set data bits
procedure TCustomSerialPort.SetDataBits(const Value: TDataBits);
begin
if Value <> FDataBits then
begin
FDataBits := Value;
ApplyDCB;
end;
end;
// set discard null charachters
procedure TCustomSerialPort.SetDiscardNull(const Value: Boolean);
begin
if Value <> FDiscardNull then
begin
FDiscardNull := Value;
ApplyDCB;
end;
end;
// set event charachters
procedure TCustomSerialPort.SetEventChar(const Value: Char);
begin
if Value <> FEventChar then
begin
FEventChar := Value;
ApplyDCB;
end;
end;
// translated numeric string to port string
function ComString(Str: string): TPort;
var
Num: Integer;
begin
if UpperCase(Copy(Str, 1, 3)) = 'COM' then
Str := Copy(Str, 4, Length(Str) - 3);
try
Num := StrToInt(Str);
except
Num := 1;
end;
if (Num < 1) or (Num > 96) then
Num := 1;
Result := Format('COM%d', [Num]);
end;
// set port
procedure TCustomSerialPort.SetPort(const Value: TPort);
var
Str: string;
begin
Str := ComString(Value);
if Str <> FPort then
begin
FPort := Str;
if (FConnected) and (not ((csDesigning in ComponentState) or
(csLoading in ComponentState))) then
begin
Close;
Open;
end;
end;
end;
// set stop bits
procedure TCustomSerialPort.SetStopBits(const Value: TStopBits);
begin
if Value <> FStopBits then
begin
FStopBits := Value;
ApplyDCB;
end;
end;
// set event synchronization method
procedure TCustomSerialPort.SetSyncMethod(const Value: TSyncMethod);
begin
if Value <> FSyncMethod then
begin
if (FConnected) and (not ((csDesigning in ComponentState) or
(csLoading in ComponentState))) then
raise EComPort.CreateNoWinCode(CError_SyncMeth)
else
FSyncMethod := Value;
end;
end;
// sets RxChar triggering
procedure TCustomSerialPort.SetTriggersOnRxChar(const Value: Boolean);
begin
FTriggersOnRxChar := Value;
end;
// returns true if RxChar is triggered when data arrives input buffer
function TCustomSerialPort.GetTriggersOnRxChar: Boolean;
begin
Result := FTriggersOnRxChar;
end;
// set flow control
procedure TCustomSerialPort.SetFlowControl(const Value: TComFlowControl);
begin
FFlowControl.Assign(Value);
ApplyDCB;
end;
// set parity
procedure TCustomSerialPort.SetParity(const Value: TComParity);
begin
FParity.Assign(Value);
ApplyDCB;
end;
// set timeouts
procedure TCustomSerialPort.SetTimeouts(const Value: TComTimeouts);
begin
FTimeouts.Assign(Value);
ApplyTimeouts;
end;
// set buffer
procedure TCustomSerialPort.SetBuffer(const Value: TComBuffer);
begin
FBuffer.Assign(Value);
ApplyBuffer;
end;
(*****************************************
* EComPort exception *
*****************************************)
// create exception with windows error code
constructor EComPort.Create(ACode: Integer; AWinCode: Integer);
begin
FWinCode := AWinCode;
FCode := ACode;
inherited CreateFmt(ComErrorMessages[ACode] + ' (win error code: %d)', [AWinCode]);
end;
// create exception
constructor EComPort.CreateNoWinCode(ACode: Integer);
begin
FWinCode := -1;
FCode := ACode;
inherited Create(ComErrorMessages[ACode]);
end;
(*****************************************
* other procedures/functions *
*****************************************)
// initialization of PAsync variables used in asynchronous calls
procedure InitAsync(var AsyncPtr: PAsync);
begin
New(AsyncPtr);
with AsyncPtr^ do
begin
FillChar(Overlapped, SizeOf(TOverlapped), 0);
Overlapped.hEvent := CreateEvent(nil, True, True, nil);
Data := nil;
Size := 0;
end;
end;
// clean-up of PAsync variable
procedure DoneAsync(var AsyncPtr: PAsync);
begin
with AsyncPtr^ do
begin
CloseHandle(Overlapped.hEvent);
if Data <> nil then
FreeMem(Data);
end;
Dispose(AsyncPtr);
AsyncPtr := nil;
end;
// enumerate serial ports on local computer
procedure EnumComPorts(Ports: TStrings);
var
BytesNeeded, Returned, I: DWORD;
Success: Boolean;
PortsPtr: Pointer;
InfoPtr: PPortInfo1;
TempStr: string;
begin
Success := EnumPorts(
ni
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -