-
Доброго времени суток!!!
Столкнулся с проблемой....
Суть: мне необходимо сделать свой компонент для моего приложения для автоматики .. Компонент - это некий "примитив"
включающий в себя панельку.. и на панельки например - метку...
...
и необходимо чтобы наследовался допустим только цвет панельки и метки (т.е чтобы можно было его менять)
мой код: (который чо - то не работает)
===========
unit SSFSLoop;
interface
uses
SysUtils, Classes, Controls, ExtCtrls,StdCtrls,Graphics;
type
TSSFSLoop = class(TCustomPanel)
private
{ Private declarations }
FLabel: TLabel;
protected
{ Protected declarations }
public
{ Public declarations }
constructor Create(AOwner:TComponent); override;
published
{ Published declarations }
property Color;
end;
procedure Register;
implementation
procedure Register;
begin
RegisterComponents('my', [TSSFSLoop]);
end;
constructor TSSFSLoop.Create(AOwner:TComponent);
begin
inherited Create(AOwner);
FLabel := TLabel.Create(Self);
FLabel.Parent:=Self;
FLabel.Left:=1;
FLabel.Top:=1;
FLabel.Visible:=true;
end;
end.
=======
при установке этого компонента и переноса его на форму - на форме отображается только Panel ... Но метки нету почему то!!!
Если же я вместо FLabel := TLabel.Create(Self);
пищу FLabel := TLabel.Create(AOwner);
то метка появляется... но без ИМЕНИ !!!
В общем я хочу сделать некий компонент TLOOP (к примеру)
- панелька у которой была метка.. и при перетаскивании на форму много "моих" компонентов - чтобы ИМЯ метки не менялось!! (т.е как назвал я ее так шоб она и оставалась) ..
---
Подскажите.. можно ли так сделать ???
-
пардон...
метка создается... но недоступны ее сфойства (например мне нада Caption сменить программно или цвет метки) как мне в таком случае написать код компонента?
-
опс.. все .. вроде разобрался...
надо просто
FLabel: TLabel; - в public написать :)
-
> но недоступны ее сфойства (например мне нада Caption сменить
> программно или цвет метки) как мне в таком случае написать
> код компонента?
А чего вдруг свойства метки должны быть доступны, если сама метка у тебя в private?
-
type
TSSFSLoop = class(TCustomPanel)
private
FLabel: TLabel;
public
constructor Create(AOwner:TComponent); override;
property Label: TLabel read FLabel;
published
property Color;
end;
constructor TSSFSLoop.Create(AOwner:TComponent);
begin
inherited;
FLabel := TLabel.Create(Self);
FLabel.Parent := Self;
FLabel.Left := 1;
FLabel.Top := 1;
end;
-
Вдогонку - это в случае, когда метка должна быть доступна только в коде (как Вы и гооворили). Если же она (или ее отдельные свойства) должны быть доступны еще и в Object Inspector, то это тоже возможно, но немного иначе. Как именно - это зависит от того, что конкретно должно быть доступно.
-
Что бы ваша метка была доступна в инспекторе, вынесите её в секцию published, а в конструкторе сделайте SetSubComponent
TSSFSLoop = class(TCustomPanel)
private
FLabel: TLabel;
protected
public
constructor Create(AOwner:TComponent); override;
published
property Color;
property Label: TLabel read fLabel write SetLabel;
end;
constructor TSSFSLoop.Create(AOwner:TComponent);
begin
inherited;
FLabel := TLabel.Create(Self);
FLabel.Parent := Self;
FLabel.Left := 1;
FLabel.Top := 1;
fLabel.Caption := 'Test Caption';
fLabel.SetSubComponent (true);
end;
метод SetLabel может быть и пустой, главное что бы он был, иначе свойства метки записываться не будет.
-
Большое вам спасибо!!!! ОГромное...!!!
А то я книгами обложился.... Инфы много.. а времени нету для изучения!!
Еще раз.. спасибо!!
Но у меня еще вопросик есть..
Например я сделал этот компонент.. добавив в код след.. изменения при создании панели:
------
constructor TSSFSLoop.Create(AOwner:TComponent);
begin
inherited Create(AOwner);
Width:=98;
Height:=37;
AutoSize:=True;
Caption:='';
TabOrder:=0;
//Invalidate;
//
//SetupInternal;
end;
-------
т.е указал чтобы сво-во Caption было пустым... Но при перетаскивании компонента на форму - в свойстве Caption почему-то появляется имя компонента???? А мне нада шоб там пусто было!!!
Помогите пожалуйста разобраться. :)
-
Вместо Caption:='' напишите:
ControlStyle := ControlStyle - [csSetCaption];
Подробности в справке по TControl.
-
Спс.. но до конца у меня не получается что то..
т.е. компонент когда я перетаскиваю на форму - то его размер равен дефолтному размеру панели... но если цепляю мышкой на форме его и перетаскиваю (смещаю немного) то - размер подстраивается как надо сам 8-/
НО... потом когда я компилю проект - то при работающем приложении размер опять становится по дефолту 8-(
Вопрос:
что мне изменить в коде компонента - чтобы при его создании его размер автоматически подстраивался под размеры его внутренностей..
вот код:
-------------
unit SSFSLoop;
interface
uses
SysUtils, Classes, Controls, ExtCtrls,StdCtrls,Graphics;
const
MAX_EV = 6;//
type
TSSFSLoop = class(TCustomPanel)
private
{ Private declarations }
FLoopTitle :TCustomLabel;
FLoopEvents :TPanel;
FaEv :array [1..MAX_EV] of TShape;
protected
{ Protected declarations }
public
{ Public declarations }
constructor Create(AOwner:TComponent); override;
procedure SetupInternal;
property LoopTitle: TCustomLabel read FLoopTitle;
property LoopEvents: TPanel read FLoopEvents;
property EvWarning: TShape read FaEv[1];
property EvAlarm: TShape read FaEv[2];
property EvButton: TShape read FaEv[3];
property EvFault: TShape read FaEv[4];
property EvShortCircuit: TShape read FaEv[5];
property EvBreakage: TShape read FaEv[6];
published
{ Published declarations }
end;
procedure Register;
implementation
procedure Register;
begin
RegisterComponents('Realteh', [TSSFSLoop]);
end;
constructor TSSFSLoop.Create(AOwner:TComponent);
begin
inherited Create(AOwner);
ControlStyle:=ControlStyle-[csSetCaption];
SetupInternal;
AutoSize:=True;
end;
{**}
procedure TSSFSLoop.SetupInternal;
var
i :Integer;
begin
//создаем title
if Assigned(FLoopTitle) then exit;
FLoopTitle:=TCustomLabel.Create(Self);
with FLoopTitle do begin
Parent:=Self;
Left:=1;
Top:=1;
Caption:='';
AutoSize:=True;
end;//with
//создаем events панель
if Assigned(FLoopEvents) then exit;
FLoopEvents:=TPanel.Create(Self);
with FLoopEvents do begin
Parent:=Self;
Left:=1;
Top:=20;
BevelOuter:=bvLowered;
BevelWidth:=2;
AutoSize:=true;
end;//with
//создаем все 6 ev
for i:=1 to MAX_EV do begin
if Assigned(FaEv[i]) then exit;
FaEv[i]:=TShape.Create(Self);
with FaEv[i] do begin
Parent:=FLoopEvents;
Constraints.MaxWidth:=15;
Constraints.MaxHeight:=15;
Shape:=stRoundSquare;
Align:=alLeft;
end;//with
end;//for
end;
end.
------------
Подскажите пожалуйста ...
-
Установить свой размер
-
блина..
когда пишу
---
constructor TSSFSLoop.Create(AOwner:TComponent);
begin
inherited Create(AOwner);
Height:=100;
Width:=100;
ControlStyle:=ControlStyle-[csSetCaption];
SetupInternal;
//AutoSize:=True;
end;
----
то все равно компонент получается размером с панельку по умолчанию ((
-----
да я и не знаю точно какой мне нужен размер компонента... этот размер должен высчитываться автоматически при создании компонента как то
-
Ох, если бы я вас понял ......
Подсчитайте размер всех ваших контролов, и установите размеру панели.
-
:)
в общем решилось так:
+++++++++++
unit SSFSLoop;
interface
uses
SysUtils, Classes, Controls, ExtCtrls,StdCtrls,Graphics;
const
MAX_EV = 6;//
type
TSSFSLoop = class(TCustomPanel)
private
{ Private declarations }
FSubLabel :TCustomLabel;
FSubPanel :TPanel;
FaEv :array [1..MAX_EV] of TShape;
procedure SetupInternal;
protected
{ Protected declarations }
public
{ Public declarations }
constructor Create(AOwner:TComponent); override;
property LoopTitle : TCustomLabel read FSubLabel;
property EvWarning : TShape read FaEv[1];
property EvAlarm : TShape read FaEv[2];
property EvButton : TShape read FaEv[3];
property EvFault : TShape read FaEv[4];
property EvShortCircuit : TShape read FaEv[5];
property EvBreakage : TShape read FaEv[6];
published
{ Published declarations }
property Color;
property AutoSize;
property Width;
property Height;
property OnClick;
end;
procedure Register;
implementation
procedure Register;
begin
RegisterComponents('Realteh', [TSSFSLoop]);
end;
constructor TSSFSLoop.Create(AOwner:TComponent);
begin
inherited Create(AOwner);
ControlStyle:=ControlStyle-[csSetCaption];
SetupInternal;
end;
{**}
procedure TSSFSLoop.SetupInternal;
var
i :Integer;
begin
//создаем title
if Assigned(FSubLabel) then exit;
FSubLabel:=TCustomLabel.Create(Self);
FSubLabel.Parent:=Self;
FSubLabel.Left:=1;
FSubLabel.Top:=1;
FSubLabel.Caption:='';
//создаем events панель
if Assigned(FSubPanel) then exit;
FSubPanel:=TPanel.Create(Self);
FSubPanel.Parent:=Self;
FSubPanel.Left:=1;
FSubPanel.Top:=20;
FSubPanel.BevelOuter:=bvLowered;
FSubPanel.BevelWidth:=2;
FSubPanel.AutoSize:=true;
//создаем все 6 ev
for i:=1 to MAX_EV do begin
if Assigned(FaEv[i]) then exit;
FaEv[i]:=TShape.Create(Self);
FaEv[i].Parent:=FSubPanel;
FaEv[i].Constraints.MaxWidth:=15;
FaEv[i].Constraints.MaxHeight:=15;
FaEv[i].Shape:=stRoundSquare;
FaEv[i].Align:=alLeft;
end;//for
end;
end.
+++++++++++++++
т.е
1) в конструкторе
constructor TSSFSLoop.Create(AOwner:TComponent);
я не указываю ни длины ни ширины панели TSSFSLoop ни его св-ва AutoSize (т.к. по деволту оно false)
2) при перетаскивании компонента на форму - его размеры (т.е размеры панельки TSSFSLoop ) получаются дефолтными (меня это не устраивает)
3) в инспекторе ставлю св-во AutoSize:=true (компонент на форме автоматически подгоняется под необходимые размеры)
4) потом в инспекторе ставлю AutoSize:=false
5) компилю проект
и в итоге - на форме размер моего компонента такой какой мне нужен...
ЗЫ: я просто хотел чтобы СРАЗУЖЕ при перетаскивании компонента на форму - его размер сразу становился таким каким надо :) (шоб в инспекторе не мудохацца с false/true) и ваабще - размер компонента меняться не должен!!!
Ну.. как я сделал - так сделал.. и так сайдет :)
Всем спасибо кто отозвался!!!! Респект и уважуха!!!