📄 usms.~pas
字号:
unit USMS;
interface
uses
Windows,Forms,Messages,Dialogs,SysUtils,USComm;
type
TSMSSet = record
ChkNewMsg:boolean;
ChkEnCode:boolean;
ChkMsgDelay:word;
SMSCenter:string;
SMSMode:string;
end;
type
TRxMsg = record
Index:string;
Mobile:string;
Date:string;
SMSMsg:string;
end;
type
Strings=array of string;
const
WM_DIP_MSG = WM_USER + 1024;
lenSmsInfo = '00';
firstOctet = '11';
TPMessageReference = '00';
TPValidityPeriod = '01'; //aa is 4 day
TypeOfAddress = '91';
TpId = '00';
TpDcs = '08';//"00" is 7 bitencode "08" is 8 bit encode;
type
TSMSControl = Class
private
function SendInEncodeText(SMSData:string;Mobile:string):boolean;
function SendInEncodePdu(SMSData:string;Mobile:string):boolean;
function ExchangeCode(SmobNO:string):string;
function EnCodeGB(var s:widestring):string;
function DeCodeUnicode(var s:string):string;
function SEncodeMobNO(SmobNO: string): string;//将手机号码进行PDU编码
function MakePDU(DestNumber: PChar; Content: PChar):String;
function SMSEncode(S: WideString; Result_Code: PChar): Boolean;
function CheckInPdu:boolean;
function CheckInText:boolean;
// function EnCodeEn(s:string):string; //7Bit编码方式
public
SMSSet:TSMSSet;
RxMsg:TRxMsg;
ErrMsg:integer;
area:string;
Busy:boolean;
SComm:TSComm;
Constructor Create;
published
function SendSMS(var strSMS:string;Mobile:string):boolean; //发送短消息
function CheckNewSMS:boolean; //接收短消息
function IniSMS:integer;
end;
var
SMS:TSMSControl;
implementation
uses
UFConfig;
constructor TSMSControl.Create;
begin
inherited Create;
SMSSet.ChkNewMsg := TRUE;
SMSSet.ChkEnCode := FALSE;
SMSSet.ChkMsgDelay := 5;
SMSSet.SMSCenter := '';
SMSSet.SMSMode := 'PDU';
ErrMsg := 0;
RxMsg.Index := '';
RxMsg.Mobile := '';
RxMsg.Date := '';
RxMsg.SMSMsg := '';
SComm := TSComm.Create;
end;
function IntToHexStr(mInt:integer):string;
var
H,L:integer;
begin
H := mInt div 16;
if H < 10 then H:=H+48 else H:=H+55;
L := mInt mod 16;
if L < 10 then L:=L+48 else L:=L+55;
result := chr(H) + chr(L);
end;
function HexStrToInt(mStr:string):integer;
var
H,L:integer;
begin
H := ord(mStr[1]);
if H >= 65 then H:=H - 55 else H:=H - 48;
L := ord(mStr[2]);
if L >= 65 then L:=L - 55 else L:=L - 48;
result := H*16 + L;
end;
function TSMSControl.IniSMS:integer;
var
parBuffer:array[1..20] of char;
RunDir:string;
SendData:string;
ReceData:string;
// strTmp:Pchar;
iNum:integer;
begin
result := 0;
RunDir := ExtractFileDir(Application.ExeName);
GetPrivateProfileString('System','DelayTime','5',PChar(@parBuffer[1]),500,Pchar(RunDir+'\'+IniPath));
self.SMSSet.ChkMsgDelay := StrToInt(Copy(parBuffer,1,strlen(@parBuffer[1])));
GetPrivateProfileString('System','ChkNewMsg','1',PChar(@parBuffer[1]),500,Pchar(RunDir+'\'+IniPath));
if Copy(parBuffer,1,strlen(@parBuffer[1])) = '1' then self.SMSSet.ChkNewMsg := TRUE else self.SMSSet.ChkNewMsg := FALSE;
GetPrivateProfileString('System','ChkEnCode','1',PChar(@parBuffer[1]),500,Pchar(RunDir+'\'+IniPath));
if Copy(parBuffer,1,strlen(@parBuffer[1])) = '1' then self.SMSSet.ChkEnCode := TRUE else self.SMSSet.ChkEnCode := FALSE;
GetPrivateProfileString('SMS','SMSCenter','',PChar(@parBuffer[1]),500,Pchar(RunDir+'\'+IniPath));
self.SMSSet.SMSCenter := Copy(parBuffer,1,strlen(@parBuffer[1]));
GetPrivateProfileString('SMS','SMSMode','PDU',PChar(@parBuffer[1]),500,Pchar(RunDir+'\'+IniPath));
self.SMSSet.SMSMode := Copy(parBuffer,1,strlen(@parBuffer[1]));
GetPrivateProfileString('Serial','Area','',PChar(@parBuffer[1]),500,Pchar(RunDir+'\'+IniPath));
self.area := Copy(parBuffer,1,strlen(@parBuffer[1]));
SComm.purgeReadWrite(0); //清接收缓冲区
SComm.purgeReadWrite(1); //清发送缓冲区
SendData := 'ATE0'+chr(13); //关闭回显
SComm.WriteCom(SendData,0,TRUE,500);
SComm.ReadCom(ReceData,iNum,6,FALSE,1000); //延时并清接收缓冲区
if (copy(ReceData,1,4) <> 'ATE0') and (copy(ReceData,3,2) <> 'OK') then
begin
result := -1;
exit;
end;
SComm.ReadCom(ReceData,iNum,500,FALSE,100); //先清接收缓冲区
SendData := 'AT+CSCS="GSM"'+chr(13); //设置命令参数输入编码方式,选择"UCS2"方式时,设置短消息中心时应使用PDU的UCS2编码方式,否则ERROR!
SComm.WriteCom(SendData,0,FALSE,200);
SComm.ReadCom(ReceData,iNum,10,FALSE,200); //延时并清接收缓冲区
if (copy(ReceData,3,2) <> 'OK') then
begin
result := -4;
exit;
end;
if(self.SMSSet.SMSCenter<>'') then
begin
SendData := 'AT+CSCA="+'+self.SMSSet.SMSCenter+'"'+chr(13); //设置短消息中心
SComm.WriteCom(SendData,0,FALSE,200);
SComm.ReadCom(ReceData,iNum,6,FALSE,500); //延时并清接收缓冲区
if (copy(ReceData,3,2) <> 'OK') then
begin
SComm.ReadCom(ReceData,iNum,3,FALSE,200); //接收剩余字节
result := -5;
exit;
end;
end;
if self.SMSSet.SMSMode = 'Text' then
begin
SendData := 'AT+CMGF=1'+chr(13); //Text模式
SComm.WriteCom(SendData,0,FALSE,200);
SComm.ReadCom(ReceData,iNum,6,FALSE,500); //延时并清接收缓冲区
if (copy(ReceData,3,2) <> 'OK') then
begin
SComm.ReadCom(ReceData,iNum,3,FALSE,200); //接收剩余字节
result := -6;
exit;
end;
end else
begin
SendData := 'AT+CMGF=0'+chr(13); //PDU模式
SComm.WriteCom(SendData,0,FALSE,200);
SComm.ReadCom(ReceData,iNum,6,FALSE,500); //延时并清接收缓冲区
if (copy(ReceData,3,2) <> 'OK') then
begin
SComm.ReadCom(ReceData,iNum,3,FALSE,200); //接收剩余字节
result := -7;
exit
end;
SendData := 'AT+CSCS="UCS2"'+chr(13); //设置命令参数输入编码方式,选择"UCS2"方式时,设置短消息中心时应使用PDU的UCS2编码方式,否则ERROR!
SComm.WriteCom(SendData,0,FALSE,200);
SComm.ReadCom(ReceData,iNum,6,FALSE,500); //延时并清接收缓冲区
if (copy(ReceData,3,2) <> 'OK') then
begin
SComm.ReadCom(ReceData,iNum,3,FALSE,200); //接收剩余字节
result := -8;
exit;
end;
end;
end;
function TSMSControl.SendInEncodeText(SMSData:string;Mobile:string):boolean;
var
SendData:string;
ReceData:string;
iNum:integer;
begin
result := FALSE;
SComm.ReadCom(ReceData,iNum,0,TRUE,0); //先清接收缓冲区
SendData := 'AT+CMGS="'+(Mobile)+'"'+chr(13);
SComm.WriteCom(SendData,0,FALSE,200);
SComm.ReadCom(ReceData,iNum,3,FALSE,500); //延时100ms
if (copy(ReceData,3,1) <> '>') then
begin
result := FALSE;
exit;
end;
SendData := SMSData + chr(26); //chr(26)为ctrl+z
SComm.WriteCom(SendData,0,FALSE,200);
SComm.ReadCom(ReceData,iNum,9,FALSE,6000); //延时100ms
//#$D#$A'+CMGS: 14'#$D#$A#$D#$A'OK'#$D#$A OK 时返回19个字节
//#$D#$A'ERROR'#$D#$A Error时返回 9个字节
if copy(ReceData,4,5) = '+CMGS' then
begin
SComm.ReadCom(ReceData,iNum,10,FALSE,200); //延时100ms
result := TRUE;
end
end;
{
function TSMSControl.EnCodeEn(s:String):String; //7Bit编码方式
var
i,j,len:Integer; //j 用于移位计数
cur:Integer;
t:String;
begin
Result := '';
len := Length(s);
i := 1;
j := 0;
while i<=len do
begin
if i<len then //数据变换
begin
cur := (ord(s[i]) shr j) or ((ord(s[i+1]) shl (7-j)) and $FF)
end else
begin
cur:=(ord(s[i]) shr j) and $7F;
end;
FmtStr(t,'%2.2X',[cur]);
Result:=Result+t;
inc(i);
j:=(j+1) mod 7;if j=0 then inc(i); //移位计数达到7位的特别处理
end;
end;
}
function TSMSControl.EnCodeGB(var s:widestring):string;
var
sLen:integer;
cur:integer;
i:integer;
strTmp:string;
begin
result := '';
sLen := length(s);
i := 1;
while i <= sLen do
begin
cur := ord(s[i]); //先返回序数值
FmtStr(strTmp,'%4.4X',[cur]); //格式化序数值(BCD转换)
result := result + strTmp;
inc(i);
end;
end;
function TSMSControl.DeCodeUnicode(var s:String):String;
var
Buf:array[0..100] of widechar; //[1..70]
len,i:integer;
begin
len := round(Length(s)/4)-1;
for i:=0 to Len do
begin
buf[i] := widechar(StrToint('$'+copy(s,4*i+1,4)));
end;
buf[Len+1] := #0;
result := WideCharToString(Buf);
end;
function TSMSControl.ExchangeCode(SmobNO:string):string;
var
TempPchar: Pchar;
i: integer;
Str: string;
begin
if (copy(smobno, 1, 1) = '+') then //判断是否包含国家编码
SmobNO := copy(smobno, 2, length(smobno) - 1); //去掉手机号码中的'+'
if ((length(SmobNO) mod 2) = 1) then
SmobNO := SmobNO + 'F';
TempPchar := Pchar(SmobNO); //将字符串 Char数组化
i := 0;
Str := '';
while i < length(TempPchar) do begin
Str := Str + TempPchar[i + 1] + TempPchar[i];
i := i + 2;
end;
ExchangeCode := Str;
end;
{
function TSMSControl.ExchangeCode(src:string):string;
var
strTmp:string;
srcLen:integer;
i:integer;
begin
strTmp := '';
srcLen := length(src);
{if (srcLen <> 11) and (srcLen <> 13) then
begin
ExchangeCode := '';
exit;
end;}
{
src := src+'F';
i := 1;
while i<= srcLen do
begin
strTmp := strTmp + src[i+1]+src[i];
inc(i,2);
end;
ExchangeCode := strTmp;
end;
}
{
function TSMSControl.SendInEncodePdu(SMSData:string;Mobile:string):boolean;
var
Widesms:widestring;
SendData:string;
HeadData:string;
ReceData:string;
strTmp:string;
strlen:integer;
iNum:integer;
begin
result := FALSE;
SendData := '0891';
strTmp := ExchangeCode(SMS.SMSSet.SMSCenter);
SendData := SendData + strTmp;
SendData := SendData + '11000D91';
strTmp := ExchangeCode(mobile);
SendData := SendData + strTmp;
SendData := SendData + '0008A7';
Widesms := widestring(SMSData);
strTmp := EnCodeGB(Widesms);
strlen := length(strTmp) div 2;
SendData := SendData + IntToHexStr(strlen)+strTmp; //16进制数
strlen := (length(SendData) -18) div 2; //不包括开头前9个字节
HeadData := 'AT+CMGC='+IntToStr(strlen)+chr(13); //10进制数
SendData := SendData + chr(26);
SComm.ReadCom(ReceData,iNum,0,TRUE,0); //先清接收缓冲区
SComm.WriteCom(HeadData,0,FALSE,500);
SComm.ReadCom(ReceData,iNum,3,FALSE,500); //延时100ms
if (copy(ReceData,3,1) <> '>') then
begin
result := FALSE;
exit;
end;
SComm.WriteCom(SendData,0,FALSE,500);
SComm.ReadCom(ReceData,iNum,10,FALSE,6000); //延时100ms
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -