2015-09-01 5 views
8

Я пытаюсь перенести некоторый код, который работает в Delphi XE8, в Delphi 10 Seattle. Этот код вызывает функцию GetPath в Winapi.Windows.Delphi 10 Seattle переходит на Win32 GetPath и избыточные типы записей TPoint и _POINTL

Новая функция Win32 API подписи:

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

В X Е8, ранее функция была «Var точек, типов», который обычно известная как «нетипизированный вар» параметр.

Фиксация кода для работы с Delphi 10 Сиэтл означает «объединение» произвольных типов в код приложения, чтобы использовать точно типы, объявленные в самом блоке. Однако меня смущает то, что есть два типа: PPointL и TPoint, а когда я получаю функцию GetPath, заполняемые ею данные заполняются в массив записей _POINTL, объявленных таким образом в Winapi.Windows:

Тем не менее, есть и другой тип TPoint, объявленный в System.Types:

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

в другом месте, FixedInt является псевдонимом для LONGINT как для 32-битной и 64-битной Windows, и так TPoint и _POINTL эквивалентны, так как насколько я могу судить, на платформе Windows, по крайней мере.

Если существующий код компонента приложения все с использованием типа с именем TPoint, как это:

procedure AddPoint(const P:TPoint); 

... Какой смысл я сделать ситуацию на местах внутри источников RTL в Delphi 10? Каким должен быть мой подход к исправлению этого? Псевдоним TPoint на _POINTL на уровне единицы?

Как исправить это и продолжить? Поскольку этот код является коммерческим компонентом, я думаю, что подожду, пока поставщик этого не исправит, но тогда я думаю, что понимание _POINTL и TPoint в RTL и почему эти структуры избыточно/дублированы в определении, помогло бы другие портируют код Win32 низкого уровня от Delphi XE8 до Delphi 10 Seattle.

Update: В качестве обходного пути, я нахожу, что я могу повторно объявить импорт функции GetPath, и он останется, как вар нетипизированного в собственном импорте частных единицу площади реализации, и по-прежнему:

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

Типы не являются избыточными, поскольку оба, кажется, используются где-то, но я согласен с тем, что используется неправильный тип. Это должно быть 'PPoint', а не' PPointL'. –

+0

@RudyVelthuis Некоторые API Win32 используют 'POINTL' вместо' POINT', по причинам, которые я не могу понять. Но да, 'GetPath' использует' POINT'. –

+0

@DavidHeffernan: Вот почему я сказал, что тип «POINTL» не избыточен в Delphi. FWIW, 'POINTL' и' RECTL', похоже, используются в API-интерфейсах Metafile. Я понятия не имею, почему они не могут использовать обычные структуры «POINT» и «RECT». Вероятно, конкурирующая группа разработчиков внутри MS, не общаясь с другими.

ответ

9

Об этом мало что можно сказать, кроме того, что изменение в Winapi.Windows.GetPath в DX Seattle ошибочно. Я имею в виду, что технически он будет работать, но он оставляет любой код, который использует GetPath в изолированном бункере.

Этот тип TPointL не является новым, но это неправильный тип для GetPath. Функция API Win32 является:

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

И LPPOINT является POINT* и POINT карты в TPoint. Есть некоторые функции API Win32, которые используют POINTL, но большинство используют POINT. Конечно, Microsoft не помогает, заявив два идентичных типа, когда их хватит.

Очень сложно понять, как разработчику Embarcadero удалось создать POINTL в новом GetPath, но там вы идете.На мой взгляд, вы должны представить отчет о QP и запросить, чтобы декларация была изменена с PPointL на PPoint.

В то же время простой актер будет достаточным, поскольку эти два типа совместимы с бинарными. Вы хотите передать PPoint, но компилятор хочет PPointL. Итак, перейдите PPointL(...), где ... - это выражение, которое дает PPoint.

+0

Это исправлено в Delphi 10.1 Berlin https://quality.embarcadero.com/browse/RSP-12086 –