Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi Integer in ListItem eines ListViews speichern (https://www.delphipraxis.net/80800-integer-listitem-eines-listviews-speichern.html)

hoika 15. Nov 2006 14:22


Integer in ListItem eines ListViews speichern
 
Hallo #,

irgendwie stehe ich auf dem Schlauch.
Ich fülle ein ListView mit Konstanten.
Jeder Konstante ist ein Text zugeordnet.

Wie bekomme ich die Konstante als verstecktes Feld mit rein.
Data geht nicht.

Bsp.
Delphi-Quellcode:
const
  C_X1 = 1;
  C_X2 = 2;

ListItem:= ListView.Items.Add;
ListItem.Caption:= ConstAsText(C_X1); // ConstAsTexti st meine
ListItem.Data:= ?? order wo soll C_X1 hin ?
Heiko

arbu man 15. Nov 2006 14:26

Re: Integer in ListItem eines ListViews speichern
 
Delphi-Referenz durchsuchenIntToStr

bzw.

Delphi-Quellcode:
type
  TConstHolder = class
  public
    FConst: integer;
end;

var
  ch:TConstHolder ;
begin
  ch:= TConstHolder.Create;
  ch.FConst:= C_X1;
  ListItem.Data:= ch;
end;

hoika 15. Nov 2006 14:29

Re: Integer in ListItem eines ListViews speichern
 
OK,

erzeugt aber memory leaks,
falls die Klassen nicht im FormDestroy freigegeben werden.


Heiko

arbu man 15. Nov 2006 14:34

Re: Integer in ListItem eines ListViews speichern
 
Nun das muss man dann noch machen,is schon klar sollte nur ein gerüst sein...

Alternativ kanst du den integer als Pointer in Data Speichern...

DennisHB 15. Nov 2006 14:36

Re: Integer in ListItem eines ListViews speichern
 
Ist jetzt ungetestet sollte aber gehen

Delphi-Quellcode:
var
   Item : TListItem;
   i : integer;
Begin
   ...
   Item.Data := Pointer(i);

   ...
   i := Integer(Item.Data);

mkinzler 15. Nov 2006 14:38

Re: Integer in ListItem eines ListViews speichern
 
@DennisHB:Das führt aber zu einem schönen Bombenhagel! Da i nach Ende der Methode futsch ist.

hoika 15. Nov 2006 14:53

Re: Integer in ListItem eines ListViews speichern
 
;)

und ausserdem wollte ich Konstanten benutzen,
da klappt das eh nicht.
Muss ich das halt über die Klasse machen.
Schade, dass TListItem kein Tag hat.

Heiko

DennisHB 15. Nov 2006 15:00

Re: Integer in ListItem eines ListViews speichern
 
:) MÖP es geht - nu auch getestet - n Pointer is doch nix anderes als ne Zahl (Integer? evtl Unsigned?)
Man kann ja auch Objecte an ein xyz.Tag hängen (eben umgekehrt)

Delphi-Quellcode:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ComCtrls;

type
  TForm1 = class(TForm)
    lv: TListView;
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
    procedure lvSelectItem(Sender: TObject; Item: TListItem;
      Selected: Boolean);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
     Item : TListItem;
begin
     item := lv.Items.Add;
     Item.Data := Pointer(45);
     Item.Caption := 'Test';
end;

procedure TForm1.lvSelectItem(Sender: TObject; Item: TListItem;
  Selected: Boolean);
begin
     If Assigned(Item) then
          Caption := IntTostr(Integer(Item.Data));
end;

end.

Schwedenbitter 8. Feb 2013 09:43

AW: Re: Integer in ListItem eines ListViews speichern
 
Zitat:

Zitat von DennisHB (Beitrag 550507)
Delphi-Quellcode:
...

procedure TForm1.Button1Click(Sender: TObject);
var
     Item : TListItem;
begin
     item := lv.Items.Add;
     Item.Data := Pointer(45);
     Item.Caption := 'Test';
end;

procedure TForm1.lvSelectItem(Sender: TObject; Item: TListItem;
  Selected: Boolean);
begin
     If Assigned(Item) then
          Caption := IntTostr(Integer(Item.Data));
end;

end.

Der Code läuft zumindest beim Bestücken der Liste einfach genial. Trotzdem nochmal eine Frage dazu:

Recht es aus, wenn ich beim Beenden des Programmes
Delphi-Quellcode:
procedure TForm1.Destroy(Sender: TObject);
begin
     lv.clear;
end;
mache oder muss ich die Liste durchgehen und die ganzen Einträge nebst dem in Data gespeicherten Integer von Hand "beseitigen"?
Ich selbst weiß es leider nicht, kann es mir nicht herleiten und möchte nicht um es herauszufinden mittels try and error FastMemory dazunehmen.

Gruß und Dank, Alex

DeddyH 8. Feb 2013 09:49

AW: Integer in ListItem eines ListViews speichern
 
Wenn Du wirklich Pointer(45) einträgst, was willst Du denn da freigeben? Hier wurde ja nur ein harter Cast dazu verwendet, eine Zahl in einer Pointer-Property zu hinterlegen, der Pointer selbst zeigt ja ins Nirwana. Von daher wäre es sogar gefährlich, eine Freigabe zu versuchen, da man gar nicht weiß, auf welchen Speicher man eigentlich zeigt.

CCRDude 8. Feb 2013 09:52

AW: Integer in ListItem eines ListViews speichern
 
Bin mir nicht sicher, seit welcher Version, aber TListView hat nen sehr praktischen Event, der das Erweitern von TListItem um eigene Daten komfortabel und ohne Trickserei ermöglicht:

Delphi-Quellcode:
type
   TMyListItem = class(TListItem)
      MyNumber: integer;
   end;

procedure TForm1.lvCreateItemClass(Sender: TCustomListView; var ItemClass: TListItemClass);
begin
   ItemClass := TMyListItem;
end;

DeddyH 8. Feb 2013 09:59

AW: Integer in ListItem eines ListViews speichern
 
Das ist doch mal eine nützliche Erweiterung. Unter Delphi 2007 gibt es das Event noch nicht, unter XE aber schon, es muss also irgendwann dazwischen eingeführt worden sein.

Schwedenbitter 8. Feb 2013 12:39

AW: Integer in ListItem eines ListViews speichern
 
Zitat:

Zitat von DeddyH (Beitrag 1202572)
Wenn Du wirklich Pointer(45) einträgst, was willst Du denn da freigeben? ...

"Natürlich" will ich dort den Wert einer Variable hinterlegen:
In meiner TListView lege ich Dateinamen nebst Größe etc. an. Auf die Größe muss ich immer wieder zugreifen und damit rechnen und es nervt, wenn ich das von String nach
Delphi-Quellcode:
Int64
und zurück umwandeln muss. Daher such(t)e ich nach einer Möglichkeit, den Zahlenwert mit unterzubringen.
Immerhin heißt das Thema ja auch "Integer in ListItem eines ListViews speichern" - von Konstanten steht dort nichts. Das kommt dann erst im Beispielcode. Meine Frage rührtvon diesem Thema.

Ich glaube es jetzt auch verstanden zu haben:
Pointer speichert (numerisch) die Adresse zu einem Objekt und wird im Beispielcode von DennisHB de facto als direkter Speicher einer Zahl selbst missbraucht. Und genau aus diesem Grunde dürfte mein Plan damit nicht aufgehen. Denn Pointer hat eine Größe von 4 Byte, kann damit also maximal auch 4 Bytes aufnehmen, während ich Int64 brauche, was aber 8 Bytes benötigt. Es wäre auch zu schön gewesen.

Leider arbeite ich aus Kostengründen noch mit TurboDelphi. Ich bin reiner Hobbyprogrammierer und kann/will mir daher die € 1.000,- für eine sinnvolle Delphi-Lizenz nicht leisten. Aus diesem Grunde dürfte der von CCRDude vorgschlagene Code mir nichts bringen.

Gruß und Dank, Alex

DeddyH 8. Feb 2013 12:57

AW: Integer in ListItem eines ListViews speichern
 
Nochmal zum Unterschied: im Beispielcode wurde wie gesagt der Pointer dazu missbraucht, eine 4-Byte-Zahl zu hinterlegen, der Pointer an sich zeigte aber nirgends hin. Du kannst aber natürlich einen echten Pointer dort ablegen, der auch auf echte Daten zeigt, ob da nun 8 oder 2.000.000 Bytes dahinterstecken, spielt keine Rolle. Zum Freigeben dieser Daten dürfte dann das OnDeletion-Ereignis der ListView die richtige Stelle sein, wenn ich nicht irre.

Schwedenbitter 8. Feb 2013 13:55

AW: Integer in ListItem eines ListViews speichern
 
Richtiger wäre also so etwas in der Art:
Delphi-Quellcode:
Interface

Type
   TInt64Obj  = Class(TObject)
               Private
                  FValue  : Int64;
               Public
                  Constructor Create(Const Value: Int64);
                  Property Value: Int64 Read FValue Write FValue;
               End;

Implementation

Constructor TInt64Obj.Create(Const Value: Int64);
Begin
   Inherited Create;
   FValue:=Value;
End;

Procedure ErzeugeEintrag(Value: Int64);
Begin
   With MyListView.Items.Add Do
   Begin
      Caption:=FormatFloat('0,', FileSize);
//    Data:=Pointer(FileSize); // <- reicht nicht aus, wie festgestellt wurde.
//
// Wie bekomme ich mein Int64 in das Item?
//
// Es gibt im Gegensatz zu z.B. TCheckListBox kein Items.AddObject();
// in TCheckListBox hatte ich z.B. mal neben dem Eintrag weitere Strings gespeichert...
      SubItems.Add(FileName);
   End;
End;

Function LiesEintrag(Index: Integer): Int64;
Begin
   Result:=TInt64Obj(MyListView.Items[Index].Data).Value;
End;

DeddyH 8. Feb 2013 13:59

AW: Integer in ListItem eines ListViews speichern
 
Delphi-Quellcode:
Procedure ErzeugeEintrag(Value: Int64);
var
  Int64Obj: TInt64Obj;
Begin
   Int64Obj := TInt64Obj.Create(value);
   With MyListView.Items.Add Do
   Begin    
      Caption:=FormatFloat('0,', FileSize);
      Data := Int64Obj;
      SubItems.Add(FileName);
   End;
End;

Schwedenbitter 8. Feb 2013 14:20

AW: Integer in ListItem eines ListViews speichern
 
So klappt es - tausend Dank.
Ich habe den Code im Beitrag davor auch noch bereinigt, was das
Delphi-Quellcode:
LiesEintrag;
anbelangt.

DeddyH 8. Feb 2013 14:26

AW: Integer in ListItem eines ListViews speichern
 
Man könnte in LiesEintrag auch noch auf Assigned abfragen, bevor man auf die Properties zugreift ;) Und wie vorher schon gesagt: im OnDeletion der ListView das Objekt in Data wieder freigeben, das sollte IMO passen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 15:41 Uhr.

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