#delphi #firemonkey #vcl
Вопрос:
Вопрос уже был задан, но я все еще не могу найти хороший способ сделать это. Я только что создал компонент, который просто рисует некоторые вещи на форме. в основном это точно такой же код, касающийся FMX или VCL, но на fmx он использует FMX.form, а на vcl он использует VCL.form.
- Как сделать мой компонент совместимым с обоими фреймворками? В идеале я не хочу разделять блок (например, один FMX.myunit.pas и один VCL.MyUnit.pas)
- Как сделать так, чтобы мой компонент отображался на панели инструментов только для
VCL project
или только дляFMX project
или только дляboth projects
? - Как в моем dpr/dproj я могу сказать, что мой проект использует платформу VCL или FMX? Может ли проект использовать как фреймворк, так и VCL и FMX?
- Для компонентов fmx, почему мне нужно сделать
RegisterComponents('myGroup', [TMyControl]);
следующееRegisterFmxClasses([TMyControl]);
(это выглядит так во всех образцах, которые я видел).
Комментарии:
1. Не ответ на ваш основной вопрос, но… Компонент не рисуется на форме, по крайней мере напрямую. Компонент рисует в своем собственном окне, которое является дочерним окном TForm или другого контейнера.
2. Используйте условную компиляцию и включайте файл. В качестве примера посмотрите исходный код ICS , чтобы узнать, как это было сделано.
3. @AndreasRejbrand Ты действительно думаешь, что я этого не знаю?
4. @fpiette: Я думаю, вы уже знали об этом, но ваш первый комментарий был не очень точным, поэтому для удобства других людей, читающих этот вопрос, я добавил некоторые детали.
5. «нарисуйте что-нибудь на форме. в основном это точно такой же код..». Возможно, вы можете опубликовать этот код здесь, чтобы кто-нибудь мог разработать для вас решение?
Ответ №1:
Я только что создал компонент, который просто рисует некоторые вещи на T-форме.
Элемент управления пользовательским интерфейсом вообще не должен отображаться в форме. Он должен опираться на Canvas
то, что предоставляет ему платформа VCL/FMX, например, в переопределенном Paint()
методе.
Как сделать мой компонент совместимым с обоими фреймворками? В идеале я не хочу разделять блок (например, один FMX.myunit.pas и один VCL.MyUnit.pas)
Вам не нужно использовать области единиц измерения в ваших собственных единицах измерения, если только вы не разделяете единицы измерения между пакетами и не хотите различать их.
Если вы не создадите отдельные блоки для каждой платформы, то вам понадобится IFDEF
этот блок по мере необходимости при использовании кодирования для конкретной платформы.
Если вы пишете код, не зависящий от фреймворка, то для обоих фреймворков можно использовать один пакет. Но если вам нужно написать код для конкретной платформы (т. Е. Из-за кода пользовательского интерфейса и т. Д.), Вам нужно будет создать отдельные пакеты для каждой платформы.
Что касается самого компонента, если вы идете по маршруту IFDEF, то, если возможно, попробуйте вывести свой компонент из базового класса, существующего в обеих системах.
Для невизуальных компонентов, производных от TComponent
, он ведет себя одинаково в обоих фреймворках.
Для визуальных элементов управления, производных TControl
или потомков по мере необходимости. Просто обратите внимание, что существуют различия в том, как каждая платформа реализует визуальные элементы управления, поэтому вам, скорее всего, потребуется IFDEF
соответствующий код реализации или использовать отдельные модули для каждой платформы.
Как сделать так, чтобы мой компонент отображался в палитре инструментов только для проекта VCL или только для проекта FMX или для обоих проектов ?
Пакет может иметь сходство с определенной структурой (см. Далее ниже).
Если он указывает конкретную структуру, то это единственная структура, для которой он будет отображаться. Если в нем не указан фреймворк, то он будет доступен для обоих фреймворков.
Когда вы регистрируете элемент управления пользовательского интерфейса, вы должны позвонить GroupDescendentsWith()
, чтобы сгруппировать свой элемент управления в TControl
группу классов, например:
RegisterComponents('My Control', [TMyControl]);
GroupDescendentsWith(TMyControl, TControl);
Не полностью уточняйте область действия единицы измерения TControl
ни в этом вызове , ни в вашем uses
предложении. Используйте только Controls
модуль и позвольте компилятору выбирать между FMX.Controls.TControl
или Vcl.Controls.TControl
в зависимости от того, какая версия TControl
доступна, в зависимости от того, для какой платформы компилируется ваш пакет.
Как в моем dpr/dproj я могу сказать, что мой проект использует платформу VCL или FMX?
В .dproj
, во-первых <PropertyGroup>
, есть доступный <FrameworkType>
элемент (добавьте его, если он отсутствует), который может быть установлен в VCL
, FMX
, или None
.
Может ли проект использовать как фреймворк, так и VCL и FMX?
Официально-нет. Но есть неофициальные способы (т. е. сторонние решения) сделать это. Я бы не рекомендовал делать это внутри пакета, только внутри приложения.
Для компонентов fmx, почему мне нужно сделать
RegisterComponents('myGroup', [TMyControl]);
следующееRegisterFmxClasses([TMyControl]);
(это выглядит так во всех образцах, которые я видел).
Все, что на самом деле делается, — это группировка TMyControl
в группу TFmxObject
классов, которая доступна только тогда, когда активна платформа FMX. Это просто еще одна группа, используемая для фильтрации отображения компонентов в интегрированной среде разработки. Группировка элемента управления пользовательского интерфейса в группу TControl
классов выполняет то же самое.