1

我正在尝试使用 GDI 绘制多边形。此代码有效:

type
  TPolygon: Array[0..2] of TPoint;

var 
  ACanvas: TGPGraphics;
  MyBrush: TGPLinearGradientBrush;

...

procedure DrawPolygon;
var
  Polygon: TPolygon;
begin
  Polygon[0].X := 1;
  Polygon[0].Y := 5;
  Polygon[1].X := 10;
  Polygon[1].Y := 15;
  Polygon[2].X := 1;
  Polygon[2].Y := 5;

  ACanvas.FillPolygon(MyBrush, PGPPoint(@Polygon), length(Polygon));
end;

...

此代码产生GDI 值溢出错误:

type
  TPolygon: Array of TPoint;

var 
  ACanvas: TGPGraphics;
  MyBrush: TGPLinearGradientBrush;

...

procedure DrawPolygon;
var
  Polygon: TPolygon;
begin
  SetLength(Polygon, 3);

  Polygon[0].X := 1;
  Polygon[0].Y := 5;
  Polygon[1].X := 10;
  Polygon[1].Y := 15;
  Polygon[2].X := 1;
  Polygon[2].Y := 5;

  ACanvas.FillPolygon(MyBrush, PGPPoint(@Polygon), length(Polygon));
end;

...

唯一的区别是一个点数组是动态的,另一个是静态的。显然底层的内存值是不同的,但是以什么方式呢?

4

2 回答 2

8

您的代码无效。(首先,没有FillPolygonin TCanvas,其次,多边形至少需要三个顶点。此外,还有一些语法错误,例如 : 而不是 = 在 const 声明中。)我建议使用示例

Polygon[0].X := 1;
Polygon[0].Y := 1;
Polygon[1].X := 1;
Polygon[1].Y := 100;
Polygon[2].X := 100;
Polygon[2].Y := 1;

这是一个很好的三角形。总之,虽然

Windows.Polygon(Canvas.Handle, Polygon, 3)

适用于静态数组,您必须这样做

Windows.Polygon(Canvas.Handle, Polygon[0], 3)

对于动态数组。原因是静态数组“就地”存储在内存中,即直接存储在@Polygon,就像cardinal存储数字(例如 ),或ShortString,或此类简单类型的记录一样。相反,如果Polygon是一个动态数组,那么它实际上是一个指向实际可变长度数据的指针(与普通可变长度字符串的工作方式大致相同)。也就是说,在@Polygon你只有一个指针, a NativeUInt。实际数据从这个新地址开始,您可以通过写@Polygon[0].

于 2012-11-15T13:11:56.807 回答
5

动态数组已经是一个指针,因此只需@在将动态数组传递给时删除运算符FillPolygon()

ACanvas.FillPolygon(MyBrush, PGPPoint(Polygon), length(Polygon));

或者,如果您想使用适用于静态和动态数组的语法,请改为执行以下操作:

ACanvas.FillPolygon(MyBrush, PGPPoint(@Polygon[0]), length(Polygon));
于 2012-11-15T17:15:50.407 回答