Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   C++ Komponente erweitern (https://www.delphipraxis.net/80726-komponente-erweitern.html)

Maiky 14. Nov 2006 13:03


Komponente erweitern
 
Hallo.

Ich arbeite normal mit dem CBuilder, habe jedoch eine Komponente die auf Pascal basiert und jetzt ein Modifikationsproblem, da ich mich mit Pascal noch nicht so gut auskenne.

Ich möchte der Komponente eine Funktionalität hinzufügen.

Ich möchte gern in diese Komponente zusätzlich Daten ablegen und zwar zusammengehörige: {Name, Anzahl, WertProStueck} und das ähnlich wie ein TStringList mit Add beliebig viele hinzufügen und mit Delete(index) löschen können.

DieKomponente.Daten.Add("Name1",2,5);
DieKomponente.Daten.Add("Name2",1,3);
DieKomponente.Daten.Add("Name3",4,2);
DieKomponente.Daten.Delete(2); // entfernt ("Name2",1,3)

Kennt jemand dafür vielleich ein Tutorial oder kann helfen?

So habe ich angefangen, komme aber irgendwie nicht weiter :)

Delphi-Quellcode:
Daten = Record
   Name: WideString;
   Anzahl: Integer;
   WertProStueck: Integer;
end;

DatenArray = class
private
   Datas: array of Daten;
public
   procedure Add(Name: WideString, Anzahl: Integer, WertProStueck: Integer);
   procedure Delete(Index: Integer);
end;

MeineKomponente = class
private
public
   property Items: DatenArray ????
end;

constructor DatenArray.Create;
begin
end;

destructor DatenArray.Destroy;
begin
end;

procedure DatenArray.Add(Name: WideString, Anzahl: Integer, WertProStueck: Integer);
begin
end;

procedure Delete(Index: Integer);
begin
end;

Maiky 14. Nov 2006 15:52

Re: Komponente erweitern
 
Ich habe mich mal weiter dran probiert

Delphi-Quellcode:
Daten = Record
   Name: WideString;
   Anzahl: Integer;
   WertProStueck: Integer;
end;

DatenArray = class
private
   SList: TList;
public
   constructor Create;
   destructor Destroy; override;
   procedure Add(Name: WideString; Anzahl: Integer; WertProStueck: Integer);
   procedure Delete(Index: Integer);
end;


implementation {===============================================================}


constructor DatenArray.Create;
begin
   SList := TList.Create;
end;

destructor DatenArray.Destroy;
begin
   SList.Free;
end;

procedure DatenArray.Add(Name: WideString; Anzahl: Integer; WertProStueck: Integer);
begin
   
   ?????????

   datenx.Name := Name;
   datenx.Anzahl := Anzahl;
   datenx.WertProStueck := WertProStueck;
   SList.Add(datenx);
end;

procedure DatenArray.Delete(Index: Integer);
begin
   SList.Delete(Index);
end;
Mein Problem nun liegt in de Zeile "SList.Add(datenx);" bzw besser gesagt wie reserviere ich Speicher für das "Daten : Record", damit ich es in die SList eintragen kann??

SirThornberry 14. Nov 2006 16:10

Re: Komponente erweitern
 
du musst dafür "Daten" (besser TDaten) einen Pointertyp anlegen
Delphi-Quellcode:
Daten = Record
   Name: WideString;
   Anzahl: Integer;
   WertProStueck: Integer;
end;
//neu
PDaten = ^Daten;
dann kannst du mit
Delphi-Quellcode:
var
  DatenVariable: PDaten;
begin
  new(DatenVariable);
speicher für PDaten anfordern und mit
Delphi-Quellcode:
DatenVariable^.Anzahl := ...
Dinge zuweisen.
Da es sich dann um einen Pointertyp handelt kann dieser auch der TList hinzugefügt werden.
mit
Delphi-Quellcode:
Dispose(SList.Item[i]);
kann dann der reservierte Speicher wieder frei gegeben werden.

Maiky 14. Nov 2006 17:20

Re: Komponente erweitern
 
