I'm trying to fix another VCL bug; this time in Vcl.Printers.pas.
For now we are doing this by copying the buggy VCL source files to another folder in the Delphi library path, and applying fixes to those files. We applied the fix to TPrinter.SetPrinter.
But there are six methods in the file that are decorated with attributes:
[PrintingPermission(SecurityAction.LinkDemand, Level=PrintingPermissionLevel.AllPrinting)]
procedure TPrinter.Abort;
begin
...
[PrintingPermission(SecurityAction.LinkDemand, Level=PrintingPermissionLevel.AllPrinting)]
procedure TPrinter.EndDoc;
begin
...
[PrintingPermission(SecurityAction.LinkDemand, Level=PrintingPermissionLevel.AllPrinting)]
procedure TPrinter.NewPage;
begin
...
[PrintingPermission(SecurityAction.LinkDemand, Level=PrintingPermissionLevel.AllPrinting)]
{$IF DEFINED(CLR)}
procedure TPrinter.SetPrinter(ADevice, ADriver, APort: string; ADeviceMode: IntPtr);
{$ELSE}
procedure TPrinter.SetPrinter(ADevice, ADriver, APort: PChar; ADeviceMode: THandle);
{$ENDIF}
var
...
[PrintingPermission(SecurityAction.LinkDemand, Level=PrintingPermissionLevel.AllPrinting)]
function SetPrinter(NewPrinter: TPrinter): TPrinter;
begin
...
Each of these methods causes a warning:
[dcc32 Warning] Vcl.Printers.pas(968): W1025 Unsupported language feature: 'custom attribute'
[dcc32 Warning] Vcl.Printers.pas(978): W1025 Unsupported language feature: 'custom attribute'
[dcc32 Warning] Vcl.Printers.pas(1015): W1025 Unsupported language feature: 'custom attribute'
[dcc32 Warning] Vcl.Printers.pas(1026): W1025 Unsupported language feature: 'custom attribute'
[dcc32 Warning] Vcl.Printers.pas(1080): W1025 Unsupported language feature: 'custom attribute'
[dcc32 Warning] Vcl.Printers.pas(1599): W1025 Unsupported language feature: 'custom attribute'
I could just remove the attributes. Or presumably there is a way to suppress the warnings. But i assume attributes added by Embarcadero have some purpose.
What is the way to make the language support the feature custom attributes?
Why is it not a warning in the VCL source?
Why is VCL source allowed to use it when i'm not?
What are these attributes doing?
Who reads these attribues?
Are there issues with removing them?
If there are no issues with removing them, why are they there?
I'm really asking:
How do i make it work?
But i'd also love to know:
Why is it not working?
And the why makes it a much more useful question, but the fix it would be good.
Bonus Chatter
Yes, we eventually plan to think about the possibility of investigating the use of detours. Although presumably the detoured method should still have the attribute (otherwise why would the attribute exist?)
The error message is a little misleading. I'll try to translate for you. When the compiler says:
Unsupported language feature: 'custom attribute'
what it really means is:
Cannot find a class, derived from TCustomAttribute, that matches the attribute name that you specified.
These PrintingPermission attributes, which are defined by the .net framework, have meaning for the Delphi .net compiler. Which is still used by Embarcadero to build portions of the IDE. Hence the retention of the conditional code which switches on the presence of the CLR define. When this VCL unit is compiled by the Delphi .net compiler, the compiler can see the .net framework class System.Drawing.Printing.PrintingPermissionAttribute.
There's little to be gained by you trying to deal with warnings in VCL units. It's not your code, and your goal when modifying a VCL unit is to get in and out as quickly as possible. You should be aiming to make the smallest change possible.
So, ignore the warnings. Suppress warnings and hints for the VCL units that you modify. Stuff {$W-} at the top of any VCL units you compile, and move on. Or if you just cannot bring yourself to be quite so draconian, you could use {$WARN UNSUPPORTED_CONSTRUCT OFF}.
Taking your questions in turn:
What is the way to make the language support the feature custom attributes?
It's not a language limitation. It's just that these attributes are only defined when targeting .net.
Why is it not a warning in the VCL source?
It is, at least when compiling for a target other than .net.
Why is VCL source allowed to use it when i'm not?
You would be allowed to use them too if you use the .net compiler.
What are these attributes doing?
System.Drawing.Printing.PrintingPermissionAttribute
Who reads these attribues?
The .net framework. I guess.
Are there issues with removing them?
It won't affect the output produced by the Windows compilers. It will increase the volume of differences in your revision control system.
If there are no issues with removing them, why are they there?
Because they are used on .net.
Related
I added a TOPenDialog component to a form and am writing the menu method to operate it. I copied code from a VCl project including the line openDialog1.Options := [ofReadOnly];.
The compiler rejects it since ofReadOnly (and other options) are not recognized. The TopenOptions type is included in VCL.Dialogs but does not seem to appear in the FMX version.
I am currently using the Delphi starter version which does not include the FMX.dialogs.pas file text so I cannot add the options into the unit. WIll including the VCL.dialogs file in the Uses section fix this? I have heard that it is not a good idea to mix VCL and FMX units together in the same program.
If you read Embarcadero's documentation, you will see that the FMX.Dialogs.TOpenDialog.Options property uses the same System.UITypes.TOpenOptions type that the VCL.Dialogs.TOpenDialog.Options property uses, so both dialogs have the same options available.
The reason your code is not compiling is because the TOpenOption enum has been declared with the {SCOPEDENUMS ON} directive enabled (see Scoped Enumerations). You need to prefix scoped enum values with their containing enum type name, eg
uses
..., System.UITypes;
OpenDialog1.Options := [TOpenOption.ofReadOnly];
I have an extension for a tabControl downloaded, im a newbie at delphi could somebody please tell me how i can make use of it in my current project.
I have downloaded the following file and saved it as FMX.Extensions.UX.TabControl in my project folder from here and added it to my uses on project1.
TabControl Extension
i have a project1 with a tabcontrol and a few simple items on each tab, can somebody help me in learning how to use this extension, i have no idea where to go from here.
Kind Regards
UPDATE:
I added this to my includes under form1.
{$R *.fmx}
{$I 'FMX.Extensions.UX.TabControl.pas'}
But now when i try to compile the project in delphi XE5 i get the errors.
[dcc32 Error] FMX.Extensions.UX.TabControl.pas(1): E2029 Declaration expected but 'UNIT' found
[dcc32 Error] FMX.Extensions.UX.TabControl.pas(53): E2003 Undeclared identifier: 'TIntAnimation'
[dcc32 Error] FMX.Extensions.UX.TabControl.pas(54): E2007 Constant or type identifier expected
[dcc32 Error] FMX.Extensions.UX.TabControl.pas(65): E2029 Declaration expected but 'IMPLEMENTATION' found
[dcc32 Fatal Error] FMX.Extensions.UX.TabControl.pas(65): E2226 Compilation terminated; too many errors
You need to first install the UX package. You can find it under Packages/ FMX.Extensions.UX.dproj. To install, open the package in the Delphi IDE then right click and select install.
You should also remove the line you added to the form ({$I 'FMX.Extensions.UX.TabControl.pas'}).
Disclaimer: I am the author of this component.
To add a Delphi unit to you project you need to add it to one of the uses clauses in each unit file where it will be referenced.
The structure of a unit file is:
unit <unitname>;
interface
uses <files>;
//interface declarations
implementation
uses <files>;
//code here
end.
Each uses statement takes a comma separated list of unit names, so for you this would be
uses FMX.Extensions.UX.TabControl;
As a general rule you should place the units in the uses statement of the implementation section unless anything in your interface section references it, in which case us that in your interface section. Units referenced in your interface section can lead to issues with circular unit references.
Depending on where you save the file you may also need to add it's location to your library, either under Tools/Options/Delphi Options/Library/Library Path (for all projects) or Project/Options/Delphi Compiler/Search Path (current project only).
(I would recommend saving third party code in it's own folder so you have a record of what code comes from where).
The code you are including adds components which are used at design time. These components need registering with the IDE, which #norgepaul has explained how to do. If you use these components at design time then Delphi will add them to your uses clause for the form for you.
I am looking for a predefined symbol to write a code like that:
{$IFDEF LAZARUS}
// code compiles by fpc/lazarus
{$ELSE}
// code compiles by delphi
{$ENDIF}
Use FPC
{$IFDEF FPC}
For GUI applications afaik the "LCL" symbol is defined inside Lazarus projects. In this case it probably won't matter.
In general, for bigger codebases, I would avoid having too much ifdef FPC/LCL and ifdef in your sourcecode though. It makes adding an exception or other version harder.
Use a system like JCL and Zeos(7) are using, where you give most differences an own name (like "USE_FPCUNIT" or "USE_DUNIT") and link these to versions in a central includefile.
For a short treatise on the subject see http://www.stack.nl/~marcov/porting.pdf (chapter 2)
P.s. I would consider Pocketstudio, TP,GPC,VP and WDSybil (and whatever I forgot) dead for most practical purposes and the bytecode variants Canterbury Pascal/Component Pascal/Oxygene/Prism/Delphi.NET incompatible (most are more Oberon than Pascal anyway). That pretty much leaves Delphi, Kylix and FPC to worry about.
I am trying to get rid of lots of warnings in a project after converting it from BDS 2006 to Delphi 2009.
The project needs a type library named MSHTML_TLB. The source file mshtml_tlb.pas is an incredibly large file (about 16MB and >440.000 lines of code) which is generated when the Type Library is imported into Delphi 2009.
This file produces many warnings when building the project:
W1010 Method 'ToString' hides virtual method of base type 'TObject'
Since Delphi itself has created that file, I am wondering why these warnings come up and if I should just ignore them?
If so, is there a way to disable this kind of warning just for this file?
Delphi introduced this virtual method in TObject. Your declaration of ToString in a derived class does not use override so the ToString method of TObject is not accessible anymore. Adding override to your ToString method should solve the problem unless you declared your method differently.
Write to the beginning of the MSHTML_TLB.pas file this line (in bold):
unit MSHTML_TLB;
{$WARNINGS OFF}
and at the end:
{$WARNINGS ON}
end.
As a last resort, you can hide warnings. In Delphi 2010 this is in Project Options/Delphi Compiler/Hints and Warnings. I think this particular warning is "Redeclaration of a symbol hides a member in the base class".
Start up Delphi.
On the "Component" menu in the main toolbar select "Import ActiveX Control..."
In the list box scroll and and select "Microsoft HTML Object Library".
The "Class names" should then list "TScriptlet".
Click "Install...", then click "OK" on the "Install" form that appears and "Yes" on the confirm prompt.
I am writing a class to handle security in my executable (checking serials, trial date check etc). After I compile the executable (even in Release build, with all debug and RTTI generation turned off), when I open it in NotePad and search the method name in the raw data, I can see all the names of the methods that assemble my class. There are no published members in any class in the code base.
This is bad for protection. Is there any way to tell Delphi not to store method names in the executable ? Why is it storing them at all if there is no RTTI needed and no COM explosion? Is there any compiler option controlling this?
It may be that ANY method of ANY class in the target executable is stored inside the executable in text form. Apparently this is caused by the extended RTTI being turned on by default for all classes in Delphi 2010.
If you are asking about the extended RTTI in Delphi 2010, it can be switched off by
{$RTTI EXPLICIT METHODS([]) PROPERTIES([]) FIELDS([])}
see also docwiki.
Also strip relocations, take up the following in the project's dpr file:
{$IFDEF RELEASE}
// Leave out Relocation Table in Release version
{$SetPEFlags IMAGE_FILE_RELOCS_STRIPPED}
{$ENDIF RELEASE}
... and don't forget to turn off "td 32 debug info" (in older versions) or debug info in the linker tab in later ones.
What you probably will see is your form definition as a resource (eg the binary represetation of the DFM files of your project).
If you don't want to show these (for the serial info screen etc) you shouldcreate these forms "in code". Eg create a TForm, place a TButton and TEdit onto it, attach the event handlers in code.
To do this in a handly way: start with a form and create the DFM. When vieing the form, choose View as text from the context menu and you will know what things you should copy into code. And make sure NOT to place any varaiablerefernces under de published (always put public/protected/private as the first line within your class definition.