2015-09-01 11 views
8

Tôi đang cố gắng chuyển một số mã hoạt động trong Delphi XE8 sang Delphi 10 Seattle. Mã này gọi hàm GetPath trong Winapi.Windows.Delphi 10 Seattle thay đổi thành Win32 GetPath và các loại bản ghi TPoint và _POINTL dư thừa

Các Win32 API chức năng chữ ký mới là:

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

Trong XE8, trước đây chức năng đã "var điểm, loại" được biết đến phổ biến như là một "untyped var" tham số.

Sửa mã để làm việc với Delphi 10 Seattle có nghĩa là "hợp nhất" các loại tùy ý trong mã ứng dụng để sử dụng chính xác các loại được khai báo trong đơn vị. Tuy nhiên điều gây nhầm lẫn cho tôi là có hai loại, PPointL và TPoint và khi tôi nhận hàm GetPath hoạt động, dữ liệu mà nó điền được điền vào một mảng các bản ghi _POINTL, được khai báo như vậy trong Winapi.Windows:

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

Tuy nhiên, đó cũng là một loại TPoint, khai báo trong System.Types:

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

ở những nơi khác, FixedInt là bí danh của Longint cho cả 32 bit và 64 bit Windows, và vì vậy TPoint và _POINTL là tương đương, như như tôi có thể nói, trên nền tảng Windows ít nhất.

Nếu mã thành phần ứng dụng hiện tại là tất cả sử dụng một loại tên TPoint, như thế này:

procedure AddPoint(const P:TPoint); 

... cảm giác gì tôi làm cho tình hình trên mặt đất bên trong nguồn RTL trong Delphi 10? Cách tiếp cận của tôi để sửa lỗi này là gì? Bí danh TPoint đến _POINTL ở cấp đơn vị?

Làm cách nào để khắc phục điều này và tiếp tục? Vì mã này là một thành phần thương mại, tôi nghĩ tôi sẽ chờ cho đến khi nhà cung cấp sửa lỗi này, nhưng sau đó, tôi nghĩ rằng hiểu được _POINTL và TPoint trong RTL, và tại sao các cấu trúc này được thừa/trùng lặp trong định nghĩa, sẽ giúp những người khác porting cấp thấp Win32 Mã từ Delphi XE8 đến Delphi 10 Seattle.

Cập nhật: Là một workaround, tôi thấy tôi có thể tái tuyên bố một nhập khẩu của hàm getPath, và có nó vẫn là var untyped ở riêng nhập khẩu đơn vị tư nhân khu vực thực hiện của tôi, và tiếp tục:

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

Các loại không thừa, vì cả hai loại này đều được sử dụng ở đâu đó, nhưng tôi đồng ý rằng loại sai được sử dụng. Nó phải là 'PPoint', không phải là' PPointL'. –

+0

@RudyVelthuis Một số API Win32 sử dụng 'POINTL' thay cho' POINT', vì những lý do mà tôi không thể hiểu được. Nhưng có, 'GetPath' sử dụng' ĐIỂM '. –

+0

@DavidHeffernan: Đó là lý do tại sao tôi nói loại POINTL' không phải là dư thừa trong Delphi. FWIW, 'POINTL' và' RECTL' dường như được sử dụng trong các API Metafile. Tôi không biết tại sao những người đó không thể sử dụng các cấu trúc 'POINT' và' RECT' bình thường. Có lẽ là một nhóm phát triển cạnh tranh bên trong MS, không giao tiếp với những người khác.

Trả lời

9

Không có gì nhiều để được nói về điều này, ngoài thực tế là sự thay đổi để Winapi.Windows.GetPath trong DX Seattle là sai. Tôi có nghĩa là, về mặt kỹ thuật nó sẽ làm việc, nhưng nó để lại bất kỳ mã nào sử dụng GetPath trong một silo bị cô lập.

Loại TPointL này không phải là loại mới, nhưng đó là loại sai cho GetPath. Chức năng Win32 API là:

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

LPPOINTPOINT*POINT bản đồ để TPoint. Có một số chức năng API Win32 sử dụng POINTL, nhưng phần lớn sử dụng POINT. Tất nhiên, Microsoft không giúp đỡ bằng việc tuyên bố hai loại giống nhau khi một người sẽ đủ.

Rất khó để xem cách nhà phát triển Embarcadero đã quản lý để tìm ra POINTL trong GetPath mới, nhưng bạn đã đến đó.Theo quan điểm của tôi, bạn nên gửi báo cáo QP và yêu cầu tuyên bố được thay đổi từ PPointL thành PPoint.

Trong khi đó, dàn diễn viên đơn giản sẽ đủ vì hai loại này tương thích với nhị phân. Bạn muốn vượt qua một PPoint, nhưng trình biên dịch muốn PPointL. Vì vậy, hãy vượt qua PPointL(...) trong đó ... là cụm từ mang lại một số PPoint.

+0

Điều này được khắc phục trong Delphi 10.1 Berlin https://quality.embarcadero.com/browse/RSP-12086 –

Các vấn đề liên quan