How to avoid insert namespace in Delphi uses - delphi

I manage a huge project in Delphi 2007. The target is to upgrade it to Delphi 10.1 Berlin this year. So in the meantime the source is compiled in both versions.
If there is a problem with the new Delphi we want the old version as backup.
My problem in unit dmActions.pas that is a unit inherited from TDataModule.
uses
// VCL
ActnList,
ActnMan,
Classes,
Controls,
Forms,
Graphics,
ImgList,
Menus,
SysUtils,
XPStyleActnCtrls,
Variants,
{$IFDEF BOLD_DELPHI16_OR_LATER}
System.ImageList,
System.Actions,
{$ENDIF}
BusinessClasses;
Delphi IDE don't understand my IFDEF so it automatically insert missing units to this
uses
// VCL
ActnList,
ActnMan,
Classes,
Controls,
Forms,
Graphics,
ImgList,
Menus,
SysUtils,
XPStyleActnCtrls,
Variants,
{$IFDEF BOLD_DELPHI16_OR_LATER}
System.ImageList,
System.Actions,
{$ENDIF}
BusinessClasses, System.ImageList, System.Actions;
But this don't compile in Berlin with this message
[dcc32 Error] dmActions.pas(36): E2004 Identifier redeclared: 'System.ImageList'
[dcc32 Error] dmActions.pas(36): E2004 Identifier redeclared: 'System.Actions'
And of course "System.ImageList, System.Actions" don't compile in D2007.
So what is my best action to solve this ?

You can make use of the Unit Aliases feature of Delphi here - at least as your Delphi 2007 supports dotted unit names in the first place. This allows to use the new unit names like System.SysUtils from Delphi 10.1 Berlin and still compile that project with Delphi 2007.
For this you have to add mappings to the Unit Aliases of the Delphi 2007 project like this:
System.SysUtils=SysUtils
System.Classes=Classes
For units that don't exist in Delphi 2007, like the ones you mention in your post, simply map to an existing unit:
System.Actions=ActnList
System.ImageList=ImgList
As a benefit you end up with uses clauses free of IFDEFs.

As https://stackoverflow.com/users/2916756/nolaspeaker said it works by test compiler version directly. I used an inc-file and that don't work well in this case
But in my case I check Berlin so:
{$IFDEF VER310}
System.ImageList,
System.Actions,
{$ENDIF}

Related

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.

former worked code does not work

There are code below and worked well before
unit Unit1;
{$DEFINE _Full}
// {$DEFINE _Trial}
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms;
{$ifdef _Trial}
_programname='abc';
{$endif}
{$ifdef _Full}
_programname='abc';
{$endif}
but today I run Delphi and try to compile, it reported
Identifier redeclared: '_programname'
it looks like
{$DEFINE _Full}
does not work
your comment welcome
Both conditionals are defined. That can be inferred from the compiler error.
Either single line // comments do not comment out defines. Or you are defining _Trial at the project level. To the very best of my knowledge, a single line // comment will comment out a directive. So I presume that _Trial is defined at the project level.
The idiomatic way to comment out defines is like this:
{.$DEFINE _Trial}
For an either or condition it might be simpler with a single conditional:
{$IFDEF _Trial}
.... stuff for trial version
{$ELSE}
.... stuff for full version
{$END}
All that said, perhaps your actual problem is different because the code you show does not match the error message you reported. I'd expect an error saying that a keyword was expected, but identifier _programname found. The code in the question appears to omit the const keyword before the declaration of _programname.
I am submitting this under the assumption that _programname is supposed to be a constant, as that is most consistent with t
he code you are showing. Your constant declarations need to be declared in a CONST section block. Try this:
unit Unit1;
{$DEFINE _Full}
// {$DEFINE _Trial}
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms;
CONST //<< Changed Code
{$ifdef _Trial}
_programname='abc';
{$endif}
{$ifdef _Full}
_programname='abc';
{$endif}

EFilererror exception in Delphi 7

I have registered the package TMS Unicode Component Pack in my Delphi 7 containing TNT components.
This package contains a class named TTntCustomComboBox which I use to create my own custom component named Combobox2 :
unit Combobox2;
interface
uses
Windows, Messages, Classes, Graphics, Controls, StdCtrls, ImgList, ActiveX, SysUtils, TntStdCtrls, TntWindows;
type
TCombobox2 = class(TTntCustomComboBox)
...
procedure Register;
begin
RegisterComponents('Standard', [TCombobox2]);
end;
...
I've added this component (TCombobox2) to the package dclusr.dpk.
Compiling dclusr.dpk works but installing the package raises an exception :
Registration procedure Combobox2.Register in package C:\program files\Delphi7\Projects\Bpl\dclusr.bpl raised an exception class EFilererror : A class named TTntCustomComboBox already exists
So, how do I fix that ?
Thanks for help.
The error message indicates that your package is trying to register a component that is already registered, namely TTntCustomComboBox.
It's not obvious from the details that you have provided why this would happen. One possible reason would be if you included the TNT components in your package instead of referencing that in your package's requires clause. Another possible reason would be if your Register function attempted to register TTntCustomComboBox. This could happen if your actual declaration of TCombobox2 was like so:
TCombobox2 = TTntCustomComboBox;
Put {$WEAKPACKAGEUNIT ON} after unit caption.

What unit scope do I need for this?

I am trying to install a 3rd party package and I get a compile error:
[DCC Error] fiile/line : E2003 Undeclared identifier: 'Windows'
which refers to this line:
wnd := Windows.GetFocus;
It seems fairly obvious that I don't have my Unit Scopes right - but which do I need (and is there a general approach to find which use clause I need)?
I currently have
Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;System;Xml;Data;Datasnap;Web;
Soap;Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;Winapi;System.Win
[Update]
interface
uses
SysUtils, winapi.windows, Classes, Controls, ExtCtrls, Graphics, StdCtrls,
Dialogs, IniFiles, winapi.messages, Forms, Math
{$IFDEF DELPHI6_LVL}
, Variants
{$ENDIF}
;
No uses in the impementation section.
[Upate]
I forgot to mention. I failed (in the same way) to install it on one laptop. Then I succeeded on a second. The trouble is that I'd rather have it on my desktop and after a fresh install of XE2 starter I get these problems.
Assuming that your uses names the Windows unit at all, it would appear to do so by naming the unit as Winapi.Windows. And so your code must also do so and be written as
wnd := Winapi.Windows.GetFocus;
When you use a unit by naming the fully scoped unit name, you must also use the fully scoped name in subsequent code in that unit.
Now, if you want to use the name Windows then you must name the unit as Windows in the uses clause and let the unit alias setting do its job. If you imported the unit by naming it Windows then your original code will work.
To be very clear:
uses
Winapi.Windows;
is what you have now but you would need:
uses
Windows;
for your code to compile.
You unit scope looks fine, so try these two options
declare in your uses section Windows instead of Winapi.Windows
or modify your code like so
wnd := Winapi.Windows.GetFocus;

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