Source code for Andreas Hausladen’s DfmCheck available

 Delphi  Comments Off on Source code for Andreas Hausladen’s DfmCheck available
Sep 092020

Andreas Hausladen – most probably know him because he wrote the very popular Delphi IDE Fixpackhas just announced (in German) that he published the source code of one of his other useful tools: DFMCheck. It’s in his GitHub repository.

Now I have just to figure out how to actually use it. ­čśë

 Posted by on 2020-09-09 at 09:21

GExperts for Delphi 10.4.1

 Delphi, GExperts  Comments Off on GExperts for Delphi 10.4.1
Sep 052020

I have received a few reports about bugs in GExperts in Delphi 10.4.1 that do not occur in Delphi 10.4. Here is a GExperts DLL that was compiled with Delphi 10.4.1. Maybe it will solve some of theses problems.

Simply extract the DLL and put it into the GExperts installation directory, replacing the original one.

Let me know on Delphi Praxis whether this fixes the problems.

 Posted by on 2020-09-05 at 11:36

Delphi’s TZipFile working on a stream

 Delphi  Comments Off on Delphi’s TZipFile working on a stream
Aug 202020

Recent versions of Delphi (for a suitable definition of “recent”) come with a TZipFile class implemented in the unit System.Zip. This class has the really neat feature that it can not only read the contents of a ZIP file directly from a stream but also extract a file from that stream to a TBytes array, thus it does not require any file system access.

E.g. imagine you have got a memory stream containing the contents of a ZIP archive (e.g. you got a zipped XML description from a GenICam compatible camera using the GCReadPort (PDF) function.). You now want to read a file from this stream and immediately process that file’s content without first writing it to the file system. This can be done like this:

  ms: TMemoryStream;
  ZIP TZipFile;
  Data: TBytes;
  // [...]
  // Some code here retrieves the ZIP archive's content and stores it in ms
  Zip := TZipFile.Create;
    ms.Position := 0;
    Zip.Open(ms, zmRead);
    if Zip.FileCount > 0 then begin
      Zip.Read(0, Data);
  // now we have the file's content in Data and can process it.

One very important step here is to set the stream’s position to 0 before passing it to TZipFile.Open. If you forget that (guess who did) you will likely get an EZipException in TZipFile.Read with the error message ‘Invalid Zip Local Header signature’. The reason for this is that TZipFile.Open assumes that the current stream position is the first byte of the first file stored in the ZIP archive:

procedure TZipFile.Open(ZipFileStream: TStream; OpenMode: TZipMode);
  // [...]
  FStream := ZipFileStream;
  FStartFileData := FStream.Position;
  // [...]

If it isn’t, it will try to read the files starting from that position and will fail with the exception mentioned above.

If you want to discuss this article, you can do so in the corresponding post in the international Delphi Praxis forum.

 Posted by on 2020-08-20 at 18:08

Filtering and sorting for the GExperts PE Information Exports list

 Delphi, GExperts  Comments Off on Filtering and sorting for the GExperts PE Information Exports list
Aug 092020

The GExperts PE Information tool just got a small improvement:

The Exports list can now be sorted by clicking on the column header and filtered on the export name by simply typing text.

The Escape key resets the filter.

If you want to discuss this article, you can do so in the corresponding post in the international Delphi Praxis forum.

 Posted by on 2020-08-09 at 14:44

External Exception $406D1388 in Delphi

 Delphi  Comments Off on External Exception $406D1388 in Delphi
Aug 012020

Reminder to self: Exception $406D1388 is the exception used to set a name for a thread, like in:

procedure SetThreadName(const _Name: AnsiString);
  ThreadNameInfo: TThreadNameInfo;
  ThreadNameInfo.FType := $1000;
  ThreadNameInfo.FName := PAnsiChar(_Name);
  ThreadNameInfo.FThreadID := $FFFFFFFF;
  ThreadNameInfo.FFlags := 0;
    RaiseException($406D1388, 0, SizeOf(ThreadNameInfo) div SizeOf(LongWord), Pointer(@ThreadNameInfo));
    // ignore

