AW: Record zu TStringlist hinzufügen
Zitat:
Delphi-Quellcode:
Sprite[Count].Top := Bottom;
Array habe ich schon warum dann extra eine Liste wie auch immer verwenden wenn ich doch wieder Array nutzen muss.
Delphi-Quellcode:
Sprite: TArray<TSprite>;
gruss |
AW: Record zu TStringlist hinzufügen
Zitat:
Und höre auf deine Beiträge ständig nach zu editieren, man weiß gar nicht auf was man antworten soll. Erstelle einfach einen neuen Beitrag. Das von jaenicke gezeigte
Delphi-Quellcode:
ist ein ganz normaler Zugriff auf eine Liste.
Sprite[Count].Top := Bottom;
Ja, auch Listen können mit Integer-Indizes angesprochen werden. |
AW: Record zu TStringlist hinzufügen
Zitat:
Im Falle einer Liste läuft das ganze auf eine Index-Property mit einer Getter-Methode, die das Element zurückliefert. Sinnvoll ist aus Performancegründen natürlich eher ohne die vielen Indexzugriffe zu arbeiten und das aktuelle Element in eine Variable zu packen:
Delphi-Quellcode:
Meinst du das?
var
Sprites: TObjectList<TSprite>; Sprite: TSprite; begin ... Sprite := Sprites[Count]; Sprite.Top := ...; Sprite.Def := ...; |
AW: Record zu TStringlist hinzufügen
Zitat:
gruss |
AW: Record zu TStringlist hinzufügen
Gibt es einen Grund, weshalb du keine Arrays möchtest?
Wenn man wüsste warum, könnte man vielleicht andere, bessere Lösungen ausarbeiten. |
AW: Record zu TStringlist hinzufügen
Zitat:
|
AW: Record zu TStringlist hinzufügen
Schau dir dieses simple Konsolenprogramm mal an und versuche die einzelnen Abschnitte zu verstehen:
Delphi-Quellcode:
program Project1;
{$APPTYPE CONSOLE} {$R *.res} uses SysUtils, Generics.Collections; type TSprite = class Top, Left, Right, Bottom: Integer; function ToString: string; end; TSprites = TObjectList<TSprite>; { TSprite } function TSprite.ToString: string; begin Result := 'Sprite-Werte' + sLineBreak; Result := Result + ' Top: ' + IntToStr(Top) + ' Left: ' + IntToStr(Left) + ' Right: ' + IntToStr(Right) + ' Bottom: ' +IntToStr(Bottom); end; procedure Main; var SingleSprite: TSprite; Sprites: TSprites; I: Integer; begin Sprites := TSprites.Create; try Sprites.Add(TSprite.Create); Sprites.Add(TSprite.Create); Sprites.Add(TSprite.Create); Writeln('Sprites.Count: ' + IntToStr(Sprites.Count)); // Zugriff auf Listenelement - Variante 1 Sprites[0].Top := 1; Sprites[0].Left := 2; Sprites[0].Right := 3; Sprites[0].Bottom := 4; // Zugriff auf Listenelement - Variante 2 Sprites.Items[1].Top := 4; Sprites.Items[1].Left := 6; Sprites.Items[1].Right := 7; Sprites.Items[1].Bottom := 8; // Zugriff auf Listenelement - Variante 3 SingleSprite := Sprites.Items[2]; SingleSprite.Top := 9; SingleSprite.Left := 10; SingleSprite.Right := 11; SingleSprite.Bottom := 12; Writeln; Writeln('Iterieren durch die Liste mit Index:'); for I := 0 to Sprites.Count - 1 do begin Writeln(IntToStr(I) + '. ' + Sprites.Items[I].ToString) end; Writeln; Writeln('Iterieren durch die Liste mit for-in:'); for SingleSprite in Sprites do begin Writeln(SingleSprite.ToString) end; Writeln; Writeln('Löschen des mittleren Elements aus Sprites!'); Sprites.Delete(1); Writeln('Sprites.Count: ' + IntToStr(Sprites.Count)); Writeln; Writeln('Entfernen des ersten Elements aus Sprites!'); SingleSprite := Sprites.First; Sprites.Remove(SingleSprite); Writeln('Sprites.Count: ' + IntToStr(Sprites.Count)); finally Sprites.Free; end; end; begin try Main; Readln; except on E: Exception do Writeln(E.ClassName, ': ', E.Message); end; end. |
AW: Record zu TStringlist hinzufügen
Zitat:
Na ja.. Warum ich das machen will hat eigentlich mit der Code Struktur zu tun. Ich möchte das ganze etwas aufgeräumt haben bevor ich den Quelltext hoch lade. Das mit den Arrays ist ein totales Kuddelmuddel. Deshalb will ich das weg haben. (Aber nicht mit aller Gewalt, wenn es nicht geht lass ich es lieber). gruss |
AW: Record zu TStringlist hinzufügen
Zitat:
gruss |
AW: Record zu TStringlist hinzufügen
Zitat:
Dann kannst du deinen Code an die Möglichkeiten der Liste anpassen, das was du machen willst um den "Salat" aufzuräumen, den du siehst, wobei von außen betrachtet jetzt nicht klar ist, was das sein könnte, aber man könnte z.B. for-Schleifen mit Index durch for each Schleifen erstzen usw. |
AW: Record zu TStringlist hinzufügen
So würde ich das ansatzweise machen. Minimale Implementation:
Delphi-Quellcode:
type
// Du nimmst natürlich Deinen Record TDataRecord = record Name : string[20]; Zahl : Integer; end; PDataRecord = ^TDataRecord; TDataRecordList = class(TList) protected function GetItem(AIndex: Integer): PDataRecord; procedure SetItem(AIndex: Integer; const Value: PDataRecord); public function Add(AData: TDataRecord): Integer; procedure Clear; override; property Items[AIndex : Integer] : PDataRecord read GetItem write SetItem; default; end; implementation { TDataRecordList } function TDataRecordList.Add(AData: TDataRecord): Integer; var PData : PDataRecord; begin New(PData); // Record-Inhalt kopieren (evtl. auch mit move). So bleibt Erzeugung und Freigabe in der Klasse. // Natürlich könnte man ein Overload von Add mit PData machen. PData.Name := AData.Name; PData.Zahl := AData.Zahl; Result := inherited Add(PData); end; procedure TDataRecordList.Clear; var PData : PDataRecord; I : Integer; begin for I := 0 to Count - 1 do begin PData := Items[I]; Dispose(PData); end; inherited; end; // Setter und Getter geben jeweils wieder den Pointer zurück, um sich Kopiervorgänge zu ersparen function TDataRecordList.GetItem(AIndex: Integer): PDataRecord; begin Result := inherited Items[AIndex]; end; procedure TDataRecordList.SetItem(AIndex: Integer; const Value: PDataRecord); begin inherited Items[AIndex] := Value; end; |
AW: Record zu TStringlist hinzufügen
Danke für das Beispiel.. Im Moment scheint es zu gehen obwohl in der Liste 2 Einträge mehr addiert werden als ich initialisiert habe.
Macht Probleme wenn ich den Count überprüfe. Siehe Pic! Warum werden mehr Einträge addiert? gruss |
AW: Record zu TStringlist hinzufügen
Dem Screenshot nach steht Count auf "6", was den Einträgen #0 bis #5 entspricht. Alles korrekt.
Wie die Liste sich intern verwaltet, manchmal dimensioniert sie das interne Array eine Idee größer (Stichwort Eigenschaft "Grow"), ist nur für sie selbst von Bedeutung. |
AW: Record zu TStringlist hinzufügen
Zitat:
Habe ja noch 6 und 7 auch wenn sie NIL sind. Werden diese mitgezählt beim Sprites.Count ?. Sorry habe mich mit dem Kram noch nie beschäftigt. gruss |
AW: Record zu TStringlist hinzufügen
Nein, Count sollte in Deinem Fall 6 ergeben (man darf Count nicht mit Capacity verwechseln).
|
AW: Record zu TStringlist hinzufügen
Zitat:
gruss |
AW: Record zu TStringlist hinzufügen
Habe da jetzt ein kleines Problem ;)
Wie kann ich die Einträge in der Liste verschieben ?
Delphi-Quellcode:
vorher mit dem Array war das kein Problem.
if (Item + ID_MAIN) <> FlagFound then
begin if Prop.ShortCutfound > 0 then NewLen := Sprites.Count + Prop.ShortCutfound else NewLen := Sprites.Count; Sprites.Add(TSprite.Create); CreateRecycleBin(MainHandle, NewLen); for x := ID_FIRST to NewLen do begin Sprites[x] := Sprites[x + 1]; if x = (NewLen - Prop.ShortCutfound) then begin for X1 := (NewLen - 1) downto (NewLen - Prop.ShortCutfound) do Sprites.Delete(X1); end; end; FlagFound := count; end;
Delphi-Quellcode:
gruss
if (Item + ID_MAIN) <> FlagFound then
begin if Prop.ShortCutfound > 0 then NewLen := High(Sprite) + Prop.ShortCutfound else NewLen := High(Sprite) + 1; Setlength(Sprite, NewLen); CreateRecycleBin(MainHandle, NewLen); for x := ID_FIRST to NewLen do begin Sprite[x] := Sprite[x + 1]; if x = (NewLen - Prop.ShortCutfound) then begin for X1 := (NewLen - 1) downto (NewLen - Prop.ShortCutfound) do Delete(Sprite, X1); end; end; FlagFound := count; end; |
AW: Record zu TStringlist hinzufügen
Delphi-Quellcode:
bzw.
TList<>.Move
Delphi-Quellcode:
.
TList<>.Exchange
http://docwiki.embarcadero.com/Libra...TList.Exchange |
AW: Record zu TStringlist hinzufügen
Zitat:
gruss |
AW: Record zu TStringlist hinzufügen
Noch ein einfache frage.. reicht ein einfaches Free damit alle Classen freigegeben werden oder muss ich da
noch etwas besonderes beachten? gruss |
AW: Record zu TStringlist hinzufügen
Soweit ich weiß muss man jedes Objekt selber freigeben und dann die Liste.
|
AW: Record zu TStringlist hinzufügen
Moin...:P
Mit TList<> mußt du dich selbst um die Freigabe kümmern. Die TObjectList<> kümmert sich selbst um die Freigabe. 8-) |
AW: Record zu TStringlist hinzufügen
Zitat:
Da ich TObjectList verwende sollte das dann reichen. OK bevor ich diese Freigebe lösche ich natürlich noch die Bitmap Ressourcen. Mehr ist das ja nicht. Danke. gruss |
AW: Record zu TStringlist hinzufügen
Bei TList mit Pointern ja,
in TList<IrgendeinPointer> auch, aber die TList<EinRecordOderEinAndererEinfacherTypSowieDynA rraysUndInterfaces> kümmert sich um alles. Unter ARC werden auch Objekte gut verwaltet ... da ist dann eine TList<> und TObjektList<> praktisch das Selbe. Bei TObjectList und Anderen kann man im Constructor angeben, ob sich die Liste um das Free kümmert. |
AW: Record zu TStringlist hinzufügen
Zitat:
Habe es jetzt fertig hoffe das mein Teil noch läuft.. Bei mir geht's (Aber das ist ja immer so). gruss |
AW: Record zu TStringlist hinzufügen
Zitat:
|
AW: Record zu TStringlist hinzufügen
Zitat:
|
AW: Record zu TStringlist hinzufügen
Das mache ich alles nach PostQuitMessage.
Danke.
Delphi-Quellcode:
gruss
// Windows Messagen verarbeiten
while GetMessage(Msg, 0, 0, 0) do begin if IsDialogMessage(MainHandle, Msg) = false then begin TranslateMessage(Msg); DispatchMessage(Msg); end; end; KillTimer(MainHandle, 1); // Menu Resource freigeben GDIP_DisposeImage(ImgBack); GDIP_DisposeImage(ImgHover); GDIP_DisposeImage(SideBarImg); if hNotifyRBin > 0 then SHChangeNotifyDeregister(MainHandle); CreateIcon.ShowDesktopIcons(True); for X := 0 to Sprites.Count - 1 do begin if Sprites[X].h_Bitmap <> 0 then begin DeleteObject(Sprites[X].h_Bitmap); Sprites[X].h_Bitmap := 0; end; end; Sprites.Free; FreeAndNil(CreateIcon); FreeAndNil(DockBar); FreeAndNil(ShortCut); SKAERO_Free; |
AW: Record zu TStringlist hinzufügen
Genau, sauberer wäre aber, wenn sich ein TSprite selbst darum kümmern würde. Sprich statt:
Delphi-Quellcode:
So:
for X := 0 to Sprites.Count - 1 do
begin if Sprites[X].h_Bitmap <> 0 then begin DeleteObject(Sprites[X].h_Bitmap); Sprites[X].h_Bitmap := 0; end; end; Sprites.Free;
Delphi-Quellcode:
type
TSprite = class ... public destructor Destroy; override; end; destructor TSprite.Destroy; begin inherited; if h_Bitmap <> 0 then begin DeleteObject(h_Bitmap); h_Bitmap := 0; end; end; // und dann an deiner Stelle nur noch: Sprites.Free; |
AW: Record zu TStringlist hinzufügen
Du hast recht ;)
Habe zwar den Quelltext schon hochgeladen werde es aber trotzdem deinem Beispiel zu folgen noch ändern. Danke schön. Ist dann im nächsten Update enthalten. (Wenn noch eins kommt) Moment ;) Nein geht nicht! (Bei normalen Classen schon) Ich habe ja keine Class in herkömmlichen sinne. Sondern nur meinen Record umbenannt.
Delphi-Quellcode:
gruss
TSprite = class
CtrlName: WideString; CtrlIndex: Integer; Left: Single; Top: Single; Width: Integer; Height: Integer; Scale: Single; Opacity: Byte; ShellTo: string; IconPath: WideString; WorkDir: WideString; UseLabel: string; CmdLine: WideString; ShowCmd: longint; h_Bitmap: HBitmap; Visible: Bool; end; PSprite = ^TSprite; |
AW: Record zu TStringlist hinzufügen
Ja und? Du kannst doch trotzdem den Destruktor überschreiben.
|
AW: Record zu TStringlist hinzufügen
Zitat:
Normale Class
Delphi-Quellcode:
hier wurden Create und Destroy definiert..
TMagnetic = class(TInterfacedPersistent, ISkinMagnetic, ISkinMagneticEx)
constructor Create; destructor Destroy; override; somit kann ich sie beim start und beenden verwenden/überschreiben oder was auch immer. Schicke ich ein Free wird Destroy aufgerufen. Beide werden aber in meiner Class TSprite nicht erstellt und auch nicht code mäßig aufgerufen. Intern allerdings schon verwaltet. Also erstelle ich meine Class wird im Quelltext Create gar nicht aufgerufen. Somit kann ich da auch gar nichts eingeben. Verstehst was ich meine? Ich rede nicht davon das es grundsätzlich nicht geht sondern davon das ich beides in meiner Class/Record nicht definiert habe. Ohne Definition kann ich dort Codemäßig auch nichts eingeben. Die Funktionen existieren nicht! Ich möchte sie auch in der Class nicht definieren diese soll weiterhin wie ein Record aussehen. gruss |
AW: Record zu TStringlist hinzufügen
Du kannst den Destruktor doch jederzeit hinzufügen:
Delphi-Quellcode:
Ändern tut sich dadurch ja sonst nichts.
TSprite = class
CtrlName: WideString; CtrlIndex: Integer; Left: Single; Top: Single; Width: Integer; Height: Integer; Scale: Single; Opacity: Byte; ShellTo: string; IconPath: WideString; WorkDir: WideString; UseLabel: string; CmdLine: WideString; ShowCmd: longint; h_Bitmap: HBitmap; Visible: Bool; public destructor Destroy; override; end; |
AW: Record zu TStringlist hinzufügen
Zitat:
Alles andere verwirrt nur. ;) Hatte meine Beitrag oben nochmal korrigiert. Sorry. Zitat:
gruss |
AW: Record zu TStringlist hinzufügen
Auf der anderen Seite wir TSprite von TObjectList verwaltet und auch von dieser freigegeben.
Es ist nicht nötig hier ein Destroy zu definieren und zu überschreiben. Das mit den HBitmaps mache ich vorsorglich da ich mir nicht sicher bin das TObjectList diese korrekt frei gibt. Und ja ich weiß das TObjectList den Destructor aufruft wenn ich diese Freigebe aber ich möchte den Destructor nicht definieren. gruss |
AW: Record zu TStringlist hinzufügen
Die Objektliste gibt nur die in ihr enthaltenen Objekte frei. Enthalten diese wiederum selbst erstellte Ressourcen o.ä., so ist es deren Aufgabe, sich um das korrekte Abräumen zu kümmern.
|
AW: Record zu TStringlist hinzufügen
Zitat:
Und es geht nicht weil nicht definiert. Also der Record soll als solcher Sichtbar erhalten bleiben (Auch wenn es hier niemand verstehen will ist halt meine Art) LOL Wichtig ist das die Resourcen frei gegeben werden. gruss |
AW: Record zu TStringlist hinzufügen
Ja, Du machst es von außen. Besser wäre es aber, wenn die Sprite-Objekte das selbst in die Hand nehmen. Und Du hast keinen Record mehr, finde Dich damit ab ;). Mal abgesehen von etwas mehr Overhead sollte man meiner persönlichen Meinung nach Klassen eh den Vorzug geben.
|
AW: Record zu TStringlist hinzufügen
Zitat:
Werde ihn definieren habe mich damit abgefunden. Danke euch. :) Zitat:
gruss |
AW: Record zu TStringlist hinzufügen
Habe es jetzt mal gemacht.
Und so wie gedacht wird TSprite Destroy nun doppelt aufgerufen. Einmal von TSprite und einmal von TObjectList. Verwende ich nur TSprites.Free(TObjectList) dann sind alle TSprite schon NIL bevor ich irgendetwas aufräumen kann. Sehe jetzt nicht wirklich den Vorteil davon das Destroy nun zweimal aufgerufen wird. Nun gut wie dem auch sei.
Delphi-Quellcode:
SPrite.Free;
Sprites.Free; gruss |
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:43 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