unit UnitThread;
interface
uses
Windows,Classes,Graphics,MSCommLib_TLB,DB, ADODB,NeoNumLED,dateutils,SysUtils,syncobjs,StdCtrls,dialogs,ExtCtrls,MMSystem;
//引入Mscomm控件的时候,Mscommlib_tlb不能少
//使用showmessage函数的时候,dialogs不能少
//使用数据库控件时,DB,ADODB不能少
//使用日期函数如DecodeDateTime时,dateutils不能少
//使用now函数时,sysutils不能少
//使用criticalsection时syncobjs不能少
//使用Tedit时,StdCtrls不能少
//使用Tshape时,ExtCtrls不能少
//使用Tshape的颜色值时,Graphics不能少
type
TScanThread = class(TThread)
{************派生线程扫描接收机*************}
private
Rnum:string;
shape:Tshape;
table:string;
NeonumledR,NeonumledD,NeonumledC:TNeonumled;
portnumR,portnumG:integer;
commR:TMSComm;
query:TADOQuery;
procedure ScanDataR ;//扫描接收机
procedure ScanDataD;//扫描数据库
procedure comparedata;//比较
protected
procedure Execute;
override;
public
constructor create(createsuspend:boolean;//create flag
AcommR:TMSComm;//接收机端口控件
Aquery:TAdoquery;//扫描数据库预设值
ANeonumledR:TNeonumled;//显示预设值
ANeonumledC:TNeonumled;//显示频率差
ANeonumledD:TNeonumled;//显示实际频率
Atable:string;//预设值所在数据库
AportnumR:integer;//接收机端口号
Ashape:Tshape;//报警信号标志
ARnum:string);//接收机号
overload;
end;
TScanthreadG=class(TThread)
{************派生线程扫描GPS*************}
private
NeonumledG:TNeonumled;
commG:TMSComm;
portnumG : integer;
procedure ScanDataG;
protected
procedure Execute;override;
public
constructor create(createsuspend:boolean;
AcommG:TMSComm;//GPS端口控件
ANeonumledG:TNeonumled;//显示GPS时间
AportnumG:integer);//GPS端口号
overload;
end;
TScanThreadE=class(TThread)
{************派生线程写错误日志*************}
private
queryerr:TADOQuery;
procedure writeerr;
protected
procedure Execute;
override;
public
constructor create(createsuspend:boolean;
Aqueryerr:TAdoquery);//向数据库写入错误日志
overload;
end;
//errnum=(y = 1,e = 2,s = 3,ss = 4,w = 5,l = 6,q = 7,b = 8);
implementation
uses unitmain;
var
//flag:array of boolean;
//criticalsection,criticalsection1:Tcriticalsection;
facttime,errfre,yushefre:string;
errnum:string;
weekflag:word;
i:integer;
n:integer;
constructor TScanThreadG.create(createsuspend:boolean;AcommG:TMSComm;ANeonumledG:TNeonumled;AportnumG:integer);
{********************扫描GPS端口的线程的构造函数*******************************}
begin
NeonumledG:=ANeonumledG;
portnumG:=AportnumG ;
commG:=AcommG;
create(createsuspend);
freeOnTerminate:=true;
Priority:=tptimecritical;
end;
constructor TScanThread.create(createsuspend:boolean;AcommR:TMSComm;Aquery:TAdoquery;
ANeonumledR:TNeonumled;ANeonumledC:TNeonumled;ANeonumledD:TNeonumled;Atable:string;AportnumR:integer;Ashape:Tshape;ARnum:string);
{********************扫描接受机端口的线程的构造函数*******************************}
begin
create(createsuspend);
Rnum:=ARnum;
shape:=Ashape;
commR:=AcommR;
query:=Aquery;
NeonumledR:=ANeonumledR;
NeonumledC:=ANeonumledC;
NeonumledD:=ANeonumledD;
table:=Atable;
portnumR:=AportnumR;
freeOnTerminate:=true;
end;
constructor TScanThreadE.create(createsuspend:boolean;Aqueryerr:TAdoquery);
{********************写错误日志的线程的构造函数*******************************}
begin
queryerr:=Aqueryerr;
create(createsuspend);
freeOnTerminate:=true;
Priority:=tpnormal;
end;
procedure TScanThreadG.Execute;
{********************扫描GPS端口的线程的执行函数*******************************}
begin
//criticalsection1.Enter;
while truedo
begin
try
synchronize(scandataG);
sleep(200);
except
showmessage('GPS err!');
eixt;
end;
end;
//criticalsection1.Leave;
end;
procedure TScanThread.Execute;
{********************扫描接受机端口的线程的执行函数*******************************}
begin
while truedo
begin
try
//criticalsection.Enter;
synchronize(scandataD);
synchronize(scandataR);
synchronize(comparedata);
sleep(500);
// criticalsection.Leave;
except
showmessage('接收机错误');
exit;
end;
//try
end;
end;
procedure TScanThreadE.Execute;
{********************写错误日志的线程的执行函数*******************************}
begin
while truedo
begin
try
synchronize(writeerr);
sleep(500);
except
showmessage('写入日志错误');
exit;
end;
//try
end;
//while
end;
procedure TScanThreadE.writeerr;
{********************写错误日志*******************************}
begin
if (i>5) then
//如果频率差大于5,写日志
begin
queryerr.SQL.Clear;
queryerr.SQL.Text:='insert into errlogo values
errtime,:reiceivenum,:yushefre,:errfre,:memo)';
queryerr.Parameters.ParamByName('reiceivenum').Value:=errnum;
queryerr.Parameters.ParamByName('errtime').Value:=strtodatetime(facttime);
queryerr.Parameters.ParamByName('yushefre').Value:=yushefre;
queryerr.Parameters.ParamByName('errfre').Value:=errfre;
if strtoint(errfre)=0 then
begin
queryerr.Parameters.ParamByName('memo').Value:='接收机无接收数据';
end
else
begin
queryerr.Parameters.ParamByName('memo').Value:='频率值不正确';
end;
queryerr.ExecSQL;
queryerr.Close;
end;
//if first
end;
procedure TScanThread.ScanDataR;
////////////////////////////////////////扫描接收机端口频率值///////////////////////////////
var
Rdata
levariant;
Rstr:string;
begin
{扫描接收机}
commR.CommPort:=portnumR;
commR.InBufferSize:=1024;
commR.OutBufferSize:=512;
commR.InBufferCount:=0;
commR.OutBufferCount:=0;
commR.Settings:='9600,n,8,1';
commR.RThreshold:=128;
commR.InputLen:=0;
if commR.CommEvent=comEvReceive then
begin
try
Rdata:=commR.Input;
Rstr:=Rdata;
//接受接收机端口数据,这里还要添加相应的处理数据的程序
NeonumledR.Text:=Rstr;
errfre:=Rstr;
if Rdata='' then
begin
showmessage('端口无数据');
abort;
end;
except
showmessage('数据接受失败!');
abort;
end;
//try
end
else
begin
NeonumledR.Text:='0';
errfre:='0';
end;
end;
procedure TScanThreadG.ScanDataG ;
//////////////////////////////////扫描GPS端口时间值///////////////////////////////////
var
Gdata
levariant;
Gstr:string;
y,m,d,h,min,sec,milisec,weekofyear,dayofweek:WORD;
years,mons,days,hours,minutes,seconds,miliseconds,weeks:string;
begin
{扫描GPS}
commG.CommPort:=portnumG;
commG.InBufferSize:=1024;
commG.OutBufferSize:=512;
commG.InBufferCount:=0;
commG.OutBufferCount:=0;
commG.Settings:='9600,n,8,1';
commG.RThreshold:=128;
commG.InputLen:=0;
if commG.InBufferCount<>0 then
begin
{取GPS时间}
if commG.CommEvent=comEvReceive then
begin
try
Gdata:=commG.Input;
Gstr:=Gdata;
if Gdata='' then
begin
showmessage('GPS端口无数据!');
end;
except
showmessage('GPS数据接收失败!');
abort;
end;
//try
end;
NeonumledG.Text:=Gstr;
facttime:=Gstr;
end
else
begin
try
{取系统时间}
Decodedatetime(now,y,m,d,h,min,sec,milisec);
Decodedateweek(now,y,weekofyear,dayofweek);
weekflag:=dayofweek+3;
case dayofweek of
1:
weeks:='星期一';
2:
weeks:='星期二';
3:
weeks:='星期三';
4:
weeks:='星期四';
5:
weeks:='星期五';
6:
weeks:='星期六';
7:
weeks:='星期天';
end;
years:=inttostr
;
mons:=inttostr(m);
days:=inttostr(d);
hours:=inttostr(h);
minutes:=inttostr(min);
seconds:=inttostr(sec);
miliseconds:=inttostr(milisec);
NeonumledG.Text:=years+'-'+mons+'-'+days+' '+hours+':'+minutes+':'+seconds ;
facttime:=years+'-'+mons+'-'+days+' '+hours+':'+minutes+':'+seconds ;
except
showmessage(' 系统时间获取失败');
exit;
end;
//try
end;
end;
//over
procedure TScanThread.ScanDataD;
////////////////////////////////////////////扫描数据库预设值//////////////////////////////////////////
begin
{扫描数据库}
query.SQL.Clear;
query.SQL.text:='select * from '+ table+' where
settime between 开始时间 and 结束时间) and(发射机号='+''''+Rnum+''''+')';
if facttime<>'' then
begin
{拿当前时间和数据库中预设时间段进行比较}
query.Parameters.ParamByName('settime').Value:=strtodatetime(facttime);
end
else
begin
showmessage('无时间值');
abort;
//terminate,exit,abort中,经过试验得出的结论是,abort能
//退出到程序(暂时不执行线程)外,效果最强
end;
query.open;
if query.Fields.Fields[weekflag].Value=true then
begin
if query.Fields.Fields[1].asstring<>'' then
//数据库里的预设频率值是否为零
begin
NeonumledD.Text:=query.Fields.Fields[1].asstring;
yushefre:=query.Fields.Fields[1].asstring;
end
else
begin
NeonumledD.Text:='0';
end;
end
else
if query.Fields.Fields[weekflag].Value=false then
{判断星期的标志}
begin
if query.Fields.Fields[1].asstring<>'' then
begin
NeonumledD.Text:='0';
NeonumledR.Text:='0';
NeonumledC.Text:='0';
end;
end
else
//如果星期为nil值,即没有符合扫描条件数据值时
begin
NeonumledD.Text:='0';
end;
//以上的逻辑是:如果星期标志设置,那么看扫到纪录的预设频率值相,若频率值非空,此值为预设频率值
end;
//end procedure
procedure TScanThread.comparedata;
//////////////////////////////////////比较预设值与实际值,并进行相应处理///////////////////////////////
var
soundstr:string;
soundnum:string;
begin
i:=strtoint(NeonumledD.Text)-strtoint(NeonumledR.Text);
//数据库预设置-实际频率值
NeonumledC.Text:=inttostr(i);
if i>5 then
//如果频率差大于5 ,进行相应的处理
begin
shape.Brush.Color:=clRed;
errnum:=rnum;//保存错误接收机号 ,rnum是从构造函数赋值的
if errnum='一号机' then
begin
soundnum:='1.wav';
end
else
if errnum='二号机' then
begin
soundnum:='2.wav';
end
else
if errnum='三号机' then
begin
soundnum:='3.wav';
end
else
if errnum='四号机' then
begin
soundnum:='4.wav';
end
else
if errnum= '五号机' then
begin
soundnum:='5.wav';
end
else
if errnum='六号机' then
begin
soundnum:='6.wav';
end
else
if errnum='七号机' then
begin
soundnum:='7.wav';
end
else
if errnum='八号机' then
begin
soundnum:='8.wav';
end
else
begin
showmessage('找不到声音文件');
exit;
end;
{if errnum='一号机' then
begin
flag[0]:=true;
end
else
if errnum='二号机' then
begin
flag[1]:=true;
end
else
if errnum='三号机' then
begin
flag[2]:=true;
end
else
if errnum='四号机' then
begin
flag[3]:=true;
end
else
if errnum='五号机' then
begin
flag[4]:=true;
end
else
if errnum='六号机' then
begin
flag[5]:=true;
end
else
if errnum='七号机' then
begin
flag[6]:=true;
end
else
if errnum='八号机' then
begin
flag[7]:=true;
end
else
begin
for n:=0 to 7do
begin
flag[n]:=false;
end;
//for
end;
}
try
if query.Fields.Fields[11].asstring<>''then
begin
if fileexists(query.Fields.Fields[11].asstring) then
begin
soundstr:=query.Fields.Fields[11].asstring;
end
else
begin
soundstr:=extractfilepath(paramstr(0))+'/res/'+ soundnum;
end;
mciexecute(pchar('play '+soundstr));
{播放报警声音}
//注意这里不能使用playsound或者snplaysound,不然这里的播放效率会非常低
//而且有可能 造成死机
// PlaySound(Pansichar('1wave'),hinstance ,SND_RESOURCE or SND_NODEFAULT);
//记住上面使用wave类型资源文件的方法
// abort;
end
else
begin
exit;
end;
except
abort;
end;
//end try
end //end if i>5
else
begin
shape.Brush.Color:=clLime;
end;
end;
//over
initialization
//criticalsection:=Tcriticalsection.Create;
end.