2015-09-01 4 views
8

Ich versuche, etwas Code, der in Delphi XE8 zu Delphi 10 Seattle funktioniert. Dieser Code ruft die GetPath-Funktion in Winapi.Windows auf.Delphi 10 Seattle ändert sich in Win32 GetPath und redundante TPoint und _POINTL Record-Typen

Die neue Win32-API-Funktion Signatur ist:

function GetPath(DC: HDC; Points: PPointL; Types: PByte; nSize: Integer): Integer; stdcall; 

In XE8, zuvor die Funktion "var Punkte, Types" hatte, die allgemein als "var untypisierten" Parameter bekannt ist.

Korrigieren des Codes für die Arbeit mit Delphi 10 Seattle bedeutet "Vereinheitlichung" der willkürlichen Typen im Anwendungscode, um genau die Typen zu verwenden, die in der Einheit selbst deklariert sind. Was mich jedoch verwirrt, ist, dass es zwei Typen gibt, PPointL und TPoint, und wenn ich die GetPath-Funktion zum Laufen bringe, werden die Daten in ein Array von _POINTL-Datensätzen eingetragen, die so in Winapi.Windows deklariert sind:

Allerdings gibt es auch eine andere Art TPoint, in System.Types erklärt:

TPoint = record 
    X: FixedInt; 
    Y: FixedInt; 
    public 

Anderswo FixedInt ist aliased sowohl für 32-Bit- und 64-Bit-Windows LONGINT, und so TPoint und _POINTL äquivalent sind, wie soweit ich das beurteilen kann, zumindest auf der Windows-Plattform.

Wenn bestehende Anwendungskomponente Code ist alles eine Art mit dem Namen TPoint, wie folgt aus:

procedure AddPoint(const P:TPoint); 

... Was Sinn bin ich 10 innerhalb der RTL Quellen in Delphi der Lage vor Ort zu machen? Was sollte mein Ansatz sein, um dies zu beheben? Alias ​​TPoint zu _POINTL auf Einheitenebene?

Wie behebe ich das Problem und fahre fort? Da dieser Code eine kommerzielle Komponente ist, denke ich, dass ich warten werde, bis der Anbieter das behebt, aber dann denke ich, dass das Verständnis von _POINTL und TPoint in der RTL und warum diese Strukturen in der Definition redundant/dupliziert sind, helfen würde Andere portieren Win32-Code niedriger Ebene von Delphi XE8 nach Delphi 10 Seattle.

Update: Wie dieses Problem zu umgehen, finde ich, kann ich einen Import der Funktion GetPath erneut erklären, und haben es als var bleiben untypisierten in meiner eigenen Einheit Implementierungsbereich importieren und weiter:

{$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} 
+0

Die Typen sind nicht redundant, da beide scheinbar irgendwo verwendet werden, aber ich stimme zu, dass der falsche Typ verwendet wird. Es sollte "PPoint" sein, nicht "PPointL". –

+0

@RudyVelthuis Einige Win32-APIs verwenden 'POINTL' anstelle von' POINT', aus Gründen, die ich nicht ergründen kann. Aber ja, 'GetPath' verwendet' POINT'. –

+0

@DavidHeffernan: Deshalb habe ich gesagt, dass der Typ "POINTL" in Delphi nicht redundant ist. FWIW, "POINTL" und "RECTL" scheinen in den Metafile-APIs verwendet zu werden. Ich habe keine Ahnung, warum diese die normalen "POINT" - und "RECT" -Strukturen nicht verwenden können. Wahrscheinlich eine konkurrierende Entwicklergruppe innerhalb von MS, die nicht mit den anderen kommuniziert.

Antwort

9

Es gibt nicht viel darüber zu sagen, abgesehen von der Tatsache, dass die Änderung zu Winapi.Windows.GetPath in DX Seattle falsch ist. Ich meine, technisch wird es funktionieren, aber es lässt jeden Code, der GetPath in einem isolierten Silo verwendet.

Dieser Typ TPointL ist nicht neu, aber es ist der falsche Typ für GetPath. Die Win32-API-Funktion ist:

int GetPath(
    _In_ HDC  hdc, 
    _Out_ LPPOINT lpPoints, 
    _Out_ LPBYTE lpTypes, 
    _In_ int  nSize 
); 

Und LPPOINT ist POINT* und POINT Karten TPoint. Es gibt einige Win32-API-Funktionen, die POINTL verwenden, aber die Mehrheit verwendet POINT. Natürlich hilft Microsoft nicht, indem er zwei identische Typen deklariert, wenn einer ausreicht.

Sehr schwer zu sehen, wie der Embarcadero-Entwickler mit POINTL in der neuen GetPath gekommen ist, aber da gehen Sie.Aus meiner Sicht sollten Sie einen QP-Bericht einreichen und beantragen, dass die Deklaration von PPointL zu PPoint geändert wird.

In der Zwischenzeit wird eine einfache Umwandlung ausreichen, da diese beiden Typen binärkompatibel sind. Sie möchten eine PPoint übergeben, aber der Compiler will PPointL. Übergeben Sie also PPointL(...), wobei ... der Ausdruck ist, der PPoint ergibt.

+0

Dies ist in Delphi 10.1 Berlin https://quality.embarcadero.com/browse/RSP-12086 behoben –

Verwandte Themen