急急急急,上百个Panel控件同时创建速度问题----高手请进来帮帮忙(在线等待)!(100分)

B

baeyk

Unregistered / Unconfirmed
GUEST, unregistred user!
我在一个窗体上创建二三百个改良过的Panel控件,创建过程大概需要十几秒吧,而且每创建一个屏蔽就会闪一下,怎么能提高创建多控件的速度!!!
创建的panel控件是用来显示仓库中货场、货区、货架、货层、货段的示意图,有谁有这样的控件也可以!!
 
要提高速度不知道有没有什么办法。你可以动态创建,先不让它们显示,创建完了才显示。这样就不会影响屏幕显示了
 
这我也试过,不过我创建的控件在创建时有顺序并有坐标的,采用先创建后显示后坐标乱了,不知是什么问题,也就是显示不是创建显示时的效果!
 
你把代码放上来看看。
我刚才只是动态产生了300个panel,好像没有影响屏幕显示。
 
unit UMainFrm;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, cDragPanel, StdCtrls, Buttons, ExtCtrls, MyPanel, ArtPanel,
Gauges, ComCtrls, UMyThread;

type
TArrhqPanel = array of TArtPanel
//货区
TArrhjPanel = array of TArtPanel
//货架
TArrhcPanel = array of TArtPanel
//货层
TArrhdPanel = array of TDragPanel;

HqInfo = record
ckname :string;
ckbm :string;
hqname :string;
hqbm :string;
hqPanel :TArrhqPanel
end;

HcInfo = Record
hjname :string;
hjbm :string;
hjlayer :Integer;
hcPanel :TArrhcPanel;
end;

TMainFrm = class(TForm)
Panel1: TPanel;
ScrollBox1: TScrollBox;
Panel2: TPanel;
Edit1: TEdit;
BitBtn2: TBitBtn;
Label1: TLabel;
BitBtn3: TBitBtn;
BitBtn4: TBitBtn;
ArtPanel1: TArtPanel;
Label3: TLabel;
ArtPanel2: TArtPanel;
Label4: TLabel;
Label2: TLabel;
BitBtn1: TBitBtn;
Panel3: TPanel;
Edit2: TEdit;
Bevel1: TBevel;
Bevel2: TBevel;
ArtPanel3: TArtPanel;
Bevel3: TBevel;
BitBtn5: TBitBtn;
Status: TStatusBar;
Gauge1: TGauge;
procedure BitBtn1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
Procedure DestroyPanel;
procedure FormClose(Sender: TObject
var Action: TCloseAction);
procedure BitBtn2Click(Sender: TObject);
procedure BitBtn4Click(Sender: TObject);
procedure BitBtn3Click(Sender: TObject);
procedure BitBtn5Click(Sender: TObject);
procedure StatusDrawPanel(StatusBar: TStatusBar;
Panel: TStatusPanel
const Rect: TRect);
private
Process :TProgressBar;
StatusDrawRect:TRect
//记录要插入状态条特技的坐标范围
{ Private declarations }
public
ArrhqPanel :TArrhqPanel
//货区
ArrhjPanel :TArrhJPanel
//货架
ArrhcPanel :TArrhCPanel
//货层
ArrhdPanel :TArrhdPanel
//货段
j :integer;
{ Public declarations }
end;

var
MainFrm: TMainFrm;
implementation

{$R *.dfm}

Procedure TMainFrm.DestroyPanel;
var v_count,i :integer;
begin
//释放货段
v_count := Length(ArrhdPanel);
For i:=0 to v_count -1 do
If ArrhdPanel <> nil then
begin
ArrhdPanel.Free;
ArrhdPanel := nil;
end;
//释放货层
v_count := Length(ArrhcPanel);
For i:=0 to v_count -1 do
If ArrhcPanel <> nil then
begin
ArrhcPanel.Free;
ArrhcPanel := nil;
end;
//释放货架
v_count := Length(ArrhjPanel);
For i:=0 to v_count -1 do
If ArrhjPanel <> nil then
begin
ArrhjPanel.Free;
ArrhjPanel := nil;
end;
//释放货段
v_count := Length(ArrhqPanel);
For i:=0 to v_count -1 do
If ArrhqPanel <> nil then
begin
ArrhqPanel.Free;
ArrhqPanel := nil;
end;
end;


//*************** 货段 **************//
procedure TMainFrm.BitBtn1Click(Sender: TObject);
var v_count, i :integer;
p:tpoint;
v_hccount,j :integer;

v_hdcount,v_pro :integer;

A,B :MyThread;
begin
try
{ progress:=TProgressbar.create(MainFrm);
staPanleWidth:=status.Panels.Items[2].width;
status.Panels.Items[2].width:=600
// 改变宽度
status.repaint;
with progress do
begin
top:=StatusDrawRect.top;
left:=StatusDrawRect.left;
width:=StatusDrawRect.right-StatusDrawRect.left;
height:=StatusDrawRect.bottom-StatusDrawRect.top;

//设定进程条的宽度和高度
visible:=true;
try
Parent := status
//该进程条的拥有者为状态条status
Min := 0
Max := Count
//进程条的最大和最小值
Step := 1
//进程条的步长
for i := 1 to Count do

Stepit
// 累加进程条
//ShowMessage('现在,进程条将要从内存中被释放');
finally
Free
//释放进程条
end
//try
end
//with
status.Panels.Items[2].width:=staPanleWidth
//恢复状态条嵌板的宽度
}

v_pro :=1;
Gauge1.Visible := True;
Try
v_hdcount := StrToInt(Edit2.Text);
Except
MessageDlg('错误!', mtInformation,[mbOk], 0);
Exit;
end;
v_hccount :=Length(ArrhcPanel);
Gauge1.MaxValue :=v_hdcount * v_hccount
Gauge1.Progress :=0;
For j:=0 to v_hccount -1 do
begin
A:=MyThread.Create(ArrhdPanel,ArrhcPanel,j,v_hdocunt);
{for i:=0 to v_hdcount do
begin
V_Count :=Length(ArrhdPanel);
SetLength(ArrhdPanel,V_Count+1);
ArrhdPanel[V_Count] :=TDragPanel.Create(self);
ArrhdPanel[V_Count].Parent := ArrhcPanel[j];
ArrhdPanel[V_Count].Width := 30;
ArrhdPanel[V_Count].Height :=50;
ArrhdPanel[V_Count].Caption := IntToStr(i);
If i = 0 then
begin
//Showmessage(inttostr(arrhcPanel[j].Top)+#13+Inttostr(ArrhcPanel[j].Left));
ArrhdPanel[V_Count].Top :=0;//ArrhcPanel[j].Top;
ArrhdPanel[V_Count].Left:=0;//ArrhcPanel[j].Left;
end else
begin
//Showmessage(inttostr(ArrhdPanel[V_Count-1].Top)+#13+Inttostr(ArrhdPanel[V_Count-1].Left+ArrhdPanel[V_Count-1].Width));
ArrhdPanel[V_Count].Top :=ArrhdPanel[V_Count-1].Top;
ArrhdPanel[V_Count].Left:=ArrhdPanel[V_Count-1].Left+ArrhdPanel[V_Count-1].Width;
end;
Gauge1.Progress :=v_pro;
Inc(v_pro);
end
}
end;
BitBtn1.Enabled := False;
BitBtn3.Enabled := False;
BitBtn4.Enabled := False;
Gauge1.Progress :=0;
Gauge1.MaxValue :=0;
Gauge1.Visible := False;
finally

end;
end;

//*************** 货区 **************//
procedure TMainFrm.FormCreate(Sender: TObject);
begin
j:=0;

end;

//*************** 货层 **************//
procedure TMainFrm.FormClose(Sender: TObject
var Action: TCloseAction);
begin
DestroyPanel;
end;

procedure TMainFrm.BitBtn2Click(Sender: TObject);
begin
DestroyPanel;
BitBtn1.Enabled := False;
BitBtn3.Enabled := False;
BitBtn4.Enabled := True;
end;

