Did you know that handles are 64 bit wide in native 64 bit applications? While this doesn’t affect any Delphi developer just yet, things will change next year with the release of Delphi “Commodore” as outlined on CodeGear’s Delphi and C++Builder Roadmap page. This means, among other things, that type-casting a THandle or HANDLE from or to something like a Cardinal, Longint or DWORD is a sin.

The reason for this becomes clear if you look into the Windows SDK headers, where HANDLE is declared as:

typedef void *HANDLE;

Since the processor architecture determines the width of the pointer types, this will be 64 bit. Now Delphi on the other hand (taking Delphi 2006 as an example) declares this:

THandle = LongWord;

Which is a non-pointer type of 32 bit width. If memory serves me right, there were some changes over time in how THandle was declared and it juggled between Cardinal, LongWord and some other type. In any case, there will have to be a change in “Commodore”, unless LongWord changes its meaning from 32 to 64 bit.

Things get even crazier if you look at how the SDK declares INVALID_HANDLE_VALUE:

#define INVALID_HANDLE_VALUE ((HANDLE)(LONG_PTR)-1)

Note the explicit type-cast. This is necessary to ensure that the value will not be truncated to $FFFFFFFF instead of $FFFFFFFFFFFFFFFF.

Delphi 2006 declares it as:

const
  INVALID_HANDLE_VALUE = DWORD(-1);

… which is clearly invalid for 64 bit code. So watch out for these caveats in your code. I am sure CodeGear will do their part before the release.