Stop Delphi automatically adding units incorrectly [duplicate] - delphi

This question already has answers here:
Delphi conditional compilation in uses clause
(4 answers)
Closed 7 years ago.
I am updating our projects from XE7 to XE8. For the time being they will still need to work with XE7, so a few conditionals are required. For example, ImageList has changed units, so Vcl.ImgList is Syste.ImageList in XE8. To make it work on both Delphi versions the uses clause looks something like this:
uses
System.SysUtils, System.Classes, Vcl.Controls
{$IF CompilerVersion >= 29.0}
,System.ImageList
{$else}
,Vcl.ImgList
{$endif}
,cxGraphics;
Sometimes this works fine. However, quite often Delphi automatically re-adds the System.Imagelist unit even though it is already there, albeit in a conditional e.g.
uses
System.SysUtils, System.Classes, Vcl.Controls
{$IF CompilerVersion >= 29.0}
,System.ImageList
{$else}
,Vcl.ImgList
{$endif}
,cxGraphics, System.ImageList;
When this is compiled, XE8 complains.
[dcc32 Error] dmImagesU.pas(13): E2004 Identifier redeclared: 'System.ImageList'
a) Why does Delphi add the unit? b) Anybody know a workaround?

The "parser" that is responsible for adding units to the uses in this case is not considering compiler directives properly (that issue already occured with the introduction of System.Actions.pas).
I usually create a dummy unit for older Delphi versions so I don't have to put any directives into the uses.
So in your case just create an empty System.ImageList.pas and put that somewhere <= XE7 finds it.

Related

Compiler directive is not set in Delphi 10.2

I have the following unit implementation in my delphi probject.
uses
{$IFDEF Ver270} JSON, {$ELSE} DBXJSON, {$ENDIF}
In Delphi XE4 DBXJSON will be implemented - that's fine.
In Delphi XE6 JSON will be implemented - that's fine too.
But in Delphi 10.2, DBXJSON will be implemented - not JSON. Why? Is this a bug in Delphi 10.2?
This is not a bug, it is by design. Each version has exactly one VERXXX definition. VER270 is defined in XE6 and XE6 only. For version 10.2 VER320 is defined.
In your scenario it is much simpler to use code like this:
uses
{$IF RTLVersion >= 27} JSON, {$ELSE} DBXJSON, {$IFEND}
Another option is to use a standard include file like jedi.inc. This takes the pain out of such conditional statements. If you use jedi.inc then you can code it like this:
uses
{$IFDEF DELPHIXE6_UP} JSON, {$ELSE} DBXJSON, {$ENDIF}

What is the Delphi 10 equivalent to DesignIntf?

