真诚要请你来指正我程序不足之处,提出有效建议者,20分赠送 找会计电算化软件下载
库存管理软件版1楼: 软件编写的背景是,电台的频率接受机需要实现在某个时间段接受一个频率定值,这个定值的误差在+5(可调),如果超过该范围,就会导致电台停播,这对于电台来讲是重大事故,所以必须对频率值进行监控,并对出错情况进行相应的处理。
我编写的这个软件针对需求主要分三个模块:
(1)从gps获得相关数据,如精确到秒的时间值
(2)提供界面让工作人员可以随时将预定时间段的预设值写入数据库;监控接受机端口接收到的频率值,并扫描数据库,然后将频率值与从数据库中读取的预设值进行比对,如果超过误差范围,进行报警。
(3)向数据库中写入相关错误信息供工作人员查看。
软件整体使用了多线程,从Tthread派生了三个类,比对报警线程类,读GPS线程类,写错误日志线程类,
相关代码都在前面的程序单元里,里面也有相关构造函数参数的相关注释
对您的审阅表示感谢,如能得到你的指点,将不胜荣幸!
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;
//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 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;
procedure TScanThread.Execute;
{********************扫描接受机端口的线程的执行函数****************************}
begin
while true do
begin
try
//criticalsection.Enter;
synchronize(scandataD);
synchronize(scandataR);
synchronize(comparedata);
sleep(500);
// criticalsection.Leave;
except
showmessage(''接收机错误'');
exit;
end;//try
end;//while
end;//procedure
procedure TScanThread.ScanDataR;
{********************扫描接收机端口频率值**************************************}
var
Rdata:olevariant;
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;//if
end;//procedure
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
begin
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 7 do
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 orSND_NODEFAULT);
//记住上面使用wave类型资源文件的方法
//abort;
end
else
begin
exit;
end;
except
abort;
end; //end try
end
else
begin
shape.Brush.Color:=clLime;
end;//end if i>5
end;//procedure
initialization
//criticalsection:=Tcriticalsection.Create;
end.
unit UnitthreadE;
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
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,unitthreadR,unitthreadG;
var
//flag:array of boolean;
//criticalsection,criticalsection1:Tcriticalsection;
facttime,errfre,yushefre:string;
errnum:string;
weekflag:word;
i:integer;
n:integer;
constructor TScanThreadE.create(createsuspend:boolean; Aqueryerr:TAdoquery);
{********************写错误日志的线程的构造函数********************************}
begin
queryerr:=Aqueryerr;
create(createsuspend);
freeOnTerminate:=true;
Priority:=tpnormal;
end;
procedure TScanThreadE.Execute;
{********************写错误日志的线程的执行函数********************************}
begin
while true do
begin
try
synchronize(writeerr);
sleep(500);
except
showmessage(''写入日志错误'');
exit;
end;//try
end;//while
end;//procedure
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
initialization
//criticalsection:=Tcriticalsection.Create;
end.
unit UnitthreadG;
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
TScanthreadG=class(TThread)
{************派生线程扫描GPS*************}
private
NeonumledG:TNeonumled;
commG:TMSComm;
portnumG : integer;
procedure ScanDataG;
protected
procedure Execute;override;
public
//扫描GPS线程的构造函数
constructor create( createsuspend:boolean;
AcommG:TMSComm; //GPS端口控件
ANeonumledG:TNeonumled; //显示GPS时间
AportnumG:integer //GPS端口号
);
overload;
end;
//errnum=(y = 1,e = 2,s = 3,ss = 4,w = 5,l = 6,q = 7,b = 8);
implementation
uses
unitmain,unitthreadR,unitthreadE;
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;
procedure TScanThreadG.Execute;
{********************扫描GPS端口的线程的执行函数*******************************}
begin
//criticalsection1.Enter;
while true do
begin
try
synchronize(scandataG);
sleep(200);
except
showmessage(''GPS err!'');
eixt;
end; //try
end; //while
//criticalsection1.Leave;
end;//procedure
procedure TScanThreadG.ScanDataG ;
{********************扫描GPS端口时间值*****************************************}
var
Gdata:olevariant;
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(y);
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;//if
end;//procedure
initialization
//criticalsection:=Tcriticalsection.Create;
end.
由于我水平有限,所以一直不能有所改进,
Rainstorey给我提供很好的改进建议,尤其是使用接口技术,非常的感谢,
衷心希望各位高手继续给小弟拍砖,不胜感激,小分一点聊表谢意!!
我编写的这个软件针对需求主要分三个模块:
(1)从gps获得相关数据,如精确到秒的时间值
(2)提供界面让工作人员可以随时将预定时间段的预设值写入数据库;监控接受机端口接收到的频率值,并扫描数据库,然后将频率值与从数据库中读取的预设值进行比对,如果超过误差范围,进行报警。
(3)向数据库中写入相关错误信息供工作人员查看。
软件整体使用了多线程,从Tthread派生了三个类,比对报警线程类,读GPS线程类,写错误日志线程类,
相关代码都在前面的程序单元里,里面也有相关构造函数参数的相关注释
对您的审阅表示感谢,如能得到你的指点,将不胜荣幸!
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;
//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 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;
procedure TScanThread.Execute;
{********************扫描接受机端口的线程的执行函数****************************}
begin
while true do
begin
try
//criticalsection.Enter;
synchronize(scandataD);
synchronize(scandataR);
synchronize(comparedata);
sleep(500);
// criticalsection.Leave;
except
showmessage(''接收机错误'');
exit;
end;//try
end;//while
end;//procedure
procedure TScanThread.ScanDataR;
{********************扫描接收机端口频率值**************************************}
var
Rdata:olevariant;
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;//if
end;//procedure
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
begin
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 7 do
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 orSND_NODEFAULT);
//记住上面使用wave类型资源文件的方法
//abort;
end
else
begin
exit;
end;
except
abort;
end; //end try
end
else
begin
shape.Brush.Color:=clLime;
end;//end if i>5
end;//procedure
initialization
//criticalsection:=Tcriticalsection.Create;
end.
unit UnitthreadE;
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
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,unitthreadR,unitthreadG;
var
//flag:array of boolean;
//criticalsection,criticalsection1:Tcriticalsection;
facttime,errfre,yushefre:string;
errnum:string;
weekflag:word;
i:integer;
n:integer;
constructor TScanThreadE.create(createsuspend:boolean; Aqueryerr:TAdoquery);
{********************写错误日志的线程的构造函数********************************}
begin
queryerr:=Aqueryerr;
create(createsuspend);
freeOnTerminate:=true;
Priority:=tpnormal;
end;
procedure TScanThreadE.Execute;
{********************写错误日志的线程的执行函数********************************}
begin
while true do
begin
try
synchronize(writeerr);
sleep(500);
except
showmessage(''写入日志错误'');
exit;
end;//try
end;//while
end;//procedure
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
initialization
//criticalsection:=Tcriticalsection.Create;
end.
unit UnitthreadG;
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
TScanthreadG=class(TThread)
{************派生线程扫描GPS*************}
private
NeonumledG:TNeonumled;
commG:TMSComm;
portnumG : integer;
procedure ScanDataG;
protected
procedure Execute;override;
public
//扫描GPS线程的构造函数
constructor create( createsuspend:boolean;
AcommG:TMSComm; //GPS端口控件
ANeonumledG:TNeonumled; //显示GPS时间
AportnumG:integer //GPS端口号
);
overload;
end;
//errnum=(y = 1,e = 2,s = 3,ss = 4,w = 5,l = 6,q = 7,b = 8);
implementation
uses
unitmain,unitthreadR,unitthreadE;
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;
procedure TScanThreadG.Execute;
{********************扫描GPS端口的线程的执行函数*******************************}
begin
//criticalsection1.Enter;
while true do
begin
try
synchronize(scandataG);
sleep(200);
except
showmessage(''GPS err!'');
eixt;
end; //try
end; //while
//criticalsection1.Leave;
end;//procedure
procedure TScanThreadG.ScanDataG ;
{********************扫描GPS端口时间值*****************************************}
var
Gdata:olevariant;
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(y);
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;//if
end;//procedure
initialization
//criticalsection:=Tcriticalsection.Create;
end.
2楼: 大家可以随便拍砖,无论怎样批评,我都将不胜荣幸,如果能够提出能够使本程序得到重大改进建议者,我将倾我所有酬谢!! 如会计电算化软件下载
3楼: 审阅完毕,不知所云。
4楼: 首先希望得到大家关于程序本身结构问题的意见,
以上是我程序里线程的三个单元
我一直觉得线程构造函数参数太多了,不知道有没有大侠能帮忙解决一下
5楼: 代码无法测试,所以就正确性来说不得而知。仅从编程风格来说比较中庸,基本是顺着思路一路写下来,建议重构。对于线程构造函数参数太多的问题的确是这样,建议仿照VCL写个CustomXXX Class在从这个Class inherited暴露一些必要的接口,其实三个Thread有一些共同的方法和属性,不过是功能不同罢了。建议写Interface在进一步用Thread来实现,这样有比较统一完善的调度过程。呵呵,代码没细看,不足之处请批评指正
6楼: 非常感谢Rainstorey,kinneng给的点评,
由于我水平有限,所以一直不能有所改进,
Rainstorey给我提供很好的改进建议,尤其是使用接口技术,非常的感谢,
衷心希望各位高手继续给小弟拍砖,不胜感激,小分一点聊表谢意!!
库存管理软件版7楼: 多人接受答案了。