Sunday, 6 September 2020

Delphi and the WinRT API


The WinRT (Windows Runtime) API was introduced with Windows 8, although it’s fair to say that most of us have tried our level best to forget that particular Windows release and pretend it never happened. Anyway, Microsoft has been trying to convince us that new Windows APIs will be introduced in the WinRT API and what we normally refer to as the Windows API might well remain as it is. We’ll see how true that becomes. The WinRT API reference can be found documented here.

The nice thing about WinRT is that it is not another step on the .NET journey; indeed it is nothing to do with .NET whatsoever. WinRT is implemented as native code and it is made available to whatever language wishes to consume it by language projections. Microsoft offers a C# language projection to consume it in .NET but it also offers a native C++ language projection (C++/WinRT).

Each WinRT class implements various interfaces to offer up methods and properties to call. There may also be static methods (i.e. class methods) and factory methods through which you can create an instance of the class. The Microsoft language projections make all the methods implemented through all the supported interfaces directly available once you create an instance of a WinRT class.

WinRT metadata

Anyone else can make their own language projections by analysing the API metadata (which are available in .winmd files in the C:\Windows\System32\WinMetadata folder). Metadata files are rather like COM type libraries in that they describe all the WinRT classes and methods etc., but they are actually files that share the same format as Win32 executables and .NET assemblies: PE files. You can find detailed information on these files from Microsoft here. Microsoft’s C++ .winmd file parser is open-sourced and available on github.

WinRT and Delphi

Embarcadero folks started looking at how to consume the WinRT API back in 2011 and Thom Gerdes wrote a few posts on how got on. He talks about these metadata files in this old post available on the Wayback Machine.

So, do we have a Delphi language projection? Well, kinda... We have import units that pull in a good chunk of the WinRT API, but things aren’t quite as transparent and trivial to use as they are in C++and C#. However, depending on how persistent we are we can get results. Indeed there are some uses of the WinRT API in the Delphi / C++Builder RTL; it is used for Windows desktop notifications and for share contracts.

This post looks into how we might use the WinRT API directly to perform a simple task, namely to trigger a Windows notification message. This might seem an odd thing to do, given the RTL already covers this quite nicely in the TNotificationCenter class but it serves as a simple, visual example.

Friday, 14 February 2020

25 Delphi Tips for 25 Years of Delphi

It seems funny to think Delphi is 25 years old, and yet sure enough the celebrations are ongoing for the 25th Anniversary of its unveiling on 14th February 1995.

As it happens I've been part of the Delphi world for around 26 years now, as I used to work at Borland and was involved with testing and experimenting with and working with the pre-release versions.

What can I say other than Happy Birthday, Delphi? You've been a good friend to me over this last quarter of a century and I've been happy to be part of your world.

Some number of posts ago I wrote up 10 Tips for Delphi Users. When I checked I was horrified to find this was 7 years ago! (My, my, how time flies when you're having fun...) Anyway, I thought I'd take that list and build upon it, expanding it up to 25 tips for Delphi users, which is what we have here. So without further ado let's get straight into the list.

Wednesday, 12 February 2020

The Enter key and the OnKeyDown/OnKeyUp events on Android

A problem surfaced on Stack Overflow recently from a Delphi developer, Tom Byrnes, who discovered that on Android, the Enter (or Return) key no longer triggers the OnKeyDown and OnKeyUp events. This was unfortunate as Tom wanted to code to run in (one of) those handlers.

The problem had been reported as RSP-27496 but alas it had been closed at the time Tom was hunting for a solution (to my mind closed wrongly).

What to do?

Well, after some valiant fighting with the problem accompanied with the inevitable wailing and gnashing of teeth, Tom found a workaround of sorts. Setting the TEdit control's ReturnKeyType property Go, Search or Send allows the OnKeyDown event to fire for the Enter key. Good stuff! But not ideal....

I sent a note to a relevant party within EMBT and after reviewing the report it has since been re-opened. That's a start.

Tuesday, 11 February 2020

C++Builder's Android location sensor woes

There is an unfortunate problem with RAD Studio 10.3.3 for anyone using C++Builder building Android applications. However it has a quite straightforward resolution, so let's look at what the issue is.

If you make a new Multi-Device Application in C++Builder and build it, all will be well, of course. The basics work very nicely.

If you now drop a TLocationSensor component on the form and try to build now, the result will be different. Compilation goes fine. Linking looks like it is going fine.... until it fails with a rather unhelpful message:

[ldandroid Error] "ld" exited with code 1.

Let's look at how we can get more useful feedback from this rather opaque and somewhat 1990s error message and see how to resolve the underlying problem.

Rebuilding the Delphi & C++Builder Android Java files

Some while back I posted a command script (or batch file as we used to call them) that could be used by RAD Studio 10.3 users if they felt the need to change any of the few Java files underlying Delphi's (and C++Builder's) Android RTL and FireMonkey code.

The script would rebuild all the Java files into the required fmx.dex.jar and fmx.jar archives and copy them into the relevant RAD Studio installation folders to be used on subsequent builds.

When I tried to use the script with RAD Studio 10.3.3 of course it didn't work as things have changed, different files need to be involved in the process. I have updated the script now to work with RAD Studio 10.3.3 and thought I'd share it in case anyone else needs to do this.

An obvious question is: Why would anyone else want to rebuild the Java Android RTL files? Well this is normally a necessary step if you find an issue in the code as Embarcadero ships it and you want to try to fix it or enhance it. Indeed the previous post on rebuilding the 10.3 Java files was all about patching the Java code to get Android Intent support working.

If you have no interest in tweaking the Java code or fixing any issues you encounter in the Java code then you probably won't be needing this script.

If you do need the script, remember to take a backup of your original compiled archives before you proceed. These are found in:

  • C:\Program Files (x86)\Embarcadero\Studio\20.0\lib\android\debug\fmx.jar
  • C:\Program Files (x86)\Embarcadero\Studio\20.0\lib\android\debug\fmx.dex.jar
  • C:\Program Files (x86)\Embarcadero\Studio\20.0\lib\android\release\fmx.jar
  • C:\Program Files (x86)\Embarcadero\Studio\20.0\lib\android\release\fmx.dex.jar

The script needs to be run from an administrative command prompt and before you run it you should double-check the various paths set up in the environment variables at the start are all valid on your system.