Just updated the SynEdit RunTime module for Delphi 10.1 Berlin, but now I need to update the DesignTime Module... The Designer units from Delphi XE versions do not appear to be available in 10.1.
What is the recommended Design Editor and Interface module to replace the old Delphi Designers?
I was thinking there would be built-in XAML designers, since the new Delphi supports .NETCore.
Is there an alternate designer to use for FMX and cross-platform projects?
example found... requires FMX.Types unit and a header over the class
https://delphihaven.wordpress.com/2013/02/03/writing-a-simple-firemonkey-tlistlayout-implementation/
uses
System.SysUtils, System.Classes, FMX.Types;
type
[ComponentPlatforms(pidWin32 or pidWin64 or pidOSX32)]
TListLayout = class(TControl)
Here's how I changed my headers for XE, Delphi 10 and Firemonkey
(*
Directive Description
------------------------------------------------------------------------------
LINUX Defined when target platform is Linux // FOR KYLIX
// FOR WINDOWS VERSIONS USE VCL
WIN32 Defined when target platform is 32 bit Windows
WIN64 Defined when target platform is 64 bit Windows
CLR Defined when target platform is .NET
WINVCL // ADDING TO REPRESENT ALL VCL platforms
// FOR OTHER USE ELSE
// *)
{$IFDEF WIN32}
{$DEFINE WINVCL}
{$ELSE}
{$IFDEF WIN64}
{$DEFINE WINVCL}
{$ELSE}
{$IFDEF CLR}
{$DEFINE WINVCL}
{$ENDIF}
{$ENDIF}
{$ENDIF}
uses
{$IFDEF LINUX} // Kylix is target platform
QControls,
{$ELSE}
{$IFDEF WINVCL}
VCL.Controls,
{$ELSE} // ALL OTHER PLATFORMS USE FIREMONKEY CONTROLS
FMX.Controls,
FMX.Types,
{$ENDIF}
{$ENDIF}
System.Classes;
And the new controls start out like this now...
[ComponentPlatforms(pidWin32 or pidWin64 or pidAndroid or pidOSX32)]
TMyCustomComponent = class(TControl)
Nothing has changed. Your design-time package should require designide.dcp and the necessary runtime package. Designide contains what you need.
Use the Getit Package Manager
But this can be a lot simpler. I just did the following:
In the IDE, selected Getit Package Manager from the Tools menu.
Searched for Synedit
Found Synedit Turbo Pack and clicked Install
A dialog popped up. I clicked agreement and it went on installing Synedit (although with the old 230 version suffix - this ought to be changed to 240 for Berlin)
After that, I could continue editing what I was editing before this, and the latest Synedit was installed.
SyneditPropertyReg.pas still uses the same units, like DesignIntf, DesignEditors, etc.
Note that now, there are (at least) two packages: SyneditDD.dpk and SyneditDR.dpk. The latter is the runtime package, the former is the designtime package and that should require the runtime package as well as designide. I think the installer compiled a little more, but it went so fast, I couldn't see properly.

IdStreamVCLWin32 not found error in Delphi XE4

My old Delphi 7 application is using IdStreamVCLWin32 unit in one pas file. This unit is located at following location.
C:\Program Files\Indy 10 for Delphi\Source\System\IdStreamVCLWin32.pas
When I am running same code in my Delphi XE4 environment, I am getting error IdStreamVCLWin32 not found.
Note: Delphi 7 is using Indy 10 but Delphi XE4 is using Indy which comes default with it. I have not installed indy explicitly in Delphi XE4 environment.
I searched my entire C drive where Delphi XE4 is installed but found no IdStreamVCLWin32.pas file.
How to get rid from this error?
From what I can tell, you were never meant to include that unit directly. The unit IdStreamVCL would delegate to either IdStreamVCLDotNet or IdStreamVCLWin32. And so it appears to me that IdStreamVCLWin32 is an implementation detail that you are shielded from by using IdStreamVCL.
These units have, nowadays, all been coalesced into IdStreamVCL. And so you could include that. However, it's not clear to me that you should even do that. Take a look at IdStream:
unit IdStream;
interface
{$I IdCompilerDefines.inc}
uses
{$IFDEF DOTNET}
IdStreamNET
{$ELSE}
IdStreamVCL
{$ENDIF};
type
{$IFDEF DOTNET}
TIdStreamHelper = TIdStreamHelperNET;
{$ELSE}
TIdStreamHelper = TIdStreamHelperVCL;
{$ENDIF}
implementation
end.
It seems pretty clear that you are meant to use IdStream and let the compiler work out whether that implementation is provided by IdStreamNET or IdStreamVCL.
So, the answer to your question is probably that you should replace your use of IdStreamVCLWin32 with IdStream. Note that the functionality in IdStream is implemented differently now. You no longer instantiate an instance of a stream class. The modern Indy offers you a helper class TIdStreamHelper which contains class functions. So you end up writing code like this:
BytesWritten := TIdStreamHelper.Write(Stream, Bytes, Count);
However, I cannot be sure that's the right approach since I don't know what you actually use from IdStreamVCLWin32. It's quite plausible that your code uses nothing from there and the use of IdStreamVCLWin32 is simply a stray hangover from some older version of your code.
So my advice is:
Remove IdStreamVCLWin32 from your uses.
Deal with any subsequent compiler errors by studying the code and working out the right way to do it with the current Indy code.

From which version "vclunit.pas" changed to "Vcl.vclunit.pas"?

I made a component in Delphi 2007 and now I want to make it work with new versions of Delphi so I must change the uses from
uses Controls;
to
uses {$if CompilerVersion > 21}Vcl.Controls{$else}Controls{$ifend};.
But I don't know the compiler version I must write. Anyone knows it?
Unit scope names were introduced in XE2. And XE2 is compiler version 23. So the conditional is:
{$if CompilerVersion >= 23}

Delphi XE2 cannot find ComObj.dcu where did it go?

I'm trying to install the jvcl from source, but I'm getting an error in
line #1267 of unit JvInterpreter;
uses
TypInfo,
{$IFDEF JvInterpreter_OLEAUTO}
OleConst, ActiveX, ComObj,
So I removed ComObj from the uses and waited for the error further down the line:
There's an error concerning EOLEError, which is part of OleAuto I added that and hoped for the best, but....
I get an error on this line #1799:
DispatchInvoke(IDispatch(Dispatch), CallDesc, PDispIDList(#DispIDs[0]), ParamTypes, Result);
So the question is: what happened to ComObj and what unit do I need for DispatchInvoke in XE2?
The solution is to change the uses to use a fully qualified name:
uses
TypInfo,
{$IFDEF JvInterpreter_OLEAUTO}
OleConst, ActiveX,
{$IFDEF VER230} system.win.ComObj, {$ELSE} ComObj, {$ENDIF}
Now it compiles without error.
See: What is the compiler version for Delphi 2010?
For a list of compiler defines.
Simply add system.win i.e. instead of comobj use system.win.comobj

Resources