我正在尝试使用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;
...
唯一的区别是一个点阵列是动态的,另一个是静态的。显然,底层的内存值是不同的,但是以什么方式?
答案 0 :(得分:8)
您的代码无效。 (首先,FillPolygon
中没有TCanvas
,其次,多边形需要至少三个顶点。此外,还有一些语法错误,例如:在const声明中代替=。)I建议样本
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)
表示动态数组。原因是 static 数组在内存中“就地”存储,即直接存储在@Polygon
,就像存储一个数字(例如,cardinal
)一样,或ShortString
,或这些简单类型的记录。相反,如果Polygon
是一个动态数组,那么它实际上是一个指向实际可变长度数据的指针(与普通可变长度字符串的工作方式大致相同) )。也就是说,在@Polygon
,您只有一个指针NativeUInt
。实际数据从这个新地址开始,您可以通过编写@Polygon[0]
来获得。
答案 1 :(得分:5)
动态数组已经是指针,因此在将动态数组传递给@
时只需删除FillPolygon()
运算符:
ACanvas.FillPolygon(MyBrush, PGPPoint(Polygon), length(Polygon));
或者,如果要使用适用于静态和动态数组的语法,请改为:
ACanvas.FillPolygon(MyBrush, PGPPoint(@Polygon[0]), length(Polygon));