{$IF Defined(DCC) or Defined(VER210) or Defined(VER200) or Defined(VER190) or Defined(VER185) or Defined(VER180) or Defined(VER170) or Defined(VER160) or Defined(VER150) or Defined(VER140) or Defined(VER130) or Defined(VER120) or Defined(VER100) or Defined(VER90) or Defined(VER80)}
{$DEFINE Delphi} { Delphi }
{$IFEND}
You can't use
{$IF} to check for Delphi versions earlier than
VER140 (Delphi 6) since
{$IF} doesn't exist in earlier versions. You have to check
{$IFDEF CONDITIONALEXPRESSIONS} to know if
{$IF} is available to use.
Also, you are missing
VER220 for Delphi XE (
VER210 is Delphi 2010). The
DCC conditional was introduced in
VER230 (Delphi XE2).
A simpler way to detect Delphi 6-XE is to check for
CompilerVersion < 23 instead of checking each
VERxxx individually.
{$IF Defined(DELPHI) and Declared(CompilerVersion) and (CompilerVersion >= 25)}
{$LEGACYIFEND ON}
{$IFEND}
{$LEGACYIFEND} was introduced in
CompilerVersion 24 (XE3), not 25 (XE4).
This is what I would probably use:
{$IFNDEF FPC}
{$IFDEF CONDITIONALEXPRESSIONS} // Delphi 6+
{$IF CompilerVersion >= 24} // Delphi XE3+
{$LEGACYIFEND ON}
{$IFEND}
{$ENDIF}
{$IFNDEF DCC}
{$IFDEF CONDITIONALEXPRESSIONS} // Delphi 6+
{$IF CompilerVersion < 23} // Delphi 6-XE
{$DEFINE DCC}
{$IFEND}
{$ELSE}
{$IFDEF VER130} // Delphi 5
{$DEFINE DCC}
{$ENDIF}
{$IFDEF VER120} // Delphi 4
{$DEFINE DCC}
{$ENDIF}
{$IFDEF VER100} // Delphi 3
{$DEFINE DCC}
{$ENDIF}
{$IFDEF VER90} // Delphi 2
{$DEFINE DCC}
{$ENDIF}
{$IFDEF VER80} // Delphi 1
{$DEFINE DCC}
{$ENDIF}
{$ENDIF}
{$ENDIF}
{$IFDEF DCC}
{$DEFINE Delphi}
{$ENDIF}
{$ENDIF}
{$IF Defined(DELPHI) and Declared(CompilerVersion) and (CompilerVersion >= 23)}
{$DEFINE NameSpace} { Delphis NameSpace feature (eg Winapi.Windows instead of Windows) }
{$IFEND}
Technically, they are called
Unit Scope Names, not
Namespaces. They have similar syntax, but they are different features with different semantics.
{$IF Defined(DELPHI) and Declared(CompilerVersion) and (CompilerVersion >= 20)}
{$DEFINE UniCode} { Delphis UniCode support }
{$IFEND}
You might want to re-think that symbol name. The Win32 API has its own
UNICODE conditional, which Delphi and FreePascal can utilize even if they don't use the
UnicodeString type.
{$IF Defined(FPC) and Declared(FPC_VERSION) and (FPC_VERSION >= 3)}
{$DEFINE UniCode} { FreePascal UniCode support }
{$IFEND}
Likewise.
Also, if you want to detect if
UnicodeString is available in FreePascal, you can use
{$IFDEF FPC_HAS_UNICODESTRING} instead of checking the FPC compiler version. But, even if
UnicodeString is available, that doesn't guarantee the
String type maps to it (which it doesn't by default - you have to use
{$Mode DelphiUnicode} or
{$ModeSwitch UnicodeStrings} for that).
uses
{$IFDEF DELPHI}
{$IFDEF NameSpace}
{$IFDEF Windows}
Winapi.Windows,
{$ENDIF Windows}
System.SysUtils, System.Classes,
Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls, Vcl.StdCtrls,
{$ELSE NameSpace}
{$IFDEF Windows}
Windows,
{$ENDIF Windows}
SysUtils, Classes,
Graphics, Controls, Forms, Dialogs, ExtCtrls, StdCtrls,
{$ENDIF NameSpace}
{$ENDIF DELPHI}
{$IFDEF FPC}
{$IFDEF Windows}
Windows,
{$ENDIF Windows}
SysUtils, Classes,
Graphics, Controls, Forms, Dialogs, ExtCtrls, StdCtrls,
{$ENDIF FPC}
// here you can add custom units that always named same way
MyUnit
; // <- important!
Wow, that's certainly an eyesore!
You could simply add the
System,
Vcl, and
Winapi Unit Scopes to the Delphi project's options (which they should be by default) and then you can omit the Unit Scopes from the code. In which case, the two branches for Delphi and FPC units can be consolidated:
uses
{$IFDEF Windows}
Windows,
{$ENDIF Windows}
SysUtils, Classes,
Graphics, Controls, Forms, Dialogs, ExtCtrls, StdCtrls,
MyUnit;
But, if you don't want to do that, your example could still be simplified a little to reduce duplication:
uses
{$IFDEF NameSpace}
{$IFDEF Windows}
Winapi.Windows,
{$ENDIF Windows}
System.SysUtils, System.Classes,
Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls, Vcl.StdCtrls,
{$ELSE NameSpace}
{$IFDEF Windows}
Windows,
{$ENDIF Windows}
SysUtils, Classes,
Graphics, Controls, Forms, Dialogs, ExtCtrls, StdCtrls,
{$ENDIF NameSpace}
MyUnit;