Danke für die Hilfe!! Ich dachte es wäre nun soweit, aber in CBuilder sagt er bei:
MeineKomponente->MyItems->Add("huhu,1,2) Speichererror :(

Vielleicht jemand der sieht warum?
Ich mach den Quelltext in Texteditor und compiliere per Commandline ~.~

Delphi-Quellcode:
PDaten = ^TDaten;
TDaten = Record
   Name: WideString;
   Anzahl: Integer;
   WertProStueck: Integer;
end;

TDatenArray = class
private
   SList: TList;
public
   constructor Create;
   destructor Destroy;
   function Read(Index: Integer) : PDaten;
   procedure Add(Name: WideString; Anzahl: Integer; WertProStueck: Integer);
   procedure Delete(Index: Integer);
   function Count : Integer;
end;



// MAIN KOMPONENTE
MeineKomponente = class(TComponent)
private
   FMyItems : TDatenArray;
published
   property MyItems: TDatenArray read FMyItems;
end;



constructor TDatenArray.Create;
begin
   SList := TList.Create;
end;

destructor TDatenArray.Destroy;
begin
   SList.Free;
end;

procedure TDatenArray.Add(Name: WideString; Anzahl: Integer; WertProStueck: Integer);
var
   DatenVariable: PDaten;
begin
   new(DatenVariable);
   DatenVariable^.Name := Name;
   DatenVariable^.Anzahl := Anzahl;
   DatenVariable^.WertProStueck := WertProStueck;
   SList.Add(DatenVariable);
end;

function TDatenArray.Read(Index: Integer) : PDaten;
begin
   Result := nil;
   if ((Index>=0) AND (Index<SList.Count)) then
   begin
   Result := SList.Items[Index];
   end;
end;

function TDatenArray.Count : Integer;
begin
   Result := SList.Count;
end;

procedure TDatenArray.Delete(Index: Integer);
var
   daten : PDaten;
begin
   if ((Index>=0) AND (Index<SList.Count)) then
   begin
      daten := SList.Items[Index];
      SList.Delete(Index);
      Dispose(daten);
   end;
end;

SirThornberry 14. Nov 2006 17:31

Re: Komponente erweitern
 
so wie es aussieht hast du nirgends die Instanz von "MyItems" erzeugt.
Somit ist
Delphi-Quellcode:
MeineKomponente->MyItems
nil (NULL)

Also einfach für "MeineKomponente" noch einen Constructor und Destructor anlegen wo du "FMyItems" mit "TDatenArray.Create" erzeugst.

Was auch verwirrend ist. Deine Klasse heißt "MeineKomponente" und deine Instanzvariable heißt auch so. In Delphi ist es üblich einer Klasse ein "T" vorran zu stellen wie du es auch bei "TDatenArray" gemacht hast.

Maiky 14. Nov 2006 17:35

Re: Komponente erweitern
 
Argh, GENAU DAS WARS :wall: :wall: :wall:
Vielen Dank! Super Hilfe, geht jetzt alles :firejump:

Das mit dem "T" Wird beherzigt, danke.

Maiky 14. Nov 2006 18:08

Re: Komponente erweitern
 
Eine Frage hätte ich jetzt doch noch abschliessend (sorry, nächstes mal Edit)


Delphi-Quellcode:
TMeineKomponente = class(TComponent)
private
   FMyItems : TDatenArray;
published
   property MyItems: TDatenArray read FMyItems;
end;

Das funktioniert nun wo ich in Create es erstelle und Destroy wieder freigebe.
Mein letztes Problem nun ist, das ich eine Klasse habe die viele Klassen vereint.


Delphi-Quellcode:
TDocuemnt = class(TComponent)
private
   FKomp : TMeineKomponente;
public
   procedure SaveToTextFile(AFileName: string);
end;

Ist noch etwas komplexer, da TMeineKomponente noch vorher in einer weiteren Klasse liegt und erst diese in TDocument enthalten ist.

Die geniale Funktion SaveToTextFile speichert die "Komponente" als Textfile. Diese sieht dann aus wie eine DFM Datei, nur leider ist dort nirgends mein "MyItems" aus "TMeineKomponente" enthalten.

Wenn ich in "TMeineKomponente" ein weiteres Property wie Integer oder so einfüge, dann ist es im Textfile.

Woran könnte das liegen? Ist TDatenArray TDocument "unbekannt" oder wie muss ich das verstehen? (Falls mich hier überhaupt wer versteht :D)

shmia 14. Nov 2006 18:09

Re: Komponente erweitern
 
Ich würde aus dem Record eine Klasse machen.
Das lohnt sich sobald auf die Daten Funktionen angewendet werden
Delphi-Quellcode:
TDaten = class(TPersistent)
   public
   // die internen Variablen bleiben zunächst public
   // später können diese in Properties verpackt werden
   Name: WideString;
   Anzahl: Integer;
   WertProStueck: Integer;
   function GetGesamtwert:integer;  // = Anzahl*WertProStueck
   procedure Clear;
   function AsFormatedString:Ansistring;
end;

Maiky 14. Nov 2006 18:24

Re: Komponente erweitern
 
Wie bekommst jetzt mehrere? Du hast lediglich eine Klasse mit 3 Variablen und willst auf die Counter machen? Sehe da jetzt irgendwie nicht wirklich den Sinn.


Alle Zeitangaben in WEZ +1. Es ist jetzt 00:08 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