Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.145.105.105] |
|
Страницы: (2) [1] 2 все ( Перейти к последнему сообщению ) |
Сообщ.
#1
,
|
|
|
Вобщем, есть наследник от TPanel, на котором лежит сплиттер (не стандартный, но всё же...). Сплиттер постоянно имеет какой-то Align. И если сплиттер у меня alLeft, а я бросаю на компоненту какую-то другую компоненту и ставлю ей Align=alTop, то сплиттер... правильно, располагается ПОД компонентой, т.к. выравнивание сверху/снизу имеет более высокий приоритет, чем выравнивание слева/справа. Как эту радость обойти? Я пытался создать на панели ещё одну панельку, на которую собственно и будут кидаться все остальные компоненты в режиме конструктора (и создаваться в рантайме), но почему-то компоненты, которые я кидаю в дизайн-тайме, не записываются как находящиеся на этой панели и не отображаются (в DFM их НЕ видно как будто они НЕ находятся на форме; при чём если выйти из режима просмотра DFM то получим сообщение о том, что этой панельки типа вообще-то и нима, и не стоит ли её убрать).
Как повлиять на ситуацию? Нужно чтобы если я установил сплитер справа, то он и занимал ВСЮ правую часть панели, игнорируя то, что какие-то компоненты могут быть заалигнены alTop/alBottom? Как создаю панельку? А вот так: FContainer := TPanel.Create(Self); FContainer.Parent := Self; FContainer.BevelInner:=bvNone; FContainer.BevelOuter:=bvNone; FContainer.Align := alClient; FContainer.SetSubComponent(True); |
Сообщ.
#2
,
|
|
|
Цитата --= Eagle =-- @ Я пытался создать на панели ещё одну панельку, на которую собственно и будут кидаться все остальные компоненты в режиме конструктора (и создаваться в рантайме), но почему-то компоненты, которые я кидаю в дизайн-тайме, не записываются как находящиеся на этой панели и не отображаются (в DFM их видно как будто они находятся не на моей панели, а на той же форме, на которой и сама панель; при чём если выйти из режима просмотра DFM то получим сообщение о том, что этой панельки типа вообще-то и нима, и не стоит ли её убрать). Хм, ничего кроме отсутствующего в ControlStyle флага csAcceptControls не приходит в голову. |
Сообщ.
#3
,
|
|
|
Цитата Smike, 06.09.2006, 20:24:14, 1252858 Хм, ничего кроме отсутствующего в ControlStyle флага csAcceptControls не приходит в голову. Не стояло. Но не помогаеть... Цитата --= Eagle =--, 06.09.2006, 19:16:17, 1252781 в DFM их видно как будто они находятся не на моей панели, а на той же форме, на которой и сама панель; тут я ошибся - не добавляется оно на форму вообще! |
Сообщ.
#4
,
|
|
|
SetSubComponent случайно не мешает?
|
Сообщ.
#5
,
|
|
|
Думаю нет... Когда я его не ставил - была та же ситуёвина...
Добавлено З.Ы. csAcceptControls там походу по-умолчанию стоит... Добавлено З.З.Ы. Если хочешь - попробуй сам создать компоненту унаследованную от TPanel и создай на ней в конструкторе ещё одну понельку, допустим красного цвета. А потом попробуй в дизайн-тайме кинуть на этукомпоненту какой-то батон. У меня этот батон прописывается в .PAS, а в .DFM - нет... |
Сообщ.
#6
,
|
|
|
Цитата --= Eagle =-- @ Если хочешь - попробуй сам создать компоненту унаследованную от TPanel и создай на ней в конструкторе ещё одну понельку, допустим красного цвета. Давно бы попробывал, но стоит Turbo Delphi, а там невозможна инсталляция компонентов... |
Сообщ.
#7
,
|
|
|
оффтоп:
Цитата Smike, 06.09.2006, 21:49:02, 1252950 Давно бы попробывал, но стоит Turbo Delphi, а там невозможна инсталляция компонентов... Хмм... я думал, ты уже о нём своё мнение составил... Неее... я таким извратом страдать не буду, если оно конфликтует с другой версией установленной делфы... У меня стояли D6, D7 и BDS2006 - и всё как не может быть гуд... |
Сообщ.
#8
,
|
|
|
Цитата --= Eagle =-- @ Неее... я таким извратом страдать не буду, если оно конфликтует с другой версией установленной делфы... У меня стояли D6, D7 и BDS2006 - и всё как не может быть гуд... Не конфликтует. Просто это естественное ограничение. Бесплатная версия Turbo-продукта не может быть одновременно инсталлирована с каким-то другим продуктом семейства Turbo или BDS 2006. Завтра на работе поэкспериментирую с панелями, сейчас уже неохота переустанавливать |
Сообщ.
#9
,
|
|
|
Спасибо
|
Сообщ.
#10
,
|
|
|
Пока нарыл такой вот код:
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 на этом участке: try inherited ReadState(Reader); finally процедуры WriteComponents у предков походу нету... З.Ы. Делфи 6... |
Сообщ.
#11
,
|
|
|
Млин, пару дней бьюсь над проблеммой - никакого результата... У кого-то есть хорошие идеи по поводу сабжа?
|
Сообщ.
#12
,
|
|
|
Все очень даже логично Таким образом все будет работать:
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. Добавлено Да, еще один выход: использовать фреймы вместо компонента. |
Сообщ.
#13
,
|
|
|
Цитата 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 Да, еще один выход: использовать фреймы вместо компонента. Если имеется в виду что фрейм нужно в дизайн-тайме кидать, то всё же это не подходит, хотя действительно работает без проблемм... |
Сообщ.
#14
,
|
|
|
Вот такой вот код мне подкинули на Мастерах Делфи:
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-ами). Это можно как-то полечить? |
Сообщ.
#15
,
|
|
|
Это не лечится, поскольку встроеннвя панель создаётся автоматом и не прописана не в ресурсе не в списке компонентов формы, фактически о её сушествовании ничо не известно, вот и получается что где лежат компоненты непонятно. ObjectTreeView думает что на форме.
|