现在做的东西要用到动态创建组件,如panel,image等。但在窗体创建时调用组件的创建过程,程序就变的很慢。不,是超慢!!所以我想用线程来动态创建一些组件。但是没接触过这些东西,做了一天了,还是没调试出来,麻烦各位大虾帮忙解决一下,小弟不胜感激!有源码更好。先行谢过!

解决方案 »

  1.   

    今天一直在线,可以MSN 到:[email protected]
      

  2.   

    也就是这样了private
      m_Panel: TPanel;
    public  Constructor Create(AOwner:TComponent);
      Destructor Destroy;override;......
    constructor TReceiveFile.Create(AOwner: TComponent;SaveFileName:string);
    begin
      m_Panel:= TPanel.Create(AOwner);
      inherited Create( false );
    end;destructor TReceiveFile.Destroy;
    begin
      m_Panel.Destroy;
      inherited;
    end;
      

  3.   

    能详细点吗?我是菜鸟,我复制了你的代码调试不出来~
    unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs;type
      TForm1 = class(TForm)
      private
       m_Panel:TPanel;
     { Private declarations }
      public
      Constructor Create(AOwner:TComponent);
      Destructor Destroy;override;
      { Public declarations }
      end;var
      Form1: TForm1;implementation{$R *.dfm}
    constructor TReceiveFile.Create(AOwner: TComponent;SaveFileName:string);
    begin
      m_Panel:= TPanel.Create(AOwner);
      inherited Create( false );
    end;destructor TReceiveFile.Destroy;
    begin
      m_Panel.Destroy;
      inherited;
    end;
    end.
    我把TReceiveFile改成TForm1也不行。
      

  4.   

    你一个form要创建多少个组件?
      

  5.   

    开线程也没用,可视控制都得放到主线程里处理
    可以在其它方面想办法,比如,分多页,某页要显示时再创建
    或者创建后设置好其它属性,最后设置parent
      

  6.   

    哦,是这样的,我在做一个酒店的管理系统,客户要求至少要有50层楼(当然实际上不会有那么多),每层至少有60间房。所以我估算一下,一般酒店顶多就1000吧。而这些房间都要在界面中显示。而且还可以根据条件进行查询。所以这些控件在查询时还得Free掉。
      

  7.   

    那你这些控件不可能一起显示的吧?至少是要分批的吧?比如说,用tabcontrol,50层楼就50个tab,然后按了哪个tab再来生成这一层楼的房间,顶多60个控件吧?
    不用一开始的时候就生成1000个
      

  8.   

    i:=1;//控制换行的变量
    for j := 1 to 40 do//开始创建     begin
                tpl[j]:=Tpanel.Create(self);
                tpl[j].Parent:=ScrollBox1;
                tpl[j].Height:=30;
                tpl[j].Width:=55;
                tpl[j].ShowHint:=true;
                tpl[j].BevelOuter:=bvnone;
                 if  j mod n=0 then//控制换行
                  begin
                     tpl[j].Top:=i*33;
                     tpl[j].left:=tpl[j-1].left+58;
                     i:=i+1;
                  end
                 else   if j mod n =1 then
                    begin
                      tpl[j].left:=1;
                      tpl[j].Top:=i*33;
                    end
                    else
                    begin
                     tpl[j].Top:=i*33;
                     tpl[j].left:=tpl[j-1].left+58;                end;
      

  9.   

    1.我觉得ysai说的有道理,可以采取分页的形式,1000多个你在控制的时候找起来都不方便的(比如点击什么的)
    2.你的客户给你提供的那个程序,不一定是全部显示的,有可能只是显示个图什么的,然后你在操作的时候程序才开始真正创建的,这个很难说,我只是猜测
    3.多线程来实现,我没试过,如果确实可以提高效率,希望告之 
      

  10.   

    我也觉得ysai说的有道理,但我们老大不会这些,有了那个参考系统之后他的态度就更坚决了!我也看了那个系统,也觉得是一开始就生成的,因为它在启动时会动态加载图片,我把图片删除之后它就显示不了呢。这说明该系统不只是一幅图片那么简单。如果能够动态加载1000多幅图片,速度还那么快,那我也想问问用什么方法可以实现这样的功能。图片是BMP格式的,有11.5K。
      

  11.   

    在线程里创建组建重要的是初始化 ~    是  coinitialize(nil) 和 couninitialize;
    //模块执行
    procedure TMythread.Execute;
    var
      AreaCodeList,ErrorGuestNumList:Tstringlist;
      i,AllGuestNum,bedNum:integer;
      FGusetNumString,DFileName,tempStr:string;
    begin
      inherited;
      coinitialize(nil);
      AreaCodeList:=Tstringlist.Create;
      ErrorGuestNumList:=Tstringlist.Create;
      DataSet:=TADOQuery.Create(nil);
      ConnectionMain:=TADOConnection.Create(nil);
      ConnectionMain.ConnectionString:=TPublicFunction.GetConnectStr;
      DataSet.Connection:=ConnectionMain;
      ConnectionMain.LoginPrompt:=False;
      .....
      couninitialize;end
      

  12.   

     TO argl521 :
    先谢过了。能详细点吗?这初始化对它的创建速度会有帮助吗?不过我觉得他对查询这一块可能有很大的作用,所以可以的话,想请你列详细点,这里只有数据库的连接。
      

  13.   

    是不是用来显示房间图标啊?动态创建panel,image还不如直接用listview还简单.
      

  14.   

    我系菜鸟,我想喃:选显示房间图标吧..当选中了.要求执行时再具体化,,程序不是一打开,窗体一出来就显示好了所有吧..我认为不可能..你用主线程做出最前面一开窗口可能看到的所有房间(这个不会要多久吧).然后偷开个线程,慢慢继续工作,如果..而且开出来的线程你得优化一下.你宁可让他的代码工作慢点.也不要猛循环..因为一般情况下没那么快就要求下一屏的东西吧..使用的人的反应没机器快的..你去看下ACDSEE加载图片的方式..当一个目录有N多图片时...我在想哈..你那个参考系统决不可能一开起.就能让上千个房间图标准备好了执行具体的工作.不会那么快.那不必达到那么快吧..使用者要到后面些的房间图标位置.他最快的办法应该是办理入楼层号,房号.而不是一页一页翻吧..如果是输楼层号.房号..你的处理还应更轻些哩.....这些都是我的想法.我是业务程序爱好者..别扔哈..HOHO...刚开始学delphi..来淘金的..嘿嘿...
      

  15.   

    50城楼,每层60个房间,就算是10000城楼,每层10000个房间,使用软件的人他一次能看几个?所以我认为你没有必要这么做,即使你硬是需要这么做那就只能使用线程,一秒钟显示出来是不可能的,只是使用了线程你的程序不会感觉卡。unit MyThUnit;interfaceuses
      Classes, sysutils,;type
      TMyTh = class(TThread)
      private
        { Private declarations }
      protected
        procedure Execute; override;
      public
        constructor Create(参数); virtual;
        destructor Destroy; override;
      end;implementationconstructor TMyTh.Create(参数);
    begin
      inherited Create(True);        
      Resume;                       
    end;procedure TMyTh.Execute;
    begin
      while not Terminated do
      begin
        //在这里写你创建控件的代码
        Sleep(50);
      end;
    end;destructor TMyTh.Destroy;
    begin
      inherited;
    end;
    然后就是你自己写代码调用这个线程了
      

  16.   

    谢谢各位大虾。你们的方法我都会一一去试,但有一点需要说明的是,我的那个参考系统真的有那么快,即使有10000个也是1到2秒那么快。这是我测试过的。它用的数据库还是ACCESS的。我来这就是想向大家学习,没必要说假话的。
    不管怎么说,在这里还是要谢谢大家的支持的!
      

  17.   

    Delphi的VCL大部分不是线程安全,你在一个线程里面全部创建了,显示还是要靠主线程,我想这个速度好不到哪里去。我不太相信创建1000个Panel会慢到用户有感觉?
    Panels:array[0..999] of TPanel
    for i:=0 to 999 do
      Panles[i]:=TPanle.Create(nil);
    我试了下,是0.01秒。再加上全部设完Parent,也就0.6秒多
      

  18.   

    在主线程里创建速度虽然没有你的0.01秒快,但还可以很快的创建出来。问题是在其他过程中要创建的话就很慢了。
    之所以要在其它过程中创建,是因为我想通过数据库查询来创建这些控件,查到不同的数据就得重新删除、创建。
    这里有个一模一样的系统可以下:http://www.motolock.com/download.asp找到2007-01版门锁管理软件
    就可以下来装了。
      

  19.   

    楼主完全不着道,显示1000多个房间,就创建1000多个TPanel,TImage啊!?有这么干的么?
    那CAD图纸、工控图上几万个元件就没法做了,TPanel可是有Handle的重量级窗口啊。正确的思路应该是根据数据自己绘制,把每个房间看作一个图元类,包含房间各种属性,
    由一个“面板”(一般可以从 TCustomControl 继承)统一管理,重载 Paint 方法,
    把“房间”绘制出来...建议看看TSimpleGraph,ExpressFlowChart,ExpressOrgChart这些控件是如何做的,
    这些控件一次显示几百个图元根本毫不费力(注意我是说创建/显示图元,之前查数据库不要算进去)
      

  20.   

    用线程会更慢,而且线程结束了,所有的都没free掉,变成你在在线程中所一个 while true do 的死循环,这种写法太耗资源了,还是重新规划吧
      

  21.   

    TO myy:
          我是得承认我很不着道了,呵呵~  刚接触delphi不久,很多东西都没有想到。所以希望像你们这样的大虾拉一把啊。你说的这些对我来说很有难度,能详细的描述一下整个绘制过程吗?要是有个实例就更好了。^_^
      

  22.   

    TSimpleGraph有源码,就是最好的实例,你仔细研究下,完全可以通过修改扩展它搞的。
      

  23.   

    TO   myy:
        TSimpleGraph的源码delphi自带吗?我在它的Demos里找不到啊?
      

  24.   

    TSimpleGraph的源码delphi自带吗?我在它的Demos里找不到啊?
    --------
    http://www.delphiarea.com/products/simplegraph/google:约有6,750项符合SimpleGraph的查询结果,以下是第1-10项 (搜索用时 0.19 秒)I服了U ...
      

  25.   

    TSimpleGraph的源码过几天看吧,我粗略的看了一下,没看明白怎么回事。没时间了,这个月30号交货。整个产品就剩下两个模块,一个就是这个房间的显示问题,也就是我摆在这的问题。另一个就是注册及安全问题。   现在看来以直接创建组件这个方法似乎行不通了,不仅因为速度慢,而且数量过多的时候就出错了(我的机子数量不能超过1900个)。对于一个刚接触delphi不久的初学者来说,myy仁兄的这个方法:“把每个房间看作一个图元类,包含房间各种属性,由一个“面板”(一般可以从   TCustomControl   继承)统一管理,重载   Paint   方法,把“房间”绘制出来...”似乎很有挑战性。我很想接受这个挑战,无奈没有充分的时间, 所以在此抛分100求myy仁兄这样的方法源码。希望大家鼎力相助,小弟感激不尽!
      

  26.   

    用线程也不能解决这样的问题的,所有的界面显示控件都是在主线程中创建和刷新的。
    1000个没有必要一次全部创建吧,应该是按层分组,在一个就是不用DELPHI的控件,自己用绘图函数进行绘制。
      

  27.   

    建议用ListView里的项目来代替你要表示房间的控件,这样速度会很快
      

  28.   

    问个别的问题:
       Adoquery查询到的数据集可以重复使用吗?例如我在button1的onclick事件中编写了Adoquery1的sql语句。那么我在button2里的onclick事件中能不能直接就这样调用:
    For i=0 to Adoquery1.Recordcount-1 do
      begin
       ...//对数据集的一些操作;
      end;

    我这样直接使用adoquery1的数据集的话,显示出来的不是在button1事件中的哪些数据,好奇怪。不知道怎样才能得到Adoquery1最后一次查询到的值?????