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

📄 smthread.pas

📁 通过串口发送多条短信的群发软件
💻 PAS
📖 第 1 页 / 共 2 页
字号:
      (current_answer[current_answer_length-2]='R') and
      (current_answer[current_answer_length-1]=#13) and
      (current_answer[current_answer_length]=#10) then
      begin
        // 当前的指令是 'AT+CSCA?'+#13
        if current_command='AT+CSCA?'+#13 then
        begin
          logForm.logMemo.Lines.Add('执行 AT+CSCA? 出错');

          //清空当前指令和返回的结果
          clear_command_answer;

          //停止超时计时器
          self.stop_timeoutTimer;
        end
        // 当前指令是 'AT+CMGS=1'+#13
        else if current_command='AT+CMGS=1'+#13 then
        begin
          logForm.logMemo.Lines.Add('发送失败! '+current_sm_content+' 到 '+current_sm_tel);
          //清空当前指令和返回的结果
          clear_command_answer;
          //清空手机号和短信内容
          current_sm_tel:='';
          current_sm_content:='';

          mainForm.smsStatusBar.Panels.Items[0].Text:='系统空闲';
          //检查该任务当前状态
          if task_index>=1 then
          begin
            //停止当前任务状态
            mainForm.taskListView.Items.Item[task_index-1].SubItems.Strings[0]:='等待';
            //设置等待图标
            mainForm.tasklistview.Items.Item[task_index-1].ImageIndex:=2;

            //停止其他正在运行的任务
            for i:=0 to mainForm.taskListView.Items.Count-1 do
              if mainForm.taskListView.Items.Item[i].SubItems.Strings[0]='发送' then
              begin
                //停止当前任务状态
                mainForm.taskListView.Items.Item[i].SubItems.Strings[0]:='等待';
                //设置等待图标
                mainForm.tasklistview.Items.Item[i].ImageIndex:=2;
              end;
            //重新初始化
            clear_task_info;
          end;

          //显示和隐藏相关按钮
          if mainForm.tasklistview.ItemIndex>=0 then
          begin
            i:=mainForm.tasklistview.ItemIndex;
            mainForm.tasklistview.ItemIndex:=-1;
            mainForm.tasklistview.ItemIndex:=i;
          end;

          //停止超时计时器
          self.stop_timeoutTimer;
        end
        // 当前指令是 'AT+CMGL=0'+#13
        else if current_command='AT+CMGL=0'+#13 then
        begin
          logForm.logMemo.Lines.Add('取未读短信发生错误!');

          //清空当前指令和返回的结果
          clear_command_answer;

          //显示相关按钮
          inboxForm.refleshSpeedButton.Visible:=True;
        end
        // 当前指令是 'AT+CMGL=1'+#13
        else if current_command='AT+CMGL=1'+#13 then
        begin
          logForm.logMemo.Lines.Add('取已读短信发生错误!');

          //清空当前指令和返回的结果
          clear_command_answer;

          //显示相关按钮
          inboxForm.refleshSpeedButton.Visible:=True;
        end
        //当前指令是 'AT+CMGD='+IntToStr(delete_rec_index)+#13
        else if current_command='AT+CMGD='+IntToStr(delete_rec_index)+#13 then
        begin
          logForm.logMemo.Lines.Add(self.current_answer);

          //重新初始化
          delete_rec_index:=0;

          //清空当前指令和返回的结果
          clear_command_answer;

          //显示相关按钮
          inboxForm.refleshSpeedButton.Enabled:=True;
          inboxForm.deleteSpeedButton.Enabled:=True;
        end;
      end
    end
    //收到空格键
    else if (current_answer[current_answer_length]=' ') then
    begin
      //收到 'AT+CMGS=1'#13#13#10'> '
      if (current_answer[current_answer_length-13]='A') and
      (current_answer[current_answer_length-12]='T') and
      (current_answer[current_answer_length-11]='+') and
      (current_answer[current_answer_length-10]='C') and
      (current_answer[current_answer_length-9]='M') and
      (current_answer[current_answer_length-8]='G') and
      (current_answer[current_answer_length-7]='S') and
      (current_answer[current_answer_length-6]='=') and
      (current_answer[current_answer_length-5]='1') and
      (current_answer[current_answer_length-4]=#13) and
      (current_answer[current_answer_length-3]=#13) and
      (current_answer[current_answer_length-2]=#10) and
      (current_answer[current_answer_length-1]='>') then
      begin
        // 从号码集中取得一个新的号码
        dest_tel:=copy(not_send_tel,1,pos(';',not_send_tel)-1);
        //取得该手机号对应的用户名
        get_username();
        // 从号码集中删除该号码
        delete(not_send_tel,1,pos(';',not_send_tel));
        not_send_account:=not_send_account-1;

        // 发送短信
        mainForm.smsStatusBar.Panels.Items[0].Text:='正在发送消息到 '+dest_tel+' '+username;
        mainForm.smsStatusBar.Refresh;

        current_sm_tel:=dest_tel;
        current_sm_content:=sm_content;

        send_message;
      end;
    end
  end;
end;

procedure smioThread.process_send_message();//处理短信发送
begin
  if not_send_account>0 then
    //开始发送短信
    begin_to_send
  //当前无任务或任务完成
  else if (not_send_account=0) then
  begin
    //取得席新的任务
    if (task_index=0) then
      get_new_task;
  end;
end;

procedure smioThread.clear_task_info();//清空当前任务信息
begin
  //初始化
  task_index:=0;
  task_state:='';

  task_id:='';
  mobile_tel:='';
  send_time:='';
  mobile_tel_account:=0;
  send_account:=0;
  error_send_account:=0;
  not_send_account:=0;
  sm_content:='';
  send_tel:='';
  error_send_tel:='';
  not_send_tel:='';

  dest_tel:='';
  username:='';
end;

procedure smioThread.get_service_tel();//取得短信中心号码
begin
  current_command:='AT+CSCA?'+#13;
  smsApdComPort.PutString(current_command);
end;

procedure smioThread.clear_command_answer();//清空当前指令和返回结果
begin
  self.current_command:='';
  self.current_answer:='';
end;

procedure smioThread.send_message();//发送短信内容
var
  s:String;
  tel_str:String;
  content_str:String;
  i:Integer;
begin
  s:='0891';
  tel_str:=serivce_tel+'F';
  for i:=0 to (Length(tel_str) div 2 - 1) do
    s:=s+tel_str[i*2+2]+tel_str[i*2+1];

  s:=s+'1100';
  s:=s+IntToHex(Length(self.current_sm_tel),2);
  s:=s+'81';

  tel_str:=self.current_sm_tel;
  if Length(tel_str) mod 2 = 1 then
    tel_str:=tel_str+'F';

  for i:=0 to (Length(tel_str) div 2 - 1) do
    s:=s+tel_str[i*2+2]+tel_str[i*2+1];

  //中文
  s:=s+'0008A7';
  content_str:=EncodeChinese(self.current_sm_content);
  s:=s+IntToHex(Length(content_str) div 2,2);
  s:=s+content_str;
  s:=s+#26;

  smsApdComPort.PutString(s);
end;

procedure smioThread.start_timeoutTimer();//启动超时计数定时器
begin
  //计数清0
  timeout_count:=0;
  //启动定时器
  timeoutTimer.Enabled:=True;
end;

procedure smioThread.stop_timeoutTimer();//停止超时计数定时器
begin
  //计数清0
  timeout_count:=0;
  //停止定时器
  timeoutTimer.Enabled:=False;
end;

procedure smioThread.timeoutTimerOnTimer(Sender: TObject);//定时器的触发器
begin
  timeout_count:=timeout_count+1;

  //执行指令 "AT+CSCA?#13" 超时情况
  if (timeout_count>=8) and (self.current_command='AT+CSCA?'+#13) then
  begin
    //关闭计时器
    stop_timeoutTimer;
    //关闭端口
    smsApdComPort.Open:=False;

    logForm.logMemo.Lines.Add('取短信服务中心号码超时!');
  end
  //执行指令 "AT+CMGS=1#13" 超时情况
  else if (timeout_count>=16) and (self.current_command='AT+CMGS=1'+#13) then
  begin
    //关闭计时器
    stop_timeoutTimer;
    //关闭端口
    smsApdComPort.Open:=False;

    logForm.logMemo.Lines.Add('发送短信超时!');    
  end;
end;

procedure smioThread.get_rec_unread();//取未读短信
begin
  current_command:='AT+CMGL=0'+#13;
  smsApdComPort.PutString(current_command);
end;

procedure smioThread.get_rec_read();//取已读短信
begin
  current_command:='AT+CMGL=1'+#13;
  smsApdComPort.PutString(current_command);
end;

procedure smioThread.process_get_rec();//处理短信接收
begin
  //判断当前是否正在检索收件记录
  if inboxForm.Visible and (not inboxForm.refleshSpeedButton.Visible) and
  (self.current_command='') then
  begin
    //取已读短信
    self.get_rec_read;

    logForm.logMemo.Lines.Add('取已读短信');
  end;
end;

procedure smioThread.translate_rec(sm_str:String;read_state:Boolean);//转换短信
var
  i,j:Integer;
  s,s1:String;
  index_str,send_time_str,tel_str,content_str:String;
  tel_len:Integer;
  listitem:TListItem;
  c:Char;
begin

  i:=Pos('+CMGL: ',sm_str);

  //若无记录,则退出
  while i>0 do
  begin
    //初始化
    index_str:='';
    send_time_str:='';
    tel_str:='';
    content_str:='';
    s:='';
    s1:='';

    delete(sm_str,1,i+6);
    j:=Pos('+CMGL: ',sm_str);
    if j=0 then
      j:=Length(sm_str)-5;
    s:=Copy(sm_str,1,j-1);
    //取索引值
    index_str:=Copy(s,1,Pos(',',s)-1);
    //删除索引值
    delete(s,1,Pos(#10,s));
    //删除短信服务中心号码
    delete(s,1,StrToInt('0x'+Copy(s,1,2))*2+2);
    //删除文件头字节
    delete(s,1,2);
    //取得对方号码长度
    tel_len:=StrToInt('0x'+Copy(s,1,2));
    //删除对方号码长度字节和被叫号码类型字节
    delete(s,1,4);
    //取对方号码
    if tel_len mod 2 = 0 then
    begin
      tel_str:=Copy(s,1,tel_len);
      //删除对方号码
      delete(s,1,tel_len);
    end
    else
    begin
      tel_str:=Copy(s,1,tel_len+1);
      //删除对方号码
      delete(s,1,tel_len+1);
    end;
    //将对方号码进行位移处理
    for i:=1 to Length(tel_str) do
      if i mod 2 = 0 then
      begin
        c:=tel_str[i];
        tel_str[i]:=tel_str[i-1];
        tel_str[i-1]:=c;
      end;
    //删除最后一位'F'
    if tel_str[Length(tel_str)]='F' then
      tel_str:=Copy(tel_str,1,Length(tel_str)-1);

    delete(s,1,4);
    //取得发信日期
    send_time_str:=Copy(s,1,10);
    //将日期进行位移处理
    send_time_str:='20'+send_time_str[2]+send_time_str[1]+'年'+send_time_str[4]+
    send_time_str[3]+'月'+send_time_str[6]+send_time_str[5]+'日 '+send_time_str[8]+
    send_time_str[7]+':'+send_time_str[10]+send_time_str[9];
    //删除日期
    delete(s,1,10);

    delete(s,1,6);

    //去掉回车键,换行键,"O","K"
    i:=1;
    while i<=Length(s) do
    begin
      if (s[i]=#13) or (s[i]=#10) or (s[i]='O') or (s[i]='K') then
      begin
        delete(s,i,1);
        i:=1
      end
      else
        i:=i+1;
    end;
    
    //取得短信内容
    while s<>'' do
    begin
      s1:='';
      if Length(s)>=240 then
      begin
        s1:=Copy(s,1,240);
        delete(s,1,240);
      end
      else
      begin
        s1:=Copy(s,1,Length(s));
        delete(s,1,Length(s));
      end;

      content_str:=content_str+DecodeChinese(s1);
    end;

    //去掉"???"
    if Length(content_str)>=3 then
      if (content_str[1]='?') and (content_str[1]='?') and (content_str[1]='?') then
        delete(content_str,1,3);

    //如果是未读短信,则将其添加到列表顶部    
    if read_state then
      //已读
      listitem:=inboxForm.inboxListView.Items.Add
    else
      //未读
      listitem:=inboxForm.inboxListView.Items.Insert(0);
        
    listitem.Caption:=index_str;
    if read_state then
      listitem.SubItems.Add('已读')
    else
      listitem.SubItems.Add('未读');
    listitem.SubItems.Add(send_time_str);
    listitem.SubItems.Add('');
    listitem.SubItems.Add(tel_str);
    listitem.SubItems.Add(content_str);

    i:=Pos('+CMGL: ',sm_str);
  end;
end;

procedure smioThread.process_delete_sm();//处理短信删除
begin
  //判断当前是否正在删除短信
  if (delete_rec_index>0) and inboxForm.Visible and (not inboxForm.deleteSpeedButton.Enabled) and
  (self.current_command='') then
  begin
    //删除索引值对应的短信
    self.delete_rec(delete_rec_index);

    logForm.logMemo.Lines.Add('删除短信'+IntToStr(delete_rec_index));
  end;
end;

procedure smioThread.delete_rec(index:Integer);//删除索引值对应的短信
begin
  current_command:='AT+CMGD='+IntToStr(index)+#13;
  smsApdComPort.PutString(current_command);
end;

procedure smioThread.add_user_name();//向收件箱添加用户名
var
  i,j:Integer;
begin
  for i:=0 to inboxForm.inboxListView.Items.Count-1 do
    for j:=0 to mainForm.userListView.Items.Count-1 do
      if (mainForm.userListView.Items.Item[j].SubItems.Strings[1]=
      inboxForm.inboxListView.Items.Item[i].SubItems.Strings[3]) or
      ('86'+mainForm.userListView.Items.Item[j].SubItems.Strings[1]=
      inboxForm.inboxListView.Items.Item[i].SubItems.Strings[3]) or
      ('0772'+mainForm.userListView.Items.Item[j].SubItems.Strings[1]=
      inboxForm.inboxListView.Items.Item[i].SubItems.Strings[3])then
        inboxForm.inboxListView.Items.Item[i].SubItems.Strings[2]:=
        mainForm.userListView.Items.Item[j].Caption;
end;

end.

⌨️ 快捷键说明

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