The Wiert Corner – irregular stream of stuff

Jeroen W. Pluimers on .NET, C#, Delphi, databases, and personal interests

  • My badges

  • Twitter Updates

  • My Flickr Stream

  • Pages

  • All categories

  • Enter your email address to subscribe to this blog and receive notifications of new posts by email.

    Join 1,862 other subscribers

Archive for the ‘Delphi’ Category

Detecting the Delphi edition that is installed

Posted by jpluimers on 2019/04/09

Via [WayBack] In what ways can you detect which edition of Delphi in installed from the installed files? I’m trying to distinguish between Standard, Professional, E… – Jeroen Wiert Pluimers – Google+

Different Delphi editions have different msbuild support files. For instance IDL is only available in Enterprise/Architect/Ultimate (which use the exact same binaries anyway).

IDL is old, see

So I updated my [WayBack] jeroenp / wiert.me / Run-Dependend-rsvars-From-Path.bat — Bitbucket (which besides running rsvars.bat, can start the various Delphi IDE personalities, or run msbuild with various configurations) with [WayBack] jeroenp / wiert.me / commit / 2c55fa1bf786 — Bitbucket:

Support 10.1 Berlin and 10.2 Berlin in Run-Dependend-rsvars-From-Path.bat, as well as Professional/Starter editions.

Thanks to Andrea Magni – Google+, Querying was simple: look for the value of the Edition entry under inside the *\X\BDS\Y.0 where Y is the BDS version, X is Borland, CodeGear or Embarcadero (depending on the BDS version) and * is the base key HKEY_CURRENT_USER\Software, HKEY_LOCAL_MACHINE\SOFTWARE , HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node.

–jeroen

Posted in Delphi, Development, Software Development | Leave a Comment »

When generics and VCL controls bite you: memory overwrites when you show the control usually ending up in access violations

Posted by jpluimers on 2019/04/09

Recently I got bitten by the 2013 reported http://qc.embarcadero.com/wc/qcmain.aspx?d=112101 (too bad the site is gone and the WayBack machine doesn’t have it archived) as a result of [WayBackdelphi – Why do I get access violations when a control’s class name is very, very long? – Stack Overflow.

It got reentered as [RSP-18399] Buffer overflow in TWinControl.CreateParams() – Embarcadero Technologies but since that requires logon, it’s not search machine indexed so it’s very hard to find unless you know where to look.

So I spent a quite some time to find out what was wrong:

