Текущий архив: 2005.10.23;
Скачать: CL | DM;
ВнизРабота с компонентом в Design-Time Найти похожие ветки
← →
Семен Сорокин © (2004-12-17 16:22) [0]Добрый день!
Вопрос в следующем: Имеется написанный компонент (TTablet), грубо говоря панель, на которой в определенном порядке находятся 3 ScrollBox"а. Компонент отлажен и работает, сами ScrollBox"ы ни в public, ни в published не вынесены, однако есть ряд свойств для манипуляции ими, они (ScrollBox"ы) занимают 90% площади компонента. Какой свойство нужно прописать чтобы я мог выбрать этот компонент (TTablet), нажав на его ScrollBox в DesignTime, чтобы он выделился в Object Inspector"е?
Сейчас я его выделяю - попав на оставшие 10% или явно из списка.
Та же ситуация при попытке перетащить из палитры компонентов какой-нибудь компонент на мой.
С уважением.
ЗЫ. csSubComponent имеется как во вложенных ScrollBox"ах, так и в самом компоненте (TTablet). Кроме этого у TTablet включен стиль csAcceptsControls, если поможет.
← →
Семен Сорокин © (2004-12-17 16:57) [1]Поправочка: csSubComponent есть только во вложенных ScrollBox"ах, в TTablet - нет.
И еще TTablet - наследник от TCustomControl.
Код я не привожу потому как слишком много занимает (уже более 4 тыс. строк) ;)
← →
Семен Сорокин © (2004-12-21 12:54) [2]Никто не сталкивался?
← →
Шурупчик (2004-12-21 22:20) [3]1, Как определены соотношения Parent-Child?
2. Код метода TTablet.СreateParams?
← →
Семен Сорокин © (2004-12-22 09:51) [4]
> Шурупчик (21.12.04 22:20) [3]
> 1, Как определены соотношения Parent-Child?
Немного не понял что имеется ввиду, вот конструктор TTablet:
constructor TTablet.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
ControlStyle := ControlStyle + [csAcceptsControls];
Height := 200;
Width := 300;
FTopHeight := 50;
FLeftWidth := 70;
FLockCount := 0;
FSelectOnClick := true;
FDragLegEnabled := true;
FViewDaysTabs := true;
FDragOptions := [doMove, doMoveFact, doChangeBortNo, doSwap];
FDaysWeek := ALL_WEEK;
FDaysTabsStyle := dtsDay;
FFirstTabsDay := dw1;
FOldMainPt := Point(0, 0);
FDates := nil;
FViewCurrentTime := false;
FResizeLegEnabled := false;
FLegPopupMenu := nil;
FPopupLeg := nil;
FBortPopupMenu := nil;
FPopupBort := nil;
FTimeMode := tmUTC;
FAutoViewLegTime := true;
FUseDrawEventes := false;
FMultiSelect := true;
FTopBox := TTopTabletBox.Create(self); // Первый ScrollBox
FTopBox.VertScrollBar.Visible := false;
FTopBox.HorzScrollBar.Visible := false;
FTopBox.Anchors := [akLeft, akRight, akTop];
FTopBox.Parent := self;
FLeftBox := TLeftTabletBox.Create(self); // Второй ScrollBox
FLeftBox.VertScrollBar.Visible := false;
FLeftBox.HorzScrollBar.Visible := false;
FLeftBox.Anchors := [akLeft, akTop, akBottom];
FLeftBox.Parent := self;
FMainBox := TMainTabletBox.Create(self); // Третий ScrollBox
FMainBox.Anchors := [akLeft, akRight, akTop, akBottom];
FMainBox.OnScroll := MainScroll;
FMainBox.OnMouseDown := MainDown;
FMainBox.OnMouseUp := MainUp;
FMainBox.OnMouseMove := MainMove;
if not (csDesigning in ComponentState) then
FMainBox.Cursor := crMoveUp;
FMainBox.Parent := self;
FDayTabs := TTabSet.Create(nil);
FDoubleLeg := true;
FLockData := []
end;
задание ряда свойств вынесено в перекрытый CreateWnd.
> 2. Код метода TTablet.СreateParams?
Никаких дополнительных стилей не подключал, поэтому перекрывать не стал.
С Уважением.
← →
Юрий Зотов © (2004-12-22 11:06) [5]1. csAcceptsControls - наоборот, уберите (причем явно, потому что у панелей он включен по умолчанию).
2. csSubComponent - в данном случае тоже не нужен.
← →
Семен Сорокин © (2004-12-23 11:33) [6]
> Юрий Зотов © (22.12.04 11:06) [5]
> 1. csAcceptsControls - наоборот, уберите (причем явно, потому
> что у панелей он включен по умолчанию).
В ходе манипуляций со стилями, выяснил следующее: csAcceptsControls - изначально не стоял (так как наследуюсь всё-же от TCustomControl), притом если его не выставлять у TTablet, то накидываемые из палитры компоненты ложатся (Parent"ом) на форму, а не на TTablet, в противном случае (стиль включен) - они ложатся на TTablet, и область их передвижения ограничена TTablet"ом (обычное поведение панели).
У вложенных ScrollBox"ов стиль явно выключил.
> 2. csSubComponent - в данном случае тоже не нужен.
А это вообще ни на что не повлияло.
В общем изначальной проблемы всё это не решило, однако узнал некоторые особенности работы со стилями :)
С Уважением.
← →
Юрий Зотов © (2004-12-23 12:44) [7]> Семен Сорокин © (23.12.04 11:33) [6]
Насчет csAcceptsControls - все как написано в справке. :о)
В Вашем случае совершенно не нужно.
Насчет csSubComponent - повлияло БЫ на сохранение внутренних компонентов, если БЫ они были вынесены в published. В Вашем случае тоже совершенно не нужно. Для примера вживления контрола в контрол-контейнер посмотрите код TSpinEdit.
В конструкторе контейнера нужно создать внутренние контролы, установить их положение/размеры и назначить им Parent. Это все, никаких стилей трогать не надо.
Еше не помешало бы перекрыть у контейнера CreateParams и добавить к Params.Style стиль WS_CLIPCHILDREN.
Если нигде в других местах соотношения Parent-Child больше не затронуты, то проблемы быть не должно.
← →
Семен Сорокин © (2004-12-24 17:52) [8]В ходе глубокого изучения проблемы была найдена причина такого поведения, все дело в перекрытом в ScrollBox"е сообщения:
procedure TScrollBox.WMNCHitTest(var Message: TMessage);
begin
DefaultHandler(Message);
end;
тогда как стандартный обработчик (TWinControl) имеет вид:procedure TWinControl.WMNCHitTest(var Message: TWMNCHitTest);
begin
with Message do
if (csDesigning in ComponentState) and (FParent <> nil) then
Result := HTCLIENT
else
inherited;
end;
что именно этот обработчик влияет на такое поведение в Design-Time было проверено на практике путем создания простого компонента с перекрытием сообщения WM_NCHITTEST как в ScrollBox.
Пришел к следующему: в наследнике TScrollBox"а прописал следующий обработчикprocedure TTabletBox.WMNCHitTest(var Message: TWMNCHitTest);
begin
with Message do
if (csDesigning in ComponentState) and (self.Parent <> nil) then
Result := HTCLIENT
else
inherited;
end;
TTabletBox - мой наследник TScrollBox
однако по прежнему проблема выделения осталась, где грабли? что именно я не учёл?
Юрий Зотов © (23.12.04 12:44) [7]
Спасибо за помощь, были изучены досканально исходники Spin.pas, кроме этого залез в RX - у них есть нечто похожее (TComboEdit), в общем пришел к выводу изложенному выше.
С Уважением.
← →
Юрий Зотов © (2004-12-24 20:58) [9]Семен, не понимаю, какие тут могут быть проблемы. Нужно сделать только то, что написано в [7], и больше не делать ничего. Вообще ничего, понимаете? Не надо трогать никаких стилей, никаких сообщений и прочего. Сделайте только то, что написано в [7].
Вот пример, который сделан именно так. И в котором все нормально работает, нормально выделяется и пр.
unit MyCustomControl;
interface
uses
Windows, Classes, Controls, Forms;
type
TMyCustomControl = class(TCustomControl)
private
FScrollBox: TScrollBox;
protected
procedure CreateParams(var Params: TCreateParams); override;
public
constructor Create(AOwner: TComponent); override;
published
property Height default 200;
property Width default 200;
end;
procedure Register;
implementation
procedure Register;
begin
RegisterComponents("Samples", [TMyCustomControl]);
end;
{ TMyCustomControl }
constructor TMyCustomControl.Create(AOwner: TComponent);
begin
inherited;
SetBounds(Left, Top, 200, 200);
FScrollBox := TScrollBox.Create(Self);
FScrollBox.Parent := Self;
FScrollBox.SetBounds(Left, Top, 200, 100)
end;
procedure TMyCustomControl.CreateParams(var Params: TCreateParams);
begin
inherited;
Params.Style := Params.Style or WS_CLIPCHILDREN
end;
end.
И если у Вас сделано так же, но работает все равно неверно, значит, напортачено где-то в другом месте. Не видя кода, сказать ничего более конкретного нельзя.
← →
Семен Сорокин © (2004-12-25 15:28) [10]проблема решена, спасибо за помощь, нашел ошибку:
в конструкторе одного из моих наследников TScollBox"а было:inherited Create(nil) // вместо AOwner
исправил - все заработало.
:))
ЗЫ. Вот так всегда лезешь в самые дебри, а ошибка под носом.
С Уважением.
Страницы: 1 вся ветка
Текущий архив: 2005.10.23;
Скачать: CL | DM;
Память: 0.49 MB
Время: 0.056 c