Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2018.03.18;
Скачать: CL | DM;

Вниз

Взаимодействие с компонентами   Найти похожие ветки 

 
Илья_666   (2016-02-28 19:28) [0]

Всем добрый вечер!

Есть компонент - наследник TCustomControl, который создает на себе несколько панелей (как в дизайн-, так и в ран-тайм).
Собственно, интересует, как можно в дизайне взаимодействовать с панелями, подобно тому, как это получается у TPageControl"a и его TabSheet"ов.
Ну или как будто просто положить на форму стандартную панель, а на нее еще 3 панели.

Код TPageControl"a я смотрел, но так и не понял, как он это творит.
Подскажите, пожалуйста, в каком направлении копать.

Заранее спасибо.


 
Юрий Зотов ©   (2016-02-28 22:22) [1]

См. AcceptControls


 
Илья_666   (2016-02-28 23:25) [2]

Юрий Зотов, если речь идет о csAcceptsControls, то этот флаг выставлен в ControlStyle компонента. Если Вы не имели в виду флаг, то никакой информации по AcceptControls я не нашел.
Я же говорю о том, что мой компонент создает в дизайн-тайм на себе несколько стандартных TPanel. Это работает прекрасно и мой компонент является владельцем и родителем панелей. Но дело в том, что все в том же дизайн-тайм, при попытке клика на любую панель, клик проходит по родительскому компоненту и он же и выделяется, и в объект-инспекторе работать можно только с ним, но не с панелью.

А я бы хотел реализовать возможность клика и работы как с родительским компонентом, так и с панелями в дизайн-тайм.
Как будто вы положили TPanel на форму, а на нее положили еще две TPanel. Теперь у вас есть возможность выделить кликом как родительскую панель и работать с ней через объект-инспектор, так и выделить любую из child-панелей и работать с ними через инспектор.

Вот как такое сделать для дизайн-тайм?


 
Юрий Зотов ©   (2016-02-29 13:47) [3]

> Как будто вы положили TPanel на форму, а на нее
> положили еще две TPanel.

В этом случае большая панель будет только родителем, а владельцем будет форма. А у Вас большая панель - и родитель, и владелец. Возможно, дело в этом.

Еще посмотрите SubComponent. Деталей уже не помню, но похоже, что это и есть то, что Вам надо.


 
Илья_666   (2016-02-29 18:50) [4]

Юрий Зотов, к сожалению, SetSubComponent не помог, равно как и назначение в качестве Owner"a для моих панелей формы, на которой лежит весь компонент. Я пробовал использовать SetDesigning(true, true), но это явно дурной тон. К тому же, такой вариант также некорректно работает.


 
Илья_666   (2016-02-29 21:24) [5]

Ладно, а что если зайти с другой стороны. У стандартного TPageControl есть PopupMenu в дизайне, в котором есть пункт "New page", нажатие на который приводит к добавлению страницы.
Если не ошибаюсь, то реализовать такое меню можно через некие пакеты с названиями DesignXXX.pas. Но суть не в этом. Суть в том, что, возможно, выделение только что добавленной страницы (а также иных страниц pageControl"a) происходит через некий код в обработчике пункта "New page".

Только вот теперь вопрос: как увидеть исходники обработчика "New page" стандартного TPageControl?

Ни у кого никаких мыслей случаем нет на этот счет?


 
Юрий Зотов ©   (2016-02-29 23:14) [6]

Это называется "редактор компонента". Его надо написать и зарегистрировать в IDE. Примеры есть в VCL


 
Илья_666   (2016-03-01 18:25) [7]

Юрий Зотов, я пошерстил исходники VCL, но ничего, связанного с PageControl так и не нашел. Почитал про TComponentEditor, но таки не понял, как он именно привязывается к PageControl"у, что дает возможность создавать компоненты. Вот застрял тут и все. Печально.


 
Юрий Зотов ©   (2016-03-01 21:02) [8]

Редактор компонента привязывается не к отдельному компоненту, а к его КЛАССУ (то есть, сразу ко всем компонентам этого класса).

См. RegisterComponentEditor.

interface

type
 TMyComponentEditor = class(TMyComponent)
 public
   procedure Edit; override;
   function GetVerb(Index: Integer): String; override;
   function GetVerbCount: Integer; override;
   procedure ExecuteVerb(Index: Integer); override;
 end;

procedure Register;

implementation

procedure Register;
begin
 RegisterComponentEditor(TMyComponent, TMyComponentEditor)
end;

procedure TMyComponentEditor.Edit;
// Процедура редактирования выбранных компонентов
// Вызывается двойным щелчком по одному из них, либо из меню
begin
  ShowMessage("Вызвана процедура Edit")
end;

procedure TMyComponentEditor.ExecuteVerb(Index: Integer);
// Выполняет команду меню с индексом Index
begin
 case Index of
 0: Edit;  // Умалчиваемая команда - редактирование
 1: ShowMessage("Пункт 1 выполнен")
 end
end;

function TMyComponentEditor.GetVerb(Index: Integer): String;
// Возвращает названия пунктов меню
begin
 case Index of
 0: Result := "Edit...";
 1: Result := "Once more";
 end
end;

function TMyComponentEditor.GetVerbCount: Integer;
// Возвращает количество пунктов меню
begin
 Result := 2;
end;


 
Илья_666   (2016-03-02 18:50) [9]

Юрий Зотов, спасибо за пример. Помимо него я только что нашел пример на
http://docwiki.embarcadero.com/RADStudio/Seattle/en/Changing_the_Double-click_Behavior


procedure TMyEditor.Edit;
var
 FontDlg: TFontDialog;
begin
 FontDlg := TFontDialog.Create(Application);
 try
   if FontDlg.Execute then
     MyComponent.FFont.Assign(FontDlg.Font);
 finally
   FontDlg.Free
 end;
end;


я попробовал таким же образом вставить панель, используя контекстное меню и получилось такое:

procedure TPanelEditor.ExecuteVerb(Index: Integer);
var
 Panel: TPanel;
begin
 Inherited ExecuteVerb(Index);
   case Index of
     0:                                    
     begin
       Panel:= TPanel.Create(Designer.Root);
       Panel.Parent := Designer.Root;
       Panel.Name := Designer.UniqueName("Panel");
       Designer.SelectComponent(Panel);
       Designer.Modified;
     end;
   end;
end;


Теперь панелька может обрабатываться через инспектор объектов и даже быть удаленной))
Честно говоря, раньше мне казалось, что создавать компоненты в через подобные редакторы невозможно, можно лишь вызвать какую-нибудь процедуру из компонента указанного класса. Но, видимо я ошибался.
Спасибо Вам, Юрий Зотов, за потраченное на дилетанта время))


 
Юрий Зотов ©   (2016-03-02 21:26) [10]

