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

📄 usms.~pas

📁 通达OA短信程序 通达OA短信程序
💻 ~PAS
📖 第 1 页 / 共 2 页
字号:
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 + -