If you encounter this in a debugging session, simply add it to the OS Exceptions and set “Handled by” to “User program” and “On Resume” to “Run handled” (The program should handle it, it’s a bug if not. But we don’t want to see it at all.)

 Posted by on 2020-08-01 at 19:30

IntToHex for UInt64 in Delphi

 Delphi  Comments Off on IntToHex for UInt64 in Delphi
Jul 292020

Just in case I ever need this again:

function IntToHex(_Value: UInt64): string; overload;
  Buf: PUInt32;
  Buf := PUInt32(UInt32(@_Value) + 8);
  Result := IntToHex(Buf^, 8);
  Buf := PUInt32(@_Value);
  Result := Result + IntToHex(Buf^, 8);

(Delphi 2007 does not have IntToHex for UInt64.)

Note: This works only for 32 bit compilers. For 64 bit, you must replace UInt32 with NativeUInt (or UInt64) in the first line (untested). Since unfortunately the NativeUInt declaration in Delphi 2007 is wrong, I cannot simply use NativeUInt here and be done with it.

Note: This works only on little endian systems (Intel):

"The little-endian system has the property that the same value can be read from memory at different lengths without using different addresses (even when alignment restrictions are imposed). For example, a 32-bit memory location with content 4A 00 00 00 can be read at the same address as either 8-bit (value = 4A), 16-bit (004A), 24-bit (00004A), or 32-bit (0000004A), all of which retain the same numeric value. Although this little-endian property is rarely used directly by high-level programmers, it is often employed by code optimizers as well as by assembly language programmers."

Source: Wikipedia – Endianness

 Posted by on 2020-07-29 at 14:38

Compiling TeeChart 2020 for Delphi 2007

 Delphi  Comments Off on Compiling TeeChart 2020 for Delphi 2007
Jul 172020

We recently bought TeeChart 2020.30 VCL/FMX with full source code (of course) and I now tried to install it.

Steema provides a “TeeChart Source Code Recompilation Tool” (TeeRecompile.exe) that supposedly does this for you. This is fine if it works, it’s a pain in the lower back if it doesn’t. It worked fine for Delphi XE2 and 10.x but it failed for Delphi 2007 with the error “[DCC Error] DclTeePro911.dpk(39): E2202 Required package ‘IndyProtocols’ not found“.

There the pain began:

I had removed the ancient Indy10 version that was shipped with Delphi 2007 from my installation and deleted all the files. Instead I have downloaded the latest sources (OK, not the latest, the dowload was on 2020-03-20), but never bothered to compile the packages since we don’t use packages, not even the runtime packages.

So I looked for the Delphi 2007 package projects. There are 3 of them:
IndySystem110.dpk, IndyCore110.dpk and IndyProtocols110.dpk (I didn’t bother with the designtime packages.). There is also a batch file Fulld_2007.bat which supposedly builds them for you. Unfortunately it doesn’t work. There were multiple “The system cannot find the file specified.” errors. Of course it didn’t tell me which files were missing, so I added “Echo on” to the batch file to find out. It turned out to be the *110.bpl and *110.dcp files it could not find when it tried to copy them to the D11 subdirectory. Since it tries to copy them from the current directory which happened to be the Indy10\lib directory, that’s small wonder: By default bpl and dcp files are created in the Package and DCP output directories which are configured in the IDE (Tools -> Options -> Environment Options -> Delphi Options -> -> Library – Win32). These default to $(BDSCOMMONDIR)\Bpl and $(BDSCOMMONDIR)\dcp respectively. And since the developers didn’t specify a custom output directory for these projects that’s where the files went.

OK, rather than bothering with the batch file, I loaded the three package projects into the IDE, set a dcu output directory so the source doesn’t get cluttered with the dcus, and built them. That worked fine, problem solved… No, unfortunately not. When I tried the TeeChart compilation tool again, it still complained about the IndyProtocols package.

