2012-11-15 75 views
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; 

... 

的唯一區別是一個點陣列是動態的,另一種是靜態的。顯然,潛在的內存價值是不同的,但以什麼方式?

回答

8

您的代碼無效。 (首先,在TCanvas中沒有FillPolygon,其次,一個多邊形至少需要三個頂點,並且還有一些語法錯誤,比如在const聲明中使用a:而不是=)我建議樣本

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你只有一個指針,一個NativeUInt。實際數據從這個新地址開始,您可以通過編寫@Polygon[0]獲得。

+0

謝謝安德烈亞斯。我的帖子沒有說Canvas是TCanvas。它實際上是TGPGraphics。我會編輯這個問題,使其更加清晰。 – norgepaul

+1

@norgepaul:我明白了。那麼,答案几乎是一樣的,但。但是,在這種情況下,你確實需要至少三個頂點? –

+0

從技術上講,多邊形確實需要被封閉。但是,在這種情況下,2點只是畫出一條直線。我看到你的觀點,然而我已經更新了這個問題:) – norgepaul

5

動態數組已經是一個指針,路過時FillPolygon()動態數組,以便只是刪除@操作:

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

另外,如果你想使用靜態和動態數組工作的語法,請改爲:

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