📄 smscomm.pas
字号:
unit SMSComm;
{$I SMSComm.inc}
interface
uses
SysUtils, Classes, Windows, Forms, Contnrs, Math, SyncObjs, DateUtils, CommQueue;
const
// auxilary constants used not defined in windows.pas
dcb_Binary = $00000001;
dcb_Parity = $00000002;
dcb_OutxCTSFlow = $00000004;
dcb_OutxDSRFlow = $00000008;
dcb_DTRControl = $00000030;
dcb_DSRSensivity = $00000040;
dcb_TxContinueOnXoff = $00000080;
dcb_OutX = $00000100;
dcb_InX = $00000200;
dcb_ErrorChar = $00000400;
dcb_Null = $00000800;
dcb_RTSControl = $00003000;
dcb_AbortOnError = $00004000;
// error codes
CError_OpenFailed = 1;
CError_WriteFailed = 2;
CError_ReadFailed = 3;
CError_InvalidAsync = 4;
CError_PurgeFailed = 5;
CError_AsyncCheck = 6;
CError_SetStateFailed = 7;
CError_TimeoutsFailed = 8;
CError_SetupComFailed = 9;
CError_ClearComFailed = 10;
CError_ModemStatFailed = 11;
CError_EscapeComFailed = 12;
CError_TransmitFailed = 13;
CError_ConnChangeProp = 14;
CError_EnumPortsFailed = 15;
CError_StoreFailed = 16;
CError_LoadFailed = 17;
CError_RegFailed = 18;
CError_LedStateFailed = 19;
CError_ThreadCreated = 20;
CError_WaitFailed = 21;
CError_HasLink = 22;
CError_RegError = 23;
FDATALEN = 256;
RETRYTIMES = 1;
SMSBOUND = 40;
NUM_OF_TASKS = 1;
type
TPort = string;
TBaudRate = (brCustom, br110, br300, br600, br1200, br2400, br4800, br9600, br14400,
br19200, br38400, br56000, br57600, br115200, br128000, br256000);
TStopBits = (sbOneStopBit, sbOne5StopBits, sbTwoStopBits);
TDataBits = (dbFive, dbSix, dbSeven, dbEight);
TParityBits = (prNone, prOdd, prEven, prMark, prSpace);
TEncodeStyle = (esSevenBit, esEightBit, esUnicode);
TSendStyle = (ctNonBlocking, ctBlocking);
TAddTaskStyle = (atInsert, atAdd);
TSMSState = (csNone, csRecUnRead, csRecRead, csStoUnSend, csStoSend);
TPhoneStyle = (psMobilePhone, psSpecialPhone);
TEventType = (etBeforeCommand, etCommand, etAfterCommand, etAfterSendSMS, etBeforeSendSMS, etReceiveSMS, etBeforeOpenModem,
etAfterOpenModem, etBeforeTimingDelSMS, etAfterTimingDelSMS);
TypeOfStatus = (tsWaiting, tsReady, tsRunning);
TTaskType = (ttNone, ttAT_CMGS, ttAT_CSCA, ttAT_CMGD, ttAT_CMGL, ttAT_CMGR, ttAT_W);
TTaskHandle = procedure of object;
TypeOfTCB = record
TaskName: string;
TaskNum: byte;
Status: TypeOfStatus;
TaskHandle: TTaskHandle;
end;
ArrayOfTCB = array[0..NUM_OF_TASKS-1] of TypeOfTCB;
//短信结构体
TSMSItem = record
SerialNo: Integer;
SCA: string;
CodedType: TEncodeStyle;
SMSTime: TDateTime;
SMSState: TSMSState;
Msg: string;
DestPhone, SourPhone: string;
end;
PSMSItem = ^TSMSItem;
TOnBeforeSendSMS = procedure(Sender: TObject; aSMSItem: TSMSItem) of object;
TOnAfterSendSMS = procedure(Sender: TObject; aSMSItem: TSMSItem; SendOK: Boolean) of object;
TOnReceiveSMS = procedure(Sender: TObject; aSMSItem: TSMSItem) of object;
TSMSComm = class;
TComPort = class;
TSMSCommThread = class;
TAbout = class(TObject);
//基础任务类
TBaseTask = class(TObject)
protected
FTaskType: TTaskType;
FSendStyle: TSendStyle;
FSuccess: Boolean;
FFinish: Boolean;
public
constructor Create(aSendStyle: TSendStyle = ctBlocking); virtual;
destructor Destroy; override;
property TaskType: TTaskType read FTaskType write FTaskType;
property SendStyle: TSendStyle read FSendStyle;
property Success: Boolean read FSuccess;
property Finish: Boolean read FFinish write FFinish;
end;
//发送消息任务
TAT_CMGS_Task = class(TBaseTask)
public
SMSItem: TSMSItem;
constructor Create(aSendStyle: TSendStyle = ctBlocking); override;
end;
TAT_CSCA_Task = class(TBaseTask)
private
FSCA: string;
public
constructor Create(aSendStyle: TSendStyle = ctBlocking); override;
property SCA: string read FSCA write FSCA;
end;
TAT_CMGD_Task = class(TBaseTask)
private
FIndex: Integer;
public
constructor Create(aSendStyle: TSendStyle = ctBlocking); override;
property Index: Integer read FIndex write FIndex;
end;
TAT_CMGL_Task = class(TBaseTask)
private
FState: Integer;
public
Msg: string;
constructor Create(aSendStyle: TSendStyle = ctBlocking); override;
property State: Integer read FState write FState;
end;
TAT_CMGR_Task = class(TBaseTask)
private
FSerialNo: Integer;
public
Msg: string;
SMSItem: TSMSItem;
constructor Create(aSendStyle: TSendStyle = ctBlocking); override;
property SerialNo: Integer read FSerialNo write FSerialNo;
end;
TAT_W_Task = class(TBaseTask);
// 发送短消息线程
TSMSCommThread = class(TThread)
private
{ Private declarations }
FOwner: TSMSComm;
FEventType: TEventType;
FSMSItem: TSMSItem;
FBool: Boolean;
procedure CommandTask;
procedure InspectTask;
procedure DeleteSMSTask;
procedure TimingDelSMS;
protected
procedure Execute; override;
procedure UpdateCaption;
public
TaskItem: TBaseTask;
procedure CallBackEvent;
property Owner: TSMSComm read FOwner;
constructor Create(AOwner: TSMSComm; CreateSuspended: Boolean = False);
destructor Destroy; override;
end;
// exception class for ComPort Library errors
EComPort = class(Exception)
private
FWinCode: Integer;
FCode: Integer;
public
constructor Create(ACode: Integer; AWinCode: Integer);
constructor CreateNoWinCode(ACode: Integer);
property WinCode: Integer read FWinCode write FWinCode;
property Code: Integer read FCode write FCode;
end;
// Timing Delete SMS settings
TTimingDelSMS = class(TPersistent)
private
FTimingDelSMS: Boolean;
FTimingDelSMSTime: integer;
FDelSMSInteval: integer;
FOwner: TComponent;
procedure SetDelSMSInteval(const Value: integer);
procedure SetTimingDelSMS(const Value: Boolean);
protected
procedure AssignTo(Dest: TPersistent); override;
public
constructor Create(AOwner: TComponent);
property Owner: TComponent read FOwner;
published
property TimingDelSMS: Boolean read FTimingDelSMS write SetTimingDelSMS default True;
property DelSMSInteval: integer read FDelSMSInteval write SetDelSMSInteval default 12;
end;
// buffer size settings
TComBuffer = class(TPersistent)
private
FOwner: TComPort;
FInputSize: Integer;
FOutputSize: Integer;
procedure SetInputSize(const Value: Integer);
procedure SetOutputSize(const Value: Integer);
protected
procedure AssignTo(Dest: TPersistent); override;
public
constructor Create(AOwner: TComPort);
property Owner: TComPort read FOwner;
published
property InputSize: Integer read FInputSize write SetInputSize default 1024;
property OutputSize: Integer read FOutputSize write SetOutputSize default 1024;
end;
// timoeout properties for read/write operations
TComTimeouts = class(TPersistent)
private
FOwner: TComPort;
FReadInterval: Integer;
FReadTotalM: Integer;
FReadTotalC: Integer;
FWriteTotalM: Integer;
FWriteTotalC: Integer;
procedure SetReadInterval(const Value: Integer);
procedure SetReadTotalM(const Value: Integer);
procedure SetReadTotalC(const Value: Integer);
procedure SetWriteTotalM(const Value: Integer);
procedure SetWriteTotalC(const Value: Integer);
protected
procedure AssignTo(Dest: TPersistent); override;
public
constructor Create(AOwner: TComPort);
property Owner: TComPort read FOwner;
published
property ReadInterval: Integer read FReadInterval write SetReadInterval default 0;//-1;
property ReadTotalMultiplier: Integer read FReadTotalM write SetReadTotalM default 2;//0;
property ReadTotalConstant: Integer read FReadTotalC write SetReadTotalC default 20;//0;
property WriteTotalMultiplier: Integer read FWriteTotalM write SetWriteTotalM default 0;//100;
property WriteTotalConstant: Integer read FWriteTotalC write SetWriteTotalC default 0;//1000;
end;
// parity settings
TComParity = class(TPersistent)
private
FOwner: TComPort;
FBits: TParityBits;
FCheck: Boolean;
FReplace: Boolean;
FReplaceChar: Char;
procedure SetBits(const Value: TParityBits);
procedure SetCheck(const Value: Boolean);
procedure SetReplace(const Value: Boolean);
procedure SetReplaceChar(const Value: Char);
protected
procedure AssignTo(Dest: TPersistent); override;
public
constructor Create(AOwner: TComPort);
property Owner: TComPort read FOwner;
published
property Bits: TParityBits read FBits write SetBits default prNone;
property Check: Boolean read FCheck write SetCheck default False;
property Replace: Boolean read FReplace write SetReplace default False;
property ReplaceChar: Char read FReplaceChar write SetReplaceChar default #0;
end;
// ComPort settings
TComPort = class(TPersistent)
private
FOwner: TComponent;
FParity: TComParity;
FTimeouts: TComTimeouts;
FBuffer: TComBuffer;
FHandle: THandle;
FUpdateCount: Integer;
FConnected: Boolean;
FBaudRate: TBaudRate;
FCustomBaudRate: Integer;
FPort: TPort;
FStopBits: TStopBits;
FDataBits: TDataBits;
procedure SetConnected(const Value: Boolean);
procedure SetBaudRate(const Value: TBaudRate);
procedure SetCustomBaudRate(const Value: Integer);
procedure SetPort(const Value: TPort);
procedure SetStopBits(const Value: TStopBits);
procedure SetDataBits(const Value: TDataBits);
procedure SetParity(const Value: TComParity);
procedure SetTimeouts(const Value: TComTimeouts);
procedure SetBuffer(const Value: TComBuffer);
protected
procedure AssignTo(Dest: TPersistent); override;
procedure ApplyTimeouts; dynamic;
procedure ApplyBuffer; dynamic;
procedure ApplyDCB; dynamic;
procedure CreateHandle; virtual;
procedure DestroyHandle; virtual;
procedure SetupComPort; virtual;
procedure Open;
procedure Close;
function Write(const Buffer; Count: Integer): Boolean;
function WriteStr(const Str: string): Boolean;
function Read(var Buffer; Count: Integer): Boolean;
function ReadStr(var Str: string; Count: Integer): Boolean;
procedure Clear;
public
constructor Create(AOwner: TComponent);
destructor Destroy; override;
property Owner: TComponent read FOwner;
property Connected: Boolean read FConnected;
//property CustomBaudRate: Integer read FCustomBaudRate write SetCustomBaudRate;
//property Handle: THandle read FHandle;
published
property BaudRate: TBaudRate read FBaudRate write SetBaudRate default br9600;
property Port: TPort read FPort write SetPort;
property StopBits: TStopBits read FStopBits write SetStopBits default sbOneStopBit;
property DataBits: TDataBits read FDataBits write SetDataBits default dbEight;
property Parity: TComParity read FParity write SetParity;
property Timeouts: TComTimeouts read FTimeouts write SetTimeouts;
property Buffer: TComBuffer read FBuffer write SetBuffer;
end;
// main component
TSMSComm = class(TComponent)
private
fAbout: TAbout;
FComport: TComPort;
FShouldQuit: Boolean;
FTimingDelSMS: TTimingDelSMS;
FCommQueue: TCommQueue;
FEncodeStyle: TEncodeStyle;
FDestPhoneStyle: TPhoneStyle;
FDatalenMsg: integer;
FReceiveBuffer: array[0..FDATALEN-1] of Byte;
FActive: Boolean;
FLock: TCriticalSection;
FInSync: Boolean;
FWaitEvent: TEvent;
FSmartSMSThread: TSMSCommThread;
FDeleteSMSList: TStringList;
FTaskCapacity: integer;
FOnBeforeTimingDelSMS: TNotifyEvent;
FOnAfterTimingDelSMS: TNotifyEvent;
FOnBeforeSendSMS: TOnBeforeSendSMS;
FOnAfterSendSMS: TOnAfterSendSMS;
FOnReceiveSMS: TOnReceiveSMS;
FOnBeforeOpenModem: TNotifyEvent;
FOnAfterOpenModem: TNotifyEvent;
function InCommThread: Boolean;
procedure DoActivate(Value: Boolean);
procedure SetActive(Value: Boolean);
procedure AddTask(aTask: TBaseTask; Style: TAddTaskStyle = atAdd; Position: Integer = -1);
procedure SetComPort(const Value: TComPort);
procedure SetTimingDelSMS(const Value: TTimingDelSMS);
procedure SetEncodeStyle(const Value: TEncodeStyle);
function _GSM_AT_CMGS(aSMSItem: TSMSItem): Boolean;
function _GSM_AT_CSCA(const SCA: string): Boolean;
function _GSM_AT_CMGD(const Index: integer): Boolean;
function _GSM_AT_CMGL(const State: integer; var Msg: string): Boolean;
function _GSM_AT_CMGR(const Index: Integer; var Msg: string): Boolean;
function _GSM_AT_W: Boolean;
protected
TaskList: TList;
procedure Loaded; override;
procedure DoReceive(aSMSItem: TSMSItem); dynamic;
procedure DoBeforeSend(aSMSItem: TSMSItem); dynamic;
procedure DoAfterSend(aSMSItem: TSMSItem; SenOK: Boolean); dynamic;
procedure DoBeforeOpenModem; dynamic;
procedure DoAfterOpenModem; dynamic;
procedure DoAfterTimgingDelSMS; dynamic;
procedure DoBeforeTimgingDelSMS; dynamic;
procedure FilterSMS(Msg: string); virtual;
function ProcessSMSItemByCMGL(const Msg: string; var aSMSItem: TSMSItem): Boolean; virtual;
function ProcessSMSItemByCMGR(const Msg: string; const Index: Integer; var aSMSItem: TSMSItem): Boolean; virtual;
function JudgeCMTI: Boolean; virtual;
function DecodeSourPhone(SourPhone: string; ProcessF: Boolean): string; virtual;
function DecodeSCA(SCA: string; ProcessF: Boolean): string; virtual;
function GetChar(CC: Byte): string; virtual;
function CodeMsg(const Msg: string; var DecodeLen: integer): string; virtual;
function DecodeChinese(Msg: string): string; virtual;
function DecodeSevenBit(Msg: string): string; virtual;
function EncodeSevenBit(Msg: string): string; virtual;
function CodeDestPhone(const DestPhone: string; var Len: Integer): string; virtual;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure Close;
function Open: Boolean;
function GSM_AT_W: Boolean;
function GSM_AT_CSCA(const SCA: string): Boolean;
function GSM_AT_CMGD(const Index: Integer): Boolean;
function GSM_AT_CMGL(const State: Integer; var Msg: string): Boolean;
function GSM_AT_CMGR(const Index: Integer; var Msg: string; SMSItem: TSMSItem): Boolean;
function GSM_AT_CMGS(const DestPhone: string; const Msg: string): Boolean;
published
property About: TAbout read fAbout write fAbout stored False;
property ComPort: TComPort read FComPort write SetComPort;
property Active: Boolean read FActive write SetActive default False;
property TimingDelSMS: TTimingDelSMS read FTimingDelSMS write SetTimingDelSMS;
property EncodeStyle: TEncodeStyle read FEncodeStyle write SetEncodeStyle default esUnicode;
property DestPhoneStyle: TPhoneStyle read FDestPhoneStyle write FDestPhoneStyle default psMobilePhone;
property TaskCapacity: integer read FTaskCapacity write FTaskCapacity default -1;
property OnBeforeTimingDelSMS: TNotifyEvent read FOnBeforeTimingDelSMS write FOnBeforeTimingDelSMS;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -