我通过继承Tpanel创建了一个控件TLabelPaenl,可以通过此控件的一个方法在上面增加Label,但是在关闭时候出了错误。。。(150分)

  • 主题发起人 主题发起人 ynfly
  • 开始时间 开始时间
Y

ynfly

Unregistered / Unconfirmed
GUEST, unregistred user!
我通过继承Tpanel创建了一个控件TLabelPaenl,可以通过此控件的一个方法在上面增加Label;
我另外创建了一个工程Project1用来测试此控件,在project1的一个form上增加一个TLabelPanel,
命名为Lp,再增加一个Button,命名为Button1,在Button1上的click事件上写上代码:
procedure TForm1.Button1Click(Sender: TObject);
begin
LP.addLabel ;
end;

现在我有两个问题:
1、我要求此Lp在打开时caption为空,而且我也在TLabelPanel的create事件上写上了,为何在使用时,
且显示Lp的caption为跟LP的Name的值一样?
2、如果通过Button1创建了100个Label的话,会产生错误,错误分别为:"project project1.exe raised
exception class EInvalidPointer with message 'Invalid pointer operation'.process stopped,
use step or run to continue ", "exception EInvalidpointer in module project1.exe at 00002794 ,
Invalid pointer operation" ,而在小于100的时候就没有错误,什么原因?


TLabelPanel组件代码如下:
unit LabelPanel;

interface

uses
Windows, Messages, SysUtils,dialogs, Classes, Controls, ExtCtrls,StdCtrls;

type
TLabelPanel = class(TPanel)
private
FcolumnNum:integer;//表示现在存在的Label个数;最大不可以超过100
{ Private declarations }
protected
{ Protected declarations }
public
NLabel:array[0..99] of TLabel;
procedure addLabel; //在Paenl上增加一个Label;
constructor create(Aowner:Tcomponent);override;
destructor destroy;override;
{ Public declarations }
published
{ Published declarations }
end;

procedure Register;

implementation

procedure Register;
begin
RegisterComponents('ActiveX', [TLabelPanel]);
end;

constructor TLabelPanel.create(Aowner:Tcomponent);
begin
inherited create(Aowner);
self.caption:='';
self.Width:=600;
self.Height:=480;
FcolumnNum:=0;
self.invalidate;
end;
destructor TLabelPanel.destroy ;
var intI:integer;
begin
if FcolumnNum>0 then
begin
//showmessage(inttostr(FcolumnNum));
for intI:=0 to FcolumnNum-1 do
begin
NLabel[intI].Free ;
invalidate;
end;
end;
inherited destroy;
end;
procedure TLabelPanel.addLabel;
var intX,intY:integer;
begin
if FcolumnNum<100 then
begin
intX:=FcolumnNum div 10;
intY:=FcolumnNum mod 10;
FcolumnNum:=FcolumnNum+1;
NLabel[FcolumnNum]:=TLabel.Create(self);
with NLabel[FcolumnNum] do
begin
parent:=self;
top:=intX*20+5;
left:=intY*30+5;
height:=20;
width:=30;
caption:=inttostr(FcolumnNum);
invalidate;
end;
end;
end;
end.
 
不Free Label都可以因为系统自动的会通过Panel去Free
 
xgz_ball,好像不行,如果我不free Tabel的话,每次关闭project都出错
 
procedure TLabelPanel.addLabel;
var intX,intY:integer;
begin
if FcolumnNum<100 then
begin
intX:=FcolumnNum div 10;
intY:=FcolumnNum mod 10;
//这一句有问题,FcolummNum从1开始了,应该放到TLabel.Create(self)的后面!!!!!!!!!!
FcolumnNum:=FcolumnNum+1;
NLabel[FcolumnNum]:=TLabel.Create(self);
with NLabel[FcolumnNum] do
begin
parent:=self;
top:=intX*20+5;
left:=intY*30+5;
height:=20;
width:=30;
caption:=inttostr(FcolumnNum);
invalidate;
end;
end;
end;
 
谢谢donkey了,我也一直想在这里有问题,但一直疏忽了,但是Caption为什么不能为空呢,
你的分我会在全部解决后给你的,欢迎继续解答
 
>>但是Caption为什么不能为空呢,
我不明白你说的什么意思?有什么异常的表现吗?
 
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls;

type
TLabelPanel = class(TPanel)
private
FcolumnNum:integer;//表示现在存在的Label个数;最大不可以超过100
{ Private declarations }
protected
{ Protected declarations }
public
NLabel:array[0..99] of TLabel;
procedure addLabel; //在Paenl上增加一个Label;
constructor create(Aowner:Tcomponent);override;
destructor destroy;override;
{ Public declarations }
published
{ Published declarations }
end;
TForm1 = class(TForm)
Button1: TButton;
Edit1: TEdit;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
LabelPanel:TLabelPanel;
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

constructor TLabelPanel.create(Aowner:Tcomponent);
begin
inherited create(Aowner);
{ self.caption:='';
self.Width:=600;
self.Height:=480;
FcolumnNum:=0;
self.invalidate;}
//改成下面的代码,简练一些:
caption:='';
Width:=600;
Height:=480;
FcolumnNum:=0;
//self.invalidate;
//因为还在创建,没有显示,所以invalidate不仅没有用,反而可能出错.
end;

destructor TLabelPanel.destroy ;
var intI:integer;
begin
if FcolumnNum>0 then
begin
//showmessage(inttostr(FcolumnNum));
for intI:=0 to FcolumnNum-1 do
begin
NLabel[intI].Free;
// invalidate;
//同样释放的时候控件也是不显示的,不用invalidate方法的.
//invalidate方法主要是刷新控件显示的.
end;
end;
//其实上面这段代码不要也可以,因为Self会自动释放它的Controls和Components.
inherited destroy;
end;

procedure TLabelPanel.addLabel;
var intX,intY:integer;
begin
if FcolumnNum<100 then
begin
intX:=FcolumnNum div 10;
intY:=FcolumnNum mod 10;
NLabel[FcolumnNum]:=TLabel.Create(self);
with NLabel[FcolumnNum] do
begin
parent:=self;
top:=intX*20+5;
left:=intY*30+5;
height:=20;
width:=30;
caption:=inttostr(FcolumnNum);
//invalidate;
//这里也不用invalidate方法的,改变Label的各种属性的时候会自动调用invalidate方法.
//而且这里赋了Left,Top,Height,Width四个属性,会Refresh四次,
//而如果用SetBounds(intY*30+5,intX*20+5,30,20);则只需Refresh一次.
end;
FcolumnNum:=FcolumnNum+1;
end;
end;

procedure TForm1.Button1Click(Sender: TObject);
Var i:Integer;
begin
For i:=0 to 99 do
LabelPanel.addLabel;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
LabelPanel:=TLabelPanel.create(Self);
LabelPanel.Parent:=Self;
end;

end.
 
caption:=inttostr(FcolumnNum);
改为caption:=' ';不行吗?应该可以的吧
 
来如风,你误会了,我说的不是Label的caption,而是TLabelPanel的caption,
我的TLabelPanel的consctructor create事件上写有:
constructor TLabelPanel.create(Aowner:Tcomponent);
begin
inherited create(Aowner);
caption:='';
end;
但是不知道为何TLabelPanel的值总是显示在TLabelPanel上呢,而且默认是跟TLabelPanel的
Name值是一样的
 
留下你的箱子,我把你的代码的演示代码发给你,没发现问题.
 
我的箱子是wthua@sohu.com
 
我做过一个控件用的是tpanel(self).caption='';没发现有问题
 
很久了,谢谢你帮我解答这个问题
 
后退
顶部