Mar 232018

A colleague of mine asked me today, how this could be:

Given this exception handler:

  // some code that calls methods
  on e: Exception do

How could e be nil? (and e.Message result in an Access Violation?)

It turned out to be an error in one of the methods that were called:

if SomeCondition then
  raise Exception('some error message');

Can you spot the problem here? For whatever reason the .Create call is missing! So instead of an exception object raise was working on a string typecasted to exception.
Changing it as follows fixed the error:

if SomeCondition then
  raise Exception.Create('some error message');

We did a grep search for “raise Exception(” in our code base and found 4 more cases where this problem existed. 4 bugs less, probably still quite a few to go.

But even worse: Greping for “raise e[a-z]*(” turned up two more cases. One in my own dzlib (unit u_dzVclUtils), another in the jcl (That one has already been fixed, my copy is a bit dated.).

In the comments to the corresponding Google+ post, David Hoyle pointed out another common mistake regarding exceptions: Forgetting to actually raise them:

if SomeCondition then
  Exception.Create('some error message');

So, I did a grep for ” e[a-z]*\.Create\(” and found several, one in the (old) SynEdit version used in GExperts, several in Indy 10 and JVCL (old versions again) and one in System.JSON.Types of the current Delphi 10.2.3 RTL (RSP-20192). None in my own code this time. 🙂

Feb 172018

UPDATE: The problem was that I was using Delphi 10.2.2 build 1978. Apparently I have missed an update in December 2017 to build 2004. I have downloaded and installed the new version, and now the patch worked fine.

I hereby apologize for being stupid, because it clearly says in the description:

This patch for RAD Studio 10.2.2 (build 2004 — it won’t work on build 1978) resolves some compatibility issues in the RTL and fixes a problem with Android animations. It is designed to be installed only on top of an existing RAD Studio 10.2.2 Tokyo installation.

(emphasis mine)

I was so sure to be running the latest version that I didn’t even check. Sorry about causing so much fuss.

I’ll leave the rest of the blog post unchanged just in case anybody is googling for some of the key words and to remind me to check first and complain later.

After I reported the problem with the Delphi 10.2.2 February 2018 Patch, Embarcadero first removed the download and has now released a new installer. Unfortunately this new patch might have solved some other problems, but it didn’t solve mine. I did a complete uninstall of Delphi 10.2.2 (I even removed all directories and files that the uninstall left behind) and a new installation from my DVD followed by applying the new patch. I could still not compile GExperts and the simple test program I described in the steps for the bug report did not compile either. (Guess what: Embarcadero apparently never actually tried to reproduce my problem, but the ticket was closed anyway.). I don’t know what exactly they think they fixed, but they didn’t fix the problem I reported which is:

RAD Studio 10.2.2 Tokyo February 2018 Patch breaks “Link with rutime packages”

  1. Create a new VCL project
  2. Open project options
  3. Select Packages -> Runtime Packages
  4. Set “Link with runtime packages” to true
  5. Close dialog with OK
  6. Compile the project
  7. -> Error

Today I tried to find out what the problem was and how to fix it. It turned out to be actually quite simple:

They updated the packages rtl.bpl and fmx.bpl together with their corresponding .dcp files. Since the .dcp files contain some versioning information the packages that use these packages (e.g. vcl.bpl which uses rtl.bpl) were no longer compatible with the new packages and the compiler complained about this.

So, the fix for this would be to recompile all the packages depending on rtl.bpl and fmx.bpl, but since I don’t have all the sources required for that, I couldn’t do that (but Embarcadero should).

What I did instead was replacing the .dcp files in libs\win32\debug and libs\win32\release with the .bak files that the Patch created. Afterwards, GExperts compiled again. And since probably the interface of the bpl files didn’t change, I don’t expect any problems. But of course, I can’t guarantee this. So, if you follow my example, you might still run into problems and, No, I won’t fix your computer. 😉

Feb 142018

IMAPcopy is a tool written by Armin Diehl. Its purpose is to copy emails from one IMAP server to another (or from one IMAP account to another) including the folder hierarchy and even the read status. It’s a command line program written in Delphi and fpc.

Since I am currently migrating a mail server I had use for such a tool and this one was the only one that did not require Java or dotNET, so I tried it. Of course, being a software developer, I found it lacking and improved it.

So, what did I improve?

Mostly one part: I did not like the fact that I had to specify the passwords of the IMAP accounts in the configuration file, so I added an option to specify “?” as the password and the tool would then let me input it at run time. I also added colouring to the the output, so it is easier to spot warnings and errors. And last but not least, I fixed a few typos in the messages.

It’s GPL code, so I’m required to give the source code to everybody to whom I give the executable. I could, of course, simply use the improved version and not tell anybody about it, so I could keep the source code “secret”, but on the other hand, why should I?

So, here is the source code. It compiles with Delphi 2007, I have not tested any other versions and I am sure it won’t compile with fpc (yes, that’s no improvement, but I don’t care).

It also needs a a Delphi port of the Borland CRT unit. I used the one released 1998 by Sergey Perevoznik, which is NOT licensed under the GPL. I have no idea where I got it from and I am not sure about the copyright since it looks like it started out as a copy of Borland’s source code. So I am not going to provide it here, sorry. But you might have a look at Embarcadero’s CodeCentral for alternatives.

Feb 112018

Note to self: In Lazarus Win64 there is no floating point type Extended, it’s mapped to Double. So, overloading something like:

function TryStr2Float(const _s: string; out _flt: Extended; _DecSeparator: Char = '.'): Boolean; overload;
function TryStr2Float(const _s: string; out _flt: Double; _DecSeparator: Char = '.'): Boolean; overload;
function TryStr2Float(const _s: string; out _flt: Single; _DecSeparator: Char = '.'): Boolean; overload;

will not compile.

Workaround: Add an {$IFNDEF Win64} around it:

{$IFNDEF Win64}
function TryStr2Float(const _s: string; out _flt: Extended; _DecSeparator: Char = '.'): Boolean; overload;
function TryStr2Float(const _s: string; out _flt: Double; _DecSeparator: Char = '.'): Boolean; overload;
function TryStr2Float(const _s: string; out _flt: Single; _DecSeparator: Char = '.'): Boolean; overload;

This probably also applies to Delphi when compiling for others than the Win32 target, e.g. Win64, Android, IOS etc.

Feb 102018

Embarcadero just released a patch for RAD Studio 10.2.2. I downloaded and installed it, and regretted doing that: It breaks linking projects with runtime packages, like GExperts, any other IDE expert and probably also most component packages.

See here for a discussion.

I submitted a bug report as RSP-19914.

Jan 292018

I have made a few changes to the code in Fake TSpeedButton based on a TBitBtn:

  • I replaced all that line drawing with a call to the WinAPI function DrawEdge.
  • I set both bitmaps to Transparent.
  • I moved the bitmap generation to a sub procedure.

Thus I got rid of about 20 LOC. That’s negative productivity for you. 😉
(Which yet again shows that Lines Of Code is an idiotic metric for software developer productivity.)

The code has been tested with several Delphi versions (6, 7, 2007, XE2 and 10.2) in Windows 8.1 and is now used in the GExperts Rename Component Expert. There is no release yet, but you can always compile your own.

Jan 282018

When you google for TSpeedButton and Focus a lot of hits are where people ask how to set the focus to a TSpeedButton and the answer of course is, that it isn’t possible because TSpeedButton descends from TGraphicControl which does not have a window handle and therefore cannot receive the input focus. And that is usually the end to it. I have found 0 (zero) answers on how to get around this shortcoming.

So I posed the same question myself in the Google+ Delphi Developers Community, hoping against hope that somebody in the 30 years that Delphi has existed has come up with a solution (e.g. a component that allows both: A Button that can stay down and still receive focus.

Apparently there are a few, most of them part of a larger component collection, mostly commercial ones, none that is simple and stand alone and free.

While waiting for answers I played around with various solutions and came up with a solution that you can see in the animated GIF above:

Take a TBitBtn, set its Caption xor assign a Glyph to it (no, it won’t work with both), set its Tag to 1, if you want it to start in the Down state, and call TdzSpeedBitBtn.Create(BitBtn).

If you don’t want to change the Down “property” yourself later on, you don’t need to keep the TdzSpeedBitBtn reference around. It will attach itself to the BitBtn and automatically be destroyed when the BitBtn is destroyed.

If you want to execute an event when the button is clicked, feel free to assign an OnClick event prior to passing it to TdzSpeedBitBtn.

If you want to be able to change the Down state, keep the reference. It does have a Down property which will let you change the Down state of the button. If you only want to read it, simply check if the Tag property is <> 0.

EDIT1: Replaced all that line drawing with a call to the WinAPI function DrawEdge.
EDIT2: Set both bitmaps to Transparent.
EDIT3: Moved bitmap generation to a sub procedure.


The helper class TdzSpeedButton isn’t even very complicated. Here is the source code:

unit GX_dzSpeedBitBtn;



  TdzSpeedBitBtn = class(TComponent)
    FCaption: string;
    FBtn: TBitBtn;
    FOrigBmp: TBitmap;
    FOrigOnClick: TNotifyEvent;
    FUpBmp: TBitmap;
    FDownBmp: TBitmap;
    procedure doOnClick(_Sender: TObject);
    procedure HandleOnClick(_Sender: TObject);
    function GetDown: Boolean;
    procedure SetDown(const Value: Boolean);
    procedure UpdateGlyph;
    constructor Create(_btn: TComponent); override;
    destructor Destroy; override;
    property Down: Boolean read GetDown write SetDown;


{ TdzSpeedBitBtn }

constructor TdzSpeedBitBtn.Create(_btn: TComponent);

  procedure PrepareBmp(w, h: Integer; _Color: TColor; _Edge: UINT; out _bmp: TBitmap);
    cnv: TCanvas;
    qrc: TRect;
    TextSize: TSize;
    _bmp := TBitmap.Create;
    _bmp.Width := w;
    _bmp.Height := h;
    _bmp.TransparentColor := clFuchsia;

    cnv := _bmp.Canvas;

    cnv.Brush.Color := _Color;
    cnv.Brush.Style := bsSolid;
    cnv.FillRect(Rect(0, 0, w, h));

    qrc := Rect(0, 0, w - 1, h - 2);
    DrawEdge(cnv.Handle, qrc, _Edge, BF_RECT);

    if FCaption <> '' then begin
      TextSize := cnv.TextExtent(FCaption);
      cnv.TextOut((w - div 2, (h - div 2, FCaption);
    end else begin
      cnv.Draw((w - FOrigBmp.Width) div 2, (h - FOrigBmp.Height) div 2, FOrigBmp);


  w: Integer;
  h: Integer;
  ColBack1: TColor;
  ColBack2: TColor;
  inherited Create(_btn);
  FBtn := _btn as TBitBtn;
  FOrigOnClick := FBtn.OnClick;
  FCaption := FBtn.Caption;

  FOrigBmp := TBitmap.Create;
  FOrigBmp.Transparent := True;

  FBtn.Caption := '';

  w := FBtn.Width - 1;
  h := FBtn.Height - 1;

  ColBack1 := rgb(240, 240, 240); // clBtnFace;
  ColBack2 := rgb(245, 245, 245); // a bit lighter than clBtnFace;

  PrepareBmp(w, h, ColBack1, EDGE_RAISED, FUpBmp);
  PrepareBmp(w, h, ColBack2, EDGE_SUNKEN, FDownBmp);

  FBtn.OnClick := HandleOnClick;


destructor TdzSpeedBitBtn.Destroy;
  // If we get here, either the constructor failed (which automatically calls the destructor)
  // or FBtn was already destroyed, so we must not access it at all.

procedure TdzSpeedBitBtn.doOnClick(_Sender: TObject);
  if Assigned(FOrigOnClick) then

procedure TdzSpeedBitBtn.HandleOnClick(_Sender: TObject);
  Down := not Down;

function TdzSpeedBitBtn.GetDown: Boolean;
  Result := (FBtn.Tag <> 0);

procedure TdzSpeedBitBtn.SetDown(const Value: Boolean);
  if Value then
    FBtn.Tag := 1
    FBtn.Tag := 0;

procedure TdzSpeedBitBtn.UpdateGlyph;
  if FBtn.Tag <> 0 then
    FBtn.Glyph := FDownBmp
    FBtn.Glyph := FUpBmp;


There is no support for grouping these buttons (yet). I’ll probably not bother but simply use the OnClick event for that.

I have so far tested this only with Delphi 2007 and on Windows 8.1. So it is still possible that it doesn’t work with other Delphi versions (I am going to use it in GExperts, so I will find out) or on other Windows versions (I have only Windows 8.1 to test, so that’s up to people who use GExperts on these versions.).

I will also add this unit to my dzlib library once I am

Jan 272018

The ToolsAPI interface IOTAComponent declares two methods for getting property values:

  IOTAComponent = interface(IUnknown)
  // [...]
    { Given the index or name, returns the property value. The untyped var
      must be large enough to hold the returned value.  If the property is
      a descendant of TPersistent, the return value is a IOTAComponent. For
      properties of any other object type, the return value is nil. }
    function GetPropValue(Index: Integer; var Value): Boolean;
    function GetPropValueByName(const Name: string; var Value): Boolean;

The comment says “The untyped var must be large enough to hold the returned value.” which pretty much lets us guess, how large it must be for an enum (or even a Boolean). Let’s say, we want to read the Enabled property of a component, do we simply pass a Boolean? Or for the Anchors property, do we pass a TAnchors variable (which is a set of TAnchorKind)?

David Hoyle’s The Delphi Open Tools API Book only mentions what to pass for strings. I had to find out the hard way: For Enums, Booleans and Sets, the methods always expect 4 bytes. So for enums and sets, better pass an integer, for Booleans, pass a LongBool.

  BoolValue: LongBool;
  IntValue: integer;
  AlignValue: TAlign;
  if _Component.GetPropValueByName('Align', IntValue) then begin
    AlignValue := TAlign(IntValue);
    _Component.GetPropValueByName('AlignWithMargins', BoolValue);
Jan 072018

When Mozilla released their last big update, they deprecated quite a few APIs for plugins. One of these plugins was FireGestures which I used to get some of the mouse gestures of Opera in Firefox. There are a few new plugins that try to replace FireGestures but none of them really seemed to work quite the way I wanted them, so I thought “Hey, you are a programmer, just write it yourself. It can’t be that hard.”.

It turned out it isn’t that hard, really. So, here comes dzMouseGestures, a tool, that supports 3 different mouse gestures and converts them to keyboard input for Mozilla Firefox:

  • Down -> Right: Ctrl+w
  • Left -> Right: Alt+Left
  • Right -> Left: Alt+Right

It requires the user to hold down the right mouse button while making these gestures.

It took me a few hours to figure out how to install a system wide mouse hook and use that to interpret the mouse movements, convert them to gestures and send key sequences to Firefox. It works for me.

The source code and version 0.0.2 of the binaries (a dll with the hook and an executable that loads this dll and displays some debug information) is available on SourceForge.

Jan 032018

Today, I finally found the time to read up on some rather ancient e-mails. One was from Paolo in the dxgettext mailing list about a bug in gnugettext.pas:

With SVN revision 75 and the following, AddDomainForResourceString() has no effect, additional translations are not used.

Suggested patch:

original code from SVN revision 79:

function TGnuGettextInstance.LoadResString(
  ResStringRec: PResStringRec): UnicodeString;

patched code:

function TGnuGettextInstance.LoadResString(
  ResStringRec: PResStringRec): UnicodeString;

He is right: After the change I made in revision 75 AddDomainForResourceString no longer worked as expected. I had never experienced that problem because I don’t use resource strings but prefer calling _() explicitly.

Having had not much sleep last night (at least that’s a good excuse because it’s even true), I simply took the suggested patch and committed it. This turned out to be a bad idea because it was reverting the change I made in revision 75 back in July 2016. That change fixed a bug that “Der schöne Günther” mentioned in Delphi Praxis. Unfortunately that bugfix introduced the new bug.

Good thing that Obones apparently had slept well 😉 and spotted the problem immediately:

Before changing this back, please consider where it comes from:

I’m not sure which one is correct, but going back to the global instance in an method of the instance itself seems a bit counterintuitive.
If one wants to call .LoadResString, I believe one should make sure it works on the expected domain.
But if one wants to have the support for multiple domains, then no specific instance method should be called.

My 2 cents.

That woke me up and I actually went and wrote a test program based on the code which Der schöne Günther posted. Then I fixed the bug, or actually, both:

As of revision 83 TGnuGettextInstance has a method ResourceStringGettext which takes both, the selected language of that instance as well as the domains added with AddDomainForResourceString into account. The fix was even quite simple: Just move the code from the global ResourceStringGettext function to the new method and from the global function call the method of the DefaultInstance like it is done e.g. in the GetText method.

%d bloggers like this: