I am trying to port some code that works in Delphi XE8 to Delphi 10 Seattle. This code calls the GetPath function in Winapi.Windows.
The new Win32 API function signature is:
function GetPath(DC: HDC; Points: PPointL; Types: PByte; nSize: Integer): Integer; stdcall;
In XE8, previously the function had "var Points,Types" which is known commonly as a "var untyped" parameter.
Fixing the code to work with Delphi 10 Seattle means "unifying" the arbitrary types in the application code to use exactly the types declared in the unit itself. However what is confusing me is that there are two types, PPointL, and TPoint, and when I get the GetPath function working, the data it populates is populated into an array of _POINTL records, declared thus in Winapi.Windows:
type
_POINTL = record { ptl }
x: Longint;
y: Longint;
end;
{$EXTERNALSYM _POINTL}
PPointL = ^TPointL;
TPointL = _POINTL;
However, there is also another type TPoint, declared in System.Types:
TPoint = record
X: FixedInt;
Y: FixedInt;
public
Elsewhere, FixedInt is aliased to Longint for both 32 bit and 64 bit Windows, and so TPoint and _POINTL are equivalent, as far as I can tell, on the Windows platform at least.
If existing application component code is all using a type named TPoint, like this:
procedure AddPoint(const P:TPoint);
... What sense am I to make of the situation on the ground inside the RTL sources in Delphi 10? What should my approach to fixing this be? Alias TPoint to _POINTL at the unit level?
How do I fix this and proceed? Since this code is a commercial component, I'm thinking I'll wait until the vendor fixes this, but then, I think that understanding the _POINTL and TPoint in the RTL, and why these structures are redundantly/duplicated in definition, would help others porting low level Win32 Code from Delphi XE8 to Delphi 10 Seattle.
Update: As a workaround, I find I can re-declare an import of the function GetPath, and have it remain as var untyped in my own private unit implementation area import, and continue:
{$ifdef D23}
{$POINTERMATH ON}
// Delphi 10 Seattle: function GetPath(DC: HDC; Points: PPointL; Types: PByte; nSize: Integer): Integer; stdcall;
// previously had "var Points,Types" untyped,
const
gdi32 = 'gdi32.dll';
{$EXTERNALSYM GetPath}
function GetPath(DC: HDC; var Points, Types; nSize: Integer): Integer; stdcall; external gdi32 name 'GetPath';
{$endif}
PPoint
, notPPointL
. – BurnishPOINTL
instead ofPOINT
, for reasons that I cannot fathom. But yes,GetPath
usesPOINT
. – ObergPOINTL
type is not redundant in Delphi. FWIW,POINTL
andRECTL
seem to be used in the Metafile APIs. I have no idea why those can't use the normalPOINT
andRECT
structs. Probably a competing development group inside MS, not communicating with the others. <g> – Burnish