The Wiert Corner – irregular stream of stuff

Jeroen W. Pluimers on .NET, C#, Delphi, databases, and personal interests

  • My badges

  • Twitter Updates

  • My Flickr Stream

  • Pages

  • All categories

  • Enter your email address to subscribe to this blog and receive notifications of new posts by email.

    Join 1,861 other subscribers

Archive for the ‘Event’ Category

FastMM4: turn warnings W1047 and W1048 off

Posted by jpluimers on 2021/05/12

(Tagged FastMM4 as that’s the first code I saw these warnings to be turned off)

Delphi 7 introduced introduced warnings for unsafe constructs like W1047 and W1048 so you could prepare your code for the first Delphi .NET compilers .

The oldest online documentation on this is in Delphi 2007:

After Delphi 2007, the .NET compiler got shelved, but the errors and warning stayed as they serve a good purpose for native code as well.

Delphi 2007 did not document any of the other directives.

Unlike the D2007 documentation, however, the UNSAFECODE should be written UNSAFE_CODE as with using {$WARN UNSAFECODE ON}, you will get this error:

E1030 Invalid compiler directive: 'UNSAFECODE'

Looking at the library code and example code that ships with Delphi, these are the valid $WARN compiler directives having to do with UNSAFE:

  • UNSAFE_CAST (since Delphi 7, but only used in Vcl.WinXPanels.pas introduced in Delphi 10.2 Tokyo and up)
  • UNSAFE_CODE (since Delphi 7, but still documented as UNSAFECODE)
  • UNSAFE_TYPE (since Delphi 7)
  • UNSAFE_VOID_POINTER (since Delphi XE3, as precursor to the NEXTGEN compilers)

The ultimate source for these is the file DCCStrs.pas that has shipped since Delphi 2009: [WayBack] warnings – Identifiers for Delphi’s $WARN compiler directive – Stack Overflow.

A problem is that current documentation still lists the wrong name in many places:

This one finally got it right: [WayBack] Warning messages (Delphi) – RAD Studio

UNSAFE_TYPE W1046
UNSAFE_CODE W1047
UNSAFE_CAST W1048

Note it also documented UNSAFE_VOID_POINTER:

UNSAFE_VOID_POINTER W1070

[WayBack] W1070 Use of untype pointer can disrupt instance reference counts (Delphi) – RAD Studio

And these warning messages still do not contain the directives, but do explain the underlying code construct better:

You have to use these directives:

// Get rid of "W1047 Unsafe code 'ASM'", "W1047 Unsafe code '^ operator'", "W1047 Unsafe code '@ operator'" and similar

{$WARN UNSAFE_CODE OFF}

// Get rid of "W1048 Unsafe typecast of 'TFreedObject' to 'PByte'" and similar

{$WARN UNSAFE_CAST OFF}

Back in the days, some people were not amused and disabled the warnings, for instance in [Archive.is] Re: How can I eliminate these warnings in Delphi 7 which did not appear in Delphi 5. – Google Groups:

Dennis Passmore:
I have one include file that I usually include in all projects as follows—– WarningsOff.inc —————-
{$IFDEF CONDITIONALEXPRESSIONS}
  {$IF CompilerVersion >= 14}
{$WARN SYMBOL_PLATFORM OFF}
{$WARN SYMBOL_DEPRECATED OFF}
{$WARN SYMBOL_LIBRARY OFF}
{$WARN UNIT_DEPRECATED OFF}
{$WARN UNIT_LIBRARY OFF}
{$WARN UNIT_PLATFORM OFF}

{$WARN UNSAFE_TYPE OFF}
{$WARN UNSAFE_CODE OFF}
{$WARN UNSAFE_CAST OFF}

  {$IFEND}
{$ENDIF}
———————and it gets ride of all unwanted warnings in the IDE or even DCC32.exe when compiling the project
from the command line.

I just add the following line to the project .dpr file and do not worry about the rest.

{$I WarningsOff.inc}

Dennis Passmore

“If you cannot conceive the idea you
will never achieve the desired results”

I disagree with such an approach, as those warnings have their purpose.

Knowing how to selectively disable/enable them however, is important.

–jeroen

Posted in Conference Topics, Conferences, Delphi, Development, Event, Software Development | Leave a Comment »

file – String format procedure similar to writeln – Stack Overflow

Posted by jpluimers on 2021/05/11

Cool Format feature from [WayBack] file – String format procedure similar to writeln – Stack Overflow:

The cool thing about using Format is that you use for Format Strings not only to parameterize things like width and precision inside that Format String, but also as parameters like you normally would provide values.

You can get very close to using a width of 8 and a precision of 2, like the example in your question.

For instance, to quote the documentation:

Format ('%*.*f', [8, 2, 123.456]);

is equivalent to:

Format ('%8.2f', [123.456]);

That is a much overlooked feature of Format and Format Strings.

Edit 20250910:

This was part of my answer¹ there to mimic WriteLn formatting behaviour which was not even documented at the now deleted [Wayback/Archive] Standard Routines and I/O.

Normally deleted information like above results in worse information at their current documentation site.

This time however was an exception: the current documentation is better².

¹ the start of my answer:

Read the rest of this entry »

Posted in Conference Topics, Conferences, Delphi, Development, Event, Software Development, Undocumented Delphi | Leave a Comment »

Delphi: types you cannot deprecate

Posted by jpluimers on 2021/05/06

Deprecating all types in a unit besides deprecating the unit itself will cause a hint and warning storm. Especially in projects having a lot of hints and warnings (taking over maintenance of a legacy project comes to mind) this can be very helpful to spot these locations inside many files where some obscure unmaintained unit like GIFImage.pas is still used.

[WayBack] TGIFImage for Delphi | MelanderBlog got donated to (then CodeGear, now Embarcadero) for inclusion in Delphi 2007. It was, as GifImg unit, but only documented since the [WayBack] Delphi 2009 GIFImg Namespace). For more information: delphi 2007 gifimg unit – Google Search

Delphi allows you to deprecate a lot of types, but you cannot deprecate these forms:

  • array [...] of TSomeType
  • ^TSomeType
  • class of TSomeType
  • procedure(...) ...
  • function(...): TSomeType ...
  • reference to procedure(...) ...
  • reference to function(...): TSomeType ...

Putting a deprecated 'use SomeUnit.TSomeOtherType' will fail with:

  • either a compiler error  pair
    • E2029 ';' expected but identifier 'deprecated' found“.
    • E2029 '=' expected but string constant found
  • a compiler error
    • E1030 Invalid compiler directive: 'DEPRECATED'

You can enumerate these kinds of types:

  • enumerations
  • records
  • classes, but only a full class declaration, so
    • not the class forward declaration like TMyClass = class
    • not a shortened class declaration like TMyException = class(Exception), this has to be the full TMyException = class(Exception) end deprecated 'reason';
  • methods only after the last separating ; of the method (so the virtual form is like procedure Name(...); virtual; deprecated 'use another method';)
  • named constants
  • global variables

The last few are not technically types, but included for completeness.

–jeroen

Posted in Conference Topics, Conferences, Delphi, Development, Event, Software Development | Leave a Comment »

<3 "Minimum Defendable Product": it is part of "Minimum Viable Product".

Posted by jpluimers on 2021/04/21

An important concept in [Archive.is] Kristian Köhntopp on Twitter: “<3 “Minimum Defendable Product”. Das ist ein wichtiges Konzept, das übernehme ich in meinen Sprachgebrauch.… “ quoting

[Archive.is] Mario Hachemer on Twitter: “Ich hab einen Vortrag gehalten zu dem Thema IT Security in Start-ups. Einen Begriff den ich zu dem Zweck definiert hab war das “Minimum Defendable Product” im Kontrast zum MVP. Es bietet sich an als Startup kritisch zu ermitteln welche Assetklassen man sichern kann. Das spart.… “

It is from this thread (also a threat) [Archive.is] Kristian Köhntopp on Twitter: “Operational excellence… “:

Operational excellence

Secrets gehören nicht in Source. Keine SSL Keys, keine Datenbank Passworte, und auch sonst nichts.

In Source gehört Code, der Secrets aus einem Secrets Service (Vault et al) holt, oder, wenn man einige Jahre hinterher ist, aus Files, die von hierasecrets gebaut werden.
Auch zum Testen gehören keine Secrets in den Code. auch hier können Testkeys wie in Production provisioniert werden und nach dem Test verworfen werden (wenn man will)

Die Option, Secrets im Code zu haben muss im Code Review angemeckert werden.
Willkommen in 2021, willkommen zu Operational Excellence.

[Wayback] docs.aws.amazon.com/config/latest/…
Hier die passende AWS OE Security Pillar

The first tweet quoted a surprise about the Luca App (which is highly controversial in Germany: it is a Corona contact tracing app which has some [Wayback] severe security issues):

Read the rest of this entry »

Posted in Conference Topics, Conferences, Development, Event, Security, Software Development | Leave a Comment »

Delphi TestInsight: running both DUnitX and DUnit tests in a test project

Posted by jpluimers on 2021/04/06

If you want to run both DUnitX and DUnit tests in a test project using TestInsight as runner encapsulation, then you need to be aware that when there are no DUnitX tests, it will raise an exception.

So use this code to prevent that:

    try
      TestInsight.DUnitX.RunRegisteredTests;
    finally
      TestInsight.DUnit.RunRegisteredTests;
    end;

–jeroen

Posted in Conference Topics, Conferences, Delphi, Development, Event, Software Development | Leave a Comment »

Delphi: got “EOleException with message ‘Microsoft MSXML is not installed'” in a console or test project?

Posted by jpluimers on 2021/03/31

Did you ever get this run-time error in a console or test project?

EOleException with message 'Microsoft MSXML is not installed'

It means that CoInitialize or CoInitializeEx needs to be called in the thread that uses MSXML.

Then an easy workaround is to:

  1. use the unit System.Win.ComObj in any unit that (indirectly) uses Xml.XMLDoc (for instance any unit using an XML Data Binding generated unit),
  2. use the unit System.SysUtils as well (because it defines TProcedure used below)
  3. add this code in in your initialization section (which is what VCL TApplication.Initialize does):

if InitProc <> nil then TProcedure(InitProc); // Calls CoInitialize for the main thread and prevents "EOleException with message 'Microsoft MSXML is not installed'"

The initialization section of System.Win.ComObj sets up InitProc to cals CoInitialize for the main thread, which usually suffices for these simple VCL projects, but not for most console or test projects.

Based on ideas I got after reading [WayBack] 为什么LoadXMLDocument在线程类中使用会报错?-CSDN论坛 (for which Google Translate actually does a goot job [Archive.is])

–jeroen

Posted in Conference Topics, Conferences, Delphi, Development, Event, Software Development, Undocumented Delphi | Leave a Comment »

Delphi: Any idea why Delphi (At least since Seattle) does this to Dproj files:  nodes change places – Tommi Prami – Google+

Posted by jpluimers on 2021/03/25

From a while back, but still so very relevant: [WayBackAny idea why Delphi (At least since Seattle) does this to Dproj files:  <DeployClass …> nodes change places – Tommi Prami – Google+.

Luckily most of the thread is archived by now, as G+ is dead.

This thread brought DProjNormalizer to my attention, but by now you should be better using Project Magician.

DProjNormalizer normalizes the XML structure of Delphi .dproj files, both during IDE save actions, and manually using the command-line tool DprojNormalizerCmd.exe too.

Note that the manual tool does an in-place modification of your .dproj files, so better use version control, have good backups, or use InplaceExeWrapper .

In the mean time, Project Magician has been released that too has a command-line tool ProjectMagicianCmd.exe:

The general usage is:
ProjectMagicianCmd [-v:<version> | -n | -r | -x | -f] [<filepath>]<filename> [-l:<logfile>] [-s]

The parameters have the following meaning:

  • -v = Sets VersionInfo in dproj files to a given value. Clears all version info entries in child build configurations.
    <version> up to 4 numbers separated by dots
  • -n = Normalize
  • -r = Removes unused platforms
  • -x = Removes “Excluded Packages”
  • -f = Refreshes and adds missing form type entries
  • <filename> may contain wildcards. If no extension is given .dproj is assumed

Project Magician adds more functionality, including the ability to specify settings on project, project group and global levels. An explanation of settings is at [WayBack] Keep Your Project Files Clean With Project Magician – The Art of Delphi Programming.

These are my global default settings from the Tools -> Options menu option, then following these bits of the tree:

You can get to all levels via the Project -> Project Magician menu option, then following the various tabs:



Note that if you have combinations of installed previous versions before, that you should ensure you install the most recent versions of these, as there have been incompatibility issues between them:

  • ProjectMagician (or DProjNormalizer)
  • SelectiveDebugging

Related searches

Thread

  • Jeroen Wiert Pluimers's profile photo

    +Walter Prins interesting tool! Do you know of a tool that can downgrade .dproj files so you can use them with older Delphi versions? (the opposite of what the IDE does)?

    Or someone that has written more than my XSD on .dproj files? My one is so small that’s hardly a real attempt. https://wiert.me/2013/08/31/delphi-first-try-on-an-xsd-for-groupproj-files/

  • Walter Prins's profile photo
    +Jeroen Wiert Pluimers No, but interesting idea. I suppose you’re probably aware that the JEDI JCL/JVCL takes a somewhat similar (ish) related approach, in that it generates project and package files that are compatible with every desired version of Delphi from minimalist (XML) template files. Every so often I think it might be worth looking whether one can re-use the code from there easily but haven’t gotten around to it. Always something else to do first. :/
  • Jeroen Wiert Pluimers's profile photo
    +Walter Prins no I didn’t. Where should I start reading on that minimalist template approach?
  • Walter Prins's profile photo

    +Jeroen Wiert Pluimers  Sorry I see I missed out the word installer in my comment: It’s the Jedi JCL/JVCL installers that uses xml templates etc.

    But the point stands: I guess it should be (perhaps) possible to reuse its infrastructure for ones own projects, though as I say I keep meaning to look into this but haven’t really done so.

    (BTW I’m assuming you are familiar with the JCL/JVCL and in in particular their installers that bootstrap from source code? If not then perhaps my comments may not be that useful?)

    Anyway, not sure if or where there’s particular documentation about this (kind of doubt it), but if you have the JCL/JVCL installed somewhere, then first of all have a look at the “xml” folders e.g. “<jclroot>\jcl\packages\xmls” and “<jvclroot>\jvcl\packages\xml“.

    These files appear to define projects and packages in a seemingly abstract/somewhat minimal way using XML. This seemingly is then used to automatically produce .dproj and .dpk files which are placed in e.g. “<jclroot>\jcl\packages\dXX” and “<jvclroot>\jvcl\packages\dXX” where dXX corresponds to a folder for each of the supported Delphi versions and compiled/used during installation.

    Having just looked into this briefly a bit further as a result of this conversation: Key units here (in the case of JVCL) seems to be “jvclroot>\devtools\PackagesGenerator\PackageGenerator.pas“, “<jvclroot>\install\JVCLInstall\PackageUtils.pas” and “jvclroot>\devtools\common\PackageInformation.pas” (used predictably by <jvclroot>\JVCLInstall.dproj)

    (Additionally, having looked at this a bit more closely, it also appears that the JCL does not actually replace all or even most of its .dproj and .dpk files after all, but ships version specific .dproj and .dpk files in most cases, though the JVCL does appear to mostly do so. )

    Edit: The JCL also has this interesting sounding unit “<jclroot>\source\windows\JclMsBuild.pas” which appears to be an MSBuild project file parser…

  • Jeroen Wiert Pluimers's profile photo
    +Walter Prins​ I was aware of the bootstrap and it’s been on my “eventually I’ll take a look” list like forever. One day…
  • Walter Prins's profile photo
    Same as me then basically, ha. ^^

–jeroen

Posted in Conference Topics, Conferences, Delphi, Development, Event, Software Development | Leave a Comment »

When your Delphi IDE suddenly skips unsaved changes during compilation(TL;DR: watch early signs your IDE is hosed, then restart without saving)

Posted by jpluimers on 2021/03/24

A while ago, I observed that when compiling, my Delphi IDE would not take into account unsaved changes any more.

This ws in a time when I was tracking down some hard to reproduce problems of code that sometimes would and sometimes would not compile at all.

The solution was this:

[HKEY_CURRENT_USER\Software\Embarcadero\BDS\18.0\Compiling]
"BackgroundCompilation"="False"

Somehow, the Delphi IDE had turned this flag to True without me telling it did, nor me changing an option (heck if you do a “Delphi” “BackgroundCompilation” – Google Search you hardly get any meaningful results).

Luckily, I did remember what happened around the bahaviour change: the compiler had encountered a strange error, and the IDE had become unstable.

With an unstable IDE, I did have seen damage in saved source files in the past, so I always use version control with Delphi as that allows easier to spot file differences.

What I did not anticipate was that it could corrupting my persisted IDE settings, though every now and then.

Detecting early signs of the IDE becoming unstable

  • any internal compiler error (AV or not)
  • refactoring not succeeding while it should
  • insert mode suddenly becomes override or vice versa
  • editor block selection is suddenly turned on
  • any access violation or pointer error exception

Sometimes (but not always) these can be early signs too

  • debugger blue dots not matching compiled code lines
  • the debugger not being able to debug code despite blue dots being there
  • properties in the object inspector having changed without manual action

Be prepared for an unstable IDE

  • Save your work often
  • At the earliest sign of an unstable IDE: kill (do not save work!) the affected bds.32 process using Process Explorer

BackgroundCompilation

A “Delphi” “BackgroundCompilation” – Google Search did not get much relevant results. Below are the most relevant ones I could find from it:

Too bad Google does not index the WayBack machine, as I think it contains relevant material that is now hard to find.

So it looks like the feature was introduced somewhere close to Delphi 5:

[HKEY_CURRENT_USER\Software\Borland\Delphi\5.0\Compiling]
"Show Compiler Progress"="True"
"Warn on Package Rebuild"="-1"
"Compile Beep"="0"
"Cache Headers"="0"
"BackgroundCompilation"="0"

“Delphi” “Background Compilation” – Google Search shows much more information, based on what it returned I found that the first actual documentation was for Background Compilation in Delphi 2010, some 10 years after it became available:

The image in the blog post of former product manager Andreano Lanusse shows why I did not see the behaviour: when background compiling is active, the progress dialog is transparent (and non-modal). I did not have the compiler progress enabled, so never saw that dialog change behaviour.

–jeroen

 

Posted in Conference Topics, Conferences, Delphi, Development, Event, Software Development, Undocumented Delphi | Leave a Comment »

Delphi object instance lifetime demo; do not use AfterConstruction as a poor-mans way to work around non-virtual constructor or undetermined Create hierarchy calls

Posted by jpluimers on 2021/03/23

I think using AfterConstruction is a poor man’s solution that you should only use in exceptional cases, as it is:

  • called only after the last constructor in the chain is called.
  • called outside of the constructor chain (i.e. exceptions in it will not automatically call the destructor chain, nor BeforeDestruction)
  • meant to add any initialization code that requires a fully created object instance.

There were quite a few customer sites I visited that were using AfterConstruction. Usage roughly falls into two cases:

Read the rest of this entry »

Posted in Conference Topics, Conferences, Delphi, Development, Event, Software Development, Undocumented Delphi | 1 Comment »

delphi – Invalid floating point operation calling Trunc() – Stack Overflow

Posted by jpluimers on 2021/03/18

I bumped into [WayBack] delphi – Invalid floating point operation calling Trunc() – Stack Overflow, while searching for what might have tests like these fail:

TValueRecordTests.Int64_Through_Value_Container_via_Currency_Intermediate_Is_Identity_Operation(9223372036854775807) = 9223372036854775807
EInvalidOp with message 'Invalid floating point operation'

In the end, it reproduced with a much more simple test case class of which the first three fail (EInvalidOp with message 'Invalid floating point operation'), but the last three succeed.

Lesson learned:

  • High(Int64) stored in Currency or Double, will not Trunc back to their original value.
  • Low(Int64) stored in Currency will not Trunc back to their original value.
  • Testing boundary conditions is nice, but be sure what your boundary conditions are in the first place.

Read the rest of this entry »

Posted in Conference Topics, Conferences, Delphi, Development, Event, Software Development | Leave a Comment »