AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Dynamisches Record?

Ein Thema von Thanatos81 · begonnen am 22. Mai 2005 · letzter Beitrag vom 22. Mai 2005
 
Robert_G
(Gast)

n/a Beiträge
 
#4

Re: Dynamisches Record?

  Alt 22. Mai 2005, 17:17
Wenn es mit etwas Umwegen gehen darf, wäre eine TList-Ableitung möglich.
Diese würde den ItemTypen bekommen und könnte damit sofort loslegen. (die Felder einer Klasse sind nichts weiter als ein Record )

Hier erstmal das FileOfClass-Dingsbums...
Delphi-Quellcode:
unit uFileOfClass;

interface
uses
  Classes,
  Contnrs;

type
  TFileOfClass = class(TObjectList)
  private
    fItemType: TClass;
  protected
    procedure WriteItemToStream(const aItem: TObject; aStream: TStream); virtual;
    function ReadItemFromStream(aStream: TStream): TObject; virtual;
  public
    property ItemType: TClass read fItemType;

    procedure SaveToStream(aStream: TStream); virtual;
    procedure LoadFromStream(aStream: TStream); virtual;

    procedure SaveToFile(const aFileName: string); virtual;
    procedure LoadFromFile(const aFileName: string); virtual;

    constructor Create(aItemType: TClass; aOwnsObjects: Boolean = True); virtual;
  end;


implementation
uses
  SysUtils;

{ TFileOfClass }

constructor TFileOfClass.Create(aItemType: TClass; aOwnsObjects: Boolean);
begin
  inherited Create(aOwnsObjects);
  fItemType := aItemType;
end;

procedure TFileOfClass.LoadFromFile(const aFileName: string);
var
  Stream : TStream;
begin
  Stream := TFileStream.Create(aFileName, fmOpenRead);
  try
    LoadFromStream(Stream);
  finally
    Stream.Free();
  end;
end;

procedure TFileOfClass.LoadFromStream(aStream: TStream);
begin
  while aStream.Position < aStream.Size do
    Add(ReadItemFromStream(aStream));
end;

function TFileOfClass.ReadItemFromStream(aStream: TStream): TObject;
begin
  Result := ItemType.NewInstance();
  aStream.Read(Pointer(Result)^, ItemType.InstanceSize - SizeOf(Pointer));
end;

procedure TFileOfClass.SaveToFile(const aFileName: string);
var
  Stream : TStream;
begin
  Stream := TFileStream.Create(aFileName, fmCreate);
  try
    SaveToStream(Stream);
  finally
    Stream.Free();
  end;
end;

procedure TFileOfClass.SaveToStream(aStream: TStream);
var
  i : Integer;
begin
  for i := 0 to Count - 1 do
  begin
    WriteItemToStream(Items[i], aStream);
  end;
end;

procedure TFileOfClass.WriteItemToStream(const aItem: TObject; aStream: TStream);
begin
  aStream.Write(Pointer(aItem)^, ItemType.InstanceSize - SizeOf(Pointer));
end;

end.
Ist nicht schön.... aber was kann in Verbindung mit typisierten Dateien schon schön sein.
Dein "record" sähe wohl so aus.
Delphi-Quellcode:
type
   TBlubbClass = class
   private
      fLfdNr: Integer;
      fKdNr: Integer;
      fName: myShortString;
      fVorname: myShortString;
   published
      property LfdNr: Integer read fLfdNr write fLfdNr;
      property KdNr: Integer read fKdNr write fKdNr;
      property Name: myShortString read fName write fName;
      property Vorname: myShortString read fVorname write fVorname;
   end;
Reinschreiben könntest du es so:
Delphi-Quellcode:
var
  myList : TFileOfClass;
  Blubb : TBlubbClass;
begin
  myList := TFileOfClass.Create(TBlubbClass);
  try
    Blubb := TBlubbClass.Create();
    Blubb.LfdNr := 1;
    Blubb.KdNr := 10;
    Blubb.Name := 'Schulz';
    Blubb.Vorname := 'Hans';

    myList.Add(Blubb);

    Blubb := TBlubbClass.Create();
    Blubb.LfdNr := 2;
    Blubb.KdNr := 20;
    Blubb.Name := 'Müller';
    Blubb.Vorname := 'Bert';

    myList.Add(Blubb);

    myList.SaveToFile('Miep.txt');
  finally
    myList.Free();
  end;
end;
Auslesen wäre so möglich:
Delphi-Quellcode:
var
  myList : TFileOfClass;
  i : Integer;
begin
  myList := TFileOfClass.Create(TBlubbClass);
  try
    myList.LoadFromFile('Miep.txt');

    for i := 0 to myList.Count - 1 do
      with TBlubbClass(myList[i]) do
        ListBox1.Items.Add(Name + ', ' + Vorname);

  finally
    myList.Free();
  end;
end;
Dumm ist nur, dass es eigentlich totaler Blödsinn ist.
Ändere den "record" zu einer Ableitung von TCollectionItem und schon kannst du auch strings und alles andere benutzen.
Anstatt der TFileOfClass würde die dpCollectiondpCollection ins Spiel kommen.
Bist du auf Kompatibilität zu ekligen typisierten Dateien angewiesen musst du wohl den Weg oben gehen (und hoffen, dass der Compiler die Felder nicht irgendwann intern verdreht).
Bist du es nicht sehe ich keine Ausrede weiterhin typisierte Dateien zu nehmen.
Delphi-Quellcode:
type
   TBlubbClass = class(TCollectionItem)
   private
      fLfdNr: Integer;
      fKdNr: Integer;
      fName: string;
      fVorname: string;
   published
      property LfdNr: Integer read fLfdNr write fLfdNr;
      property KdNr: Integer read fKdNr write fKdNr;
      property Name: string read fName write fName;
      property Vorname: string read fVorname write fVorname;
   end;
  Mit Zitat antworten Zitat
 


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 16:26 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