Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Problem mit dem zugreifen auf dyn. Shapes. (https://www.delphipraxis.net/31855-problem-mit-dem-zugreifen-auf-dyn-shapes.html)

Thorben86 14. Okt 2004 22:07


Problem mit dem zugreifen auf dyn. Shapes.
 
Hi, ich hab wieder ein Problem mit meinen dynamischen Shapes. Ic hspeicher die jetzt in nem Array. allerdings kommt eine Exception wenn ich in der 2. Procedure die erste For-Schleife auf die größe des Arrays stelle. wenn ich dort die anzahl der scheiben einstelle, kommt keine exception, er findet jedoch die Komponente auch nicht. Mache ich beim Suchen irgend was falsch, weil eigentlich müsste es die Komponente mit dem Namen ja geben.

Erstellung:
Delphi-Quellcode:
var i:integer;
shape:TShape;
anzahl:integer;
begin
  for I:=1 to 30 do
  shapes[i].free;
  Stapel[1].Anzahl := 0;
 
  for anzahl := 1 to sp_scheibenzahl.value do begin
     Shapes[anzahl] := TShape.Create(self);
    Shapes[anzahl].Name :='im_st'+ InttoStr(Startstapel) + 'nr' +  InttoStr(Stapel[Startstapel].Anzahl);
    Shapes[anzahl].Parent := Form1;
    shapes[anzahl].Width := 100;
    shapes[anzahl].Height := 15;
    shapes[anzahl].Top := Stapel[Startstapel].Top - (15 * (Stapel[Startstapel].Anzahl+1));
    shapes[anzahl].Left := Stapel[Startstapel].left - (shapes[anzahl].Width div 2);
    shapes[anzahl].Shape := stRoundRect;
    inc(Stapel[Startstapel].Anzahl);
end;

end;
Zugreifen:
Delphi-Quellcode:
var
   Kompo:TShape;
   i:Integer;
begin
for i:=1 to 30 do //Hier Exception
begin
if (Shapes[i].name = 'im_st'+ InttoStr(Startstapel) + 'nr' + InttoStr(Stapel[Startstapel].Anzahl)) then
begin
showmessage('1');
Kompo := Shapes[i];
end;
end;

if (Kompo <> nil) then
begin
Kompo.Left := Stapel[Zielstapel].left - (Kompo.Width div 2);
Kompo.Top := Stapel[Zielstapel].Top - (15 * (Stapel[Zielstapel].Anzahl+1)) ;
inc(Stapel[Startstapel].Anzahl,-1);
inc(Stapel[Zielstapel].Anzahl);
Kompo.Name := 'im_st'+ InttoStr(Zielstapel) + 'nr' + InttoStr(Stapel[Zielstapel].Anzahl);
end;

end;
Edit: Array deklaration: shapes : Array[1..30] of TShape;

die showmesage ist nur dafür da, um zu sehen, of der in die if-Abfrage rein kommt, tut er aber nicht, also is kompo dann nil und der verändert nix, ich weis aber nicht, wie ich das ändern kann.

Nicodius 14. Okt 2004 22:23

Re: Problem mit dem zugreifen auf dyn. Shapes.
 
zwei sachen


das showmessage('1'); versteh ich nicht :mrgreen:

ähhm kompo hat kein parent ;)


ps.: wäre auch nett wenn du die array dekleration zeigen würdest ^^ ;)

Nicodius 14. Okt 2004 22:33

Re: Problem mit dem zugreifen auf dyn. Shapes.
 
Zitat:

Delphi-Quellcode:
if (Shapes[i].name = 'im_st'+ InttoStr(Startstapel) + 'nr' + InttoStr(Stapel[Startstapel].Anzahl))



was wird denn da abgefragt???

Thorben86 14. Okt 2004 22:40

Re: Problem mit dem zugreifen auf dyn. Shapes.
 
ich bau gerade den turm von hanoi, und da besteht der name er Komponente aus stapelnummer(1,2 oder 3) und der stelle auf dem stapel, also unten ist 1. Scheibe und dann nach oben raufgezählt, da ich ja die oberste scheibe haben will. bei der abfrage ist halt dan der stapel und halt die anzahl der scheiben auf dem Stapel(also die oberste). über die variablen übergeben.
Also frag ich damit die oberste scheibe auf dem stapel ab.

Ich hab die Frage bekommen, was ich mit der If-Abfrage haben will:
ich will wissen welche komponente das ist, bevor ich das mit nem array gemacht habe, hab ich per findcomponent gesucht, welche komponente diesen namen hat, die dann auf Kompo geschrieben und dann dmit gearbeitet(verschieben usw.), aber mir wurde gesagt, dass das schlechtes programieren ist und ich das mit ner TList oder nem array machen soll, vonTList hab ich nicht verstanden, also hab ich ein array genommen. theoretisch will ich auf kompo wieder sowas haben, wie bei findcomponent, so dass ich dann damit arbeiten kann

dizzy 14. Okt 2004 23:32

Re: Problem mit dem zugreifen auf dyn. Shapes.
 
Wäre da nicht ein 3-dimensionales Array sinnvoller, eine Dimension pro Stapel, und 3 Zähler die ständig den jeweils obersten Index enthalten? Dann musst du nicht erst langwierig über Strings suchen. So wie du es jetzt machst ist es nämlich kaum besser als mit FindComponent -> langsam. Den Vorteil des indizierten Zugriffs hast du völlig unterwandert ;).

Und da du eh niemals eine Scheibe von "zwischendrin" brauchst, reicht das alle Male wenn du dir den Top-Index ständig merkst. Der muss nur gewissenhaft verwaltet werden.

n8i,
Fabian

Thorben86 15. Okt 2004 00:28

Re: Problem mit dem zugreifen auf dyn. Shapes.
 
Hmm, dreidimensionales array wäre ne überlegung wert, hab zwar noch nicht damit gearbeitet, abre ich weis, das hier im Forum was drüber steht, was meinst du mit gewissenhaft verwaltest, wie müsst ich das array aufbauen, damit es gewissenhaft verwaltet werden kann?

dizzy 15. Okt 2004 08:23

Re: Problem mit dem zugreifen auf dyn. Shapes.
 
Das Array selber hat mit der Top-Index-Verwaltung nicht viel zu tun. Damit war eher gemeint, dass man sich drum kümmern muss, dass beim Verschieben von Scheiben die Indezes korrekt mit verändert werden, damit man nicht irgendwann in leere greift, oder gar Scheiben aus der Mitte zieht ;).

Da fällt mir ein: Ein 2-dimensionales ist viel besser geeignet...

Deklaration eines 2-dim. Arrays:
Delphi-Quellcode:
var
  My2DimArray = array[1..3, 1..30] of TShape;
Der erste Index gibt den Stapel an, der zweite die Scheibe.

Und der 2. Index ist der, bei dem man sich den höchsten vorhandenen Index separat merken muss. Da könnte man sich auch ein kleines Array vorstellen:
Delphi-Quellcode:
var
  MyTopIndezes = array[1..3] of Integer;
Das hat den Vorteil, dass du mit ein und dem selben Wert einen Stapel und gleich seinen aktuellen Top-Index indizieren kannst.

Ich hoffe das ist einigermaßen durchsichtig :D

gruss,
Fabian

Art 15. Okt 2004 09:02

Re: Problem mit dem zugreifen auf dyn. Shapes.
 
Schaue dir das genau an,

1.
Zitat:

for anzahl := 1 to sp_scheibenzahl.value do begin
Shapes[anzahl] := TShape.Create(self);
Shapes[anzahl].Name :='im_st'+ InttoStr(Startstapel) + 'nr' + InttoStr(Stapel[Startstapel].Anzahl);
Shapes[anzahl].Parent := Form1;
shapes[anzahl].Width := 100;
shapes[anzahl].Height := 15;
shapes[anzahl].Top := Stapel[Startstapel].Top - (15 * (Stapel[Startstapel].Anzahl+1));
shapes[anzahl].Left := Stapel[Startstapel].left - (shapes[anzahl].Width div 2);
shapes[anzahl].Shape := stRoundRect;
inc(Stapel[Startstapel].Anzahl);
end;
2.
Zitat:

for i:=1 to 30 do //Hier Exception
begin
if (Shapes[i].name = 'im_st'+ InttoStr(Startstapel) + 'nr' + InttoStr(Stapel[Startstapel].Anzahl)) then
begin
showmessage('1');
Kompo := Shapes[i];
end;
end;
Im Fall 1. hast du Array of TShape bis zu sp_scheibenzahl.value definiert, aber im Fall 2. hast du
Array bis zu dreizigstem Element abgefragt. Wenn sp_scheibenzahl.value<30 die restliche Elemente sind Nil. Das Element NIL Hat kein Name-Eigenshaft. Deshalb kriegst du Exeption an diese stelle. Du versuchst mit nicht existierendem Exemplar von TShape zu reden.
Meiner meinung nach Code muss folgendermassen modifiziert werden:

Code:
for i:=1 to 30 do //Hier Exception
begin
if (Shapes[i]<>nil) and
   (Shapes[i].name = 'im_st'+ InttoStr(Startstapel) + 'nr' + InttoStr(Stapel[Startstapel].Anzahl)) then
begin
showmessage('1');
Kompo := Shapes[i];
end;
end;

dizzy 15. Okt 2004 14:30

Re: Problem mit dem zugreifen auf dyn. Shapes.
 
NIchtsdesto trotz bleibt der Umweg über die Name-Property langsam und unnötig ;)


Alle Zeitangaben in WEZ +1. Es ist jetzt 14:00 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz