GExperts for Delphi 11 isn’t here yet

 Delphi, GExperts  Comments Off on GExperts for Delphi 11 isn’t here yet
Sep 122021

I’m working on a GExperts release for Delphi 11. But due to the changes for High DPI support in the IDE this might still take a while.

If you are adventurous, you can always get the sources and build your own DLL. There is a project and build scripts for Delphi 11 already. But be warned: There will be bugs!

 Posted by on 2021-09-12 at 18:19

Separate cache directories per platform in the Uses Clause Manager in GExperts

 Delphi, GExperts  Comments Off on Separate cache directories per platform in the Uses Clause Manager in GExperts
Aug 082021

The Uses Clause Manager in GExperts has an “Identifier” tab that can be used instead of the Find Unit refactoring of the Delphi IDE (which for me doesn’t work most of the time and if it does is very slow). And of course the Uses Clause Manager also works for older Delphi versions which simply didn’t have this refactoring.

For this to work it parses all source files in the various search paths of the project. And because this takes a while it caches the results and only updates this cache if a new unit is found or a unit has been changed.

Until recently this parser was assuming that the current project is a Win32 application and set the conditional defines accordingly. Later I chanted the conditional defines depending on the currently selected platform but this caused a problem: Units parsed for different platforms ended up in the same cache so it was possible that the lookup was showing wrong results or at least the “Open Unit” button placed the cursor on the wrong line.

Today I changed this to use separate cache directories for each platform, so this problem should no longer occur.

There is not yet a GExperts release containing this change. If you want to use it, you will have to compile your own DLL which is much easier than you might think.

btw: Did yo know that Stefan Glienke has published a similar tool called Delphi Uses Helper? Mine of course is better and much faster. 😉
(Actually it depends on your computer and the project size. On my computer for large projects both tools are about on par, but mine is more flexible. Stefan thinks otherwise. But check it out yourself.)

If you want to comment on this blog post, you can do so in the corresponding topic in the international Delphi Praxis forum.

 Posted by on 2021-08-08 at 10:00

Separate lists for VCL and FMX in GExperts Rename Components expert

 Delphi, GExperts  Comments Off on Separate lists for VCL and FMX in GExperts Rename Components expert
Aug 072021

The Rename Components expert in GExperts now has separate lists for the names and additional properties for VCL and FMX components. Previously it was a hassle to have additional properties shown in the rename dialog if these have different names in VCL vs. FMX e.g. the Caption vs. Text property of TLabel. Now you simply configure them differently.

This is the configuration for a VCL label:

And this for an FMX label:

Now the expert checks which designer the current project is using and selects the proper list for it.

So, for a VCL label the rename dialog looks like this:

While for a FMX label, it looks like this:

There is not yet a GExperts release containing this change. If you want to use it, you will have to compile your own DLL which is much easier than you might think.

If you want to comment on this blog post, you can do so in the corresponding topic in the international Delphi Praxis forum.

 Posted by on 2021-08-07 at 15:24

Limited GExperts support for Delphi 6

 Delphi, GExperts  Comments Off on Limited GExperts support for Delphi 6
Jun 202021

A few weeks back something happened with my Delphi 6 installation which now results in an access violation every time I start the IDE. I tried for several hours to find and fix the problem to no avail. It’s not GExperts related, disabling the DLL was the first thing I tried. Now I’m giving up. This will mean that while GExperts will still continue to support Delphi 6 and I will compile a dll with every release (as long as the command line compilation still works), I will not be able to debug and fix any issues.

If you are still using Delphi 6 you are invited to take over this task. I will of course mention you in the credits if you do.
(There is no money in GExperts, just whatever fame there still is left. I’m getting less in donations than I pay for this website. And I usually donate even that money to other tools that I use regularly.)

If you want to comment on this blog post, you can do so in the corresponding topic in the international Delphi Praxis forum.

 Posted by on 2021-06-20 at 15:51

GExperts and older / unpatched Delphi IDEs

 Delphi, GExperts  Comments Off on GExperts and older / unpatched Delphi IDEs
May 162021

GExperts is always compiled with the latest update of any of the supported Delphi versions. That unfortunately means that it may not work if the IDE hasn’t been updated to the latest version. E.g. The latest GExperts release will not work with Delphi 10.2, but only with Delphi 10.2.3, the latest update to Delphi 10.2. This is due to changes in the runtime packages that are not always backward compatible.

Until a few years ago, this was no problem because when you bought Delphi you were automatically entitled to receive all updates for this version. E.g. if you bought Delphi 2007 you could download all updates for it and GExperts would simply work for you.

This changed when Embarcadero tried to force all their customers to buy a maintenance subscription. Now, if you don’t have such a subscription, you will no longer receive updates and bug fixes. You automatically get a subscription for 1 year when you buy a new Delphi license so this sounds like a minor issue. But a subscription not only gets you updates but also upgrades to the yearly major releases, e.g. from 10.2 to 10.3.
So, if you do not extend an existing subscription shortly after a new major release you will not get updates and bug fixes for this release. You have only two options then: Stick with the previous major release + all updates and bug fixes, or keep using the latest major release and hope that you don’t need the updates for it. Of course that’s on purpose to keep customers extending their subscriptions.

This also affects GExperts: If you are stuck using a non-updated major release GExperts might not work for you.

I have been asked whether I could make releases for these cases. Unfortunately this would require me to keep all minor Delphi releases around, e.g. 10.2, 10.2.1, 10.2.2 and 10.2.3. These cannot be installed on the same computer so that would mean 4 virtual machines for Delphi 10.2.x alone + several for other major versions. Yes, I could do that. But since GExperts is currently a one man (me) show, it would take quite a lot of my time for very little gain. (But everybody is invited to contribute!)

So, what can be done? If you are one of those people affected by this, simply build your own DLL. It’s not difficult at all. This will create a DLL that is compatible to the Delphi version you are using, so your problem is solved.

If you want to comment on this blog post, you can do so in the corresponding topic in the international Delphi Praxis forum.

 Posted by on 2021-05-16 at 16:59

GExperts bug: CTRL+V on FMX form designer inserts into secondary editor window

 Delphi, GExperts  Comments Off on GExperts bug: CTRL+V on FMX form designer inserts into secondary editor window
Apr 112021

I got a bug report for GExperts and Delphi 10.4 that’s really curious:

When a secondary editor window is open in the IDE and the FMX form designer is active, trying to insert a component from the clipboard into the form inserts the textual description of that component into the editor windows instead.

I could immediately reproduce this but finding the culprit took quite a bit longer.

Observation 1: It does not happen for the VCL form designer.

Observation 2: It only happens, if you use CTRL+V to insert the component. The form designer’s context menu entry works fine.

Observation 3: Even disabling all experts in GExperts did not solve this problems… Until you restart the IDE, then it’s gone, even if you then enabled the experts again… Until you restart the IDE again which brings it back.

After a lot of trial and error I found that the cause are two of the GExperts editor experts:

  • Goto Previous Modification
  • Goto Next Modification

Disabling these experts and restarting the IDE solves the problem.

These are rather simple experts that only add entries to the editor window’s context menu for a functionality that already is part of the IDE. I added them to make that functionality more visible, and because I could. Since Delphi 10.3 I had to use a workaround to still be able to add entries to that menu because apparently it is being recreated in the OnPopup event. I think this code somehow activates the menu entries or their associated actions even if the editor window doesn’t have the focus.

So for now until I find a real workaround: If you have this problem, disable these two experts.

(The workaround might be to remove these experts altogether. They aren’t that useful anyway.)

If you want to comment on this blog post, you can do so in the corresponding topic in the international Delphi Praxis forum.

 Posted by on 2021-04-11 at 18:06

GExperts 1.3.18 experimental twm 2021-02-21 released

 Delphi, GExperts  Comments Off on GExperts 1.3.18 experimental twm 2021-02-21 released
Feb 212021

COVID-19 got us all down a bit and even with the vaccines theoretically available now, the light at the end of the tunnel seems very far away. My own turn for a jab will probably not come before fall 2021, so I can only hope that summer will reduce the infection rates as much as it did last year, but the new mutants that spread around the world definitely aren’t good news.

Maybe I can lighten up your mood a bit with a new GExperts release.

There are a few bug fixes and an also a few new features in the new version, but nothing really exciting.

The “major” new feature is the Explicit Properties Filter expert. This was the one functionality I missed most when Andreas Hausladen did not update his ddevextensions for Delphi 10.4. But did you know that Andreas has now open sourced this plugin?

There is also a small speed improvement in the Project Option Sets expert.

I hope this time the installers won’t be wrongly detected as malware by virus scanners. Sorry about that.

Please note that GExperts for Delphi 10.4 requires Update 1!

The new version is available for download on the GExperts download page.

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

 Posted by on 2021-02-21 at 15:53

When sorting a “StringList” is very costly

 Delphi, GExperts  Comments Off on When sorting a “StringList” is very costly
Jan 052021

The following code looks innocuous but slows down a program significantly:

  TJCHListSortCompare = function(Item1, Item2: Integer): Integer of object;
  TCheckListBoxWithHints = class(TCheckListBox)
    procedure QuickSort(L, R: Integer; SCompare: TJCHListSortCompare);

// [...]
procedure TCheckListBoxWithHints.QuickSort(L, R: Integer; SCompare: TJCHListSortCompare);
  I, J, P: Integer;
  tmpObj: TObject;
  tmpStr: string;
  tmpChecked: Boolean;
    I := L;
    J := R;
    P := (L + R) shr 1;
      while SCompare(I, P) < 0 do Inc(I);
      while SCompare(J, P) > 0 do Dec(J);
      if I <= J then
        // exchange I and J
        tmpStr           := Items[I];
        tmpObj           := Items.Objects[I];
        tmpChecked       := Self.Checked[I];

        Items[I]         := Items[J];
        Items.Objects[I] := Items.Objects[J];
        Self.Checked[I]  := Self.Checked[J];

        Items[J]         := tmpStr;
        Items.Objects[J] := tmpObj;
        Self.Checked[J]  := tmpChecked;
        if P = I then
          P := J
        else if P = J then
          P := I;

    until I > J;
    if L < J then QuickSort(L, J, SCompare);
    L := I;
  until I >= R;

Yes it’s Quicksort and it sorts strings in a TCheckListBox’s Items property, swapping not only the strings but also the objects and the Checked values.

Now, run this with, lets say 100 entries. That shouldn’t be any problem for Quicksort, should it? But it takes about 2 seconds on my computer which is muuuuuuch longer than I expected. The same code running on a simple TStringList takes less than 1/10 of a second. Why is that?

It’s because accessing the strings and changing them each results in a Windows message to be sent, handled and checked.

TCheckListBox inherits its Items property from TCustomListBox which declares it as:

    property Items: TStrings read FItems write SetItems;

Still looks innocuous? Now, let’s see how it is actually instantiated:

  FItems := TListBoxStrings.Create;
  TListBoxStrings(FItems).ListBox := Self;

So, what is TListBoxStrings? It’s a class that descends from TStrings and provides access to the strings stored in a TCustomListBox using Windows messages. E.g.:

function TListBoxStrings.Get(Index: Integer): string;
  Len: Integer;
  // [...]
    Len := SendMessage(ListBox.Handle, LB_GETTEXTLEN, Index, 0);
    if Len = LB_ERR then Error(SListIndexError, Index);
    SetLength(Result, Len);
    if Len <> 0 then
      Len := SendMessage(ListBox.Handle, LB_GETTEXT, Index, Longint(PChar(Result)));
      SetLength(Result, Len);

To get a string, it sends two messages to the Listbox’s handle and interprets its results.


procedure TListBoxStrings.Put(Index: Integer; const S: string);
  I: Integer;
  TempData: Longint;
  I := ListBox.ItemIndex;
  TempData := ListBox.InternalGetItemData(Index);
  ListBox.InternalSetItemData(Index, 0);
  InsertObject(Index, S, nil);
  ListBox.InternalSetItemData(Index, TempData);
  ListBox.ItemIndex := I;

In order to set a string to a new value, it first deletes it and then inserts it again.

Want to guess what Delete() does? It sends a message to the listbox’s handle. And what does InsertObject do? It sends a message to the listbox’s handle.

While all this is an ingenious way to provide simple access to the strings normally only available using the mentioned messages, it’s far from efficient when you do a lot of comparisons and some swapping, which is exactly what a sorting algorithm does.

So, what can be done?

First, don’t work on the Items property directly but take a copy of it. Also, don’t swap the Checked property values (which also use messages) directly but take a copy of these too (in particular since some of the Compare functions passed to the sorting code also test the Checked property). Then sort the copy and assign it back to the listbox’s Items and Checked properties:

  cnt: Integer;
  tmpList: TStringList;
  ChkArr: TBoolArray;
  i: Integer;
  tmpList := TStringList.Create;
    SetLength(ChkArr, cnt);
    for i := 0 to cnt - 1 do
      ChkArr[i] := Checked[i];
    QuickSort(tmpList, ChkArr, 0, cnt - 1, Compare);
      Items := tmpList;
      for i := 0 to cnt - 1 do
        Checked[i] := ChkArr[i];

This code is from the GExperts Project Option Sets expert. This is one of the experts I had never used before and was shocked that, when I opened the dialog, it took several seconds before anything was shown. The reason turned out that the sorting described above was executed not only once but even twice in the FormShow event. After the changes I outlined above and reducing it to sort only once, it was down to less than half a second. That still felt like eternity, but was a significant improvement.

After I added some more tweaks, e.g. use a lookup list into an array of several hundred entries rather than linear search to find a particular string, the dialog now opens nearly instantly (on my computer).

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

 Posted by on 2021-01-05 at 16:16

New Explicit Properties Filter expert in GExperts

 Delphi, GExperts  Comments Off on New Explicit Properties Filter expert in GExperts
Dec 272020

I never understood the benefit of writing the ExplicitLeft / Top / Width / Height properties for TControl and descendants, which were added in Delphi 2007, to the dfm files. They store the control’s position and size before its Align property was set to something like alClient or alRight, so they can be restored later. That’s useful if you change these by accident or double click on the Align property to go through the possible values, but as soon as you save the form, you don’t really need them any more. Even worse, they seem to change often with no apparent reason and therefore clutter a dfm file’s diff with changes that nobody is interested in.

That’s probably why Andreas Hausladen added the option “Do not store the Explicit* properties into the DFM” (under “Form Designer”) to his DDevExtensions plugin. I have enabled that option since I found it. Unfortunately Andreas has not yet released a Delphi 10.4 version of DDevExtensions (and his other useful tools) because there is no Community Edition of Delphi 10.4 yet and he no longer has access to the latest Delphi versions (From what I read in the forums he chose not to accept a free license from Embarcadero, probably due to some strings attached to that offer.) Whatever the reason: Having those annoying properties back has irked me for a while now.

Achim Kalwa has written a plugin that removes them, but I didn’t want to install an additional plugin just for this functionality.

So I eventually came around adding it to GExperts. It’s a bit hidden because it does have a menu entry, only a configuration dialog:

In addition it’s not active by default so it won’t conflict with DDevExtensions if that’s also active.

So, if you want to use this new expert, you will have to explicitly activate it. It also allows you to selectively write some of the ExplicitXxx properties anyway, but I doubt that anybody will ever use that.

There is no GExperts release with this Expert yet. If you don’t want to wait, you’ll have to compile your own DLL.

If you want to discuss this article, go to the related post in the international DelphiPraxis forum.

 Posted by on 2020-12-27 at 12:02