Canvas do es not allow Drawing!!真是不明白?!! (50分)

  • 主题发起人 主题发起人 wldandan
  • 开始时间 开始时间
程序一直在查询吗?是否消耗的CPU资源太多了
改为中断或多线程吧
 
是用线程作的阿!!
我是创建了线程的,只不过没写出来,这些查询都是在线程中作得
 
在线程中操作VCL要用Synchronize(),否则是会有这样的错的。
 
是这样的,我是在线程中定义了些函数,很多都是很数据库有关的
然后我执行,没错,连上串口通讯后,就出错了
出的错误都是在执行sql语句时候出错,但是单步执行,没错
请问怎么用Synchronize()这个函数,有很多各种情况的查询阿!!
 
Synchronize很简单,我举个例子:

TConvertThread=class(TThread)
private
Index: integer;
protected
procedure Execute; override;
Procedure Convert;
Procedure ShowFinish;
end;

var
MainForm: TMainForm;
FinishEvent: Thandle;
TemList, FileNameList: TStringList;
CurFileName: string;

implementation
uses MSHTML;
{$R *.DFM}

procedure TConvertThread.Convert;
begin
with MainForm do
begin
CurFileName := FileNameList.Strings[index];
WebBrowser1.Navigate(CurFileName);
end;
end;

procedure TConvertThread.ShowFinish;
begin
ShowMessage('Convert has finished.');
end;

procedure TConvertThread.Execute;
var
i: integer;
begin
for i:=1 to FileNameList.Count do
begin
Index := i-1;
ReSetEvent(FinishEvent);
Synchronize(Convert);
WaitForSingleObject(FinishEvent,5000{INFINITE});
end;
Synchronize(ShowFinish);
end;
 
TO:zw84611
好像不行的阿,用了这个函数后,程序执行后就不动了,
因为中间存在很多函数之间的调用,还是不太明白。
程序的执行过程是这样的
判断当前时间-〉1。0点对时;
2。分发任务;
3。和单片机通讯,取回当前的状态,
然后再用Timage的图来表示当前的状态,你帮我看看该怎么弄吧!!
 
把你的代码帖出来吧

我要回去了,明天见。
 
朋友:
如果不介意,请把整个工程发过来,说不定能够帮你。
请参阅我网站 http://www.to-happy.com 上的《大事》软件,说不定能受些启发。
 
希望大侠们能帮帮小弟。。。耐心帮我看完
现在一执行,就停在了doWhenCommSucc的
if currMachine.currStatus = status_OFFLINE then doWhenOffline(currMachine,currRBuf)
这句话这地方,然后下一步就去执行doWhenOffline的第一个WhenDBError,就这样
unit MainForm;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs,GlobalVar, SPComm, DB, DBTables, ExtCtrls, StdCtrls,DateUtils,Math,
Menus;
type
TFormMain = class(TForm)
CommTimer: TTimer;
Comm: TComm;
mainQuery: TQuery;
MainMenu1: TMainMenu;
N1: TMenuItem;
N2: TMenuItem;
N3: TMenuItem;
N4: TMenuItem;
redrawTimer: TTimer;
N5: TMenuItem;
jhrw_plan: TMenuItem;
jhrw_query: TMenuItem;
N8: TMenuItem;
N9: TMenuItem;
N10: TMenuItem;
N11: TMenuItem;
bb_onwork: TMenuItem;
bb_history: TMenuItem;
bb_month: TMenuItem;
bb_worker: TMenuItem;
xx_product: TMenuItem;
xx_workorder: TMenuItem;
xx_machine: TMenuItem;
xx_worker: TMenuItem;
N6: TMenuItem;
N7: TMenuItem;
N12: TMenuItem;
Database1: TDatabase;
Memo1: TMemo;

procedure CommTimerTimer(Sender: TObject);
procedure CommReceiveData(Sender: TObject; Buffer: Pointer;
BufferLength: Word);
procedure Button1Click(Sender: TObject);
procedure ImageDblClick(Sender: TObject);
procedure redrawTimerTimer(Sender: TObject);
procedure N2Click(Sender: TObject);
procedure N3Click(Sender: TObject);
procedure N4Click(Sender: TObject);
procedure jhrw_planClick(Sender: TObject);
procedure jhrw_queryClick(Sender: TObject);
procedure bb_onworkClick(Sender: TObject);
procedure bb_historyClick(Sender: TObject);
procedure bb_monthClick(Sender: TObject);
procedure bb_workerClick(Sender: TObject);
procedure xx_productClick(Sender: TObject);
procedure xx_workorderClick(Sender: TObject);
procedure xx_machineClick(Sender: TObject);
procedure xx_workerClick(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure N6Click(Sender: TObject);
procedure N7Click(Sender: TObject);
procedure N12Click(Sender: TObject);
private
{ Private declarations }
procedure init();
function readVarDB():boolean;
public
{ Public declarations }
end;
type
TCommClass = class(TThread)
commonQuery : TQuery;
procedure init();
procedure mainRoutine();
function timeToDo(currentDate : TDateTime) : integer;
procedure adjustTime();
procedure schedule();
procedure doRoutine();
function doCommunication(sendBuf : frameBuf) : frameBuf;
function makeSbuf(currMachine : machine; frameType : integer) : frameBuf;
procedure doWhenCommSucc(var currMachine : machine ; currRBuf : frameBuf);
procedure doWhenCommFail(var currMachine : machine);
function sendData(sbuf : frameBuf) : boolean;
function makeScheduleBuf(addr : byte;orderID : byte; bufType : integer;varible :string) : frameBuf;
function parseStrToInt(str : string) : integer;
procedure doWhenOffline(var currMachine : machine ; currRBuf : frameBuf);
procedure doWhenNormal(var currMachine : machine ; currRBuf : frameBuf);
function makeHistFrame(currMachine : machine;daysToNow : byte;workOrderID:byte): frameBuf;
procedure DoCommon(var currMachine: machine);
procedure ChangeCurrOrder();
protected
procedure Execute; override;
end;


var
FormMain: TFormMain;
statusBMPArray : array[0..3] of TPicture;
machineBMPArray : array of Timage;
CommThread : TCommClass;

implementation

uses ju_plan, jh_query, bb_onwork, bb_history, bb_month, bb_worker,
xx_product, xx_workorder, xx_machine, xx_worker, xt_modifypass, xt_backup,
about;

{$R *.dfm}

///////////////////////////////////////////////////////////////
// TFormMain.init //
// 这个过程初始化串行口和一些别的东西,现在还没有完善 //
///////////////////////////////////////////////////////////////

procedure TFormMain.init();
begin
//调用readVarDB来初始化所有参数,如果不成功退出。
if not(readVarDB()) then
begin
showMessage('初始化数据失败,请检查数据库。');
exit;
end;

//初始化串口
comm.CommName := commVars.commName;
comm.BaudRate := commVars.baudRate;
comm.IgnoreNullChar := false;
//打开串口
try
comm.StartComm;
except
on ECommsError do begin
showMessage('打开串口时出现错误');
exit;
end;
end;
//初始化定时器
commTimer.Interval := time_TIMEOUT;
commTimer.enabled := false;

//如果在这个form里面还应该加上初始化检测界面。
end;

///////////////////////////////////////////////////////////////
// TFormComm.readVarDB:boolean //
// 这个函数主要完成从数据表中读取一些系统参数,同时完成内存 //
// 中表示机器状态的数组的初始化。应该还有一些别的东西, //
// 等待加入。 //
///////////////////////////////////////////////////////////////

function TFormMain.readVarDB():boolean;
var
tempString,tempResult : string;
tempDate : TDateTime;
i,j,incTop : integer;
begin
//读取数据表中预设的一些参数值
mainQuery.SQL.Clear;
mainQuery.SQL.Add('select * from 系统参数');
try
mainQuery.open;
except
WhenDBError;
end;

if mainQuery.Eof then
begin
readVarDB:=false;
exit;
end;

while not(mainQuery.eof) do
begin
tempString:=mainQuery.fieldByName('参数名称').asString;
if tempString='机器数量' then systemEnv.machineCount:=mainQuery.fieldByName('参数值').asInteger;
if tempString='轮询间隔' then systemEnv.checkInterval:=mainQuery.fieldByName('参数值').asInteger;
if tempString='串口名称' then commVars.commName:=mainQuery.fieldByName('参数值').AsString;
if tempString='波特率' then commVars.baudRate:=mainQuery.fieldByName('参数值').asInteger;
if tempString='班次转换时间' then systemEnv.changeOrderTime := mainQuery.fieldByName('参数值').AsInteger;
mainQuery.Next;
end;
mainQuery.Close;

for i := 0 to 3 do statusBMPArray := TPicture.Create;
statusBMPArray[status_RUN].LoadFromFile('c:/program Files/pcb/bmp/auto.bmp');
statusBMPArray[status_MANUAL].LoadFromFile('c:/program Files/pcb/bmp/hand.bmp');
statusBMPArray[status_OFFLINE].LoadFromFile('c:/program Files/pcb/bmp/offline.bmp');
statusBMPArray[status_STOP].LoadFromFile('c:/program Files/pcb/bmp/stop.bmp');

//取班次信息,判断当前时间的班次。

mainQuery.SQL.Clear;
mainQuery.SQL.Add('select * from 班次');
try
mainQuery.Open;
except
WhenDBError;
end;

i := 0;
tempDate := Time ;
while not(mainQuery.Eof) do
begin
setlength(workOrders , i+1);
workOrders.workOrderName := mainQuery.FieldByName('班次名称').AsString;
workOrders.workOrderID := mainQuery.FieldByName('班次编号').AsInteger;
workOrders.startTime := mainQuery.FieldByName('开始时间').AsDateTime;
workOrders.lastTime := mainQuery.fieldByName('持续时间').asInteger;
if ((workOrders.startTime+workOrders.lastTime/24)<1) then
if (tempDate >= workOrders.startTime) and (tempDate < workOrders.startTime + workOrders.lastTime / 24) then
begin
currentWorkOrder := workOrders;
currentWorkDay := date;

end
else
begin
if (tempDate >= workOrders.startTime) and (tempDate < 1) then
begin
currentWorkOrder := workOrders;
currentWorkDay := date;
end
else
if (tempDate < (workOrders.startTime + workOrders.lastTime / 24 - 1)) then
begin
currentWorkOrder := workOrders;
currentWorkDay := date - 1;

end;
end;
i := i + 1;
mainQuery.Next;
end;
mainQuery.Close;
workOrderCount := i;

if workOrderCount = 0 then
begin
showMessage('错误:没有班次信息,请配置后重新启动通讯');
readVarDB:=false;
exit;
end;

//读取所有机器信息
//为了矫正机器数量
mainQuery.SQL.Clear;
mainQuery.SQL.Add('select count(*) as sum from 机床');
try
mainQuery.open;
except
WhenDBError;
end;
if systemEnv.machineCount<>mainQuery.fieldByName('sum').asinteger then
systemEnv.machineCount:=mainQuery.fieldByName('sum').asinteger;
mainQuery.Close;

if systemEnv.machineCount=0 then
begin
showMessage('错误:没有机器信息,请配置后重新启动通讯');
readVarDB:=false;
exit;
end;

setLength(machines,systemEnv.machineCount); //重置机器数组长度
setLength(machineBMPArray,systemEnv.machineCount);
//showmessage('机器数量:'+inttostr(systemEnv.machineCount));
incTop := FirstBMPTOP;
for i := 0 to systemEnv.machineCount - 1 do
begin
machineBMPArray := TImage.Create(self);
machineBMPArray.Parent := self;
machineBMPARRAY.OnDblClick:=FormMain.ImageDblClick;
with machineBMPArray do
begin
left := FirstBMPLEFT;
width := 80;
height := 100;
Stretch := false;
end;
if (i mod 5) = 0 then
begin
machineBMPArray.Left := FirstBMPLEFT;
machineBMPArray.top := incTop+20;
inc(IncTop,120);
end
else begin
machineBMPArray.Left := machineBMPArray[i-1].left+machineBMPArray[i-1].Width+20;
machineBMPArray.top := machineBMPArray[i-1].top;
end;
machineBMPArray.Picture := statusBMPArray[0];
end;
//初始化机器状态数组
mainQuery.SQL.Clear;
mainQuery.SQL.Add('select * from 机床');
try
mainQuery.Open;
except
WhenDBError;
end;

for i:= 0 to systemEnv.machineCount-1 do
begin
with machines do
begin
machineID := mainQuery.fieldByName('机床编号').asString;
addr := mainQuery.fieldByName('下位机地址').asInteger;
checkIndex := '';
operatorID := '';
workDay := currentWorkDay;
workOrderID := 0;
scheduled := 0;
completed := 0;
incToLast := 0;
currStatus := status_OFFLINE;
recordTime := now ;
machineBMPARRAY.hint:=machines.machineID;
machineBMPARRAY.ShowHint:=true;
end;
mainQuery.Next;
end;
mainQuery.Close;


//读取计划任务,如果没有则报告,建议重新设置计划任务
mainQuery.SQL.Clear;
mainQuery.SQL.Add('select count(*) as sum from 计划任务');
mainQuery.SQL.Add(' where 日期=:currDate and 班次编号=:currWorkOrderID');
mainQuery.ParamByName('currDate').AsDateTime := currentWorkDay;
mainQuery.ParamByName('currWorkOrderID').AsInteger := currentWorkOrder.workOrderID;
try
mainQuery.Open;
except
WhenDBError;
end;

j := mainQuery.fieldByName('sum').AsInteger;
//showmessage('计划任务:'+Datetostr(currentWorkDay));
//showmessage('计划任务:'+inttostr(currentWorkOrder.workOrderID));
//showmessage('计划任务:'+inttostr(j));
if j < systemEnv.machineCount then
begin
if MessageBox(0,'一个或多个机器没有设定计划任务,是否继续?','计划任务',MB_YESNO+MB_DEFBUTTON2)=IDNO then
readVarDB := false;
exit; //这里要进行判断。等到判断结束后再说。还没有完成代码。
end;
mainQuery.SQL.Clear;
mainQuery.SQL.Add('select * from 计划任务');
mainQuery.SQL.Add(' where 日期=:currDate and 班次编号=:currWorkOrderID');
mainQuery.ParamByName('currDate').AsDateTime := currentWorkDay;
mainQuery.ParamByName('currWorkOrderID').Asinteger := currentWorkOrder.workOrderID;
try
mainQuery.Open;
except
WhenDBError;
end;

while not(mainQuery.Eof) do
begin
tempString := mainQuery.FieldByName('机床编号').AsString;
for j := 0 to systemEnv.machineCount-1 do
if machines[j].machineID = tempString then
with machines[j] do
begin
checkIndex := mainQuery.FieldByName('跟单号').AsString;
operatorID := mainQuery.FieldByName('操作员编号').asString;
workOrderID := mainQuery.FieldByName('班次编号').asInteger;
scheduled := mainQuery.FieldByName('计划产量').asInteger;

end;
mainQuery.Next;
end;
mainQuery.Close;

readVarDB := true;
end;

/////////////////////////////////////////////////////
// TFormMain.CommTimerTimer //
// timer的事件过程 //
/////////////////////////////////////////////////////
procedure TFormMain.CommTimerTimer(Sender: TObject);
begin
timeOut :=false;
commTimer.enabled := false;
end;

/////////////////////////////////////////////////////
// TFormMain.CommReceiveData //
// comm的收到数据事件处理过程 //
/////////////////////////////////////////////////////

procedure TFormMain.CommReceiveData(Sender: TObject; Buffer: Pointer;
BufferLength: Word);
var i:integer;viewstring:string;
begin
move(buffer^,receiveBuf,bufferlength);
dataReceived := true;
if Receivebuf[0]= $fc then
for i:=0 to bufferlength-1 do
begin
viewstring:=inttohex(receivebuf,2)+''+'';
//viewstring:=viewstring+inttostr(rbuf[7]);
//viewstring:='接受'+'buffer'+inttostr(i)+'is'+inttostr(receiveBuf);
memo1.lines.add(viewstring);
end;
end;

procedure TFormMain.Button1Click(Sender: TObject);
var
CommThread : TCommClass;
begin
init;
CommThread := TCommClass.Create(false);
end;


/////////////////////////////////////////////////////
// TCommClass.Execute //
// 主线称过程 //
/////////////////////////////////////////////////////

procedure TCommClass.Execute;
begin
init();
//Synchronize(mainRoutine);
//Application.ProcessMessages;
mainRoutine();
end;

///////////////////////////////////////////////////////////////
// TCommClass.init //
// 初始化数据 //
///////////////////////////////////////////////////////////////

procedure TCommClass.init();
begin
commonQuery:=TQuery.Create(nil);
commonQuery.DatabaseName := dataBaseName;
end;

///////////////////////////////////////////////////////////////
// TCommClass.mainroutine //
// 这个过程是整个工作的主过程,一直循环,处理通讯结果等 //
///////////////////////////////////////////////////////////////
procedure TCommClass.mainRoutine();
var
currTime : TDateTime;
tempMS : Integer;
begin
while true do
begin
currTime := now;
case timeToDo(currTime) of
0 : doRoutine();
1 : adjustTime();
2 : schedule();
3 : changeCurrOrder();
end;
tempMS := (MilliSecondsBetween(now,currTime) mod systemEnv.checkInterval);
tempMS := systemEnv.checkInterval - tempMS;
sleep(tempMS);
end;
end;

///////////////////////////////////////////////////////////////
// timetodo //
// 这个函数返回当前时间所要进行任务的代号 (0,1,2,3) //
///////////////////////////////////////////////////////////////

function TcommClass.timeToDo(currentDate : TDateTime) : integer;
var
i : integer;
begin

if MinuteOfTheDay(Now)= 0 then //对时在凌晨
begin
timeToDo := 1 ;
exit;
end;

for i := 0 To workOrderCount -1 do
begin
if (minuteOfTheDay(time) = minuteOfTheDay(workOrders.startTime - systemEnv.changeOrderTime/(24 * 60)) - 2) then //每次换班开始前二分钟计划任务
begin
timeToDo := 2;
exit;
end;
if (minuteOfTheDay(time) = minuteOfTheDay(workOrders.startTime )) then //转换当前班次和当前工作天
begin
timeToDo := 3;
exit;
end;
end;

timeToDo := 0;
end;

/////////////////////////////////////////////////////
// TCommClass.adjustTime //
// 对时过程 //
/////////////////////////////////////////////////////

procedure TCommClass.adjustTime();
var
tempRbufCC,tempRBufCD,tempRBufOrder : frameBuf;
i,j : integer;
begin

for j := 1 to 3 do
begin
tempRBufCD[0] := $FC;
tempRBufCD[1] := $FA;
tempRBufCD[2] := $CD;
tempRBufCD[3] := Byte(StrToInt('$'+IntToStr(yearOf(date) mod 100)));
tempRBufCD[4] := Byte(StrToInt('$'+IntToStr(monthOf(date))));
tempRBufCD[5] := Byte(StrToInt('$'+IntToStr(dayOf(date))));
tempRBufCD[6] := $FF;
tempRBufCD[7] := $ED;
if not sendData(tempRBufCD) then exit;
sleep(6000);
tempRBufCC[0] := $FC;
tempRBufCC[1] := $FA;
tempRBufCC[2] := $CC;
tempRBufCC[3] := Byte(StrToInt('$'+IntToStr(hourOfTheDay(time))));
tempRBufCC[4] := Byte(StrToInt('$'+IntToStr(minuteOfTheHour(time))));
tempRBufCC[5] := Byte(StrToInt('$'+IntToStr(secondOfTheMinute(time))));
tempRBufCC[6] := $FF;
tempRBufCC[7] := $ED;
if not sendData(tempRBufCC) then exit;
sleep(6000);
for i := 0 to workOrderCount - 1 do
begin
tempRBufOrder[0] := $FC;
tempRBufOrder[1] := $FA;
tempRBufOrder[2] := workOrders.workOrderID * 16 + workOrders.workOrderID;
//showmessage(inttostr( workOrders.workOrderID * 16 + workOrders.workOrderID));
tempRBufOrder[3] := hourOfTheDay(workOrders.startTime);
tempRBufOrder[4] := minuteOfTheHour(workOrders.startTime);
tempRBufOrder[5] := hourOfTheDay(workOrders.startTime + workOrders.lastTime/24);
tempRBufOrder[6] := minuteOfTheHour(workOrders.startTime + workOrders.lastTime/24);
tempRBufOrder[7] := $ED;
if not sendData(tempRBufOrder) then exit; //在这里几乎没有错误处理,因为发送很少出错。
end;
end;
end;

/////////////////////////////////////////////////////
// TCommClass.schedule //
// 计划任务分发过程 //
/////////////////////////////////////////////////////

procedure TcommClass.schedule();
var
tempCurrDate : TDateTime;
tempWorkOrder,addr : byte;
tempStr : string;
i : integer;
tempRBuf : frameBuf;
begin
if currentWorkOrder.workOrderID = workOrder_LAST then
begin
tempCurrDate := currentWorkDay +1 ;
tempWorkOrder := workOrder_FIRST ;
end
else begin
tempCurrDate := currentWorkDay;
tempWorkOrder := currentWorkOrder.workOrderID + 1;
end;
commonQuery.SQL.Clear;
commonQuery.SQL.Add('select 计划任务.*,机床.下位机地址 from 计划任务,机床');
commonQuery.SQL.Add(' where 计划任务.机床编号=机床.机床编号');
commonQuery.SQL.Add(' and 计划任务.日期=:currWorkDay and 计划任务.班次编号=:currWorkOrderID');
commonQuery.ParamByName('currWorkDay').asDatetime := tempCurrDate;
//commonQuery.ParamByName('currWorkOrderID').AsInteger := 10;
//commonQuery.ParamByName('currWorkDay').asString := dateToStr(tempCurrDate);
commonQuery.ParamByName('currWorkOrderID').AsInteger := tempWorkOrder;
try
commonquery.Open;
except
WhenDBError;
end;

while not commonQuery.eof do
begin
for i := 0 to 3 do
begin
addr := commonQuery.fieldByName('下位机地址').AsInteger;
case i of
0 : tempStr := commonQuery.fieldByName('产品编号').AsString;
1 : tempStr := commonQuery.fieldByName('工序编号').AsString;
2 : tempStr := commonQuery.fieldByName('操作员编号').AsString;
3 : tempStr := commonQuery.fieldByName('计划产量').AsString;
end;

tempRBuf := doCommunication(makeScheduleBuf(addr,tempWorkOrder,i,tempStr));
//if (tempRBuf[2] mod 16) = (i + 4) then 这里应该对结果进行判断地,但是判断没有。以后或许有用。
end;
commonQuery.Next;
end;
Commonquery.Close;
end;

/////////////////////////////////////////////////////
// TCommClass.makeScheduleBuf //
// 根据不同类型组装不同计划任务的帧。 //
/////////////////////////////////////////////////////

function TCommClass.makeScheduleBuf(addr : byte;orderID : byte; bufType : integer;varible :string) : frameBuf;
var
tempInt : integer;
begin
makeScheduleBuf[0] := $FC;
makeScheduleBuf[1] := byte(strtoint('$'+inttostr(addr)));
makeScheduleBuf[2] := orderID * 16 + bufType;
makeSchedulebuf[7] := $ED;
case bufType of
0..2 : begin
tempInt :=parseStrToInt(varible);
makeSchedulebuf[3] := tempInt div (256*256*256);
makeScheduleBuf[4] := (tempInt div (256*256)) mod 256;
makeScheduleBuf[5] := (tempInt div 256) mod 256;
makeScheduleBuf[6] := tempInt mod 256;
end;
3 : begin
tempInt := strToInt(varible);
makeSchedulebuf[3] := tempInt div (256*256*256);
makeScheduleBuf[4] := (tempInt div (256*256)) mod 256;
makeScheduleBuf[5] := $FF;
makeScheduleBuf[6] := $FF;
end;
end;
end;

/////////////////////////////////////////////////////
// TCommClass.parseStrToInt //
// 将编号转化成数据帧中存储结构 //
/////////////////////////////////////////////////////

function TcommClass.parseStrToInt(str : string) : integer;
var
tempInt1,tempInt2 : integer;
i,j : integer;
begin
tempInt1 := 0;
tempInt2 := 0;
j := 0;
for i := 1 to 4 do
begin
case str of
'A'..'Z' : tempInt1 := (tempInt1*32) + (ord(str)-ord('A'));
'-' :
begin
j := i;
TempInt1 := (TempInt1*32) + 27; //27为'-'
end
else
if str='' then
tempInt1 := tempInt1*32 + 26;//26为空格
end;
end;
for i := j+1 to strlen(pchar(str)) do
case str of
'0'..'9' : tempInt2 := tempInt2 * 10 + ord(str) - ord('0');
end;
parseStrToInt := tempInt1 * 256 * 256 + tempInt2;
end;

/////////////////////////////////////////////////////
// TCommClass.doRoutine //
// 正常情况下每采样间隔的数据采集与处理 //
/////////////////////////////////////////////////////

procedure TcommClass.doRoutine();
var
i : integer;
rbuf : frameBuf;
begin
for i := 0 to systemEnv.machineCount-1 do
begin
rbuf := doCommunication(makeSBuf(machines,0));
if rbuf[0] = frame_OK then doWhenCommSucc(machines,rbuf)
else doWhenCommFail(machines);
end;
end;

/////////////////////////////////////////////////////
// TCommClass.makeSBuf //
// 组装正常询问数据帧 //
/////////////////////////////////////////////////////

function TcommClass.makeSbuf(currMachine : machine ;frameType : integer) : frameBuf;
begin
makeSbuf[0] := $FC;
makeSbuf[1] := byte(strtoint('$'+inttostr(currMachine.addr)));
showmessage(IntToStr(currMachine.workOrderID));
makeSbuf[2] := currMachine.workOrderID * 16 + $0C;
makeSbuf[3] := $FF;
makeSbuf[4] := $FF;
makeSbuf[5] := $FF;
makeSbuf[6] := $FF;
makeSbuf[7] := $ED;
end;
/////////////////////////////////////////////////////
// TCommClass.doCommunication //
// 处理整个系统的通讯过程 //
/////////////////////////////////////////////////////

function TcommClass.doCommunication(sendBuf : frameBuf) : frameBuf;
var
sendCount : integer;
tempBuf : frameBuf;
begin
timeout := false;
sendCount := 1;
while sendCount <= resend_TIME do
begin
dataReceived := false;
if not sendData(sendBuf) then
begin
tempBuf[0] := $00; //可以讲$00改成不同的状态常量。
break;
end;
//FormMain.CommTimer.enabled := true;
sleep(time_TIMEOUT); //调试代码
//while not (timeout or dataReceived) do sleep(2);
if dataReceived then
begin
tempBuf := receiveBuf;
if (tempBuf[0] = $FC) and (tempBuf[7] = $ED) and (tempBuf[1]=sendBuf[1]) then
begin
doCommunication := tempBuf;
exit;
end;
//FormMain.CommTimer.enabled := false;
end;
sendCount := sendCount + 1;
end;
if sendCount > resend_TIME then tempBuf[0] := $00; //同样也可以设置成常量;
end;

/////////////////////////////////////////////////////
// TCommClass.SendData //
// 系统中的数据发送过程 //
/////////////////////////////////////////////////////

function TcommClass.sendData(sbuf : frameBuf) : boolean;
var
i : integer;
begin
sendData := true;
for i := 0 to 7 do
begin
if not FormMain.Comm.writecommdata(@sbuf,1) then
begin
sendData := false;
break;
end;
sleep(2); //据说是字节间延迟
end;
end;

/////////////////////////////////////////////////////
// TCommClass.doWhenCommSucc //
// 通常情况下,数据接收正常的处理 //
/////////////////////////////////////////////////////

procedure TcommClass.doWhenCommSucc(var currMachine: machine ; currRBuf : frameBuf);
begin

if currMachine.currStatus = status_OFFLINE then doWhenOffline(currMachine,currRBuf)
else doWhenNormal(currMachine,currRBuf);
doWhenNormal(currMachine,currRBuf);
end;

/////////////////////////////////////////////////////
// TCommClass.doWhenOffline //
// 数据接收正常时,前状态为吊线的处理 //
/////////////////////////////////////////////////////

procedure TCommClass.doWhenOffline(var currMachine : machine ; currRBuf : frameBuf);
var
tempByte : byte;
tempWorkDay : TDateTime;
tempDay : TDateTime;
tempWorkOrderID : byte;
i,j : integer;
tempRBuf : frameBuf;
begin
tempByte := currRBuf[2] div 16 ;
//判断是不是来的帧的工序ID还是上个班次的ID。
if (tempByte = workOrder_LAST) and (currentWorkOrder.workOrderID = workOrder_FIRST) then
tempWorkDay := currentWorkDay - 1
else tempworkDay := currentWorkDay;
//判断是不是来的帧已经是下一天的头班次了。
if (tempByte = workOrder_FIRST) and (currentWorkOrder.workOrderID = workOrder_LAST) then
tempWorkDay := currentWorkDay + 1
else tempworkDay := currentWorkDay;
//取当前tempWorkDay的tempByte的计划任务
CommonQuery.Close;
commonQuery.SQL.Clear;
commonQuery.SQL.Add('select * from 计划任务');
commonQuery.SQL.Add(' where 日期=:currDate and 班次编号=:currWorkOrderID');
commonQuery.SQL.Add(' and 机床编号=:currMachineID');
commonQuery.ParamByName('currDate').AsDateTime := date;
commonQuery.ParamByName('currWorkOrderID').Asinteger := 10;
commonQuery.paramByName('currMachineID').AsString := 's39';
//commonQuery.ParamByName('currDate').AsDateTime := tempWorkDay;
//commonQuery.ParamByName('currWorkOrderID').Asinteger := tempByte;
//commonQuery.paramByName('currMachineID').AsString := currMachine.machineID;
try
commonQuery.Open;
except
WhenDBError;
end;

with currMachine do
begin
if not commonQuery.Eof then
begin
checkIndex := commonQuery.FieldByName('跟单号').AsString;
operatorID := commonQuery.FieldByName('操作员编号').asString;
workOrderID := commonQuery.FieldByName('班次编号').asInteger;
scheduled := commonQuery.FieldByName('计划产量').asInteger;
end
else begin
checkIndex := '';
operatorID := '';
workOrderID := tempByte;
scheduled := 0;
end;

//这里作一个判断,当前workDay+该班次的开始时间和当前时间比较。如果大于workday-1。
workDay := tempWorkDay ;
end;
commonQuery.Close;

commonQuery.SQL.Clear;
commonQuery.SQL.Add('select * from 生产记录');
commonQuery.SQL.Add(' where 机床编号=:machineID ');
commonQuery.SQL.Add(' order by 当前时间 desc');
commonQuery.paramByName('machineID').AsString := currMachine.machineID;
try
commonQuery.Open;
except
WhenDBError;
end;

if not commonQuery.Eof then
begin
tempDay := commonQuery.fieldByName('日期').asDateTime;
tempWorkOrderID := commonQuery.fieldByName('班次编号').asInteger;
currMachine.completed := commonQuery.fieldByName('完成任务量').asInteger;
end
else begin
tempDay := currMachine.workDay;
tempWorkOrderID := tempByte;
currMachine.completed := 0;
end;
commonQuery.close;

//判断是不是一天,一个班次的任务,如果不是,全部的完成产量和inctoLast值0;
if (tempDay <> tempWorkDay) or (tempWorkOrderID <> tempByte) then
begin
currMachine.completed := currRBuf[3]*256+currRBuf[4];
currMachine.incToLast := currRBuf[3]*256+currRBuf[4];
end
else begin
currMachine.incToLast := currRBuf[3]*256+currRBuf[4] - currMachine.completed;
currMachine.completed := currRBuf[3]*256+currRBuf[4];
end;
if (currRBuf[6] mod 2)= 1 then
currMachine.currStatus := currRBuf[6] mod 16
else begin
currMachine.currStatus := status_STOP;
end;
currMachine.recordTime := now;
//整历史记录
for i := 1 to (floor(currMachine.workDay)-floor(tempDay)) do
begin
if i <= 12 then
for j := workOrder_FIRST to workOrder_LAST do
begin
tempRBuf := doCommunication(makeHistFrame(currMachine,i,j));
if tempRBuf[0] = frame_OK then
begin
//补足计划任务的完成情况
commonQuery.SQL.Clear;
commonQuery.SQL.Add('insert into 生产任务');
commonQuery.SQL.Add('(机床编号,日期,班次编号,完成产量)');
commonQuery.SQL.Add(' values (:machineID,:currDate,:currWorkOrderID,:completed)');
commonQuery.paramByName('machineID').asstring := currMachine.machineID;
commonQuery.paramByName('currDate').asstring := DateToStr(currMachine.WorkDay -i);
commonQuery.paramByName('currWorkOrderID').asInteger := tempRBuf[2] div 16;
commonQuery.paramByName('completed').asInteger := tempRBuf[4]*256+tempRBuf[5];
try
commonQuery.ExecSQL;
except
WhenDBError;
end;
commonQuery.close;
//给生产记录中加入相关条目
commonQuery.SQL.Clear;
commonQuery.SQL.Add('insert into 生产记录');
commonQuery.SQL.Add(' (机床编号,日期,班次编号,完成任务量,完成增量,当前时间,操作员编号)');
commonQuery.SQL.Add(' values (:machineID,:currDate,:workOrderID,:completed,:incToLast,:currTime,:operatorID)');
commonQuery.paramByName('machineID').asString :=currMachine.machineID;
commonQuery.paramByName('currDate').asString :=DateToStr(currMachine.WorkDay -i);
commonQuery.paramByName('workOrderID').asInteger :=tempRBuf[3] div 16;
commonQuery.paramByName('completed').asInteger :=tempRBuf[4]*256+tempRBuf[5];
commonQuery.paramByName('incToLast').asInteger :=tempRBuf[4]*256+tempRBuf[5];
commonQuery.paramByName('currTime').asString :=dateTimeTostr(currMachine.WorkDay -i);
commonQuery.paramByName('operatorID').asString :='';
try
commonQuery.ExecSQL;
except
WhenDBError;
end;
commonQuery.Close;
end;
end;
end;
for j:= workOrder_FIRST to (tempWorkOrderID-1) do
begin
tempRBuf := doCommunication(makeHistFrame(currMachine,0,j));
if tempRBuf[0] = frame_OK then
begin
commonQuery.SQL.Clear;
commonQuery.SQL.Add('insert into 生产任务');
commonQuery.SQL.Add('(机床编号,日期,班次编号,完成产量)');
commonQuery.SQL.Add(' values (:machineID,:currDate,:currWorkOrderID,:completed)');
commonQuery.paramByName('machineID').asstring := currMachine.machineID;
commonQuery.paramByName('currDate').asstring := DateToStr(currMachine.WorkDay );
commonQuery.paramByName('currWorkOrderID').asInteger := tempRBuf[3] div 16;
commonQuery.paramByName('completed').asInteger := tempRBuf[4]*256+tempRBuf[5];
try
commonQuery.ExecSQL;
except
WhenDBError;
end;
commonQuery.close;
//给生产记录中加入相关条目
commonQuery.SQL.Clear;
commonQuery.SQL.Add('insert into 生产记录');
commonQuery.SQL.Add(' (机床编号,日期,班次编号,完成任务量,完成增量,当前时间,操作员编号)');
commonQuery.SQL.Add(' values (:machineID,:currDate,:workOrderID,:completed,:incToLast,:currTime,:operatorID)');
commonQuery.paramByName('machineID').asString :=currMachine.machineID;
commonQuery.paramByName('currDate').asString :=DateToStr(currMachine.WorkDay -i);
commonQuery.paramByName('workOrderID').asInteger :=tempRBuf[3] div 16;
commonQuery.paramByName('completed').asInteger :=tempRBuf[4]*256+tempRBuf[5];
commonQuery.paramByName('incToLast').asInteger :=tempRBuf[4]*256+tempRBuf[5];
commonQuery.paramByName('currTime').asString :=dateTimeTostr(currMachine.WorkDay -i);
commonQuery.paramByName('operatorID').asString :='NONE';
try
commonQuery.ExecSQL;
except
WhenDBError;
end;
commonQuery.Close;
end;
end;
docommon(currMachine);
end;

/////////////////////////////////////////////////////
// TCommClass.makeHistFrame //
// 数据接收正常时,前状态为吊线的处理,此时查询 //
// 历史数据,组帧过程 //
/////////////////////////////////////////////////////

function TCommClass.makeHistFrame(currMachine : machine;daysToNow : byte;workOrderID:byte): frameBuf;
begin
makeHistFrame[0] := $FC;
makeHistFrame[1] := currMachine.addr;
makeHistFrame[2] := workOrderID * 16 + $0E;
makeHistFrame[3] := daysToNow;
makeHistFrame[4] := $FF;
makeHistFrame[5] := $FF;
makeHistFrame[6] := $FF;
makeHistFrame[7] := $ED;
end;

/////////////////////////////////////////////////////
// TCommClass.doWhenNormal //
// 数据接收正常时,前状态为非吊线的处理 //
/////////////////////////////////////////////////////

procedure TCommClass.doWhenNormal(var currMachine : machine ; currRBuf : frameBuf);
var
tempArray : frameBuf;
begin
if (currRBuf[2] div 16) <> currMachine.workOrderID then
begin
tempArray := doCommunication(makeHistFrame(currMachine,0,currMachine.workOrderID));
if tempArray[0] = frame_OK then
begin
commonQuery.SQL.Clear;
commonQuery.SQL.Add('insert into 生产任务');
commonQuery.SQL.Add('(跟单号,机床编号,日期,班次编号,完成产量)');
commonQuery.SQL.Add(' values (:checkIndex,:machineID,:currDate,:currWorkOrderID,:completed)');
commonQuery.paramByName('checkIndex').asstring := currMachine.checkIndex;
commonQuery.paramByName('machineID').asstring := currMachine.machineID;
commonQuery.paramByName('currDate').asstring := DateToStr(currMachine.WorkDay );
commonQuery.paramByName('currWorkOrderID').asInteger := tempArray[3] div 16;
commonQuery.paramByName('completed').asInteger := tempArray[4]*256+tempArray[5];
try
commonQuery.ExecSQL;
except
WhenDBError;
end;
commonQuery.close;

commonQuery.SQL.Clear;
commonQuery.SQL.Add('insert into 生产记录');
commonQuery.SQL.Add(' (机床编号,日期,班次编号,计划任务量,完成任务量,完成增量,当前时间,操作员编号)');
commonQuery.SQL.Add(' values (:machineID,:currDate,:workOrderID,:scheduled,:completed,:incToLast,:currTime,:operatorID)');
commonQuery.paramByName('machineID').asString :=currMachine.machineID;
commonQuery.paramByName('currDate').asString :=dateTostr(currMachine.WorkDay);
commonQuery.paramByName('workOrderID').asInteger :=currMachine.workOrderID;
commonQuery.paramByName('scheduled').asInteger :=currMachine.scheduled;
commonQuery.paramByName('completed').asInteger :=tempArray[4]*256 + tempArray[5];
commonQuery.paramByName('incToLast').asInteger :=tempArray[4]*256 + tempArray[5]-currMachine.completed;
commonQuery.paramByName('currTime').asString :=dateTimeToStr(now);
commonQuery.paramByName('operatorID').asString :=currMachine.operatorID;
try
commonQuery.ExecSQL;
except
WhenDBError;
end;
commonQuery.Close;

//转换机器数据
commonQuery.SQL.Clear;
commonQuery.SQL.Add('select * from 计划任务');
commonQuery.SQL.Add(' where 机床编号=:machineID and 日期=:currWorkDay');
commonQuery.SQL.Add(' and 班次编号=:currWorkOrderID ');
commonQuery.paramByName('machineID').asString :=currMachine.machineID;
if currMachine.workOrderID = workOrder_LAST then
begin
commonQuery.paramByName('currWorkDay').asString :=dateToStr(currMachine.workDay+1);
commonQuery.paramByName('currWorkOrderID').asInteger :=workOrder_FIRST;
end
else begin
commonQuery.paramByName('currWorkDay').asString :=dateToStr(currMachine.workDay);
commonQuery.paramByName('currWorkOrderID').asInteger :=currMachine.workOrderID + 1;
end;
try
commonQuery.open;
except
WhenDBError;
end;

if not commonQuery.eof then
begin
with currMachine do
begin
checkIndex := commonQuery.FieldByName('跟单号').AsString;
operatorID := commonQuery.FieldByName('操作员编号').asString;
workDay := strToDate(commonQuery.FieldByName('日期').asString);
workOrderID := commonQuery.FieldByName('班次编号').asInteger;
scheduled := commonQuery.FieldByName('计划产量').asInteger;
completed := currRBuf[3] * 256 + currRBuf[4];
incToLast := currRBuf[3] * 256 + currRBuf[4];
recordTime := now;
if (currRBuf[6] mod 2)= 1 then
currMachine.currStatus := currRBuf[6] mod 16
else begin
currMachine.currStatus := status_STOP;
end;
end;
end
else begin
with currMachine do
begin
checkIndex := '';
operatorID := '';
if currMachine.workOrderID = workOrder_LAST then
begin
currMachine.WorkDay := currMachine.workDay+1;
currMachine.workOrderID := workOrder_FIRST ;
end
else begin
currMachine.workDay := date;
currMachine.workOrderID := currMachine.workOrderID + 1;
end;
scheduled := 0;
completed := currRBuf[3] * 256 + currRBuf[4];
incToLast := currRBuf[3] * 256 + currRBuf[4];
recordTime := now;
if (currRBuf[6] mod 2)= 1 then
currMachine.currStatus := currRBuf[6] mod 16
else begin
currMachine.currStatus := status_STOP;
end;
end;
end;
commonQuery.close;
end;
end
else begin
currMachine.incToLast := currRBuf[3] * 256 + currRBuf[4] - currMachine.completed;
currMachine.completed := currRBuf[3] * 256 + currRBuf[4];
currMachine.recordTime := now;
end;
docommon(currMachine);
end;
/////////////////////////////////////////////////////
// TCommClass.doCommon //
// 数据接收正常时,处理完成后的一些公共处理 //
/////////////////////////////////////////////////////

procedure TCommClass.DoCommon(var currMachine: machine);
begin
commonQuery.SQL.Clear;
commonQuery.SQL.Add('insert into 生产记录');
commonQuery.SQL.Add(' (机床编号,日期,班次编号,计划任务量,完成任务量,完成增量,当前时间,操作员编号)');
commonQuery.SQL.Add(' values (:machineID,:currDate,:workOrderID,:scheduled,:completed,:incToLast,:currTime,:operatorID)');
commonQuery.paramByName('machineID').asString :=currMachine.machineID;
commonQuery.paramByName('currDate').asString :=dateTostr(currMachine.WorkDay);
commonQuery.paramByName('workOrderID').asInteger :=currMachine.workOrderID;
commonQuery.paramByName('scheduled').asInteger :=currMachine.scheduled;
commonQuery.paramByName('completed').asInteger :=currMachine.completed;
commonQuery.paramByName('incToLast').asInteger :=currMachine.IncToLast;
commonQuery.paramByName('currTime').asString :=dateTimeTostr(currMachine.recordTime);
commonQuery.paramByName('operatorID').asString :=currMachine.operatorID;
try
commonQuery.ExecSQL;
except
WhenDBError;
end;
commonQuery.Close;

commonQuery.SQL.Clear;
commonQuery.SQL.Add('insert into 运行记录');
commonQuery.SQL.Add(' (机床编号,日期,当前班次,操作员编号,运行状态,当前时间)');
commonQuery.SQL.Add(' values (:machineID,:currDate,:currWorkOrderID,:operatorID,:currStatus,:currTime)');
commonQuery.paramByName('machineID').asString :=currMachine.machineID;
commonQuery.paramByName('currDate').asString :=dateTostr(currMachine.WorkDay);
commonQuery.paramByName('currWorkOrderID').asInteger :=currMachine.workOrderID;
commonQuery.paramByName('currTime').asString :=dateTimeToStr(currMachine.recordTime);
commonQuery.paramByName('operatorID').asString :=currMachine.operatorID;
commonQuery.paramByName('currStatus').asInteger := currMachine.currStatus;
try
commonQuery.ExecSQL;
except
WhenDBError;
end;
commonQuery.Close;
end;
/////////////////////////////////////////////////////
// TCommClass.doWhenCommFail //
// 数据接收失败时处理过程 //
/////////////////////////////////////////////////////

procedure TcommClass.doWhenCommFail(var currMachine: machine);
begin
currMachine.currStatus := status_OFFLINE; //这里可能还要一些东西。
end;
/////////////////////////////////////////////////////
// TCommClass.changeCurrOrder //
// 在时间到缓办时间转换当前班次和日期 //
/////////////////////////////////////////////////////
procedure TCommClass.ChangeCurrOrder();
var
i : integer;
tempTime : TDateTime;
begin
tempTime := time;
for i := 0 to workOrderCount - 1 do
begin
if ((workOrders.startTime+workOrders.lastTime/24)<1) then
if (tempTime >= workOrders.startTime) and (tempTime < (workOrders.startTime + workOrders.lastTime / 24)) then
begin
currentWorkOrder := workOrders;
currentWorkDay := date;
end
else
begin
if (tempTime >= workOrders.startTime) and (tempTime < 1) then
begin
currentWorkOrder := workOrders;
currentWorkDay := date;
end
else
if (tempTime < (workOrders.startTime + workOrders.lastTime / 24 - 1)) then
begin
currentWorkOrder := workOrders;
currentWorkDay := date - 1;
end;
end;
end;
end;

procedure TFormMain.redrawTimerTimer(Sender: TObject);
var
i : integer;
begin
for i := 0 to systemEnv.machineCount -1 do
begin
//machineBMPArray.Picture := statusBMPArray[machines.currStatus];
end;
self.Repaint;
end;

procedure TFormMain.N2Click(Sender: TObject);
begin
init;
redrawTimer.Enabled := true;
CommThread := TCommClass.Create(false);
N2.Enabled := false;

end;

procedure TFormMain.N3Click(Sender: TObject);
var i: integer;
begin
//CommThread.Free;
comm.StopComm;
for i:=0 to systemEnv.machineCount - 1 do
machineBMPArray.Picture := statusBMPArray[0];
//init(nil);
N2.Enabled := true;

end;

procedure TFormMain.N4Click(Sender: TObject);
begin
close;
end;
procedure TFormMain.FormClose(Sender: TObject; var Action: TCloseAction);
var i:integer;
begin
for i := 0 to systemEnv.machineCount - 1 do
begin
Application.Terminate;
action:=cafree;
end;
end;

procedure TFormMain.ImageDblClick(Sender: TObject);
var i:integer;
temp,ImageName:string;
currMachine: machine;
begin
//showmessage(datetostr((machines[1].workDay)));
ImageName:=(sender as Timage).hint;
for i := 0 to systemEnv.machineCount -1 do
begin
case machines.currStatus of
0: temp:='离线';
1: temp:='手动';
2: temp:='停止';
3: temp:='自动';
end;
if ImageName=Machines.MachineID then
showmessage('跟 单 号 :'+machines.checkIndex+#13+'机床编号: '+machines.machineID+#13+'运行状态:'+temp+#13+'当前日期:'+datetostr((machines.workDay))+#13+'记录时间:'+copy(dateTimeTostr(machines.recordTime),11,9)+#13+'操作员编号:'+machines.operatorID+#13+'计划任务量:'+inttostr(machines.scheduled)+#13+'完成任务量:'+inttostr(machines.completed));
end;
end;
 
在窗体的Create事件中创建Image,tImage.Create(self);
在窗体的Destroy事件中Image.free。
 
估计是你访问了线程不安全的东西,引起了资源冲突。
 
问一下阿,我创建了一个线程。本身的程序是不是也是一个线程!?
 
本身的程序是一个主线程。
 
To:ufo!
麻烦你高抬贵眼,帮我看看上面的程序??
呵呵,看看线程执行时候是不是又问题?
谢谢。。谢谢。。
 
我的几个个建议.
1.出现 canvas not alow draw 原因之一就是当你往canvas设备上画图的时候,此时canvas需要一个HDC.如果没有取到HDC的话就会抛出这个异常了..
解决办法就是在你画图之前判断一个canvas的handle是不是0. 如果是0就不要画图了.
2.不要在子线程中处理canvas. 最好用一个同步方法来处理.或者通过发消息让主线程来负责更新canvas.

 
在这里看复杂的程序太累,把你的程序发到aizb@163.net里吧!
 
发过来我看看journer@163.com
 
To:xwings
谢谢你的建议,可是你说的我都不怎么懂,学习delphi没多长时间,现在这个任务
很急,能不能帮帮忙??!!
 
procedure TCommClass.Execute;
var
currTime : TDateTime;
tempMS : Integer;
begin

Synchronize(init);
while true do
begin
currTime := now;
case timeToDo(currTime) of
0 : Synchronize(doRoutine);
1 : Synchronize(adjustTime);
2 : Synchronize(schedule);
3 : Synchronize(changeCurrOrder);
end;
tempMS := (MilliSecondsBetween(now,currTime) mod systemEnv.checkInterval);
tempMS := systemEnv.checkInterval - tempMS;
sleep(tempMS);
end;

end;
 
谢谢zw84611
问题是解决了,但是有一点疑问,就是在DoCommunication里面
DataReceived表示是否接受到单片机返回数据,在comm的ReceiveData里面给其赋值的。。
现在如果发送次数<3,我想将DataReceived重制为False后,重新接受,则无论在comm的ReceiveData里收到
数据与否,DataReceived都为False了,去掉这句话后,则无论接到数据否,都为true了
以前好像不是这样啊。。
顺便再问一下,加了这几个同步后,程序是怎么执行的。。
为什么错误'does not allow drawing'就消失了
 

Similar threads

后退
顶部