各位兄弟,帮忙分析一下是什么原因导致出现了“Error Saving device context”的错误。
程序要求是将每隔5秒刷新显示从串口接收的数据。屏蔽掉我做了标志(/////////////###################)的那一行代码,程序运行正常,如果打开那一行代码,程序运行后会不定时的弹出“Error Saving device context”的错误框。通过主框架的COM1控件接收串口数据存放到全局变量strlist:Tstringlist; 供线程处理。
在主框架中定义了以下类型:
type
  PReadList=^RReadList;
  RReadList=record
    ReadID:string;
    mx:Integer;
    my:Integer;
    Image:TImage;
    strHint:string;
  end;type
  PTagList=^RTagList;
  RTagList=record
    TagID:string;
    mx:Integer;
    my:Integer;
    Image:TImage;
    strHint:string;
  end;在主框架中定义了全局变量:
 P_ReadList:PReadList;
 P_TagList:PTagList;       
 TagList:TList;             ScHash:THashedStringlist;    //存放的是P_ReadList类型的数据
以下是线程定义:
unit Thread;interfaceuses
  Classes,sysUtils,windows,Dialogs,ActiveX,math,ExtCtrls;
type
  ReceiveThread = class(TThread)
  private
    { Private declarations }
    ....
    RecData:array[1..30] of integer;        //存放解析后的数据;
    
    procedure Readstr;
  protected
    list1:Tstringlist;
    strPictureTagID: string;
    procedure ProcessRecStr(const Rec:string);
    procedure SaveToDatabase;
    procedure ShowInforlist;
    procedure ShowTreeNode;
    procedure RefreshRealTime;
    procedure Execute; override;
  end;implementationuses MainForm,dataModule,InforList,PatientTree,RealTime;procedure ReceiveThread.Readstr;
begin
  iccount:= strlist.Count;          //strlist为全局变量,存放着串口接收到的数据帧
  if iccount>0 then
  begin
    Readstring:= strlist.Strings[0];
    strlist.Delete(0);
  end
  else
  begin
    Readstring:='';
  end;
end;//对从串口接收的数据进行解包处理
procedure ReceiveThread.ProcessRecStr(const Rec:string);
var
  J:Integer;
  L:Integer;
  data:integer;
  checkout:integer;
begin
  ...
  ....
  //解包处理完成后,要求对Frm_RealTime进行操作
  if assigned(Frm_RealTime) then
     RefreshRealTime
  else
     list1.Clear;
end;
//刷新显示屏(5秒刷新一次屏幕)
procedure ReceiveThread.RefreshRealTime;
var i,Index:integer;
    strReader,strTag:string;
    rx,jiao,ry:integer;
    t_Object: TObject;begin
  strReader:=inttostr(Recdata[2]);   //Recdata[2],Recdata[4] 是解包后得到的字符串
  strTag:=inttostr(Recdata[4]);  i:=list1.IndexOfName(strTag);      //list1存放的是最近5秒内收到的解包后的数据
  if i=-1 then
    list1.Add(strTag+'='+strReader)
  else
  begin
    list1.Delete(i);
    list1.Add(strTag+'='+strReader);
  end;
  if IsRefresh then               //IsRefresh是5秒钟时间到的判断符,
  begin
    if TagList.Count>0 then                    //先清空原先屏幕上的各个Image
    begin
      for i:=(TagList.Count-1) downto 0 do
      begin
        P_TagList:=TagList.Items[i];
        TagList.Delete(i);
        P_TagList.Image.Free;
        DisPose(P_TagList);
      end;
    end;    Randomize;
    if list1.Count>0 then                       //创建最新的list1里所对应的Image;
    for i:=0 to (list1.Count-1) do
    begin
      rx:=Random(50);
      jiao:=Random(360);      ry:=round(rx*sin(2*Pi*jiao/360));
      rx:=round(rx*cos(2*Pi*jiao/360));      strTag:=list1.Names[i];
      strReader:=list1.ValueFromIndex[i];      Index:=ScHash.IndexOf(strReader);
      if Index=-1 then
        continue;
      t_Object:=ScHash.Objects[Index];      new(P_TagList);
      P_TagList.TagID:=strTag;
      P_TagList.mx:=rx+PReadList(t_Object).mx;
      P_TagList.my:=ry+PReadList(t_Object).my;
      P_TagList.strHint:='标签号:'+ strTag;
      P_TagList.Image:=TImage.Create(nil);//////如果屏蔽下面一行,程序运行正常,但是不能将图片显示出来,如果运行这一行,就会在程序运行期间不定时的出现“Error Saving device context”的错误框。
    
      P_TagList.Image.Parent:=Frm_RealTime.Panel3;             /////////////#######################################       
      P_TagList.Image.Top:=P_TagList.my;
      P_TagList.Image.Left:=P_TagList.mx;
      P_TagList.Image.Width:=25;
      P_TagList.Image.Height:=25;
      P_TagList.Image.Picture.LoadFromFile(strPictureTagID);
      P_TagList.Image.Hint:=P_TagList.strHint;
      P_TagList.Image.ShowHint:=true;
      P_TagList.Image.Transparent:=true;      TagList.Add(P_TagList);
      
    end;    list1.Clear;
    IsRefresh:=false;
  end;
end;//线程执行代码
procedure ReceiveThread.Execute;
begin  list1:=Tstringlist.Create;
  TagList:=TList.Create;  strPictureTagID:= Frm_Main.IniFile.ReadString('BACKGROUND','TagID','');  while not terminated do
  begin
    synchronize(Readstr);
    if Readstring<>'' then
      ProcessRecStr(Readstring)
    else
      sleep(3000);
  end;end;end.