//*************** 货区 **************//
procedure TMainFrm.BitBtn4Click(Sender: TObject);
var v_count, i :Integer;
begin
Try
v_count := StrToInt(Edit1.Text);
Except
MessageDlg('错误!', mtInformation,[mbOk], 0);
Exit;
end;
For i:=0 to v_count - 1 do
begin
V_Count :=Length(ArrhqPanel);
SetLength(ArrhqPanel,V_Count+1);
ArrhqPanel[V_Count] :=TArtPanel.Create(self);
ArrhqPanel[V_Count].Parent := ScrollBox1;
ArrhqPanel[V_Count].Width := 804;
ArrhqPanel[V_Count].Height :=100;
ArrhqPanel[V_Count].BevelInner := bvLowered;
ArrhqPanel[V_Count].BevelOuter := bvRaised;
ArrhqPanel[V_Count].ColorHighlight := clYellow;
ArrhqPanel[V_Count].ColorShadow := clYellow;
if i = 0 then
begin
ArrhqPanel[V_Count].Top :=0;//ScrollBox1.Top;
ArrhqPanel[V_Count].Left:=0;//ScrollBox1.Left;
end else
begin
if i mod 2 <> 0then //1、3、5
begin
ArrhqPanel[V_Count].Top :=ArrhqPanel[V_Count-1].Top + ArrhqPanel[V_Count].Height + 50;
ArrhqPanel[V_Count].Left:=ArrhqPanel[V_Count-1].Left;
end else //2、4、6
begin
ArrhqPanel[V_Count].Top :=ArrhqPanel[V_Count-1].Top + ArrhqPanel[V_Count].Height;;
ArrhqPanel[V_Count].Left:=ArrhqPanel[V_Count-1].Left;
end;
end;
end;
BitBtn3.Enabled := True;
BitBtn4.Enabled := False;
end;

//*************** 货层 **************//
procedure TMainFrm.BitBtn3Click(Sender: TObject);
var v_count, i,j :Integer;
p :tpoint;
begin
j := Length(ArrhqPanel);
For i:=0 to j - 1 do
begin
V_Count :=Length(ArrhcPanel);
SetLength(ArrhcPanel,V_Count+1);
ArrhcPanel[V_Count] :=TArtPanel.Create(self);
ArrhcPanel[V_Count].Parent := ArrhqPanel;
ArrhcPanel[V_Count].Width := 800;
ArrhcPanel[V_Count].Height :=48;
ArrhcPanel[V_Count].BevelInner := bvLowered;
ArrhcPanel[V_Count].BevelOuter := bvRaised;

ArrhcPanel[V_Count].Top :=0;//ArrhqPanel[0].Top+2
//?????????????????
ArrhcPanel[V_Count].Left:=0;//ArrhqPanel.Left+2;
ArrhcPanel[V_Count].ColorHighlight := clSkyBlue;
ArrhcPanel[V_Count].ColorShadow := clSkyBlue;

V_Count :=Length(ArrhcPanel);
SetLength(ArrhcPanel,V_Count+1);
ArrhcPanel[V_Count] :=TArtPanel.Create(self);
ArrhcPanel[V_Count].Parent := ArrhqPanel;
ArrhcPanel[V_Count].Width := 800;
ArrhcPanel[V_Count].Height :=48;
ArrhcPanel[V_Count].BevelInner := bvLowered;
ArrhcPanel[V_Count].BevelOuter := bvRaised;
ArrhcPanel[V_Count].Top :=ArrhcPanel[V_Count].Top + ArrhcPanel[V_Count-1].Height +2;
ArrhcPanel[V_Count].Left:=ArrhcPanel[V_Count].Left+2;
ArrhcPanel[V_Count].ColorHighlight := clFuchsia;
ArrhcPanel[V_Count].ColorShadow := clFuchsia;
end;
BitBtn1.Enabled := True;
BitBtn3.Enabled := False;
end;
procedure TMainFrm.BitBtn5Click(Sender: TObject);
begin
Close;
end;

procedure TMainFrm.StatusDrawPanel(StatusBar: TStatusBar;
Panel: TStatusPanel
const Rect: TRect);
begin
StatusDrawRect:=rect
//记录要实现状态条特技的坐标范围
end;

end.
 
TArtPanel组件是你自己做的吗?如果是的话,你可以把你现在要的设置做成默认设置,这样可以减少很多的时间。
我再帮你看看
 
在需要显示的地方(比如整个Form)先放一个大的ParPanel,然后把这个ParPanel.Visible:=False;
然后以这个大的ParPanel为Parent创建你的近百个特殊SubPanel Visible:= True;然后ParPanel.Visible:= True;
总觉得创建这么多的Panel有点夸张,你是否应该再提炼一下你的Control的逻辑层次,几百个WinControl很占资源的(不是简单的内存资源,而是系统资源)




 
v_count := StrToInt(Edit1.Text);
For i:=0 to v_count - 1 do
begin
V_Count :=Length(ArrhqPanel);
SetLength(ArrhqPanel,V_Count+1);
ArrhqPanel[V_Count] :=TArtPanel.Create(self);
ArrhqPanel[V_Count].Parent := ScrollBox1;

既然你已经确定长度,我觉得ArrhqPanel的长度没必要一个一个加,还有v_count 这个变量在变化,有用在循环中,会不会有隐患?
这样好点:
v_count := StrToInt(Edit1.Text);
BB:=Length(ArrhqPanel);
SetLength(ArrhqPanel,V_Count+BB);
For i:=0 to v_count - 1 do
begin
ArrhqPanel[i+BB] :=TArtPanel.Create(self);

 
to yostgxf:
我那样处理我想应该是没有问题的!
to zjan521:
本人对Control的逻辑层次认识不深,任务急只好采用这种方式,望指教一二!

 
1.你可以把你现在要的设置做成默认设置,这样可以减少很多的时间。
2.按我上面的说法,也可以优化操作。
3.货层/货区等Panel,能否公用。
 
能否举例一下!
 
ArrhcPanel[V_Count].Width := 800;
ArrhcPanel[V_Count].Height :=48;
ArrhcPanel[V_Count].BevelInner := bvLowered;
ArrhcPanel[V_Count].BevelOuter := bvRaised;

ArrhcPanel[V_Count].ColorHighlight := clSkyBlue;
ArrhcPanel[V_Count].ColorShadow := clSkyBlue;
如果能默认设置,类似上面的代码都可以不要了
 
我这个几个属性都是要变化的,所以不能设置成默认!
 
LockWindowUpdate(Panel.Parent.Handle);
try
创建Panel
finally
LockWindowUpdate(0);
end;
 
能默认一部分也好,因为你要产生的组件太多。
我的意见就这么多,都说了。否则就要推翻你的设计了,哈哈
 
楼上的锁屏幕也是一个办法,不过不能缩短构建的时间
 
最好用TPaintBox自己绘制。
 
创建这么Panel。。。。。
建议把一些货场、货区、货架、货层、货段封装成类,然后在一个容器上把这些画出来
比如这样:
TWareCtrlPanel=class;

TWareBaseControl=class
private
FPanel: TWareCtrlPanel;
FBoundRect: TRect;

procedure SetLeft(const Value: Integer);
function GetLeft: Integer;

procedure SetRight(const Value: Integer);
function GetRight: Integer;

procedure SetTop(const Value: Integer);
function GetTop: Integer;

procedure SetBottom(const Value: Integer);
function GetBottom: Integer;

procedure SetHeight(const Value: Integer);
function GetHeight: Integer;
protected
procedure Draw(ACanvas: TCanvas);virtual
abstract;
public
constructor Create(APanel: TWareCtrlPanel
ARect: TRect)
virtual;
destructor Destroy
override;

property Left: integer read GetLeft write SetLeft;
property Top: integer read GetTop write SetTop;
property Width: integer read GetWidth write SetWidth;
property Height: integer read GetHeight write SetHeight;
property Right: integer read GetRight write SetRight;
property Bottom: integer read GetBottom write SetBottom;
end;
//下面的控件主要完成的是Draw方法,看你的情况画出示意图
//货区
TWareArea=class(TWareBaseControl)
protected
procedure Draw(ACanvas: TCanvas);override;
public
........
end;
//货架
TWareShelf=class(TWareBaseControl)
protected
procedure Draw(ACanvas: TCanvas);override;
public
........
end;
//货层
TWareFloor=class(TWareBaseControl)
protected
procedure Draw(ACanvas: TCanvas);override;
public
........
end;
//货段
TWareSect==class(TWareBaseControl)
protected
procedure Draw(ACanvas: TCanvas);override;
public
........
end;

TWareCtrlPanel=class(TCustomPanel)
private
//上面各个类型的容器
FControlList: TStringList;
protected
procedure Paint
override;//调用PaintControls来画出你需要的示意图
procedure PaintControls(ACanvas: TCanvas);
public
....
end;
 
1、首先谢谢以上各位的指导!
2、to jlutt-sadan
我对于TCanvas的用法不是很了解,能否照以以上创建类创建几个示意图例子给我,我在此先谢谢了!
 
上面的代码是我在家写的,没装delphi:(
等明天到单位。。

可以参照看看TForm的源码.
至于各个类的画法,你可以看TShape的源码,把它画各个形状的代码复制过来:)
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
D
回复
0
查看
2K
DelphiTeacher的专栏
D
D
回复
0
查看
2K
DelphiTeacher的专栏
D
D
回复
0
查看
1K
DelphiTeacher的专栏
D
顶部