📄 smthread.pas
字号:
unit smthread;
interface
uses
Classes,SysUtils,AdPort,ExtCtrls,ComCtrls;
type
smioThread = class(TThread)
private
current_command:String;//当前发送的指令
current_answer:String;//针对当前指令返回的结果
current_sm_tel:String;//当前短信的发送地址
current_sm_content:String;//当前短信的内容
task_index:integer;//该任务信息在数据库中的索引
task_id:string;//任务ID
mobile_tel:string;//要发送短信的手机号
mobile_tel_account:integer;//要发送短信的手机号数量
sm_content:string;//短信内容
not_send_tel:string;//未发送短信的手机号
not_send_account:integer;//未发送的手机号数量
send_tel:string;//已正确发送短信的手机号
send_account:integer;//已正确发送短信的手机号数量
error_send_tel:string;//发送错误的手机号
error_send_account:integer;//发送错误的手机号数量
send_time:string;//计划发送时间
dest_tel:string;//目的手机号
task_state:string;//任务状态
username:string;//目的手机号对应的用户名
timeout_count:Integer;//超时记数
procedure get_new_task();//取得新任务的信息
procedure set_task_state();//设置指定任务的状态
procedure get_username();//取得手机号对应的用户名
procedure save_current_task();//保存当前任务的执行结果
procedure clear_task_info();//清空当前任务信息
procedure get_service_tel();//取得短信中心号码
procedure clear_command_answer();//清空当前指令和返回结果
procedure begin_to_send();//开始发送短信
procedure send_message();//发送短信内容
procedure get_rec_unread();//取未读短信
procedure get_rec_read();//取已读短信
procedure delete_rec(index:Integer);//删除索引值对应的短信
procedure add_user_name();//向收件箱添加用户名
procedure process_open_or_close_comport();//处理打开或关闭端口
procedure process_received_buffer();//处理接收的数据
procedure process_send_message();//处理短信发送
procedure process_get_rec();//处理短信接收
procedure process_delete_sm();//处理短信删除
procedure translate_rec(sm_str:String;read_state:Boolean);//转换已读短信
procedure start_timeoutTimer();//启动超时计数定时器
procedure stop_timeoutTimer();//停止超时计数定时器
procedure timeoutTimerOnTimer(Sender: TObject);//定时器的触发器
{ Private declarations }
protected
procedure Execute; override;
public
constructor Create(CreateSuspended: Boolean);
end;
implementation
uses main, log, inbox, other;
{ Important: Methods and properties of objects in visual components can only be
used in a method called using Synchronize, for example,
Synchronize(UpdateCaption);
and UpdateCaption could look like,
procedure smioThread.UpdateCaption;
begin
Form1.Caption := 'Updated in a thread';
end; }
{ smioThread }
constructor smioThread.Create(CreateSuspended: Boolean);
begin
//初始化
clear_command_answer;
current_sm_tel:='';
current_sm_content:='';
clear_task_info;
//生成串口对象
smsApdComPort:=TApdComPort.Create(mainForm);
smsApdComPort.Parity:=pNone;
smsApdComPort.DataBits := 8;
smsApdComPort.StopBits := 1;
smsApdComPort.AutoOpen:=False;
//生成超时计数器对象
timeoutTimer:=TTimer.Create(mainForm);
timeoutTimer.Enabled:=False;
timeoutTimer.Interval:=1000;
timeoutTimer.OnTimer:=timeoutTimerOnTimer;
FreeOnTerminate := True;
inherited Create(CreateSuspended);
end;
procedure smioThread.get_new_task();
var
i:integer;
begin
//已连接手机
if serivce_tel<>'' then
for i:=0 to mainForm.taskListView.Items.Count-1 do
if mainForm.taskListView.Items.Item[i].SubItems.Strings[0]='发送' then
begin
task_index:=i+1;
taskadoquery.RecNo:=i+1;
task_id:=taskadoquery.Fields.Fields[0].AsString;
mobile_tel:=taskadoquery.Fields.Fields[1].AsString;
send_time:=taskadoquery.Fields.Fields[2].AsString;
mobile_tel_account:=taskadoquery.Fields.Fields[3].AsInteger;
send_account:=taskadoquery.Fields.Fields[4].AsInteger;
error_send_account:=taskadoquery.Fields.Fields[5].AsInteger;
not_send_account:=taskadoquery.Fields.Fields[6].AsInteger;
sm_content:=taskadoquery.Fields.Fields[7].AsString;
send_tel:=taskadoquery.Fields.Fields[8].AsString;
error_send_tel:=taskadoquery.Fields.Fields[9].AsString;
not_send_tel:=taskadoquery.Fields.Fields[10].AsString;
exit;
end;
end;
procedure smioThread.process_open_or_close_comport();//处理打开或关闭端口
var
i:Integer;
begin
//端口已关闭
if not smsApdComPort.Open then
begin
//暂停线程
if not self.Suspended then
begin
//显示中断端口连接状态
mainForm.jlljSpeedButton.Caption:='建立连接';
mainForm.ljszSpeedButton.Enabled:=True;
mainForm.jlljSpeedButton.Enabled:=True;
//显示连接状态
mainForm.smsStatusBar.Panels.Items[2].Text:='尚未检测到工作手机';
//清空短信服务中心号码
serivce_tel:='';
//清空当前指令和返回的结果
self.clear_command_answer;
//清空当前任务的信息
self.clear_task_info;
//停止当前所有任务
for i:=0 to mainForm.taskListView.Items.Count-1 do
begin
if mainForm.taskListView.Items.Item[i].SubItems.Strings[0]='发送' then
begin
//设置等待图标
mainForm.tasklistview.Items.Item[i].ImageIndex:=2;
//改变状态
mainForm.tasklistview.Items.Item[i].SubItems.Strings[0]:='等待';
end;
end;
//显示和隐藏相关按钮
if mainForm.tasklistview.ItemIndex>=0 then
begin
i:=mainForm.tasklistview.ItemIndex;
mainForm.tasklistview.ItemIndex:=-1;
mainForm.tasklistview.ItemIndex:=i;
end;
//暂停线程
self.Suspend;
end;
end
//端口已打开
else
begin
//还没取得短信服务中心号码
if (serivce_tel='') and (current_command='') then
begin
//发送短信索取短信服务中心号码
get_service_tel;
//启动超时计数定时器
start_timeoutTimer();
end;
end;
end;
procedure smioThread.set_task_state();
begin
mainForm.taskListView.Items.Item[task_index-1].SubItems.Strings[0]:=task_state;
if task_state='完成' then
mainForm.taskListView.Items.Item[task_index-1].ImageIndex:=4;
end;
procedure smioThread.save_current_task();//保存当前任务的执行结果
begin
//修改数据库中的任务信息
taskadoquery.RecNo:=task_index;
taskadoquery.Edit;
taskadoquery.Fields.Fields[4].AsInteger:=send_account;
taskadoquery.Fields.Fields[5].AsInteger:=error_send_account;
taskadoquery.Fields.Fields[6].AsInteger:=not_send_account;
taskadoquery.Fields.Fields[8].AsString:=send_tel;
taskadoquery.Fields.Fields[9].AsString:=error_send_tel;
taskadoquery.Fields.Fields[10].AsString:=not_send_tel;
taskadoquery.Post;
//修改任务列表中的信息
mainForm.taskListView.Items.Item[task_index-1].SubItems.Strings[3]:=inttostr(send_account);
mainForm.taskListView.Items.Item[task_index-1].SubItems.Strings[4]:=inttostr(error_send_account);
mainForm.taskListView.Items.Item[task_index-1].SubItems.Strings[5]:=inttostr(not_send_account);
end;
procedure smioThread.get_username();
var
i:integer;
begin
for i:=0 to mainForm.userListView.Items.Count-1 do
if mainForm.userListView.Items.Item[i].SubItems.Strings[1]=dest_tel then
begin
username:=mainForm.userListView.Items.Item[i].Caption;
exit;
end;
end;
procedure smioThread.begin_to_Send();
begin
//开始发送短信
if current_command='' then
begin
current_command:='AT+CMGS=1'+#13;
smsApdComPort.PutString(current_command);
//启动计时器
start_timeoutTimer;
logForm.logMemo.Lines.Add('准备发送短信');
end;
end;
procedure smioThread.Execute;
begin
{ Place thread code here }
repeat
//处理打开或关闭端口
Synchronize(process_open_or_close_comport);
//接收和处理数据
Synchronize(process_received_buffer);
//处理短信发送
Synchronize(process_send_message);
//处理短信接收
Synchronize(process_get_rec);
//处理短信删除
Synchronize(process_delete_sm);
until self.Terminated;
end;
procedure smioThread.process_received_buffer();//处理接收的数据
var
c:Char;
current_answer_length:Integer;
i:Integer;
begin
while smsApdComPort.Open and smsApdComPort.CharReady do
begin
c:=smsApdComPort.GetChar;
current_answer:=current_answer+c;
// logForm.logMemo.Lines.Text:=logForm.logMemo.Lines.Text+c;
//判断是否接收到完整的回复
current_answer_length:=Length(current_answer);
//收到换行键
if (current_answer[current_answer_length]=#10) then
begin
//收到 OK
if (current_answer[current_answer_length-5]=#13) and
(current_answer[current_answer_length-4]=#10) and
(current_answer[current_answer_length-3]='O') and
(current_answer[current_answer_length-2]='K') 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
serivce_tel:=Copy(current_answer,Pos('"',current_answer)+2,13);
mainForm.smsStatusBar.Panels.Items[2].Text:='连接到手机';
logForm.logMemo.Lines.Add('短信服务中心的号码是:'+serivce_tel);
//清空当前指令和返回的结果
clear_command_answer;
//显示和隐藏相关按钮
if mainForm.tasklistview.ItemIndex>=0 then
begin
i:=mainForm.tasklistview.ItemIndex;
mainForm.tasklistview.ItemIndex:=-1;
mainForm.tasklistview.ItemIndex:=i;
end;
mainForm.jlljSpeedButton.Caption:='中断连接';
mainForm.jlljSpeedButton.Enabled:=True;
//停止超时计时器
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);
send_account:=send_account+1;
send_tel:=send_tel+dest_tel+';';
//保存当前任务的执行结果
save_current_task;
//清空当前指令和返回的结果
clear_command_answer;
//清空手机号和短信内容
current_sm_tel:='';
current_sm_content:='';
mainForm.smsStatusBar.Panels.Items[0].Text:='系统空闲';
//该任务已完成
if not_send_account=0 then
begin
task_state:='完成';
//更新状态
set_task_state;
//重新初始化
clear_task_info;
//显示和隐藏相关按钮
if mainForm.tasklistview.ItemIndex>=0 then
begin
i:=mainForm.tasklistview.ItemIndex;
mainForm.tasklistview.ItemIndex:=-1;
mainForm.tasklistview.ItemIndex:=i;
end;
end;
//检查该任务当前状态
if task_index>=1 then
if mainForm.taskListView.Items.Item[task_index-1].SubItems.Strings[0]='等待' then
//重新初始化
clear_task_info;
//停止超时计时器
self.stop_timeoutTimer;
end
// 当前指令是 'AT+CMGL=0'+#13
else if current_command='AT+CMGL=0'+#13 then
begin
logForm.logMemo.Lines.Add(self.current_answer);
//显示未读短信
self.translate_rec(self.current_answer,False);
//添加用户名
self.add_user_name;
//清空当前指令和返回的结果
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(self.current_answer);
//显示已读短信
self.translate_rec(self.current_answer,True);
//清空当前指令和返回的结果
clear_command_answer;
//取未读短信
get_rec_unread;
logForm.logMemo.Lines.Add('取未读短信');
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);
//删除列表中的短信
for i:=0 to inboxForm.inboxListView.Items.Count-1 do
if inboxForm.inboxListView.Items.Item[i].Caption=IntToStr(delete_rec_index) then
begin
//删除列表中的短信
inboxForm.inboxListView.Items.Item[i].Delete;
//重新初始化
delete_rec_index:=0;
break;
end;
//清空当前指令和返回的结果
clear_command_answer;
//显示相关按钮
inboxForm.refleshSpeedButton.Enabled:=True;
inboxForm.deleteSpeedButton.Enabled:=True;
//显示选中的短信内容
i:=inboxForm.inboxListView.ItemIndex;
inboxForm.inboxListView.ItemIndex:=-1;
inboxForm.inboxListView.ItemIndex:=i;
end;
end
//收到 ERROR
else if (current_answer[current_answer_length-8]=#13) and
(current_answer[current_answer_length-7]=#10) and
(current_answer[current_answer_length-6]='E') and
(current_answer[current_answer_length-5]='R') and
(current_answer[current_answer_length-4]='R') and
(current_answer[current_answer_length-3]='O') and
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -