Wednesday, 22 June 2022

A SET up

- or how the for-in statement changed  recently.

Before Delphi 10.4, the statement:

for integer in [] do 

would operate on a set, but since then it now operates on an array. Which then also means a bit of different behaviour.

I had missed this change completely, and only recently gotten aware of it since we had a build issue - mixing source from different IDE versions. (BTW: Do not do that).

Since it previously worked on a set - the "list" when traversed would be an ordered list of values with an ordinal value no bigger than 255, and no more than 256 elements, that is now changed. I will list a few examples - illustrating the pre-10.4 behaviour compared to 10.4 and later.

Duplicates and ordering

  i: integer;
  for i in [42, 10, 42, 3, 42, 7] do


10.4+: 42, 10, 42, 3, 42, 7
pre10.4: 3,7,10,42


  i: integer;
  for i in [42, 365, MaxInt] do

10.4+: 42, 365, MaxInt
pre10.4: Does not compile - In 10.3 you get an E1012 Constant expression violates subrange bounds (earlier you might also get an E2024)

To solve that you could replace it with something like:


  i: integer;
  for i in TIntegerDynArray.Create(42, 365, MaxInt) do

I do think the change is a step up, and does syntax-wise work more like one would expect, so a change for the greater good - but do be aware of the change of behaviour. Another benefit of a newer version is the usage of inline variable declaration and type inference, like in this case:

for var i in [42, 10, 42, 3, 42, 7] do


Thursday, 14 October 2021

A Taste of WINE

- or how to detect if your Windows application is run under a flavor of WINE

It has been a while since I mentioned what has been going on with Siege Of Avalon - and the short story is that I have been involved in getting the game re-released on GOG and Steam - the long story deserves a longer post another time.

We currently have a bigger update/patch planned - that would be the 4th - since its re-release in April 2021 - but it is not finalized what goes in and what not.

But one of the minor things, is trying to make the game more Steam Play friendly - so that basically just allowing custom ddraw.dll and disabling a few things when run under Wine/Proton - so that the game is playable without the need to jump through hoops like winetricks and  protontricks.

Since these compatibility layers are meant to be transparent to the windows application, one would need to actually in some detect if running under Wine, luckily there is an extra bit in the NTDll.dll - the wine_get_version function.

So dynamically loading of the Dll, and try to get the address pointer of the function will reveal if your plain Delphi VCL Windows is run under Wine on Linux (or other Wine supported platforms).

The code for the simple test pictured:

procedure TForm10.Button1Click(Sender: TObject);
  dll: HMODULE;
  get_WINE_version: function: PAnsiChar;
  dll := LoadLibrary('ntdll.dll');
  if dll<>0 then
    @get_WINE_version := GetProcAddress(dll, 'wine_get_version');
    if Assigned(@get_WINE_version) then
      Label1.Caption := 'Running under ' + get_WINE_version()
      Label1.Caption := 'Pure ol'' Windows';

This is by no means the real deal, but if it helps bringing an existing application run on a different platform and making it aware of that - then it might be helpful.

A more "correct" way to migrate existing VCL applications could be, but in this case that is not doable - since not a standard Delphi VCL application.

But as you can see below this detection short-cut can help create an experimental build of Siege Of Avalon that is running on Steam Play out of the box. AS-IS.

Siege of Avalon launched under Steam Play on Linux - also showing the new live-mapping.

Please support the nice publisher of this re-released classic old game, and their willingness to keep releasing the Delphi code of the GOG/Steam releases.


Thursday, 9 September 2021

My favorite %11 new things in Delphi 11 Alexandria

- or all things "eleven", watch out for dialects.

With the public release of Delphi 11 (and RADStudio and C++Builder) today, I would like to share my %11 initial favorites in the new release.

%01. Styled Form designer

Together with the IDE HighDPI support, it is great that the gap between the running UI and the UI while designing has been reduced, and keeps in my opinion Delphi IDEs the best to design visual applications - whether it is on desktop OSs or mobile OSs.

%10. HTTP/2 support

I am looking forward to start experimenting with this, and see how much benefit and performance it will give when taking advantage of fully.

%11. Remote Desktop Support improvement

In this world where more people are coming to their senses, and wish to work remotely, focus on improving the IDE experience with remote connection is nice. And the things done can also benefit the applications build.

But there are many other things that not even a list of $11 things would cover it, and I am really looking forward to also experience to the various optimizations and running the IDE in HighDPI on my old Surface Pro.

Go EMBT :)

There is one slightly annoying thing that might split the Delphi community - adding to the list of:

- Is Delphi pronounced /del·fai/ or /del·fee/?

- Does "then begin" go on together on the same line?

- FreeAndNil?

and now this to split the community further and create fractions:

Well the above was just an excuse for me to include that funny Scottish sketch - no harm done I hope.

BTW: If you wonder about the % prefix - the it is the prefix for binary literals adding in Delphi 11.


Saturday, 22 May 2021

VAT's in it for me? - or I call my layer.

 - or a shout-out to the various services of

Sorry about the intended pun in the title - but it will all make sense.

Have you ever wanted to know the various VAT rates in the EU - no? - well neither have I, because it might put me in a bad mood, but it fits the intended pun for the post, and I also wanted to show how it is done from from Delphi.

The mother company of Embarcadero, Idera acquired another company early this year - this time, which provides numerous "simple" cloud-based API services - among these are:

  • IP geolocation and reverse lookup
  • Language detection
  • Mail address validation
  • Phone number validation
  • Flight tracking
  • Currency conversion and rates (including crypto currency)
  • Weather data and forecast
  • News, Headline and Stock apis
  • Conversion PDF and scraping
But go to, and read more about their various layers and tiers for these.

We will in this short demo look at the vatlayer - which does EU VAT stuff.

So I started by signing up for the free tier on - which gives you an API access key and access to a dashboard. As always do not share the access key - just saying.

Now you can fire up Delphi, create a new application and either use the REST Debugger or just manually throw in the REST component or create runtime - what you prefer.

I just threw in a edit control and a couple of memos and buttons, as seem above. And then I added an parameter on the RESTClient with the access_key - since I wanted to clear the request parameters on the RESTRequest, but keep the access_key. And set the BaseURL property to

I just took two of the methods/resources from - so the VAT lookup button looks like this:

  json: TJSONValue;
  RESTRequest1.Method := rmGET;
  RESTRequest1.Resource := 'validate';
  RESTRequest1.AddParameter('vat_number', LabeledEdit2.Text, pkGETorPOST);
  if RESTResponse1.StatusCode=200 then
    json := RESTResponse1.JSONValue;

..and the VAT rates for HU (since they have a higher VAT rate than DK :D) button looks like this:

  json: TJSONValue;
  RESTRequest1.Method := rmGET;
  RESTRequest1.Resource := 'rate';
  RESTRequest1.AddParameter('country_code', 'HU', pkGETorPOST);
  if RESTResponse1.StatusCode=200 then
    json := RESTResponse1.JSONValue;

There nice twists to these - by IP address or get list of rate types - and if combining these services by - I could make a speeding white-van "whistle-blower" mobile app - since all company owned registered vehicles in DK - need to have their VAT numbers on their fleet.

So I could lookup the company and their address, get their phone number by a different api layer - and then call and tell on them - MUHAAHAAAHAA (evil laughter)

..or maybe I should just create something useful and fun.

And the best part about writing this post, I now learned that Denmark has only the second highest VAT rate in EU :D


Monday, 15 February 2021

Closing in on Modal Jump Lists

- or getting a WM_SYSCOMMAND to a modal dialog.

An idea that initially seemed clever, has been haunting me a bit lately - I did put a modal dialog into a project before the main Application block (Initialize .. Run). Shame on me.

So the code looks similar to like this:

if (TfrmLaunchSetting.Execute = mrOK) then
  Application.MainFormOnTaskbar := True;
  Application.Title := 'MyApplication';
  Application.CreateForm(TfrmMain, frmMain);

and the TFrmLaunchSetting.Execute is just a class function returning the ModalResult, from its ShowModal.

But here comes the issue at hand - the Close Window in the task bars Jump List sends a WM_SYSCOMMAND that goes to the system menu in the main window - but if a modal form is shown the main window is disabled - and in this case I do not even have a main form yet.

So TApplication.HookMainWindow to the rescue - that would enable me to intercept messages sent to the main form - and act upon these.

So in the FormCreate of my modal dialog I hook the my hook function up like this:


And on FormDestroy I do the following:


The AppHookFunc goes as follows:

function TfrmLaunchSetting.AppHookFunc(var Message: TMessage): Boolean;
  Result := False;
  if Message.Msg = WM_SYSCOMMAND then
    PostMessage(Handle, WM_CLOSE, 0, 0);
    Result := True;

This way modal dialogs can react to Windows messages that normally be intended for the main form.

There are probably side-effects - but the issue at hand is solved - for now?

BTW: Yesterday was Delphi 26th birthday - I did not forget - but I am still wrapping up the present. Stay tuned.


Wednesday, 30 December 2020

It deploys and runs - what a Big Sur prize

- or the initial steps to get a Windows IDE to run cross-platform using CrossVCL.

Sorry about the pun, and I should also mention that this project is WIP, so no workable release/code yet.

Update: In the original image above the language selection was broken/disabled. Read the update in the end of the post on the changes I decided to do to makes this work better overall.

A few days back was a new update of CrossVCL announced in my email - for the lifetime license I had bought years earlier - which triggered an idea.

Saturday, 28 November 2020

A Set back?

- or how could I forget some set operators.

Recently a colleague of mine asked me to review some old code, and a line similar to the one below pop into my view as strange:

if (doorStates * [dsClosed, dsUnlocked] <> []) then

It had been so many years since I had used that specific syntax, that I completely forgot about some of the set operators in Pascal and Delphi - so I thought I would write up a small post on Sets in Pascal/Delphi.

In regards to the silly doorStates example above - here is a little riddle: When is a door not a door?