如何制作组合控件 ( 积分: 100 )

  • 主题发起人 主题发起人 sunjunfeng3
  • 开始时间 开始时间
S

sunjunfeng3

Unregistered / Unconfirmed
GUEST, unregistred user!
我要制作一个组合类型介面控件,把多个现有的一些介面控件TEdit,TButton,TMemo等放在一起,做一个可复用的登录窗口,就跟c#的用户控件一样,
我尝试用TPanel继承一个新类,类是设计的时候却没有可视化窗体,有没有其它的好办法
 
这是一个实例,然后根据你自己的需要调整适合自己业务需要的部份。
unit DatePick;

interface

uses windows,messages,classes,forms,stdctrls,buttons,controls,sysutils;

Type TDatePick = class(TWinControl)
private
FEdit : TEdit;
Fspbt : TSpeedButton;
//FBHeight:integer;
procedure FSetSpbtHeight(Value:integer);
function FGetSpbtHeight:integer;

procedure FSetSpbtTop(Value:integer);
function FGetSpbtTop:integer;

procedure FSetEditText(Value:string);
function FGetEditText:string;

procedure FSetReadonly(Value:boolean);
function FGetReadonly:boolean;

procedure FOnSpbtClick(Sender:TObject);
procedure FSetChange(Value:TNotifyEvent);
function FGetChange:TNotifyEvent;
procedure WMSize(var msg:TWMSize); message WM_Size;
public
constructor create(aOwner:Tcomponent);override;
destructor Destroy;override;
published

property ctl3d;
property BHeight:integer read FGetSpbtHeight write FSetSpbtHeight;
property BTop :integer read FGetSpbtTop write FSetSpbtTop;
property Text : string read FGetEditText Write FSetEditText;
property ONDateChange:TNotifyEvent read FGetChange write FSetChange;
property TextReadOnly:boolean read FGetReadonly write FSetReadonly default true;
property TabOrder;
//property TEdit.Fonts;
end;

procedure Register;

implementation

uses SelDateR;



{$R DATEPICK.RES}


constructor TDatePick.create(aOwner:Tcomponent);
begin
inherited Create(aOwner);

FEdit := TEdit.Create(self);
FEdit.Width := 75;
FEdit.Height := 19;
FEdit.Text := '';//DateTostr(now);
FEdit.Parent := self;//TWinControl(aOwner);
FEdit.Visible := true;
FEdit.Ctl3D := false;
FEdit.ReadOnly := true;


//FEdit.Top := self.Top;
//FEdit.Left := self.Left;

self.Height := self.FEdit.Height +2;

Fspbt := TSpeedButton.Create(self);
Fspbt.Width := 22;

Fspbt.Height := 19;
Fspbt.Left := self.FEdit.Left + self.FEdit.Width+1;
Fspbt.Top := self.FEdit.Top;
Fspbt.Parent := self;//TWinControl(aOwner);
Fspbt.Visible := true;
Fspbt.Glyph.LoadFromResourceName(HInstance,'SPBTBMP');
Fspbt.OnClick := self.FOnSpbtClick;

width := self.FEdit.Width+self.Fspbt.Width+1;
height := self.FEdit.Height;
// Fspbt.NumGlyphs := 1;
end;

destructor TDatePick.Destroy;
begin
FEdit.Parent := nil;
FEdit.Free;
Fspbt.Parent := nil;
Fspbt.Free;
inherited;
end;

procedure TDatePick.FOnSpbtClick(sender:Tobject);
begin
with TPickJSDate.Create(nil) do
try
if self.FEdit.Text <> '' then
sDt := self.FEdit.Text
else
sDt := DateTostr(now);
if showmodal = mrok then
begin
self.FEdit.Text := sDt
end;
self.FEdit.SetFocus;
finally
free;
end;
end;


procedure TDatePick.FSetChange(Value:TNotifyEvent);
begin
self.FEdit.OnChange := Value;
end;

{ 设置 spbt 的高度 }
procedure TDatePick.FSetSpbtHeight(Value:integer);
begin
self.Fspbt.Height := Value;
end;

function TDatePick.FGetSpbtHeight;
begin
result := self.Fspbt.Height;
end;


function TDatePick.FGetChange:TNotifyEvent;
begin
result := self.FEdit.OnChange;
end;

procedure TDatePick.WMSize(var msg:TWMSize);
begin
inherited;
self.FEdit.Width := msg.Width-self.Fspbt.Width;
self.Fspbt.Left := self.FEdit.Width;
self.FEdit.Height := msg.Height;
// self.Fspbt.Width := msg.Width;
self.Fspbt.Height := msg.Height;

end;

{ 设置 spbt 的 top }
procedure TDatePick.FSetSpbtTop(Value:integer);
begin
self.Fspbt.Top := value;

end;

function TDatePick.FGetSpbtTop:integer;
begin
result := self.Fspbt.Top;
end;

{ 设置 Edit 的 Text }
procedure TDatePick.FSetEditText(Value:string);
begin
{try
StrToDate(Value)
except
messagebox(self.Handle,pchar('无效的日期'),pchar('提示'),mb_ok+mb_applmodal);
exit;
end;
}
self.FEdit.Text := Value;
end;

function TDatePick.FGetEditText:string;
begin
result := self.FEdit.Text;
end;

{ 设置 TextRealonly 属性 }
procedure TDatePick.FSetReadonly(value:boolean);
begin
self.FEdit.ReadOnly := value;
end;

function TDatePick.FGetReadonly:boolean;
begin
result := self.FEdit.ReadOnly;
end;

procedure Register;
begin
RegisterComponents('System',[TDatePick]);
end;



end.
 
楼上的,请问控件的坐标是如何调的?难道要一点一点自己去对,设计控件的时候不能可视化地拖拉吗
 
是可视控件呀。
建立包然后编译再安装,就像DELPHI上面的控件一样设置了。
 
我是说在设计可视化控件的时候,看不到介面效果啊,并不是说在使用控件的时候,
比如我要设计一个新控件,里面要放四个TEDIT控件,放成田形,以后使用这个控件的时候,直接拖下来就有四个田形的TEDIT了,关键是在设计这个控件的时候,坐标如何调,因为设计的时候看不到控件的可能效果,只在调下坐标,运行一下看效果再调,如果控件多了要累死
 
写控件确实很好
不过还是换个思路更好
封装可视化业务的,需要用界面类,你的选择是定义成TPanel的子类
我认为定义为TForm的子类是最合适的,不要以为,窗体就是不是控件,窗体继承于TForm,向上看还有TWinControl,TComponent,是根正苗红的控件,想组合什么东西,还不是随心所欲?
窗体也可以放在dpk中编译,但不要注册到控件面板,需要的时候uses一下,就可以了
你认为这个折衷如何?
 
并且,还有一个好处,这样就可以实现所见即所得了
 
谢谢大家的回答,不过发现大家都走弯路,不知道是否没有理解我的意思,我发现delphi有比c#更强大的组合控件支持能力 就是TFrame 这个框架对象,太强了
把要的控件拖到上面,并且可以加到控件面板,要的时候再拖,并且拖出来的控件它里面的子控件还可以直接操作,太强了,c#都不能对封闭好的组合控件使用的时候再控件它的子控件,delphi就可以,通过调用一次控件的方法,再向外面提供调用函数
 
后退
顶部