Конференция "Компоненты" » Создание сложного компонента (составного)
 
  • kuzulis © (25.03.08 15:54) [0]
    Доброго времени суток!!!

    Столкнулся с проблемой....
    Суть: мне необходимо сделать свой компонент для моего приложения для автоматики .. Компонент - это некий "примитив"
    включающий в себя панельку.. и на панельки например - метку...
    ...
    и необходимо чтобы наследовался допустим только цвет панельки и метки (т.е чтобы можно было его менять)

    мой код: (который чо - то не работает)
    ===========
    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 (к примеру)
    - панелька у которой была метка.. и при перетаскивании на форму много "моих" компонентов - чтобы ИМЯ метки не менялось!! (т.е как назвал я ее так шоб она и оставалась) ..

    ---

    Подскажите.. можно ли так сделать ???
  • kuzulis © (25.03.08 16:06) [1]
    пардон...

    метка создается... но недоступны ее сфойства (например мне нада Caption сменить программно или цвет метки)  как мне в таком случае написать код компонента?
  • kuzulis © (25.03.08 16:10) [2]
    опс.. все .. вроде разобрался...
    надо просто

      FLabel:  TLabel; - в public  написать :)
  • DVM © (25.03.08 16:12) [3]

    > но недоступны ее сфойства (например мне нада Caption сменить
    > программно или цвет метки)  как мне в таком случае написать
    > код компонента?

    А чего вдруг свойства метки должны быть доступны, если сама метка у тебя в private?
  • Семеныч (25.03.08 17:34) [4]
    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;
  • Семеныч (25.03.08 17:38) [5]
    Вдогонку - это в случае, когда метка должна быть доступна только в коде (как Вы и гооворили). Если же она (или ее отдельные свойства) должны быть доступны еще и в Object Inspector, то это тоже возможно, но немного иначе. Как именно - это зависит от того, что конкретно должно быть доступно.
  • DimaBr © (26.03.08 08:46) [6]
    Что бы ваша метка была доступна в инспекторе, вынесите её в секцию published, а в конструкторе сделайте SetSubComponent


    TSSFSLoop = class(TCustomPanel)
    private
      { Private declarations }
      FLabel:  TLabel;
    protected
      { Protected declarations }
    public
      { Public declarations }
      constructor Create(AOwner:TComponent); override;    
    published
      { Published declarations }
      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 может быть и пустой, главное что бы он был, иначе свойства метки записываться не будет.
  • kuzulis © (26.03.08 09:10) [7]
    Большое вам спасибо!!!! ОГромное...!!!

    А то я книгами обложился.... Инфы много.. а времени нету для изучения!!
    Еще раз.. спасибо!!

    Но у меня еще вопросик есть..
    Например я сделал этот компонент.. добавив в код след.. изменения при создании панели:
    ------
    constructor TSSFSLoop.Create(AOwner:TComponent);
    begin
     inherited Create(AOwner);
     Width:=98;
     Height:=37;
     AutoSize:=True;
     Caption:='';
     TabOrder:=0;
     //Invalidate;
     //
     //SetupInternal;
    end;
    -------
    т.е указал чтобы сво-во Caption было пустым... Но при перетаскивании компонента на форму - в свойстве Caption почему-то появляется имя компонента???? А мне нада шоб там пусто было!!!

    Помогите пожалуйста разобраться. :)
  • Семеныч (26.03.08 10:30) [8]
    Вместо Caption:='' напишите:
    ControlStyle := ControlStyle - [csSetCaption];

    Подробности в справке по TControl.
  • kuzulis © (26.03.08 12:11) [9]
    Спс.. но до конца у меня не получается что то..

    т.е.  компонент когда я перетаскиваю на форму - то его размер равен дефолтному размеру панели... но если цепляю мышкой на форме его и перетаскиваю (смещаю немного) то - размер подстраивается как надо сам 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.
    ------------

    Подскажите пожалуйста ...
  • DimaBr © (26.03.08 13:26) [10]
    Установить свой размер
  • kuzulis © (26.03.08 13:54) [11]
    блина..

    когда пишу
    ---
    constructor TSSFSLoop.Create(AOwner:TComponent);
    begin
    inherited Create(AOwner);
    Height:=100;
    Width:=100;
    ControlStyle:=ControlStyle-[csSetCaption];
    SetupInternal;
    //AutoSize:=True;
    end;
    ----

    то все равно компонент получается размером с панельку по умолчанию  ((

    -----
    да я и не знаю точно какой мне нужен размер компонента... этот размер должен высчитываться автоматически при создании компонента как то
  • DimaBr © (26.03.08 14:44) [12]
    Ох, если бы я вас понял ......

    Подсчитайте размер всех ваших контролов, и установите размеру панели.
  • kuzulis © (26.03.08 14:55) [13]
    :)

    в общем решилось так:

    +++++++++++
    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) и ваабще - размер компонента меняться не должен!!!

    Ну.. как я сделал - так сделал.. и так сайдет :)

    Всем спасибо кто отозвался!!!! Респект и уважуха!!!
 
Конференция "Компоненты" » Создание сложного компонента (составного)
Есть новые Нет новых   [134464   +62][b:0][p:0.001]