Since Delphi 1, the [WayBackControls.TCreateParams Record has a 64-byte WinClassName field that’s blindingly copied by the TWinControl.CreateParams without range checking.

The structure is used by the [WayBackTWinControl.CreateWnd Method to call the Windows API [WayBackRegisterClass function that takes a [WayBackWNDCLASS structure with a lpszClassName field that supports up to 256 characters and it fails when it’s longer.

That overwrite cause spurious other errors depending on the memory that gets overwritten. It took almost a day to figure out the cause of the error was this field, then an hour or to track that down to the long class names created by generic code.

To my surprise, I found back [WayBack] This issue caused coworkers and me quite a few hours wasted:Long story short – refactor some forms/frames to class names longer than 64 chars and boom… – Stefan Glienke – Google+.

As of Delphi 8 (yes, that version that a lot of people want to forget, but did bring a few good things), the structure was defined as below, and the code intialising also got improved:

Params.WinClassName := ClassName;
...
Params.WinClassName := Format('%s.%d', [Params.WinClassName, AppDomain.CurrentDomain.GetHashCode]);

So there it’s a string that – if it is too long – will get rejected by the Windows API anyway just like the native Delphi VCL implementation should have done 20+ years ago.

The sad part for FMX users: that structure and code got blindingly copied to the FMX.Controls.Win unit.

Read the rest of this entry »

Posted in Delphi, Development, Software Development | Leave a Comment »

Detecting if a debugger is present is different from detecting if an IDE is present.

Posted by jpluimers on 2019/04/04

I have seen this happen in various environments: people wanting to detect if their debugger is present, but trying to detect their IDE, or vice versa.

Similar reasoning is for detecting for being running on a console, or your project having been built to run on a console.

People use these decisions, for instance to determine if their application should behave as a service, or as a regular process.

Ways to determine the various permutation points:

  • Running inside a debugger: use the [WayBackIsDebuggerPresent function (which can be true, even if Delphi DebugHook stays zero).
  • Check for the IDE: tricky; as IDEs have different behaviour over time. For Delphi, check for any TAppBuilder Window class with the [WayBack] FindWindow function.
  • Compiled for console: for Delphi check IsConsole, for .NET I could not find good information.
  • Running on a console: check if you can allocate a handle to stdout
  • Running as a service: check the hosting assembly or hosting process

Related links:

–jeroen

Posted in .NET, Delphi, Development, Software Development, Windows Development | Leave a Comment »

Firemonkey/Isometric at master · tothpaul/Firemonkey

Posted by jpluimers on 2019/04/04

This shows you how to do 2.5D isometric projection in Delphi using Firemonkey: [WayBackFiremonkey/Isometric at master · tothpaul/Firemonkey.

[WayBackIsometric projection – Wikipedia.

Via: [WayBack] I wonder what the best approach would be to use FireMonkey to develop an isometric 2.5D game in the “classic” way… – Fl Ko – Google+

–jeroen

Posted in Delphi, Development, FireMonkey, Software Development | Leave a Comment »

Delphi: do NOT use duplicate GUIDs on interfaces

Posted by jpluimers on 2019/04/04

One of the things when fixing bugs in an old codebase is wading through technical debt.

A quick win is to get rid of duplicate GUIDs when interface portions have been copy-paste re-used:

  1. interfaces with the same GUID are treated the same with as casts even if they are different.
  2. the compiler does not warn about duplicate GUID values**

These searches help big time: it shows the duplicate GUIDs if they have been indented all the same way. Good enough for most situations.

grep -Sh "\[\'{" *.pas | sort

grep -rh "\[\'{" *.pas | sort

It depends which flavour of grep you use (gnu or regular) to specify recursion.

Note that findstr doesn’t cut it as it always shows the filename: [WayBackList files recursively showing only full path and file size from Windows Command Prompt – Super User

** this compiles without warning:

program NoWarningOnDuplicateInterfaceGUID;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils;

type
  IInterface1 = interface
    ['{ECF26C39-CBFF-488E-A3AB-2629726F1005}']
  end;

  IInterface2 = interface
    ['{ECF26C39-CBFF-488E-A3AB-2629726F1005}']
  end;

var
  Subject: IInterface;
begin
  try
    (Subject as IInterface1)._Release;
    (Subject as IInterface2)._release;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.

–jeroen

Read the rest of this entry »

Posted in Delphi, Development, Software Development | Leave a Comment »

Delphi, attributes, RTTI and the IDE

Posted by jpluimers on 2019/04/03

Reminder to self: [WayBack] It took me a while to address an awful IDE crash issue. If you install a design time package which uses RTTI to populate custom attributes declared in… – Baoquan Zuo – Google+

TL;DR: be very careful using the built-in RTTI support objects as when they refer to custom defined attributes in packages, and the packages get unloaded, the cache does not get flushed.

Bug: RSP-11620: IDE crashes when rebuilding a project group that contains a component with customattribute

–jeroen

Posted in Delphi, Development, Software Development | Leave a Comment »

Interface methods are not assignment compatible with method references or methods of object.

Posted by jpluimers on 2019/04/02

Boy I wish that QC was still up and QualityPortal was publicly indexable as that would have saved me quite a bit of time tracking this down. Luckily I got help from Stefan Glienke (who maintains the awesome Spring4D library based on modern Delphi compiler support) when I mentioned

How good are you with reference to function?
I’ve an odd compiler thing throwing errors when using interfaces but not with classes.

So, for posterity:

Unlike C#, in Delphi interface methods are not compatible with method references or methods of object.

This has many manifestations, which means you can get a variety of compiler errors. I’ve listed the ones I could find below, but presume there are more and if I find more will update this post.

These are the errors you can get:

  • E2010 Incompatible types: ‘T’ and ‘Procedure’
  • E2035 Not enough actual parameters
  • E2250 There is no overloaded version of ‘FirstOrDefault’ that can be called with these arguments

These are the (now defunct, but used to be publicly accessible) QC and QualityPortal (needs sign on) entries (thanks Stefan Glienke and Blaise Thorn for reporting these):

The really frustrating part is that the RSP is marked as “new feature” whereas clearly it isn’t, so it probably never will be fixed.

A workaround for now is to wrap the interface method references with:

  • either anonymous methods (when you have just a few classes to cover, but maybe more than a few methods on the interface)
  • or instance methods on a class (when there are many classes to cover and preferably few methods on the interface)

Examples are in the code below that also shows this works fine and dandy in C#.

–jeroen

Read the rest of this entry »

Posted in Delphi, Delphi 10 Seattle, Delphi 10.1 Berlin (BigBen), Delphi 10.2 Tokyo (Godzilla), Delphi XE3, Delphi XE4, Delphi XE5, Delphi XE6, Delphi XE7, Delphi XE8, Development, Software Development, Spring4D | Leave a Comment »

Not sure why, but sometimes the Delphi IDE does not allow you to toggle the Console Application; it looks off, but is in fact on: IsConsole returns true

Posted by jpluimers on 2019/03/28

On my research list: Not sure why, but sometimes the Delphi options display a regular application, but the IsConsole returns true because of AppType Console in the main PropertyGroup.

  1. console applications are turned off in the linker
  2. the debugger still shows it as a console application when stepping through the initialization section of the System unit

One of the problems is that unlike the {$APPTYPE directive (which has not changed much over time), the AppType element is undocumented (hardly anything in the .dproj file is documented).

The $APPTYPE lists two values: Console and GUI, defaulting to GUI:

Empirically, the AppType element can have these values:

  • Application
  • Console
  • Package

This is the topmost part of the .dproj file does not matter, without AppType element valued Console, or with it or even having it valued Application: either way a console application is being built.

There is no $APPTYPE in the .dpr or any of the .pas files.

The IsConsole variable is always false and a console window always appears when debugging.

That variable is not always conclusive, as there are situations where code is inside a BPL or DLL started by an EXE, so this works better: [WayBack] How to determine if I’m running as a console app? (Delphi on Win32) – Stack Overflow:

function IAmAConsoleApp: Boolean;
var
  Stdout: THandle;
begin
  Stdout := GetStdHandle(Std_Output_Handle);
  Win32Check(Stdout <> Invalid_Handle_Value);
  Result := Stdout <> 0;
end;

The .dproj files:

Read the rest of this entry »

Posted in Delphi, Development, Software Development | 2 Comments »

Windows Manifest Files and Delphi

Posted by jpluimers on 2019/03/28

An interesting read on Windows Manifest Files in Delphi [WayBack].

TL;DR:

Do not let Delphi manage your manifest. All versions are either limited, or buggy, or both.

Basically it’s the same as doing VersionInfo in Delphi: do not let the IDE do it, but do it yourself. In this case:

Write your own manifest in XML, then load it as a resource.

Via: [WayBack] Blogged : Windows Manifest Files – In this post I look at Windows Manifest Files, what they do, why we need them and how to use them in Delphi and Finalbuilder… – Vincent Parrett – Google+

–jeroen

Posted in Delphi, Development, Software Development | Leave a Comment »

Value types not having parameterless constructors…

Posted by jpluimers on 2019/03/27

The list below is based on a G+ discussion in a single language, but has way broader aspects.

It’s on value types, mutability, parameterless constructors and expectations of compiled code.

I’ve bitten myself in the foot with mutable types in too many languages too often, so I started advocating this years ago at clients, and now in this blog-post.

TL;DR:

Read the rest of this entry »

Posted in .NET, C#, C++, Delphi, Development, Jon Skeet, Software Development | 2 Comments »