The reason is simple: The Indy Delphi 2007 package projects have a hard coded 110 suffix e.g. IndyProtocols110.dpk. The standard would have leave out that suffix e.g. IndyProtocols.dpk and configure a libsuffix (Project -> Options -> Description). This then creates IndyProtocols.dcp and IndyProtocols110.bpl. TeeChart is looking for IndyProtocols.dcp and can’t find it.

Easy to fix: Load the DclTeePro911.dpk package into the IDE, remove the requires entry for IndyProtocols and add IndyProtocols110 instead. After this change the package comiled fine in the IDE, problem solved… No, still not. The Teechart compilation tool still complained, now it didn’t find the IndyProtocols110 package. WTF? I just created it and I checked that it is where it is supposed to be: In the default DCP output directory.

Fortunately the tool also allows to output verbose messages which also writes the dcc32 calls into the log:

"c:\delphi\2007\bin\dcc32.exe"  -$D- -$L- -$W- -$O+ -$C- -$Y- -$C- -$R- -$Q-  -W+ -H  -$A8  --no-config -u"c:\delphi\2007\Lib" -u"c:\delphi\2007\Lib\Indy10" -LN"D:\Source\TeeChartPro_2020.30\Source\..\Compiled\Delphi11\Lib" -E"D:\Source\TeeChartPro_2020.30\Source\..\Compiled\Delphi11\bin" -N0"D:\Source\TeeChartPro_2020.30\Source\..\Compiled\Delphi11\Lib" -U"D:\Source\TeeChartPro_2020.30\Source\..\Compiled\Delphi11\Lib";"c:\delphi\2007\Lib";"D:\Source\TeeChartPro_2020.30\Source" -I"D:\Source\TeeChartPro_2020.30\Source" -R"D:\Source\TeeChartPro_2020.30\Source" -O"c:\delphi\2007\Lib" -M  "D:\Source\TeeChartPro_2020.30\Source\TeeImport911.dpk" -LE"D:\Source\TeeChartPro_2020.30\Source\..\Compiled\Delphi11\System"

After stupidly looking at this monster for several minutes I noticed the -u”c:\delphi\2007\Lib\Indy10″ option. Could it be that it looks for the Indy packages in that directory only? (My Delphi 2007 is installed to “c:\delphi\2007” rather than c:\program files\codegear\[whatever].)

So I copied the Indy dcp files from $(BDSCOMMONDIR)\dcp to this directory and tried again. Diesmal funktioniert alles! (This time everything works.)

Did I mention that I hate “helpful compilation tools” ? I guess I can’t really blame Steema for this (hardcoding the dcp search path is kind of – ahem – not quite a good idea though). But those indy guys seem to be kind of sloppy. You don’t really hard code the package suffixes into the project file names! That was only necessary until Delphi 5.

But hey, they are volunteers and Indy is free, so I guess you get what you pay for. ­čśë

On the other hand: Guess who has hard coded project suffixes too? TeeChart does: 911 for Delphi 2007 which means TeeChart version 9 for Delphi 11. That’s not even the standard suffix which would have been 110.

Standards are great! Everyone should have one of his own!
— attributed to Bob Metcalfe, Co-inventor of Ethernet

 Posted by on 2020-07-17 at 18:07

New Filter Exceptions expert in GExperts

 Delphi, GExperts  Comments Off on New Filter Exceptions expert in GExperts
Jul 132020

I my last GExperts related blog post I wrote about the new “Close Exception Notification” expert which I just had added to GExperts. It was a hack that hooked the Exception Notification dialog.

This spawned a discussion in the international Delphi Praxis forum and resulted in a rewrite of the expert. It’s now called “Filter Exception” expert and instead of hooking the dialog it directly hooks into the code that shows this dialog. Thus it prevents the dialog from being shown for filtered exceptions.

I have to thank Mahdi Safsafi of Delphi Detours Library fame for the detective work that lead to to this hooking code.

In that same discussion Der sch├Âne G├╝nther suggested to add a project scope to the filtering. I have implemented that too.

So now the expert can filter on:

  • Project name, which is a regular expression.
  • Exception class
  • Exception message, which again is a regular expression

I have added all those exceptions that the Delphi IDE raises on every startup to my filter. It filters on the Project = “GExperts.*”, the exception classes and the messages it shows.

That means it will no longer annoy me with them while I am debugging GExperts but will still show them for other projects.

The filter details look like this:

It’s also possible to add a filter for the current debug session only, which means that it will be deleted automatically once the debug session ends.

Unfortunately hooking of the code is only available for Delphi 2005 and later. Older versions still have got to hook the Exception Notification dialog.

If you want to test this new functionality, you’ll have to compile your own dll. Try it, it’s not rocket science!

If you want to discuss this article, you can do so in the corresponding post in the international Delphi Praxis forum.

 Posted by on 2020-07-13 at 16:59

GExperts supports even more laziness

 Delphi, GExperts  Comments Off on GExperts supports even more laziness
Jul 042020

I got into programming because I am lazy, I’d rather have the computer do the boring work than doing it myself. So it’s no wonder that I always liked Delphi and GExperts because both support my laziness.

Today I added yet another feature to save me a key stroke or mouse click: The “Close Exception Notification” expert.

You probably have encountered those libraries that always raise the same exception class on errors, or even worse, raise the generic Exception class instead of bothering to declare their own. And if I should guess, you have probably been guilty of doing that yourself (as I definitely have).

Why is that a problem, you ask?

Because you can’t easily ignore these exceptions during debugging. You always get this “Debugger Exception Notification” dialog, have to read it and decide whether you want to break and look at the code or ignore the exception:

There is this nice option to “Ignore this exception type”, but unfortunately ignoring the exception class “Exception” is rarely an option.

The same problem occurs with other rather generic exceptions like EFOpenError which you can’t really simply ignore but need to check for the file name.

So, what we need is a more finely grained filter based on the message.

Enter the new “Close Exception Notification” expert. It adds a “GExperts” button (I need a better caption) to the dialog above which lets you add filters for Exceptions based on class name and message. And since it was more convenient for me (more laziness), the message filter is a regular expression.

This button will call a configuration dialog which allows you to configure how to handle the current exception.

This dialog is mostly pre-filled if opened through the button on the “Debugger Exception Notification” dialog.
You first enter (there will be some kind of recently used list in the future) the exception class name and then a regular expression for the message. In the simplest case this can be the whole message (but beware of characters which have a special meaning in regular expressions, like ‘.’, ‘*’, ‘?’ or ‘\’). There is an additional input field which you can use to test whether the regex matches the message. When you are satisfied with your newly created rule, select the action to take automatically and press OK. The dialog will close and the action will be executed for the first time, e.g. the Ignore button will automatically be pressed.

The “Close Exception Notification” expert does not have a menu entry. But there is a configuration dialog which gives you a list of currently configured filters.

Unfortunately since this expert cannot directly modify the IDE code and I am not aware of any Open Tools API access to the exception notification, it has to hack the dialog. This results in the dialog being displayed for a short time before the expert “presses” the button for you. This is certainly not ideal but still better than not having it.

There is no GExperts release with this new functionality yet, so in order to get it, you will have to compile your own DLL.

If you want to discuss this article, you can do so in the corresponding post in the international Delphi Praxis forum.

 Posted by on 2020-07-04 at 14:54

Fixing wrong position and size of the Delphi 10.4 IDE window

 Delphi  Comments Off on Fixing wrong position and size of the Delphi 10.4 IDE window
Jun 062020

Apparently the bug that causes the Delphi IDE to not store its position correctly when placed in full screen on a secondary monitor to the left of the primary monitor (which is my setup at home and at work) still hasn’t been fixed in Delphi 10.4. Luckily the work around of editing the desktop settings still works.

For Delphi 10.4 these files are stored in

 Posted by on 2020-06-06 at 19:20