-2

我有一个单元,我想在任何 Delphi 版本下编译,比如 Delphi 2006。

它的下一个代码有编译问题:

uses
  graphics; // for previous versions can not be compiled on Delphi XE

uses
  vcl.graphics; // compiled on Delphi XE but can not compile on previous version

并且函数 StrLen、StrCopy 会产生“已弃用。移至 AnsiString”警告。

问题是:如何解决所有问题?图形从哪个编译器版本变成了 vcl.graphics,而 StrLen 移到了 AnsiStrings?创建下一个代码:

uses
  {$if CompilerVersion < ??}graphics{$ifelse}vcl.graphics{$ifend};
4

1 回答 1

2

Graphics单元Vcl.Graphics在 XE2 中重命名为 ,当时首次引入了单元范围名称。

Delphi 和 C++Builder XE2 的新功能

重要的新要求:VCL-FMX-RTL 的单元范围名称

重要提示:VCL-FMX-RTL 单元现在使用点前缀命名约定,例如System.Typesand Vcl.Styles。如果您有使用限定标识符(例如Types.IStream)的现有代码,则可能需要更改代码才能编译。

您不需要使用{$IF}语句来编写跨版本的 VCL 代码。您的uses子句可以继续单独使用Graphics单位名称:

uses
  Graphics;

只需确保Vcl包含在 XE2+ 项目的项目选项中的单元范围名称列表中(默认情况下应该是)。

这是记录在案的(实际上,文档甚至以Graphics单位为例):

Delphi 编译器项目选项 | 德尔福编译器

为 Delphi 点分命名空间指定单位范围名称(前缀),以允许您在代码和uses子句中使用部分限定名称或#include.

有两种方法可以为 Delphi 单元添加单元范围名称:

  • 在您的 uses 子句中指定完整的单元范围名称。例如:

    uses Vcl.Graphics;
    
  • 将单元范围名称 ( Vcl)添加到单元范围名称字段。然后单元范围名称Vcl会自动应用于属于该单元范围的单元名称,您可以简单地指定:

    uses Graphics; 
    

省略号弹出按钮打开一个对话框,用于选择和添加单位范围名称,如项目选项页面上的通用项有序列表对话框中所述

如果选择使用{$IF}语句,正确的语法是:

uses
  {$IF RTLVersion >= 23}Vcl.{$IFEND}Graphics;

或者:

uses
  {$IF RTLVersion >= 23}Vcl.Graphics{$ELSE}Graphics{$IFEND};

至于 和 的PAnsiChar版本SysUtils.StrLen()SysUtils.StrCopy()它们已被弃用并移至System.AnsiStringsXE4 ( RTLVersion=25.0) 中的单元。例如:

uses
  ...
  {$IF RTLVersion >= 25}, AnsiStrings{$IFEND}
  ;

var
  Src, Dest: PAnsiChar;
  Len: Integer;
begin
  Src := ...;
  Len := {$IF RTLVersion >= 25}AnsiStrings.{$IFEND}StrLen(Src);
  GetMem(Dest, Len * SizeOf(AnsiChar));
  {$IF RTLVersion >= 25}AnsiStrings.{$IFEND}StrCopy(Dest, Src);
  ...
end;

最后,请注意这{$IF}是在 Delphi 6 中引入的,因此如果您需要支持 Delphi 5 或更早版本,则必须将{$IF}语句包装在一个{$IFDEF CONDITIONALEXPRESSIONS}块中。

于 2015-09-02T22:05:41.977 回答