您的位置:程序门 -> delphi -> vcl组件开发及应用



线程中动态创建timage有特殊的要求吗


[收藏此页] [打印本页]选择字色:背景色:字体:[][][]


线程中动态创建timage有特殊的要求吗
发表于:2007-07-19 13:43:22 楼主
各位兄弟,帮忙分析一下是什么原因导致出现了“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;

interface

uses
    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;


implementation

uses   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.    
发表于:2007-07-19 13:55:531楼 得分:0
在多线程里最好不要在工作线程里进行ui操作,你可以向主线程发消息,让主线程来完成刷新的工作。


快速检索

最新资讯
热门点击