1

I am trying to draw a polygon using GDI. This code works:

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;

...

This code produces a GDI Value Overflow error:

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;

...

The only difference is that one point array is dynamic, the other is static. Obviously the underlying memory values are different, but in what way?

0

2 Answers 2

8

Your code is invalid. (First, there is no FillPolygon in TCanvas, and second, a polygon need at least three vertices. Also, there are some syntax errors, like a : instead of = at the const declaration.) I'd suggest the sample

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

which is a nice triangle. Anyhow, while

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

works for a static array, you have to do

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

for a dynamic array. The reason is that a static array is stored 'in-place' in memory, that is, directly at @Polygon, just like a number (e.g., cardinal) is stored, or a ShortString, or a record of such simple types. On the contrary, if Polygon is a dynamic array, then it is really a pointer to the actual, variable-length, data (in much the same way a normal variable-length string works). That is, at @Polygon you only have a pointer, a NativeUInt. The actual data starts at this new address, which you can get by writing @Polygon[0].

Sign up to request clarification or add additional context in comments.

4 Comments

Thanks Andreas. My post doesn't state that Canvas is TCanvas. It's actually TGPGraphics. I'll edit the question to give it more clarity.
@norgepaul: I see. Well, the answer is pretty much the same, though. But surely you need at least three vertices even in this case?
Technically, a polygon does need to be enclosed. However, in this case 2 points just draw a straight line. I see your point however and I've updated the question :)
Your answer is just what I was looking for. Thanks.
5

A dynamic array is already a pointer, so just remove the @ operator when passing the dynamic array to FillPolygon():

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

Alternatively, if you want to use a syntax that works for both static and dynamic arrays, do this instead:

ACanvas.FillPolygon(MyBrush, PGPPoint(@Polygon[0]), length(Polygon));

2 Comments

Is it possible to allocate memory to dynamic array which would have indexes numbered from e.g. 512 to 1024? Seems like the question of the OP was not competely answered. What's the difference.
@user1141649 you have already received answers to that question.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.