⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 connect.pas

📁 一个delphi使用的传送短信(SMS)到GSM手机的单元及示范.
💻 PAS
📖 第 1 页 / 共 2 页
字号:
{ Connection components }
{ Copyright (c) 1999, 2000 by Mandys Tomas - Mandy Soft }
{ email: tomas.mandys@2p.cz }
{ URL: http://www.2p.cz }

unit Connect;

interface
uses
  Classes, SysUtils, Windows, SyncObjs;

const
  lchOut = 1;
  lchIn = 2;
  lchError = 3;

type
  TConnection = class;

  TConnectionNotifyEvent = procedure(DataSet: TConnection) of object;

  TConnection = class(TComponent)
  private
    FActive: Boolean;
    FStreamedActive: Boolean;
    FBeforeOpen, FBeforeClose, FAfterOpen, FAfterClose: TConnectionNotifyEvent;
    procedure SetActive(aEnable: Boolean);
  protected
    procedure OpenConn; virtual; abstract;
    procedure CloseConn; virtual; abstract;
    procedure DoBeforeOpen; virtual;
    procedure DoBeforeClose; virtual;
    procedure DoAfterOpen; virtual;
    procedure DoAfterClose; virtual;
    procedure Loaded; override;
    procedure CheckInactive;
    procedure CheckActive;
  public
    destructor Destroy; override;
    procedure Open;
    procedure Close;
  published
    property Active: Boolean read FActive write SetActive;

    property BeforeOpen: TConnectionNotifyEvent read FBeforeOpen write FBeforeOpen;
    property BeforeClose: TConnectionNotifyEvent read FBeforeClose write FBeforeClose;
    property AfterOpen: TConnectionNotifyEvent read FAfterOpen write FAfterOpen;
    property AfterClose: TConnectionNotifyEvent read FAfterClose write FAfterClose;
  end;

  TAcceptChannelEvent = procedure(Sender: TComponent; const aLogName: string; aChannel: Byte; var aAccept: Boolean) of object;

  TLogger = class(TConnection)
  private
    FCriticalSection: TCriticalSection;
  protected
    FAcceptChannel: TAcceptChannelEvent;
    procedure DoLog(aText: string); virtual; abstract;
    function PreformatText(const aName: string; aChannel: Byte; aText: string): string; virtual; abstract;
  public
    constructor Create(aOwner: TComponent); override;
    destructor Destroy; override;
    procedure Log(const aName: string; aChannel: Byte; aText: string);
  published
    property AcceptChannel: TAcceptChannelEvent read FAcceptChannel write FAcceptChannel;
  end;

  TLogFormatFlag = (lfInsertName, lfInsertChannel, lfDivideNames, lfDivideChannels, lfHexadecimal, lfStamp);
  TLogFormatFlags = set of TLogFormatFlag;

  TStreamLogger = class(TLogger)
  private
    FLogStream: TStream;
    FLogFlags: TLogFormatFlags;
    FMaxLineLength: Integer;
    FLastChannel: Byte;
    FLastName: string;
    FLineLength: Integer;
    procedure SetLogStream(Value: TStream);
  protected
    procedure OpenConn; override;
    procedure DoLog(aText: string); override;
    function PreformatText(const aName: string; aChannel: Byte; aText: string): string; override;
  public
    constructor Create(aOwner: TComponent); override;
    property LogStream: TStream read FLogStream write SetLogStream;
  published
    property LogFlags: TLogFormatFlags read FLogFlags write FLogFlags;
    property MaxLineLength: Integer read FMaxLineLength write FMaxLineLength;
  end;

  TFileLogger = class(TStreamLogger)
  private
    FLogFile: string;
    procedure SetLogFile(const aFile: string);
  protected
    procedure OpenConn; override;
    procedure CloseConn; override;
  public
  published
    property LogFile: string read FLogFile write SetLogFile;
  end;

  TFormatLogEvent = procedure(Sender: TComponent; aChannel: Byte; var aText: string) of object;

  TLogConnection = class(TConnection)
  private
    FLogger: TLogger;
    FOnFormatLog: TFormatLogEvent;
    FLogName: string;
  protected
    procedure DoFormatLog(aChannel: Byte; var aText: string); virtual;
  public
    procedure Log(aChannel: Byte; aText: string);
  published
    property Logger: TLogger read FLogger write FLogger;
    property LogName: string read FLogName write FLogName;
    property OnFormatLog: TFormatLogEvent read FOnFormatLog write FOnFormatLog;
  end;

  TCommunicationConnection = class(TLogConnection)
  public
    function Send(S: string): Integer;  { wait until not sent }
    function InQueCount: Integer; virtual; abstract;
    function Retrieve(aCount: Integer): string;
    procedure PurgeIn; virtual; abstract;
    procedure PurgeOut; virtual; abstract;
  protected
    function Write(const Buf; Count: Integer): Integer; virtual; abstract;
    function Read(var Buf; Count: Integer): Integer; virtual; abstract;
  end;

  TCommEvent = procedure(Sender: TObject; Status: dword) of object;
  TCommEventType = (evBreak, evCts, evDsr, evError, evRing, evRlsd, evRxChar, evRxFlag, evTxEmpty);
  TCommEventTypes = set of TCommEventType;

  TBaudrate =(br110, br300, br600, br1200, br2400, br4800, br9600, br14400,
    br19200, br38400, br56000, br57600, br115200, br128000, br256000);
  TParity = (paNone, paOdd, paEven, paMark, paSpace);
  TStopbits = (sb10, sb15, sb20);
  TDatabits=(da4, da5, da6, da7, da8);
  TFlowControl = (fcNone, fcCTS, fcDTR, fcSoftware, fcDefault);

  TCommOption = (coParityCheck, coDsrSensitivity, coIgnoreXOff,
    coErrorChar, coNullStrip);
  TCommOptions = set of TCommOption;

  TCommRxCharEvent = procedure(Sender: TObject; Count: Integer) of object;
  TCommErrorEvent = procedure(Sender: TObject; Errors: Integer) of object;

  TCommHandle = class;
  
  TCommEventThread = class(TThread)
  private
    FCommHandle: THandle;
    FEvent: TSimpleEvent;
    FEventMask: dWord;
    FComm: TCommHandle;
  protected
    procedure Execute; override;
    procedure Terminate;
    procedure DoOnSignal;
  public
    constructor Create(aComm: TCommHandle; Handle: THandle; Events: TCommEventTypes);
    destructor Destroy; override;
  end;

  TCommHandle = class(TCommunicationConnection)
  private
    FhCommDev: THandle;
    FBaudrate: TBaudrate;
    FParity: TParity;
    FStopBits: TStopBits;
    FDataBits: TDataBits;
    FFlowControl: TFlowControl;
    FOptions: TCommOptions;
    FReadTimeout: Integer;
    FWriteTimeout: Integer;
    FReadBufSize: Integer;
    FWriteBufSize: Integer;
    FMonitorEvents: TCommEventTypes;
    FEventChars: array[1..5] of Char;
    FEvent: TSimpleEvent;
    FCriticalSection: TCriticalSection;
    FEventThread: TCommEventThread;
    FDontSynchronize: Boolean;
    FOnBreak: TNotifyEvent;
    FOnCts: TNotifyEvent;
    FOnDsr: TNotifyEvent;
    FOnError: TCommErrorEvent;
    FOnRing: TNotifyEvent;
    FOnRlsd: TNotifyEvent;
    FOnRxChar: TCommRxCharEvent;
    FOnRxFlag: TNotifyEvent;
    FOnTxEmpty: TNotifyEvent;
    procedure SethCommDev(Value: THandle);
    procedure SetBaudRate(Value: TBaudRate);
    procedure SetParity(Value: TParity);
    procedure SetStopbits(Value: TStopBits);
    procedure SetDatabits(Value: TDatabits);
    procedure SetOptions(Value: TCommOptions);
    procedure SetFlowControl(Value: TFlowControl);
    function GetEventChar(Index: Integer): Char;
    procedure SetEventChar(Index: Integer; Value: Char);
    procedure SetReadBufSize(Value: Integer);
    procedure SetWriteBufSize(Value: Integer);
    procedure SetMonitorEvents(Value: TCommEventTypes);
    function GetComState(Index: Integer): Boolean;
    function GetModemState(Index: Integer): Boolean;
    procedure SetEsc(Index: Integer; Value: Boolean);
    procedure UpdateCommTimeouts;
    procedure UpdateDataControlBlock;
  protected
    procedure OpenConn; override;
    procedure CloseConn; override;
    procedure UpdateDCB; virtual;
    procedure EscapeComm(Flag: Integer);
    procedure HandleCommEvent(Status: dword); virtual;
    function Write(const Buf; Count: Integer): Integer; override;
    function Read(var Buf; Count: Integer): Integer; override;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    property hCommDev: THandle read FhCommDev write SethCommDev;
    function InQueCount: Integer; override;
    function OutQueCount: Integer;
    procedure Lock;
    procedure Unlock;
    procedure PurgeIn; override;
    procedure PurgeOut; override;
    property CtsHold: Boolean index Integer(fCtlHold) read GetComState;
    property DsrHold: Boolean index Integer(fDsrHold) read GetComState;
    property RlsdHold: Boolean index Integer(fRlsHold) read GetComState;
    property XoffHold: Boolean index Integer(fXoffHold) read GetComState;
    property XOffSent: Boolean index Integer(fXoffSent) read GetComState;
    property Eof: Boolean index Integer(fEof) read GetComState;
    {Comm escape functions}
    property DTRState: Boolean index 1 write SetEsc;
    property RTSState: Boolean index 2 write SetEsc;
    property BREAKState: Boolean index 3 write SetEsc;
    property XONState: Boolean index 4 write SetEsc;
    {Comm status flags}
    property CTS: Boolean index Integer(MS_CTS_ON) read GetModemState;
    property DSR: Boolean index Integer(MS_DSR_ON) read GetModemState;
    property RING: Boolean index Integer(MS_RING_ON) read GetModemState;
    property RLSD: Boolean index Integer(MS_RLSD_ON) read GetModemState;
  published
    property Baudrate: TBaudrate read FBaudrate write SetBaudrate default br9600;
    property Parity: TParity read FParity write SetParity default paNone;
    property Stopbits: TStopbits read FStopbits write SetStopbits default sb10;
    property Databits: TDatabits read FDatabits write SetDatabits default da8;
    property Options: TCommOptions read FOptions write SetOptions;
    property DontSynchronize: Boolean read FDontSynchronize write FDontSynchronize;
    property FlowControl: TFlowControl read FFlowControl write SetFlowControl default fcDefault;
    property XonChar: Char index 1 read GetEventChar write SetEventChar default #17;
    property XoffChar: Char index 2 read GetEventChar write SetEventChar default #19;
    property ErrorChar: Char index 3 read GetEventChar write SetEventChar default #0;
    property EofChar: Char index 4 read GetEventChar write SetEventChar default #0;
    property EvtChar: Char index 5 read GetEventChar write SetEventChar default #0;
    property ReadTimeout: Integer read FReadTimeout write FReadTimeout default 1000;
    property WriteTimeout: Integer read FWriteTimeout write FWriteTimeout default 1000;
    property ReadBufSize: Integer read FReadBufSize write SetReadBufSize default 4096;
    property WriteBufSize: Integer read FWriteBufSize write SetWriteBufSize default 2048;
    property MonitorEvents: TCommEventTypes read FMonitorEvents write SetMonitorEvents;
    property OnBreak: TNotifyEvent read FOnBreak write FOnBreak;
    property OnCts: TNotifyEvent read FOnCts write FOnCts;
    property OnDsr: TNotifyEvent read FOnDsr write FOnDsr;
    property OnRing: TNotifyEvent read FOnRing write FOnRing;
    property OnRlsd: TNotifyEvent read FOnRlsd write FOnRlsd;
    property OnError: TCommErrorEvent read FOnError write FOnError;
    property OnRxChar: TCommRxCharEvent read FOnRxChar write FOnRxChar;
    property OnRxFlag: TNotifyEvent read FOnRxFlag write FOnRxFlag;
    property OnTxEmpty: TNotifyEvent read FOnTxEmpty write FOnTxEmpty;
  end;

  TComm = class(TCommHandle)
  private
    FDeviceName: string;
    procedure SetDeviceName(const Value: string);
  protected
    procedure OpenConn; override;
  public
    constructor Create(AOwner: TComponent); override;
  published
    property DeviceName: string read FDeviceName write SetDeviceName;
  end;

  EComError = class(Exception)
  end;

procedure Register;

function Int2BaudRate(BR1: Longint; var BR: TBaudRate): Boolean;
function BaudRate2Int(BR: TBaudRate): Longint;

resourcestring
  sActiveConnection = 'Connection is active';
  sInactiveConnection = 'Connection is inactive';
  sCommError = 'Error %d in function: %s';
implementation

const
  DefaultDeviceName = 'Com2';

procedure ComError(const Msg: string);
begin
  raise EComError.Create(Msg);
end;

procedure ComError2(const aFunc: string);
begin
  ComError(Format(sCommError, [GetLastError, aFunc]));
end;

destructor TConnection.Destroy;
begin
  Destroying;
  Close;
  inherited;
end;

procedure TConnection.Open;
begin
  Active:= True;
end;

procedure TConnection.Close;
begin
  Active:= False;
end;

procedure TConnection.SetActive;
begin
  if (csReading in ComponentState) then
  begin
    if aEnable then
      FStreamedActive := True;
  end
else
  if FActive <> aEnable then
  begin
    if aEnable then
      begin
        DoBeforeOpen;
        try
          OpenConn;
        except
          CloseConn;
          raise;
        end;
        FActive:= aEnable;
        DoAfterOpen;
      end
    else
      begin
        if not (csDestroying in ComponentState) then
          DoBeforeClose;
        CloseConn;
        FActive:= aEnable;
        if not (csDestroying in ComponentState) then
          DoAfterClose;
      end;
  end;
end;

procedure TConnection.DoBeforeOpen;
begin
  if Assigned(FBeforeOpen) then
    FBeforeOpen(Self);
end;

procedure TConnection.DoBeforeClose;
begin
  if Assigned(FBeforeClose) then
    FBeforeClose(Self);
end;

procedure TConnection.DoAfterOpen;
begin
  if Assigned(FAfterOpen) then
    FAfterOpen(Self);
end;

procedure TConnection.DoAfterClose;
begin
  if Assigned(FAfterClose) then
    FAfterClose(Self);
end;

procedure TConnection.Loaded;
begin
  inherited Loaded;
  if FStreamedActive then
    Active := True;
end;

procedure TConnection.CheckInactive;
begin
  if Active then
    ComError(sActiveConnection);
end;

procedure TConnection.CheckActive;
begin
  if not Active then
    ComError(sInactiveConnection);
end;

constructor TLogger.Create;
begin
  inherited;
  FCriticalSection:= TCriticalSection.Create;
end;

destructor TLogger.Destroy;
begin
  FCriticalSection.Free;
  inherited;
end;

procedure TLogger.Log;     // multithreaded
var
  F: Boolean;
begin
  if FActive then
  begin
    F:= True;
    if Assigned(FAcceptChannel) then
      FAcceptChannel(Self, aName, aChannel, F);
    if F then
    begin
      FCriticalSection.Enter;
      try
        DoLog(PreformatText(aName, aChannel, aText));
      finally
        FCriticalSection.Leave;
      end;
    end;
  end;
end;

constructor TStreamLogger.Create;
begin
  inherited;
  FLogFlags:= [lfInsertName, lfInsertChannel, lfDivideNames, lfDivideChannels, lfHexadecimal];
  FMaxLineLength:= 80;
end;

procedure TStreamLogger.SetLogStream;
begin
  CheckInactive;
  FLogStream:= Value;
end;

procedure TStreamLogger.DoLog;
begin
  FLogStream.WriteBuffer(aText[1], Length(aText));
end;

procedure TStreamLogger.OpenConn;
begin
  FLogStream.Position:= FLogStream.Size;
end;

function TStreamLogger.PreformatText;
const
  CRLF = #13#10;
var
  I: Integer;
  F: Boolean;
  function FormatCh(B: Byte): string;
  begin
    Result:= Format('%.2x)', [B]);
    if not (lfHexadecimal in FLogFlags) then
      Result:= Result+' ';
  end;
  procedure InsT(var S: string; const aT: string);
  begin
    S:= S+aT;
    Inc(FLineLength, Length(aT));
  end;
begin
  Result:= '';
  I:= 1;
  while I <= Length(aText) do
  begin
    if (FLastName <> aName) and (lfDivideNames in FLogFlags) or
       (FLastChannel <> aChannel) and (lfDivideChannels in FLogFlags) then
    begin
      FLineLength:= 0;
    end;
    F:= FLineLength = 0;
    if FLineLength = 0 then
    begin
      Result:= Result+CRLF;
      if lfStamp in FLogFlags then
        InsT(Result, DateTimeToStr(Now)+')');
    end;
    if ((FLastName <> aName) or F) and (lfInsertName in FLogFlags) then
      begin
        InsT(Result, aName+'-');
        if lfInsertChannel in FLogFlags then
          InsT(Result, FormatCh(aChannel));
      end
    else
      begin
        if ((FLastChannel <> aChannel) or F) and (lfInsertChannel in FLogFlags) then
          InsT(Result, FormatCh(aChannel));
      end;
    while I <= Length(aText) do
    begin
      if lfHexadecimal in FLogFlags then InsT(Result, Format('%.2x ', [Byte(aText[I])]))
                                    else InsT(Result, aText[I]);
      Inc(I);
      if (FMaxLineLength <> 0) and (FLineLength >= FMaxLineLength) then
      begin
        FLineLength:= 0;    // write on next line
      end;
    end;
  end;

  FLastChannel:= aChannel;
  FLastName:= aName;
end;

procedure TFileLogger.SetLogFile;
var
  SaveLogActive: Boolean;
begin
  if (csReading in ComponentState) then
  begin
    FLogFile:= aFile;
  end
else
  if aFile <> FLogFile then
  begin
    SaveLogActive:= Active;
    FActive:= False;
    FLogFile:= aFile;
    if FLogFile <> '' then
      Active:= SaveLogActive;
  end;
end;

procedure TFileLogger.OpenConn;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -