The GExperts Grep Search expert has various options to tell it which files to search:

• The current file
• All files in project
• All files in project group
• A directory list (separated by semicolon)

That sounds like an exhaustive list, but it isn’t. Both, project and project group, were only searching files explicitly listed in the project(s). Files that were linked into the project using the search path, were not searched.

Until now, that is: There is now an option to use the MAP file instead of the DPR file for project search.

The MAP file is created by the linker and contains a list of all source files linked into the program. By default, that file is not created though, you must explicitly enable it on the Linker page of the project options.

The least detailed setting “Segments” is sufficient for the new Grep functionality. If there is no MAP file, it falls back to the original method of searching files listed in the DPR file.

Beware that this will also search units located in the RTL / VCL and FMX source directories. This might not be what you want. I plan to add some more flexibility in the future.

There is no release yet and it might take a while until I feel like doing one, but you can always compile your own GExperts DLL. Make sure you delete the existing directory AppData\roaming\GExperts\DelphiXXX\UsesExpertCache when you replace the DLL with the new one.

If you get the error “PrivateGXMenuActionManager is not nil upon creation” when starting your IDE, check the entries under

There are most likely two entries for GExperts. Remove one and the error should go away.

These entries come from

1. The installer (GExperts=”path\to\dll”), because it always uses GExperts as the name for the entry.
2. The Expert Manager (GExpertsXxx=”path\to\dll”), because it uses the name of the dll file for the entry.

Yes, this is a bug. And it has been fixed on 2019-03-02.

I recently had a problem with access violations when calling methods of interfaces. The reason turned out to be duplicate GUIDs in the interface declarations. This caused AVs because the wrong methods were called and the parameters passed to them were not of the right type and numbers. Duplicate GUIDs are usually caused by copying existing interfaces and changing them, without also generating a GUID for the copy. (Btw: The Hotkey for generating a new GUID in the Delphi IDE is Ctrl+Shift+G.)

So I looked for a way to find all interfaces and their GUIDs in my program. There is a uInterfaces.Duplicates unit on GitHub which claims to retrieve this list. Unfortunately I needed this for a Delphi 2007 program and Delphi 2007 does not come with a System.RTTI unit, so this was not an option (and therefore I don’t know whether this unit would have worked).

StackOverflow didn’t help much either, apart from David Heffernan’s suggestion to parse the source code.

So this is what I did. I used GExperts Grep to search for GUIDs, or more eaxct: For the pattern that is used to add a GUID to an interface declaration in Delphi.

It always looks like this:

type
ISomeInterface = interface ['{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}'];


Where X is a hexadecimal digit in upper case.

The Regular Expression for this is:

$'\{[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}\}'$

The literals [ ] and { } must be escaped with a backslash because they have special meaning in a RegEx. [0-9A-F] means one of ‘0’..’9′ or ‘A’..’F’ which is an upper case hexadecimal digit. {4} means four of those {8} means eight and of course {12} means twelve.

You have to turn off the option “Whole Word” and turn on “Regular Expression”. Of course this needs to search at least all files in the project.

Why do I say “at least”? Because actually it needs to search all files linked into the project, including any packages if such are used. “All files in project” only searches files listed in the DPR file, so it’s potentially missing quite a lot.

Which, again, reminds me that I wanted to extend Grep Search to search all files in the MAP file. Code for getting that list is already in place and being used e.g. in the Open File Expert. I “just” need to put the pieces together.

I’m thinking about making yet another Expert out of this, that not only lists all GUIDs but shows a list of Interface names and their associated GUIDs and of course checks for duplicates.

I just fixed two (newly reported) bugs in GExperts:

1. The Set Tab Order dialog no longer worked in Delphi 6, 7 and 2005. This was due to me adding AlignWithMargins (and the associated Margins property) to the dfm file. This property apparently was introduced in Delphi 2006. Again, this underlines what I mentioned several times: I do not use Delphi < 2007 for anything but testing and fixing bugs GExperts. That’s why glitches like this tend to slip by unnoticed. That’s why I would like people to volunteer for testing the various versions. But apparently nobody can be bothered. Fine by me, but you will have to live with the consequences. I don’t have a QA department.
2. The extensions to the Uses Clause Manager caused several thousand (small) files to be created in the GExperts configuration directory. This directory is located under AppData\roaming\GExperts which means it will be copied when roaming profiles are enabledin a Windows domain. I didn’t know that anybody still uses roaming profiles since they are usually not worth the trouble, but apparently they are still being used. So I now moved that cache to AppData\local and also added a config option to disable caching altogether.

There are now 14 open bug reports on SourceForge. But if you encounter more, please do report them there!

There is no release yet and it might take a while until I feel like doing one, but you can always compile your own GExperts DLL. Make sure you delete the existing directory AppData\roaming\GExperts\DelphiXXX\UsesExpertCache when you replace the DLL with the new one.

