На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! ПРАВИЛА РАЗДЕЛА · FAQ раздела Delphi · Книги по Delphi
Обязательно выделяйте текст программы тегом [сode=pas] ... [/сode]. Для этого используйте кнопку [code=pas] в форме ответа или комбобокс, если нужно вставить код на языке, отличном от Дельфи/Паскаля.

Этот раздел предназначен для вопросов, посвященных разработке компонентов, а также для тестирования собственных бесплатных компонентов с открытым исходным кодом.

Здесь запрещается:
1. Размещать ссылки на какие-либо коммерческие компоненты, реализующие требуемую функциональность.
2. Обсуждать и тестировать коммерческие компоненты или компоненты с закрытым кодом.
3. Давать ссылки на сайты с исходным кодом компонентов. Все тестируемые исходные коды должы быть размещены на сайте ИСХОДНИКИ.RU.
Модераторы: Rouse_, DimaBr
Страницы: (2) [1] 2  все  ( Перейти к последнему сообщению )  
> Глюк с Align у панели
    Вобщем, есть наследник от TPanel, на котором лежит сплиттер (не стандартный, но всё же...). Сплиттер постоянно имеет какой-то Align. И если сплиттер у меня alLeft, а я бросаю на компоненту какую-то другую компоненту и ставлю ей Align=alTop, то сплиттер... правильно, располагается ПОД компонентой, т.к. выравнивание сверху/снизу имеет более высокий приоритет, чем выравнивание слева/справа. Как эту радость обойти? Я пытался создать на панели ещё одну панельку, на которую собственно и будут кидаться все остальные компоненты в режиме конструктора (и создаваться в рантайме), но почему-то компоненты, которые я кидаю в дизайн-тайме, не записываются как находящиеся на этой панели и не отображаются (в DFM их НЕ видно как будто они НЕ находятся на форме; при чём если выйти из режима просмотра DFM то получим сообщение о том, что этой панельки типа вообще-то и нима, и не стоит ли её убрать).
    Как повлиять на ситуацию? Нужно чтобы если я установил сплитер справа, то он и занимал ВСЮ правую часть панели, игнорируя то, что какие-то компоненты могут быть заалигнены alTop/alBottom?

    Как создаю панельку? А вот так:
    ExpandedWrap disabled
        FContainer := TPanel.Create(Self);
        FContainer.Parent := Self;
        FContainer.BevelInner:=bvNone;
        FContainer.BevelOuter:=bvNone;
        FContainer.Align := alClient;
        FContainer.SetSubComponent(True);
    Сообщение отредактировано: --= Eagle =-- -
      Цитата --= Eagle =-- @
      Я пытался создать на панели ещё одну панельку, на которую собственно и будут кидаться все остальные компоненты в режиме конструктора (и создаваться в рантайме), но почему-то компоненты, которые я кидаю в дизайн-тайме, не записываются как находящиеся на этой панели и не отображаются (в DFM их видно как будто они находятся не на моей панели, а на той же форме, на которой и сама панель; при чём если выйти из режима просмотра DFM то получим сообщение о том, что этой панельки типа вообще-то и нима, и не стоит ли её убрать).

      Хм, ничего кроме отсутствующего в ControlStyle флага csAcceptControls не приходит в голову.
        Цитата Smike, 06.09.2006, 20:24:14, 1252858
        Хм, ничего кроме отсутствующего в ControlStyle флага csAcceptControls не приходит в голову.

        Не стояло. Но не помогаеть... :(

        Цитата --= Eagle =--, 06.09.2006, 19:16:17, 1252781
        в DFM их видно как будто они находятся не на моей панели, а на той же форме, на которой и сама панель;

        тут я ошибся - не добавляется оно на форму вообще!
          SetSubComponent случайно не мешает?
            Думаю нет... Когда я его не ставил - была та же ситуёвина...

            Добавлено
            З.Ы. csAcceptControls там походу по-умолчанию стоит...

            Добавлено
            З.З.Ы. Если хочешь - попробуй сам создать компоненту унаследованную от TPanel и создай на ней в конструкторе ещё одну понельку, допустим красного цвета. А потом попробуй в дизайн-тайме кинуть на этукомпоненту какой-то батон. У меня этот батон прописывается в .PAS, а в .DFM - нет...
              Цитата --= Eagle =-- @
              Если хочешь - попробуй сам создать компоненту унаследованную от TPanel и создай на ней в конструкторе ещё одну понельку, допустим красного цвета.

              Давно бы попробывал, но стоит Turbo Delphi, а там невозможна инсталляция компонентов...
                оффтоп:
                Цитата Smike, 06.09.2006, 21:49:02, 1252950
                Давно бы попробывал, но стоит Turbo Delphi, а там невозможна инсталляция компонентов...

                Хмм... я думал, ты уже о нём своё мнение составил... :) Неее... я таким извратом страдать не буду, если оно конфликтует с другой версией установленной делфы... У меня стояли D6, D7 и BDS2006 - и всё как не может быть гуд...
                  Цитата --= Eagle =-- @
                  Неее... я таким извратом страдать не буду, если оно конфликтует с другой версией установленной делфы... У меня стояли D6, D7 и BDS2006 - и всё как не может быть гуд...

                  Не конфликтует. Просто это естественное ограничение. Бесплатная версия Turbo-продукта не может быть одновременно инсталлирована с каким-то другим продуктом семейства Turbo или BDS 2006.

                  Завтра на работе поэкспериментирую с панелями, сейчас уже неохота переустанавливать ;)
                    Спасибо :)
                      Пока нарыл такой вот код:

                      ExpandedWrap disabled
                        unit RzPnlPnl;
                         
                        interface
                         
                        uses
                          SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
                          Forms, Dialogs, ExtCtrls;
                         
                        type
                          TSubPanel = class(TPanel)
                          protected
                            procedure ReadState(Reader: TReader); override;
                          end;
                         
                          TPanelPanel = class(TPanel)
                          private
                            FSubPanel: TSubPanel;
                          protected
                            procedure WriteComponents(Writer: TWriter); override;
                            procedure ReadState(Reader: TReader); override;
                          public
                            constructor Create(AOwner: TComponent); override;
                          end;
                         
                        procedure Register;
                         
                        implementation
                         
                        procedure TSubPanel.ReadState(Reader: TReader);
                        var
                          OldOwner: TComponent;
                        begin
                          OldOwner := Reader.Owner;
                            { Сохраняем старого владельца, что необходимо для PanelPanel }
                          Reader.Owner := Reader.Root; { Задаем в качестве владельца форму }
                          try
                            inherited ReadState(Reader);
                          finally
                            Reader.Owner := OldOwner;
                          end;
                        end;
                         
                        constructor TPanelPanel.Create(AOwner: TComponent);
                        const
                          Registered: Boolean = False;
                        begin
                          inherited Create(AOwner);
                         
                          FSubPanel := TSubPanel.Create(Self);
                          FSubPanel.Parent := Self;
                          FSubPanel.SetBounds(20, 20, 200, 100);
                          FSubPanel.Name := 'SomeName';
                         
                          if not Registered then
                          begin
                            Classes.RegisterClasses([TSubPanel]);
                              { так TSubPanel может храниться в файле формы }
                            Registered := True;
                          end;
                         
                        end;
                         
                        procedure TPanelPanel.ReadState(Reader: TReader);
                        var
                          OldOwner: TComponent;
                          I: Integer;
                        begin
                          for I := 0 to ControlCount - 1 do
                            Controls[0].Free;
                         
                          OldOwner := Reader.Owner;
                          Reader.Owner := Self;
                            {Для чтения субкомпонентов, установите данный экземпляр в качестве родителя}
                          try
                            inherited ReadState(Reader);
                          finally
                            Reader.Owner := OldOwner;
                          end;
                        end;
                         
                        procedure TPanelPanel.WriteComponents(Writer: TWriter);
                        var
                          I: Integer;
                        begin
                          for I := 0 to ControlCount - 1 do
                            Writer.WriteComponent(Controls[I]);
                        end;
                         
                        procedure Register;
                        begin
                          RegisterComponents('Samples', [TPanelPanel]);
                        end;
                         
                        end.


                      Походжу должен помочь, но пока вылетает с AV на этом участке:

                      ExpandedWrap disabled
                          try
                            inherited ReadState(Reader);
                          finally


                      процедуры WriteComponents у предков походу нету...

                      З.Ы. Делфи 6...
                      Сообщение отредактировано: --= Eagle =-- -
                        Млин, пару дней бьюсь над проблеммой - никакого результата... :wall: У кого-то есть хорошие идеи по поводу сабжа?
                          Все очень даже логично ;) Таким образом все будет работать:
                          ExpandedWrap disabled
                            unit Panel1;
                             
                            interface
                             
                            uses
                              Graphics, SysUtils, Classes, Controls, ExtCtrls;
                             
                            type
                              TPanel1 = class(TPanel)
                              private
                                FPanel: TPanel;
                              public
                                constructor Create(AOwner: TComponent); override;
                              end;
                             
                            procedure Register;
                             
                            implementation
                             
                            procedure Register;
                            begin
                              RegisterComponents('Samples', [TPanel1]);
                            end;
                             
                            { TPanel1 }
                             
                            constructor TPanel1.Create(AOwner: TComponent);
                            begin
                              inherited;
                             
                              FPanel := TPanel.Create(AOwner);
                              FPanel.Name := 'Subpanel';
                              FPanel.Align := alClient;
                              FPanel.Parent := Self;
                              FPanel.Color := clRed;
                              FPanel.SetSubComponent(True);
                            end;
                             
                            end.

                          То есть любой контрол, брошенный сверху на FPanel будет правильно добавляться, но вместе с тем он и сам будет прописываться в DFM. Это создаст другие проблемы, постоянно будут выскакивать лишние панели. Выходы есть. На данный момент вижу такие:
                          1) Присваивать каждому брошенному на форму компоненту SetSubComponent и сохранять их параметры вручную.
                          2) Создавать панель FPanel только в случае, если она не загружена из DFM.

                          Добавлено
                          Да, еще один выход: использовать фреймы вместо компонента.
                            Цитата Smike, 08.09.2006, 17:46:15, 1256009
                            2) Создавать панель FPanel только в случае, если она не загружена из DFM.

                            Не катит. Subpanel не должны быть sibling моей панели, т.е. не должна лежить на форме и быть прописаной в классе формы юнита, как в твоём примере...

                            Цитата Smike, 08.09.2006, 17:46:15, 1256009
                            1) Присваивать каждому брошенному на форму компоненту SetSubComponent и сохранять их параметры вручную.

                            Если обязательным условием для этого является чтобы компонента тоже находилась в классе формы, то это не подходит...

                            Цитата Smike, 08.09.2006, 17:46:15, 1256009
                            Да, еще один выход: использовать фреймы вместо компонента.

                            Если имеется в виду что фрейм нужно в дизайн-тайме кидать, то всё же это не подходит, хотя действительно работает без проблемм...
                              Вот такой вот код мне подкинули на Мастерах Делфи:
                              ExpandedWrap disabled
                                unit Panels;
                                 
                                interface
                                uses Classes, ExtCtrls,Controls;
                                 
                                type
                                TMyPanel = class(TCustomPanel)
                                 private
                                   fPanel: TPanel;
                                 public
                                   constructor Create(AOwner: TComponent);override;
                                   destructor Destroy;override;
                                   procedure GetChildren(Proc: TGetChildProc; Root: TComponent);override;
                                   procedure Loaded;override;
                                   procedure SetParent(AParent: TWinControl);override;
                                end;
                                 
                                procedure Register;
                                implementation
                                 
                                procedure Register;
                                begin
                                 RegisterComponents('Standard',[TMyPanel]);
                                end;
                                 
                                constructor TMyPanel.Create(AOwner: TComponent);
                                begin
                                 inherited Create(AOwner);
                                 fPanel := TPanel.Create(self);
                                 Width := 200;
                                 Height := 200;
                                end;
                                 
                                destructor TMyPanel.Destroy;
                                begin
                                 FreeAndNil(fPanel);
                                 inherited;
                                end;
                                 
                                procedure TMyPanel.GetChildren(Proc: TGetChildProc; Root: TComponent);
                                var i: integer;
                                begin
                                inherited GetChildren(Proc,Root);
                                for i := 0 to fPanel.ControlCount - 1 do begin
                                  Proc( fPanel.Controls[i] );
                                end;{for}
                                end;
                                 
                                procedure TMyPanel.Loaded;
                                var i: integer;
                                begin
                                 inherited Loaded;
                                 for i :=  ControlCount-1 downto 0 do begin
                                   if (Controls[i] <> fPanel) then Controls[i].Parent := fPanel;
                                 end;{for}
                                end;
                                 
                                procedure TMyPanel.SetParent(AParent: TWinControl);
                                begin
                                 inherited;
                                 if fPanel <> nil then fPanel.Parent := self;
                                end;
                                 
                                end.

                              Это работает. Хотя, правда говоря, неудобно, что компоненты, которые я кидаю в дизайнтайме не отображаются как находящиеся на панели (т.е. в Object TreeView они располагаются не в ветке моей компоненты, а являются как бы её sibling-ами). Это можно как-то полечить? :)
                              Сообщение отредактировано: --= Eagle =-- -
                                Это не лечится, поскольку встроеннвя панель создаётся автоматом и не прописана не в ресурсе не в списке компонентов формы, фактически о её сушествовании ничо не известно, вот и получается что где лежат компоненты непонятно. ObjectTreeView думает что на форме.
                                0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                0 пользователей:


                                Рейтинг@Mail.ru
                                [ Script execution time: 0,0421 ]   [ 16 queries used ]   [ Generated: 27.04.24, 12:48 GMT ]