2015-09-01 21 views
8

Sto provando a portare un codice che funzioni in Delphi XE8 a Delphi 10 Seattle. Questo codice chiama la funzione GetPath in Winapi.Windows.Delphi 10 Seattle passa a Win32 GetPath e ai tipi di record TPoint e _POINTL ridondanti

Il nuovo Win32 firma funzione API è:

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

In XE8, in precedenza avevano la funzione "Punti var, tipi" che è conosciuto comunemente come un parametro "var non tipizzato".

Correggere il codice per lavorare con Delphi 10 Seattle significa "unificare" i tipi arbitrari nel codice dell'applicazione per utilizzare esattamente i tipi dichiarati nell'unità stessa. Tuttavia ciò che mi confonde è che ci sono due tipi, PPointL e TPoint, e quando ho la funzione di GetPath di lavoro, i dati che popola è popolato in un array di dischi _POINTL, ha dichiarato quindi in Winapi.Windows:

type 
    _POINTL = record  { ptl } 
    x: Longint; 
    y: Longint; 
    end; 
    {$EXTERNALSYM _POINTL} 
    PPointL = ^TPointL; 
    TPointL = _POINTL; 

Tuttavia, v'è anche un altro tipo TPoint, ha dichiarato in System.Types:

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

Altrove, FixedInt è alias per longint sia a 32 bit e 64 bit di Windows, e così TPoint e _POINTL sono equivalenti, come per quanto posso dire, almeno sulla piattaforma Windows.

Se il codice componente dell'applicazione esistente è tutto utilizzando un tipo di nome TPoint, in questo modo:

procedure AddPoint(const P:TPoint); 

... Che senso devo fare della situazione sul terreno all'interno delle fonti di RTL a Delfi 10? Quale dovrebbe essere il mio approccio per risolvere questo problema? Alias ​​TPoint a _POINTL a livello di unità?

Come risolvere il problema e procedere? Dato che questo codice è un componente commerciale, penso che aspetterò fino a quando il fornitore non risolverà questo problema, ma poi, penso che la comprensione di _POINTL e TPoint nella RTL e del perché queste strutture siano ridondanti/duplicate nella definizione, aiuterebbe altri porting di codice Win32 di basso livello da Delphi XE8 a Delphi 10 di Seattle.

Aggiornamento: Come soluzione alternativa, trovo posso ri-dichiarare un import della funzione GetPath, e lo hanno rimanere come var non tipizzato nella mia zona implementazione unità privata di importazione, e continuare:

{$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

I tipi non sono ridondanti, poiché entrambi sembrano essere usati da qualche parte, ma sono d'accordo che viene usato il tipo sbagliato. Dovrebbe essere 'PPoint', non' PPointL'. –

+0

@RudyVelthuis Alcune API Win32 utilizzano 'POINTL' invece di' POINT', per ragioni che non riesco a capire. Ma sì, 'GetPath' usa' POINT'. –

+0

@DavidHeffernan: Ecco perché ho detto che il tipo 'POINTL' non è ridondante in Delphi. FWIW, 'POINTL' e' RECTL' sembrano essere usati nelle API Metafile. Non ho idea del motivo per cui quelli non possono usare le normali strutture 'POINT' e' RECT'. Probabilmente un gruppo di sviluppo in competizione all'interno della SM, non in comunicazione con gli altri.

risposta

9

Non c'è molto da dire su questo, oltre al fatto che la modifica a Winapi.Windows.GetPath in DX Seattle è errata. Voglio dire, tecnicamente funzionerà, ma lascia qualsiasi codice che usi GetPath in un silos isolato.

Questo tipo di TPointL non è nuovo, ma è il tipo errato per GetPath. La funzione API Win32 è:

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

E LPPOINT è POINT* e POINT mappe a TPoint. Esistono alcune funzioni API Win32 che utilizzano POINTL, ma la maggior parte utilizza POINT. Ovviamente, Microsoft non sta aiutando dichiarando due tipi identici quando uno sarebbe sufficiente.

Molto difficile vedere come lo sviluppatore Embarcadero è riuscito a trovare POINTL nel nuovo GetPath, ma ci si va.A mio avviso, è necessario inviare un rapporto QP e richiedere che la dichiarazione venga modificata da PPointL a PPoint.

Nel frattempo un cast semplice sarà sufficiente perché questi due tipi sono compatibili con i binari. Si desidera passare un PPoint, ma il compilatore desidera PPointL. Quindi passare PPointL(...) dove ... è l'espressione che produce uno PPoint.

+0

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

Problemi correlati