btw: Did you notice that I have added menus to my blog?

GExperts has recently gained a few new features:

• Two new experts to start/stop recording and to replay a keyboard macro. These are minimal experts which allow you to add additional keyboard shortcuts to the existing IDE functionality. The idea and the code were contributed by Dejan M.
• Goto Previous / Next modification Editor Experts. These again are minimal experts that create menu items for existing functionality of the IDE. They are only available in Delphi XE5 and later. The idea comes from Kryvich who has also written an IDE plugin for that functionality.
• The Identfier tab I had already introduced into the Uses Clause Manager is now much more useful, because it fills much faster and because of the speed improvement now by default parses all units in the search path, not just the favorites.
• The Set Tab Order expert now has two buttons to set the tab order by position. It also has buttons to move a control up or down in the sort order like in the Edit Tab Order dialog of the IDE, but these button have keyboard shortcuts.
• The Remove Matching Lines editor expert in its default configuration removes the useless and annoying { Private declarations } etc. comments that are automatically added by the IDE for a new form. It can be configured to delete lines that match other text.
• The Favorite Files expert can now optionally add a new menu entry to the Files menu showing the configured files.
• And of course there is support for Delphi 10.3 Rio, currently as Beta 3 but you can expect a normal release shortly (maybe as early as later today).

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

Edit: There is a release version now!

I have just uploaded the third beta version of GExperts 1.3.12 for Delphi 10.3 Rio.

NOTE: This is still a BETA!

Also note that this is for Delphi 10.3 Rio only. It won’t work with any other versions.

This beta release contains a (ugly) work around for the redraw bug in the Goto-Dialog enhancement when theming is enabled. Also, a few other bugs have been fixed.

I am not aware of any more bugs that are specific to this version of GExperts or Delphi 10.3 Rio. If you still find some, please report them on SourceForge.

Also note, that I have still not tested the installer as I don’t have a fresh Delphi 10.3 installation for that test.

Edit: There is a release version now!

I have just uploaded the second beta version of GExperts 1.3.12 for Delphi 10.3 Rio.

NOTE: This is still a BETA!

Also note that this is for Delphi 10.3 Rio only. It won’t work with any other versions.

Beware of bugs, e.g. the Goto-Dialog enhancements still cause redraw problems if theming is enabled. But many bugs from the first beta have been fixed.

Please report any bugs on SourceForge.

Also note, that I have not yet tested the installer as I don’t have a fresh Delphi 10.3 installation for that test.

There have been multiple bug reports regarding the stand alone Experts Manager that comes with GExperts. They all have in common that they fail with the error

Expertmanager: ExpertManager.exe – System Error
The program can’t start because vclactnband250.bpl is missing from your computer. Try reinstalling the program to fix this problem.

Or similar messages giving a different package or a different version of the package.

So, what is the cause?

In short, you have most likely used the wrong GExperts installer. You must always use the one for the Delphi version you have installed. E.g. the current beta version for Delphi 10.3 Rio does not work for any of the older versions.

Technically this is what happens:

The Expert Manager executable loads the GExperts DLL to do the actual work (as do most of the other stand alone programs that come with GExperts, e.g. GExperts Grep or the stand alone Code Formatter).

It looks for that DLL in the directory where the executable is located. If there is only one DLL, it loads it, if there is more than one, the user gets a list to pick the one to load.

The GExperts DLLs are all built with runtime packages because that’s a requirement for IDE plugins to work. These runtime packages are installed with Delphi and reside in the bin subdirectory of the installation. Packages are just glorified DLLs so Windows tries to locate them using the same search path as for all other DLLs. If the Delphi version matching the GExperts DLL is not installed (e.g. You installed GExperts for Delphi 10.3 but your Delphi version is 10.2), you will get the error shown above.

Other possible causes are:

• The search path does not contain the bin directory of the required Delphi version (no idea how that can happen, but it does happen).
• The search path has become too long so it gets truncated before the required directory (see here for a possible remedy)

Edit: There is a release version now!

I have just uploaded a beta version of GExperts 1.3.12 for Delphi 10.3 Rio.

NOTE: This is a BETA!

Beware of bugs, e.g. the Goto-Dialog enhancements cause redraw problems if theming is enabled, the Run Parameters dialog enhancements (drag and drop for files and directories) don’t work at all.

Please report any bugs on SourceForge.

Also note, that I have not yet tested the installer as I don’t have a fresh Delphi 10.3 installation for that test.

There was a bug in the (yet unreleased) GExperts code that caused an access violation every time the Delphi IDE was closed. I have just found it, but boy was that difficult!

