How the handle declarations changed in Delphi

Delphi has had a THandle type for a long time (at least since Delphi 6) but didn’t use it consistently. I just had to check those declarations for various Delphi versions in order to get rid of compile errors or warnings in GExperts. Here is what I found:

  • THandle is a type declared in the System unit.
  • INVALID_HANDLE_VALUE is a constant declared in the Windows unit.
  • THandleStream, declared in the Classes unit, has got a private field called FHandle
  • THandleStream.Create has got an AHandle parameter

You would have thought that in all those places THandle is used, but it isn’t. Sometimes it’s DWord, sometimes it’s integer, and sometimes it’s THandle. Also, the declaration of the THandle type changed from LongWord to NativeUInt at some time. Only in Delphi XE2 and later it is consistent (but hey: Everybody keeps telling me to drop GExperts support for versions older than that, so there is an easy solution 😉 ).

Delphi Version THandle INVALID_HANDLE_VALUE FHandle AHandle
6 – 2007 LongWord DWord Integer Integer
2009 – XE LongWord DWord THandle Integer
XE2 and later NativeUInt THandle THandle THandle

 
So, in order to not get any compile errors or warnings I declared two different types:

type
{$IFDEF THANDLESTREAM_CREATE_HANDLE_IS_THANDLE}
  THandleStreamCreateHandleCast = THandle;
{$ELSE}
  THandleStreamCreateHandleCast = Integer;
{$ENDIF}
{$IFDEF THANDLESTREAM_HANDLE_IS_THANDLE}
  THandleCast = THandle;
{$ELSE}
  THandleCast = Integer;
{$ENDIF}

Where the conditional defines are defined as follows:

{$INCLUDE 'jedi.inc'}

// The following cond. defines address errors in various Delphi versions regarding the declaration
// of the FHandle field of THandleStream and the corresponding Create constructor parameter:
{$IFDEF DELPHI2009_UP}
// THandleStream.FHandle is declared as THandle (before that it's an Integer)
{$DEFINE THANDLESTREAM_HANDLE_IS_THANDLE}
{$ENDIF}

{$IFDEF DELPHIXE2_UP}
// AHandle is declared as THandle (otherwise it's an Integer)
{$DEFINE THANDLESTREAM_CREATE_HANDLE_IS_THANDLE}
{$ENDIF}

Really annoying but at least that takes care of these errors and warnings.