-2

I have one unit which I want to be compiled under any Delphi version from let's say Delphi 2006.

It has next code which have problems compiling:

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

And functions StrLen, StrCopy produce "deprecated. moved to AnsiString" warning.

Question is: How to sort it all out? From which compiler version graphics become vcl.graphics, and StrLen moved to AnsiStrings? To create next code:

uses
  {$if CompilerVersion < ??}graphics{$ifelse}vcl.graphics{$ifend};
Cœur
  • 37,241
  • 25
  • 195
  • 267
Mike K.
  • 145
  • 10
  • Which question do you want us to answer? The one relating to namespaces, or the one relating to deprecated functions? It's one question at a time. They are probably both duplicates. But we can't close as a duplicate of two questions. You are going to have your work cut out making code work with ANSI and Unicode Delphi. Takes a degree of skill. How well do you understand that issue? – David Heffernan Sep 02 '15 at 21:11
  • http://stackoverflow.com/q/1369191/62576 and http://stackoverflow.com/q/23704097/62576 and http://stackoverflow.com/q/8460037/62576 – Ken White Sep 02 '15 at 22:04

2 Answers2

2

The Graphics unit was renamed to Vcl.Graphics in XE2, when Unit Scope Names were first introduced.

What's New in Delphi and C++Builder XE2

Important New Requirement: Unit Scope Names for VCL-FMX-RTL

Important: VCL-FMX-RTL units now use a dotted-prefix naming convention, such as System.Types and Vcl.Styles. If you have existing code that uses qualified identifiers (such as Types.IStream), code changes may be required in order to compile.

You do not need to use an {$IF} statement to write cross-version VCL code. Your uses clause can continue to use the Graphics unit name by itself:

uses
  Graphics;

Just make sure that Vcl is included in the Unit scope names list in the Project Options of XE2+ projects (which it should be by default).

This is documented (in fact, the documentation even uses the Graphics unit as an example):

Delphi Compiler Project Options | Delphi Compiler

Specifies the unit scope names (prefixes) for Delphi dotted namespaces, to allow you to use partially qualified names in your code and in your uses clause or #include.

There are two ways to add a unit scope name for a Delphi unit:

  • Specify the fully unit-scoped name in your uses clause. For example:

    uses Vcl.Graphics;
    
  • Add the unit scope name (Vcl) to the Unit scope names field. Then the unit scope name Vcl is automatically applied to unit names that belong to that unit scope, and you can simply specify:

    uses Graphics; 
    

The Ellipsis pop-up button opens an dialog box for selecting and adding unit scope names, as described in Common Items on Project Options Pages and Ordered list dialog box

If you choose to use an {$IF} statement, the correct syntax is:

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

Or:

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

As for the PAnsiChar versions of SysUtils.StrLen() and SysUtils.StrCopy(), they were deprecated and moved to the System.AnsiStrings unit in XE4 (RTLVersion=25.0). For example:

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;

Lastly, note that {$IF} was introduced in Delphi 6, so if you need to support Delphi 5 or earlier, you have to wrap {$IF} statements in an {$IFDEF CONDITIONALEXPRESSIONS} block.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • [pre]Thanks. This is what I was looking for. uses {$IF RTLVersion >= 23}Vcl.Graphics{$ELSE}Graphics{$IFEND}; And uses ... {$IF RTLVersion >= 25}, AnsiStrings{$IFEND} This unit will be used by other people, and I want to avoid questions like "why I can not compile this" because VCL is not in included in scope names (and in dll unit it is not by default). [/pre] – Mike K. Sep 02 '15 at 23:10
  • @Mike There is documentation for this you know – David Heffernan Sep 03 '15 at 12:33
-1

You could also use unit aliases to set things up... it's a time-travel-to-the-past future compatible way if you really need it, but will be a lot of work to setup per unit for example:

A time-travel-to-the-post future compatible example of a unit alias: VCL.Graphics=Graphics

oOo
  • 261
  • 2
  • 16