一个简单的控件开发,请帮忙,谢谢!(100分)

  • 主题发起人 主题发起人 qcchan
  • 开始时间 开始时间
Q

qcchan

Unregistered / Unconfirmed
GUEST, unregistred user!
我想从TPanel继承来生成一个控件,它是一个TPanel加了两个属性,一个是FDyImage :TImage;和FDyLabel :TLabel;,我想对这两个属性赋值后在TPanel能够显示这个图片和标签。下面是我的代码:)不好意思,水平不行,别见笑,DELPHI用了好几年,但从没写过控件,,请高手帮我写一下,万分感谢!!!
unit MyPanel;

interface

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

type
TMyPanel = class(TPanel)
private
FPanelCount:Integer;
FDyImage :TImage;
FDyLabel :TLabel;
protected
public
constructor Create(AOwner: TComponent); override;
destructor Destroy(); override;
published
property PanelCount: Integer read FPanelCount write FPanelCount default 1;
property DyImage: TImage read FDyImage write FDyImage;
property DyLabel: TLabel read FDyLabel write FDyLabel;
end;

procedure Register;

implementation

procedure Register;
begin
RegisterComponents('Standard', [TMyPanel]);
end;

constructor TMyPanel.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
//初始化基类值

Width := 75;
Height := 25;
FPanelCount:=10;;//这个是用来测试一下用的:)
//下面两个是用来创建对象两个用的,我想
//把它们放在Panel上,好象不对:(
FDyImage:=TImage.Create(AOwner);
FDyImage.Parent:=self ;
FDyImage.Width :=50 ;
FDyImage.Height :=50 ;
FDyImage.Top:=0 ;
FDyImage.Left:=0 ;

FDyLabel :=TLabel.Create(AOwner);
FDyLabel.Parent:=self ;
FDyLabel.Caption :='dfdfd';
FDyLabel.Top:=60 ;
FDyLabel.Left:=0 ;
Repaint;
end;


destructor TMyPanel.Destroy;
begin
inherited;
end;

end
 
我这儿有一段代码,你可以参考参考:
动态添加控件:
procedure TForm1.Button1Click(Sender: TObject);
var button:tbutton;
begin
button:=tbutton.Create(self);
button.Parent:=self;
button.Left:=20;
button.Top:=20;
button.Caption:='sdf';
button.OnClick:=buttonclick;
end;

给动太生成的控件增加响应事件:
1、先在程序开始部份加对过程的说明:
procedure buttonclick(sender:tobject);
2、增加该控件的响应事件:
procedure TForm1.buttonClick(Sender: TObject);
begin
showmessage('我是被动太创建的');
end;
 
to 卡门
我不仅仅是要动态创建对象,我是想用户在对这两个属性赋值后,能显示到这个控件上,而,比如我有一个Tiamge和Tlabel在表单上,我把他们赋值到我做的这个控件上,然后也能显示出来
 
unit MyPanel;

interface

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

type
TMyPanel = class(TPanel)
private
FPanelCount:Integer;
FDyImage :TImage;
FDyLabel :TLabel;
protected
public
constructor Create(AOwner: TComponent); override;
destructor Destroy(); override;
published
property PanelCount: Integer read FPanelCount write FPanelCount default 1;
property DyImage: TImage read FDyImage write FDyImage;
property DyLabel: TLabel read FDyLabel write FDyLabel;
end;

procedure Register;

implementation

procedure Register;
begin
RegisterComponents('Standard', [TMyPanel]);
end;

constructor TMyPanel.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
//初始化基类值
Width := 75;
Height := 25;
FPanelCount:=10;//这个是用来测试一下用的:)
//下面两个是用来创建对象两个用的,我想
//把它们放在Panel上,好象不对:(
FDyImage:=TImage.Create(AOwner);
with FDyImage do
begin
Parent := Self;//你不能把这个漏了,除非你用其它API来替代,如果控件还有个Panel,则Self用Panel替代。
Visible:=True;
Top:=10 ;
Left:=10 ;
end;

FDyLabel :=TLabel.Create(AOwner);
//参考上面
// Repaint; 这句无效,控件还没有创建完毕,怎么这就执行重画?
end;


destructor TMyPanel.Destroy;
begin
FDyImage.free; //要释放,避免引起内存泄漏
FDyLabel.free;
inherited Destroy;
end;

end.

写这种控件要小心,因为不是什么控件都能正确放在其他控件上面的,有些隐性缺陷,
会使画面混乱,热键冲突,丧失功能,要充分测试再用。
 
要将外部控件显示到自己的控件,不需要自制控件,任何有句柄的控件都可以做底盘,
设置Parent:=你的控件,再定位即可。
如果做一个控件,装载外部控件,也不费吹灰之力。
首先 property DyImage: TImage read FDyImage write FDyImage;
改成 property DyImage: TImage read FDyImage write SetDyImage;
再在 procedure ***.SetDyImage(ADyImage: TImage);
begin
FDyImage:= ADyImage;
if FDyImage <> nil then //需要检查用户是否指定了有效的控件
with FDyImage do
begin
Parent := Self;
Visible:=True;
Top:=10 ;
Left:=10 ;
end;
end;
这样就可以显示出来,但有三个问题,首先:要拦截一些事件来检测用户是否中途杀掉他指定的控件,或者将控件重新指定给其它控件,如果省掉这步,程序不稳定,甚至崩溃,第二:如果在编程时,在属性指定控件,Delphi的IDE不一定会帮你保存,虽然可以覆盖ReadState等几个函数来保存,但效果是很有限的。第三,如果指定的控件本身又是复合控件,则不一定正确能显示,IDE也不保存,对付IDE不保存,只有在运行之后指定。
其实这种复合控件很难写好的,特别是要将控件写的坚强,其实连Delphi自己的Samples页里面的控件也写得很糊涂,看来楼主还是找高手去吧。
 
从TGraphicControl继承下来,
覆盖Paint方法,绘制所需要的东东。
 
kinneng 的提示很重要,防止内存泄露,谢谢了
这个问题总算解决了一大半,我用
myPanels.DyLabel.Color :=clwhite;
myPanels.DyLabel.Alignment:=taCenter;
myPanels.DyLabel.Caption :=inttostr(i);

myPanels.DyImage.Picture :=image1.Picture ;
myPanels.DyImage.Width :=width;
myPanels.DyImage.Height :=height;

myPanels.PopupMenu :=PopupMenu;
方式来做的,测试了一下好象没问题,这个控件我是想用来代替DBCTRLGRID,因为我的数据不是从数据库取的,以前是的,现在是从WEBSERVICE取的对象数组。有个问题,弹出菜单时我怎么知道是哪个TMyPanel对象上弹出的呢?我怎么取这个对象上的属性呢?
我现在在考虑做一个能代替DBGRID的控件,当然不用模仿它所有功能,能显示出来就行,而且想在每条记录后面加上一个复选框,能给我一些建议吗?最好给点代码:)
 
这样就能知道弹出菜单时是哪个TMyPanel对象上弹出的:)
ActivemyPanels:=PopupMenu.PopupComponent as TMyPanel;
showmessage(ActivemyPanels.DyLabel.Caption );
 
我现在在考虑做一个能代替DBGRID的控件,当然不用模仿它所有功能,能显示出来就行,而且想在每条记录后面加上一个复选框,能给我一些建议吗?最好给点代码:)
 

Similar threads

后退
顶部