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

Вниз

Графический редактор графического компонента   Найти похожие ветки 

 
AZ ©   (2003-02-24 17:08) [0]

В предыдущей ветке я писал:
---
Пишу графический компонент, наследник TGraphicControl.
На нем располагаютя графические примитивы (прямоугольники, эллипсы, и т.п.).
При редактировании необходимо перемещать их, деформировать.
Обычная реакция IDE - растягивание, сжатие или перемещение клиентской области компонента.

Или писАть какой-то свой специфический редактор?
Варианты типа "на каждую фигуру свой контрол" не подходят.
---
Mike_Goblin © (24.02.03 10:08)
(спасибо ему!) посоветовал сделать редактор.
Вот и приступил я к созданию своего графического редактора графического компонента.
Что предлагает IDE:
function GetVerbCount: integer; override;
Количество пунктов меню редактора;
function GetVerb(Index: integer): string; override;
Список названий пунктов меню редактора
procedure ExecuteVerb(Index: integer); override;
Выполнение пунктов меню.
Хорошо, но мало.
Просмотрел интерфейс IDesigner и другие.
К сожалению, ничего подходящего себе не нашел, описания интерфейсов слишком скупы.
Может, господа профессионалы подскажут путь построения подобного редактора.


 
Mike_Goblin ©   (2003-02-24 17:22) [1]

Редактор компонента - экземпляр класса-наследника TComponentEditor
Вызов его происходит след образом
Вариант 1
щелчок правой кн мыши на компоненте-контекстное меню - пункт контекстного меню
Вариант 2
Дв клик левой кнопкой мыши на компоненте
Так вот методы
function GetVerbCount: integer; override;
procedure ExecuteVerb(Index: integer); override;
отвечают за формирование дополнительных(специфичных пунктов popup)
При двойном клике вызывается метод Edit класс TComponentEditor
Если ты не переопределил Edit, то он пытается вызвать первый пукт меню
ExecuteVerb(0)


 
Mike_Goblin ©   (2003-02-24 17:47) [2]

PS Конопку почитай, если есть возможность. Там это все очень хорошо изложено


 
AZ ©   (2003-02-24 18:51) [3]

С этим я уже знаком, простые редакторы уже писАл... :)
Непонятно, как пристегнуть к редактору мышиные события, так же как обычно:
procedure WMLButtonDown(var Message: TWMLButtonDown); message WM_LBUTTONDOWN;
procedure WMLButtonUp(var Message: TWMLButtonUp); message WM_LBUTTONUP;
procedure WMMouseMove(var Message: TWMMouseMove); message WM_MOUSEMOVE;
Или нужно что-то другое?


 
viajero   (2003-02-24 18:54) [4]

Стандартный редактор компонента предназначен
для интегрирования в среду дельфи и больше ни для чего.

Такое поведение, как ты описываешь, можно организовать,
заменив оконную ф-ю компонента:

procedure TTestCtrl.NewWndProc(var Message: TMessage);
var
Form: TCustomForm;
begin
if (csDesigning in ComponentState) then
begin
Form := GetParentForm(Self);

// Здесь ты можешь перехватить сообщение и решить,
// куда оно должно направляться - в твой редактор или
// в дельфийский дизайнер
// Здесь нужно каким-то образом
// гармонично соединить стандартное поведение
// с нестандартным

if not IsMessageForMyGraphicEditor(Message) then

// Standard process

if (Form <> nil) and (Form.Designer <> nil) and
Form.Designer.IsDesignMsg(Self, Message) then Exit;
end else
OldWndProc(Message);
end;

constructor TTestCtrl.Create(AOwner: TComponent);
begin
inherited;
OldWndProc := WindowProc;
WindowProc := NewWndProc;
end;


Но тогда всю функциональность перетаскивания и
масштабирования мышью тебе придётся реализовать самому.

Других путей я не вижу.


 
AZ ©   (2003-02-25 07:33) [5]

Жалко. С оконной процедурой в подобном компоненте я уже имел дело. Появлялись побочные эффекты, с которыми было трудно бороться.
Например, автоматический выход из редактирования своего компонента при переходе курсора на чужой.
Но все равно спасибо!


 
Юрий Зотов ©   (2003-02-25 08:08) [6]

> Непонятно, как пристегнуть к редактору мышиные события

Заместите метод Edit, а в нем создавайте форму редактирования. Сама форма делается, как обычно. На ней две кнопки - OK и Cancel, показ модальный. Обычно такая форма содержит тот же компонент, что и редактируемый (собственно, этот дубль она и редактирует, а не сразу оригинал - это дает возможность использовать откат по Cancel). При подъеме формы дубль "копирует" состояние оригинала (напр., через Assign), а при нажатии OK идет ModalResult := mrOK, обратный Assing и Designer.Modified (чтобы обновить Object Inspector). При нажатии Cancel просто ничего не делаем. То есть примерно вот что:

with TEditorForm.Create(nil) do
try
Дубль_на_форме.Assign(Component);
if ShowModal = mrOK then
begin
Component.Assign(Дубль_на_форме);
Designer.Modified
end
finally
Free
end;

Этот же код можно написать и не в Edit, а в ExecuteVerb, только сначала надо проверить, тот ли пункт меню был вызван. Обычно если пункт меню единственный, используется Edit, если несколько - ExecuteVerb.

Сама форма редактирования делается, повторюсь, самым обычным образом. Пишите в ней любые обработчики любых событий и сообщений. При вызове из редактора сама эта форма будет работать, как часть IDE - то есть, в run-time. Поэтому никаких проблем.


 
AZ ©   (2003-02-25 11:33) [7]

А если эти геометрич. примитивы должны находиться в определенном положении по отношению к другим, но другого компонента?
Тогда как тогда организовывать вывод других компонентов на новую форму?
Или ограничиться редактируемым компонентам, но запомнить координаты стыковки и в процессе редактирования подогнать стыкуемые места на нужное место? Неудобно, конечно, но тоже выход.


 
Юрий Зотов ©   (2003-02-25 21:57) [8]

Так положите на форму редактора дубли ВСЕХ нужных Вам компонентов и редактируйте их СОВМЕСТНО (а сам редактор можно зарегистрировать для ВСЕХ этих компонентов).

Поймите, главное - это то, что форма редактора и ВСЕ находящиеся на ней компоненты работают в run-time. Это РЕЗКО упрощает задачу. Ведь можно писать любые обработчики любых сообщений и событий - то есть, происходит развязка с design-time, с ее хуками и прочими недокументированными средствами.


 
AZ ©   (2003-02-26 03:43) [9]

ЗдОрово!
ИМХО, таким образом можно сделать общий для всех редактор и объединить их в пакет.
Хорошая мысль, и главное, вовремя.
Еще раз спасибо.



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

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

Наверх




Память: 0.49 MB
Время: 0.036 c
1-17161
Radion
2003-02-23 17:30
2003.03.06
А как, с помошю цикла, наити самое большое число в Массиве?


1-17066
Nemo
2003-02-25 02:51
2003.03.06
А можно сделать чтобы приложение нельзя было уничтожить?


3-16976
mate
2003-02-16 17:13
2003.03.06
ADO и Базы Данных.


1-17077
malkolinge
2003-02-24 11:42
2003.03.06
Parent


3-16956
извращенец2
2003-02-17 11:11
2003.03.06
Формат даты в Interbase