Linking to the current Delphi documentation

 Delphi  Comments Off on Linking to the current Delphi documentation
Nov 302018

The quality of the online documentation for Delphi at has improved significantly since the time when Borland fired all their help authors, so it is actually worth looking at when you want to know anything.

I see links to topics in that documentation in blog posts and in online forums (e.g. DelphiPraxis [German] [English]), but they always link to a specific version of that documentation (e.g. the one for Delphi 10.1 Berlin). I am sure most posters would like to link to the latest version rather than a specific version but don’t know how to do that or that it is even possible.

The good news is: It is possible. Simply remove the name of the Delphi version from the url and you get a link that always takes you to that page in the lastest version. E.g.:

remove the “Berlin” part and you get:

Which is always (or at least has always been) the lastest version of that page (at the time of this writing it is Delphi 10.3 Rio). This of course also works for specific topcs, like WriteLn [Berlin] [latest]

 Posted by on 2018-11-30 at 12:55

GExperts 1.3.12 beta for Delphi 10.3 Rio available

 Delphi, GExperts  Comments Off on GExperts 1.3.12 beta for Delphi 10.3 Rio available
Nov 252018

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.

Download link

See also: GExperts 1.3.12 beta 2 for Delphi 10.3 Rio.

 Posted by on 2018-11-25 at 12:50

Found the cause of the AV on exiting the Delphi IDE

 Delphi, GExperts  Comments Off on Found the cause of the AV on exiting the Delphi IDE
Nov 242018

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);
  i: Integer;
  NeedsWorkaround: Boolean;

  // 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;
// ------------- workaround part 1 starts here ------------
    // Workaround for redraw issue in Delphi 10.2 when theming is enabled:
    // 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 ------------
      for i := FFormChangeCallbacks.Count - 1 downto 0 do begin
          TFormChangeCallbackItem(FFormChangeCallbacks[i]).FCallback(Self, Form);
          // just so we can have a look at any exceptions that might be raised ...
// ------------- 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
// ------------- workaround part 2 ends here ------------
    FIsInFormChangeCallback := False;

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.

 Posted by on 2018-11-24 at 15:44

If Ctrl+Alt+F8 disables your secondary monitor

 Windows  Comments Off on If Ctrl+Alt+F8 disables your secondary monitor
Nov 182018

I just pressed Ctrl+Alt+F8 and wondered why all of a sudden my secondary monitor went blank. Turns out that this is a “Feature” of the Intel HD graphics driver.

It restores the graphics default.

And since it is such a great feature, you can’t disable or customize this hotkey. Great work Intel!

Again StackOverflow was helpful. It also provided a workaround: Using AutoHotkey you catch that hotkey to do something else, e.g. show a dialog. And since I already use AutoHotkey, I added the following to my default script:

; Disable the shortcut of the Intel Graphics driver for resetting the graphics settings
; Whoever came up with this functionality and made it impossible to disable the shortcut
; is an idiot!
^!f8::msgbox, You hit Ctrl+Alt+F8 which would have reset the Intel graphics card settings to default.
 Posted by on 2018-11-18 at 16:52

Creating and calling DLLs in Delphi

 Delphi  Comments Off on Creating and calling DLLs in Delphi
Nov 182018

I just got reminded that in 2006 I wrote an article about creating DLLs with Delphi in the Delphi Wiki.

Unfortunately I got that reminder because somebody (again) vandalized it. He probably thinks he is a l33t h4x0r for being able to edit a website. I think he simply is a [enter your favorite swearword here].

But I reverted his changes and read through that article again. It’s still correct nowadays even though it should probably be updated to mention Unicode, WideString and PWideChar.


There is also a nice article by Rudy Velthuis DLL dos and don’ts.

 Posted by on 2018-11-18 at 14:31

New blog for more personal posts

 blog  Comments Off on New blog for more personal posts
Nov 172018

I have posted only a very few personal articles here, but it always felt wrong to do that and I preferred to use Google+. Unfortunately Google decided to close down Google+, so I am forced to look for an alternative. Today I have set up a new blog for that purpose: I’ll try that for a while and and see how it works.

This blog here will stay and will be used for my “professional” posts only, so it will be mostly about programming, Delphi, Windows, Linux and, of course, GExperts.

 Posted by on 2018-11-17 at 13:05

Fake TSpeedButton based on TBitBtn updated again

 Delphi  Comments Off on Fake TSpeedButton based on TBitBtn updated again
Nov 102018

My fake TSpeedButton based on TBitBtn has been updated again. It now supports any combination of Glyph and single/multi line Text. It also supports setting Margin and Spacing.

Note that it still requires the Glyph to be on the left.

(Yes, I know, I should have selected some examples where the text does actually fit the button. ;-). But this is just the same problem as in the original TBitBtn control, I even fixed some if its bugs.)

(Click on the image to view an animated demo.)

Also, the original BitBtn object is now exposed via a read only property and there is a new pointer type Data property to attach some additional information to the object.

In addition I added a new class TdzSpeedBitBtnGroup which easily emulates the behaviour of a TRadioGroup using TdzSpeedBitBtns.

The source code is part of my dzlib library which is available from OSDN.

 Posted by on 2018-11-10 at 11:27

Making “Stay-on-top-forms” do want you want in Delphi

 Delphi  Comments Off on Making “Stay-on-top-forms” do want you want in Delphi
Nov 052018

There is an article by Peter Laman on the topic Making “Stay-on-top-forms” do want you want on the Embarcadero blog. It’s from 2004 and of course the link to the component he talks about no longer works, because it points to which no longer exists.

Here is a working link.

(I don’t know whether the component still works or is even reqired. I just encountered a problem with a stay on top form and found this article.)

Edit: It’s not a component but a class TStayOnTopForm derived from TForm. You are supposed to derive your form from this class and it does everything else for you. Unfortunately it doesn’t seem to work in my test program, but it does work in the demo that comes with it.

 Posted by on 2018-11-05 at 10:42