В Delphi XE2 мы используем
{$ifdef Win32}
{$ifdef Win64}
чтобы определить, на какой платформе мы находимся.
Есть ли какие-либо предопределенные условия, которые могут идентифицировать VCL и FMX?
В Delphi XE2 мы используем
{$ifdef Win32}
{$ifdef Win64}
чтобы определить, на какой платформе мы находимся.
Есть ли какие-либо предопределенные условия, которые могут идентифицировать VCL и FMX?
Как говорят другие, нет условной директивы, определяющей, является ли ваше приложение VCL или FireMonkey. Я думаю, что самый надежный способ определить, является ли ваше приложение FireMonkey или VCL, - это использовать функцию вместо условной директивы.
Что-то вроде
Uses
Rtti;
function IsVCLApp:Boolean;
begin
Result:= CompareText(TRttiContext.Create.GetType(TApplication.ClassInfo).QualifiedName,'Vcl.Forms.TApplication')=0;
end;
function IsFireMonkeyApp:Boolean;
begin
Result:= CompareText(TRttiContext.Create.GetType(TApplication.ClassInfo).QualifiedName,'FMX.Forms.TApplication')=0;
end;
Forms
или Vcl.Forms
, код будет работать нормально. И, наконец, о вашем последнем комментарии, который зависит от типа приложения, этот ответ предлагает использовать функцию в качестве альтернативы использованию conditional directive
.
- person RRUZ; 11.10.2011
Forms
, а не Vcl.Forms
. Если вы явно используете Vcl.Forms
или Fmx.Forms
, то вы уже определились с платформой в разделе uses для модуля и, следовательно, уже имеете условный способ проверки целевого набора виджетов.
- person Zoë Peterson; 11.10.2011
IsFireMonkeyApp
до Result := {$IF DECLARED(TFmxObject)}True{$ELSE}False{$IFEND};
, и он будет вести себя точно так же.
- person Zoë Peterson; 11.10.2011
Result := GetClass('TFmxObject') <> nil;
, поскольку для этого не требуется FMX.Types - это область действия.
- person da-soft; 06.05.2012
Хотя это не задокументировано, вы можете использовать VCL и Firemonkey в одном приложении.
Нет определения компилятора.
Если вы создаете что-то, что должно быть одновременно VCL и Firemonkey, я бы рекомендовал разделить эти модули.
Возможный способ:
Смешивание кода пользовательского интерфейса из двух разных фреймворков в одном модуле - не лучшая идея. Он будет связываться с другой библиотекой, когда в ней нет необходимости.
Директивы компилятора нет, потому что технически не существует таких вещей, как приложение firemonkey или приложение vcl. Только приложения, использующие эти технологии. Приложение может использовать fxm или vcl, либо оба, либо ни то, ни другое (например, консольное приложение). Это немного похоже на вопрос, является ли это приложением SQL. Конечно, вы можете программно проверять происхождение отдельных форм, чтобы увидеть, от какой структуры они наследуются. Опять же, внутри единицы, не имеющей связанной формы, это не имеет значения.
Кажется, что компилятор не определен специально для VCL / FireMonkey. Вам нужно будет создать свой собственный.
Список предопределенных условных операторов можно найти в документации.
GUI without Firemonkey
, как показано здесь stackoverflow.com/questions/7442131/
- person RRUZ; 11.10.2011
Abbrevia поддерживает как VCL, так и CLX с использованием такого разделения:
QAbUnit1.pas:
{$DEFINE UsingCLX}
unit QAbUnit1;
{$I AbUnit1.pas}
AbUnit1.pas:
{$IFNDEF UsingCLX}
{$DEFINE UsingVCL}
unit AbUnit1;
{$ENDIF}
type
...
TMyWidget = class({$IFDEF UsingVCL}TWinControl{$ENDIF}
{$IFDEF UsingCLX}TWidgetControl{$ENDIF})
...
end;
end.
Чтобы добавить поддержку FireMonkey, я бы добавил такой файл:
FmxAbUnit1.pas:
{$DEFINE UsingFMX}
unit FmxAbUnit1;
{$I AbUnit1.pas}
{$ENDIF}
а затем внесите необходимые условные изменения в AbUnit1.pas.
Это не очень хорошее чистое разделение, как предложение Роберта, но преимущество состоит в том, что все ваше редактирование происходит в одном файле, а условное определение обрабатывается автоматически, поэтому его не нужно указывать в параметрах проекта. Кто когда-либо использует вашу библиотеку, просто включает соответствующий модуль, чтобы решить, какой из них они хотят использовать. Вы, вероятно, могли бы также воспользоваться преимуществом определения области видимости, назвав файлы Fmx.AbUnit1.pas
и Vcl.AbUnit1.pas
, но я думаю, что Embarcadero не одобряет этого.
Попробуйте этот фрагмент:
{$IF Declared(FMX)}
// FMX code here. To test this approach you may use {$MESSAGE FATAL 'FMX'}
{$ELSEIF Declared(VCL)}
// VCL code here. To test this approach you may use {$MESSAGE FATAL 'VCL'}
{$IFEND}
Он проверяет, было ли объявлено соответствующее пространство имен с использованием директива компиляции IF
Поскольку FMX не является взаимоисключающим с VCL, может потребоваться добавить следующие ветки:
{$ELSEIF Declared(FMX) and Declared(VCL)}
// FMX+VCL code here. To test: {$MESSAGE FATAL 'FMX+VCL'}
{$ELSE}
// no GUI frameworks code here. To test: {$MESSAGE FATAL 'no GUI frameworks'}