I knew the problem existed in the current source code and by trial and error I found a source code revision that did not yet have it: #2415. So I compared those revisions and step by step narrowed it down to the changes in the unit GX_IdeFormChangeManager in revision #2433 which was a fix for a redrawing bug in the Delphi 10.2 Search Path dialog.

So I removed the code I had added, which consisted of two parts:

procedure TFormChangeManagerInternal.ProcessActivatedForm(Form: TCustomForm);
var
i: Integer;
NeedsWorkaround: Boolean;
begin
Assert(Assigned(Form));

// We are executing the callbacks in last registered first order to allow callbacks to
// unregister themselves. (And we don't check whether a callback only unregisters itself, so
// please be cautios!). That means registering a new callback while executing a callback
// is not allowed.
FIsInFormChangeCallback := True;
try
// ------------- workaround part 1 starts here ------------
// Workaround for redraw issue in Delphi 10.2 when theming is enabled:
// https://sourceforge.net/p/gexperts/bugs/86/
// Disable redraws while we change the window
NeedsWorkaround := HasRedrawProblems(Form);
if NeedsWorkaround then
SendMessage(Form.Handle, WM_SETREDRAW, WParam(False), 0);
// ------------- workaround part 1 ends here ------------
try
for i := FFormChangeCallbacks.Count - 1 downto 0 do begin
try
TFormChangeCallbackItem(FFormChangeCallbacks[i]).FCallback(Self, Form);
except
// just so we can have a look at any exceptions that might be raised ...
raise;
end;
end;
finally
// ------------- workaround part 2 starts here ------------
if NeedsWorkaround then begin
// Allow and force a redraw of the whole window
SendMessage(Form.Handle, WM_SETREDRAW, WParam(True), 0);
RedrawWindow(Form.Handle, nil, 0, RDW_INVALIDATE or RDW_ALLCHILDREN);
// see Remarks on
// https://docs.microsoft.com/en-us/windows/desktop/gdi/wm-setredraw
end;
// ------------- workaround part 2 ends here ------------
end;
finally
FIsInFormChangeCallback := False;
end;
end;


I didn’t really think this could make a difference because the HasRedrawProblems function only returns true in Delphi 10.2 but the AV occurred in all versions of the IDE. And guess what? It didn’t make a difference at all! The AV still happened.

So I reverted all the changes to the unit, which included the addition of a few units to the uses clause in the implementation section: Messages, Registry and GX_IdeSearchPathEnhancer

The AV was gone!

Now what? I added Messages and Registry again, everything still was fine. Then I added GX_IdeSearchPathEnhancer and boom, the AV was back.

After I knew what to look for, the cause was simple to spot: Both units GX_IdeSearchPathEnhancer and GX_IdeFormChangeManager have got a finalization section. They both free an instance of a class that gets created some time during the life time of a GExperts session. By adding GX_IdeSearchPathEnhancer to the uses list of GX_IdeFormChangeManager, the execution order of the finalization sections changed.

The unit GX_IdeFormChangeManager provides a singleton instance of TFormChangeManagerInternal which gets created on demand in any of the class methods of TIDEFormChangeManager. That instance is freed in the finalization section.

The unit GX_IdeSearchPathEnhancer has an internal instance of TSearchPathEnhancer which also gets freed in its finalization section. TSearchPathEnhancer.Create registers itself for Screen.OnActiveFormChanged events to detect when the IDE’s Sarch Path dialog is being shown. In the Destructor it unregisters itself for that event.

So far, so good, now the problem occurs when the finalization of GX_IdeFormChangeManager runs before the one of GX_IdeSearchPathEnhancer: The singleton instance of TFormChangeManagerInternal gets freed and afterwards the destructor of TSearchPathEnhancer tries to use it to unregister itself from the OnActiveFormChanged event. This created a new TFormChangeManagerInternal instance which hooked the Screen.OnActiveFormChanged event. Since the finalization of GX_IdeFormChangeManager had already run, this new instance never got freed, so as soon as the GExperts DLL was unloaded, the event pointed to uninitialized memory and thus the access violation occurred. This of course will never show anything usable in the debugger as the offending code has already been unloaded.

Now you might ask, why in the world I added the additional unit to the uses clause? That was because of the fix introduced in that revision. It needed to know if the new active form as the Search Path dialog, and following the Don’t repeat yourself (DRY) principle [1] of good software development, I moved the code for detecting that, which was already in a method of TSearchPathEnhancer, to a public class method of that class. So I avoided duplicating the code. but in order to call that class method, I had to add the unit to the uses clause. Which introduced the bug.

Even though it was difficult to trace it, at least it was a reproducible bug, so I could finally track it down. Now I’m going to fix it and then I will start testing GExperts in Delphi 10.3 so I can make a new release.

[1] Yes, it is DRY, because the knowledge of how to detect if a form is the Sarch Path dialog is “business knowledge”, in this case knowledge about what class and name that form has in any of the IDE versions.