> мне казалось, что создавать компоненты в через подобные
> редакторы невозможно


Создать компонент можно откуда угодно, лишь бы был доступен его конструктор (а для визуальных компонентов - еще и Parent).

Ну и чтобы было совсем грамотно, сделайте так:

1. Создаем 2 пакета: rin-time (RT) и design-time (DT).

2. В пакет RT помещаем модуль самого компонента и модули, требуемые ему для работы в run-time. Больше ничего в пакет RT не помещаем.

3. В пакет DT помещаем модуль с редактором и процедурой Register (в которой 2 строчки - регистрация самого компонента и его редактора). Если компонент имеет собственную иконку, помещаем ее ресурс тоже в пакет DT.

4. В секции required пакета DT указываем пакет RT.

5. Компилируем пакет RT в доступный для IDE каталог.

5. Инсталлируем пакет DT в IDE.

6. Осознаем свою необычайную крутизну!!!


 
Германн ©   (2016-03-03 01:03) [11]


> Осознаем свою необычайную крутизну!

Которую вряд ли кто другой оценит. Ибо RT-пакеты почти никто не пользует, кроме самой Дельфи. :)


 
Игорь Шевченко ©   (2016-03-03 12:35) [12]


> Которую вряд ли кто другой оценит. Ибо RT-пакеты почти никто
> не пользует, кроме самой Дельфи. :)


Можно ты свои фантазии будешь держать при себе, а не делиться ими с форумом ? Дай отдохнуть и фонтану.


 
Илья_666   (2016-03-03 17:05) [13]

Юрий Зотов, спасибо за описание в сообщении [10]. У меня есть несколько компонентов, написанных для себя. Как раз доделаю с панельками контрол и оформлю пакеты, как полагается))

Германн, а что значит эта строка:

> RT-пакеты почти никто не пользует, кроме самой Дельфи

? Получается, такие пакеты можно использовать вне Делфи?

Игорь Шевченко, ну зачем Вы так грубо с братом по цеху? Ай-яй-яй, это же не наш метод)


 
Юрий Зотов ©   (2016-03-03 17:45) [14]

> Получается, такие пакеты можно использовать вне Делфи?

Можно откомпилировать программу с RT-пакетами. Тогда размер сильно уменьшается, но требуемые для нее пакеты придется таскать вместе с ней.


 
Игорь Шевченко ©   (2016-03-03 18:13) [15]

Илья_666   (03.03.16 17:05) [13]

Можно выяснять интересующие вас подробности, например, в чате ? На сайте есть чат, не надо его путать с форумом.


 
Илья_666   (2016-03-04 17:42) [16]

Юрий Зотов, спасибо еще раз за помощь)


 
Макс Черных ©   (2016-03-18 02:04) [17]


> Но дело в том, что все в том же дизайн-тайм, при попытке
> клика на любую панель, клик проходит по родительскому компоненту
> и он же и выделяется, и в объект-инспекторе работать можно
> только с ним, но не с панелью.А я бы хотел реализовать возможность
> клика и работы как с родительским компонентом, так и с панелями
> в дизайн-тайм.


Коли так, то стоит разобраться для чего нужно сообщение CM_DESIGNHITTEST и что будет если оному в Message.Result вернуть единицу.


 
Илья_666   (2016-03-21 17:43) [18]


> Макс Черных ©   (18.03.16 02:04) [17]

Возьмите, пожалуйста, за правило читать все, что написано до Вас.
Это избавит Вас от многих проблем как в жизни, так и в интернете.


> Илья_666   (02.03.16 18:50) [9]

Читать до наступления просветления.

З.Ы.
cmDesignHittest не помогло бы в моем случае.



Страницы: 1 вся ветка

Текущий архив: 2018.03.18;
Скачать: CL | DM;

Наверх




Память: 0.52 MB
Время: 0.005 c
8-1243716518
v1ctar
2009-05-31 00:48
2018.03.18
Обработка изображений. Сегментация.


2-1459159042
TheEd
2016-03-28 12:57
2018.03.18
Редактирование ячейки DBGridEh только кнопкой


15-1471037402
Юрий
2016-08-13 00:30
2018.03.18
С днем рождения ! 13 августа 2016 суббота


2-1459026105
lewka
2016-03-27 00:01
2018.03.18
Протоколы буфера


2-1459355702
Макака
2016-03-30 19:35
2018.03.18
TreeView