Reminder to self: write some more about the IsBinaryDfmFile and ConvertDfmToText tools in [WayBack] jeroenp / wiert.me / Native / Delphi / Apps / Console / DfmTools — Bitbucket
–jeroen
Posted by jpluimers on 2021/02/03
Reminder to self: write some more about the IsBinaryDfmFile and ConvertDfmToText tools in [WayBack] jeroenp / wiert.me / Native / Delphi / Apps / Console / DfmTools — Bitbucket
–jeroen
Posted in Delphi, Development, Software Development | Leave a Comment »
Posted by jpluimers on 2021/02/02
I had a “W1030 invalid compiler directive true” in a project that got ported from Delphi XE3 to a much more modern Delphi version.
Luckily I found [WayBack] Porting to XE5 and the “W1030 Invalid compiler directive: ‘true’” warning | The curse of Dennis D. Spreen.
The cause was this on one of the PropertyGroup elements:
<DCC_DebugInformation>true</DCC_DebugInformation>
This correspondents to the Project Options -> Delphi Compiler -> Compiling -> Debugging setting to be true which is not supported any more.
It is similar to When the Delphi XE5 commandline compiler fails with error F1026: File not found: ‘False.dpr’
Related: [WayBack] Embarcadero Discussion Forums: XE10 compiler war: [dcc32 Warning] W1030 Invalid compiler directive:’true’
–jeroen
Posted in Delphi, Development, Software Development | Leave a Comment »
Posted by jpluimers on 2021/01/28
If you have a class (like TMyClass) in the current unit, you can get the unit name as follows:
UnitName or UnitScope to get the unit nameTMyClass.UnitName or TMyClass.UnitScopeDelphi added UnitName [WayBack] and Delphi XE2 added UnitScope [Archive.is]. Their implementations are different, but I have not seen classes where the outcome is different.
The code below shows that when the underlying RTTI UnitName field inside a PTypeData referred by a PTypeInfo contains an @ sign, then UnitName takes the part before the @, and UnitScope the part after the @, but I have not yet seen units where the underlying field contains an @ sign.
If you have seen that, please let me know.
I needed this in order to research some unit initialisation order issues.
A post helpful with that was [WayBack] windows – Can I determine the order in which my units have been initialized? – Stack Overflow for which this comment by Ritsaert Hornstra is the most important bit:
Related: If you use a unit in the interface section you know that that unit will be initialized BEFORE the unit that uses that unit. When using units in the implementation section this is not the case. So usually when you are using a unit with a singleton in it, created in it’s initialization section, you should use that unit in the interface section to make sure that it is initialized before use.
There is also an answer [WayBack] by Remko Weijnen that shows how to hack the current initialisation order if you know the address of InitContext inside the System.InitUnits method.
Back to UnitName versus UnitScope, the code:
class function TObject.UnitName: string; var LClassInfo: Pointer; S: _PShortStr; begin LClassInfo := ClassInfo; if LClassInfo <> nil then begin S := @PClassData(PByte(LClassInfo) + 2 + PByte(PByte(LClassInfo) + 1)^).UnitName; if S^[1] <> '@' then Result := UTF8ToString(S^) else Result := UTF8ToString(Copy(S^, Pos(_ShortStr(':'), S^) + 1, MaxInt)); end else Result := ''; end; class function TObject.UnitScope: string; var LClassInfo: Pointer; S: _PShortStr; begin LClassInfo := ClassInfo; if LClassInfo <> nil then begin S := @PClassData(PByte(LClassInfo) + 2 + PByte(PByte(LClassInfo) + 1)^).UnitName; if S^[1] <> '@' then Result := UTF8ToString(S^) else Result := UTF8ToString(Copy(S^, 2, Pos(_ShortStr(':'), S^) - 2)); end else Result := ''; end;
Related:
–jeroen
Posted in Delphi, Development, Software Development | 1 Comment »
Posted by jpluimers on 2021/01/27
A while ago, I saw this tweet:
It mentions LISP (nowadays mostly called Lisp), likely because their derivatives like Scheme and Clojure still actively mention their ancestry.
ALGOL is not in the list, but has had so much influence on modern programming. So here the thread that followed:
–jeroen
Posted in ALGOL, Delphi, Development, LISP, Software Development | Leave a Comment »
Posted by jpluimers on 2021/01/27
On one of the sites, when having some Delphi package registration issues, the standard measure was to delete the complete Package Cache subtree (like HKEY_CURRENT_USER\Software\Embarcadero\BDS\17.0\Package Cache).
Since there is so little information about it, it is on my list of things to eventually research.
Some links I already found, but had no time for to fully read:
Hopefully the Cleaning package cache for Jcl110.bpl in this post will help me find more details.
Unrelated: You should not delete the folder C:\ProgramData\Package Cache\? – Super User, but matched my initial delphi registry “Package Cache” – Google Search.
Yup, I did it: I added an “Undocumented Delphi” category.
–jeroen
Posted in Delphi, Development, Software Development, Undocumented Delphi | Leave a Comment »
Posted by jpluimers on 2021/01/26
Every once in a while you want to have a Delphi Watch of a field inside an object (say an object of type TContext), except that the field has no value yet, but eventually will point to another object (say an object of type TUser).
However, the original object will go out of scope, so you need to employ a few tricks.
First of all, you get the address of that field:
@(Context().FCurrentUser) = $7EF6F624
Then you watch the content of that field:
TUser(PPointer($7EF6F624)^),r = nil
To get to this trick, you have to remember:
$7EF6F624 is pointer (at first nil) to a TUser.$7EF6F624 by using PPointer($7EF6F624)^.TUser(...) cast.–jeroen
Posted in Delphi, Development, Software Development | Leave a Comment »
Posted by jpluimers on 2021/01/21
There are a few TNonRefCountInterfacedObject (or maybe better named TNonReferenceCountedInterfacedObject) implementations around (see list of links below).
They can be used to expose interfaces, but do not provide interface reference counting. This means you have to do your own lifetime management, which can bring quite a few headaches.
So each class you descend from it must have proper motivation on why, and how lifetime management is performed.
One thing you can do is mark the class with a hint directive like [WayBack] library.
In addition, [Archive.is] TNonRefCountInterfacedObject / [Archive.is] TNonReferenceCountedInterfacedObject implementations should at least implement [WayBack] IInterface (or [WayBack] IUnknown in really old Delphi versions); I have seen implementations that don’t but just provide almost empty [WayBack] QueryInterface, [WayBack] _AddRef and [WayBack] _Release methods).
Some examples via “TNonRefCountInterfacedObject” – Google Search:
I used this GExperts Grep Search expression to find the entries below:
(_AddRef|_Release|QueryInterface)
Delphi itself has a few implementations of non-standard interface management that have good documentation on their use cases. So take a look at at least these before doing something odd with interface implementations yourself:
TAggregatedObject in System
IInterface implementations to a controllerIInterface itself, so a descendent must add the interface referenceTContainedObject and TPropertyPageImpl (the latter used by TActiveXPropertyPage)TContainedObject in System
IInterface implementations except QueryInterface to a controllerTSOAPHeaders (via TSOAPHeadersBase) used by TSoapPascalInvoker, TInvokableClass and TRIO, and TConnectionPoint used by TConnectionPointsTInterfacedPersistent in System.Classes
TPersistent. Classes like TCollectionItem, TFieldOptions and TEditButton implement this ownership behaviour.IInterface), but not QueryInterfaceTComponent in System.Classes
TComponent. Classes like TComponent and TCollectionItem implement this ownership behaviour.IInterface calls to the owner (including QueryInterface).TXPEditReaderStream in DUnit XP_OTAEditorUtils. It is largely undocumented.TXPInterfacedObject in DUnit XPInterfacedObject. It is largely undocumented too.Not so good examples:
TCustomVariantType in System.Variants (which is basically TSingletonImplementation with a lot of extra methods)TSingletonImplementation in System.Generics.Defaults(which is basically what most TNonRefCountInterfacedObject implementations do; this is sort of OK as it is meant to be used only in [WayBack] TCustomComparer<T> and descendants that are supposed to be singletons).IUnknown in Winapi.Ole2 (this whole unit is undocumented; the class only has virtual abstract methods; the unit – together with Winapi.OleCtl – seems to be only meant to support the depcrecated Vcl.OleAuto unit.)And of course there is the standard implementation with proper multi-threading support:
TInterfacedObject in SystemThere are quite a few classes that implement reference counting while descending from things like TComponent, usually without the proper multi-threading support that TInferfacedObject has:
Posted in Conference Topics, Conferences, Delphi, Development, Event, Software Development | Leave a Comment »
Posted by jpluimers on 2021/01/20
I always forget the syntax, so this quick grep helps me finding the lines in Delphi .dproj files that have the right copy statements for getting certain DLLs in the output directory.
Those are very useful to copy for instance the FastMM or OpenSSL DLLs from a central location.
[WayBack] GNU grep (which shows filenames and supports UTF-8 and UTF-16):
grep -inS copy *.dproj | grep -i ssl | grep -i dll | grep -v amp
Good old Borland grep:
grep -ind copy *.dproj | grep -i ssl | grep -i dll | grep -v amp
The amp trick excludes any lines having amp in them, incuding the & lines that are duplicated by the IDE throughout the .dproj file to keep build configurations linked correctly.
Related:
–jeroen
Posted in Delphi, Development, Software Development | Leave a Comment »
Posted by jpluimers on 2021/01/19
I came across some very old code that used the IdObjs unit as it was depending on the TIdStringStream type.
Digging around, I found the unit has been removed from Indy after the Delphi 2007 era.
If you need to transition away, these links – including an old version of it – will help:
Note it is still referenced from [WayBack] indy/IdTestObjs.pas at master · graemeg/indy · GitHub.
–jeroen
Posted in Delphi, Development, Software Development | Leave a Comment »
Posted by jpluimers on 2021/01/14
For my link archive: [WayBack] GitHub – pierrejean-coudert/delphi-libraries-list: List of Delphi Libraries and Frameworks
–jeroen
Posted in Conference Topics, Conferences, Delphi, Development, Event, Software Development | Leave a Comment »