![]() |
Einer Routine einen beliebigen Record übergeben
Folgendes Szenario:
Um Einstellungen in eine Ini-Datei zu speichern erstelle ich mir immer einen Record:
Delphi-Quellcode:
Diesen Record fülle ich und übergeben ihn dann an eine Routine SaveSettings:
TSettings = packed record
...: ...; ...: ...; ...: ...; end;
Delphi-Quellcode:
Das Gegenstück zum Laden dazu sieht folgendermaßen aus:
procedure SaveSettings(IniFile: String; Settings: TSettings);
Delphi-Quellcode:
Jetzt ist es ja so, das für jedes Projekt ein eigener Record definiert werden muss, weil man eben immer was anderes Speichern will. OK. Aber leider muss man auch immer wieder die obigen Routinen anpassen. Kann man jetzt irgendwas konstruieren, dass man jeweils nur den Record entsprechend anpasst und den Rest zum Speichern und Laden so lassen kann? Würde einem viel Arbeit abnehmen. Hat da jemand eine Idee oder ansatz, wie man das machen könnte?
function LoadSettings(IniFile: String; var Settings: TSettings): Boolean;
|
Re: Einer Routine einen beliebigen Record übergeben
Wenn du im Record nie Strings/Pointer (dazu zählen auch Klassen) benutzt, kannst du einfach
Delphi-Quellcode:
schreiben.
TFileStream.Write(MyRecord, sizeof(MyRecord));
|
Re: Einer Routine einen beliebigen Record übergeben
:oops: Korrektur: Du kannst bei dieser Methode schon Strings verwenden, aber nur die ShortStrings in der Form MyString: String[x] mit 0 < x < 256.
Du könntest aber auch eine "Memory-Map" des Records anlegen, die dir sagt, wo strings sind, wo Pointer sind (zusammen mit ihren Typen). Aber Klassen kannst du NIE verwenden, wenn mich mein Kenntnisstand nicht täuscht. ;) Es sei denn, du fügst deiner Klasse Methoden hinzu, die aus den Daten der Klasse einen Stream erzeugen, in dem allen Daten enthalten sind, sowie eine Methode, die das ganze dann auch wieder liest. |
Re: Einer Routine einen beliebigen Record übergeben
Das ist noch nicht so das, was ich mir vorstelle.
|
Re: Einer Routine einen beliebigen Record übergeben
Ich würd das Ini-File komplett in eine Stringliste laden.
Bei nur einer Section kannst du dann einfach mit
Delphi-Quellcode:
Auf die Variablen zugreifen.
Pfad := Settings.Values['DatanbankPfad'];
Wenn du mehrere Sections hast Den String einfach
Delphi-Quellcode:
zusammen bauen und ne passende Function für bauen um das auszulesen.
String := Section + '#' + Name + '#' + Value;
Sonst mit Records fällt mir da nichts ein... |
Re: Einer Routine einen beliebigen Record übergeben
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:
Ich habe mir mal vor einiger Zeit ein "typisiertes Variant-Array" gebastelt. Man hat also ein Array vom Datentyp Variant wobei jedes Element entweder über einen Namen oder einen Indez angesprochen werden kann. Bei der Initialisierung wird zusätzlich zum Namen und Index auch noch ein Datentyp mitgegeben. Der Zugriff auf die Daten sieht z.B. so aus:
Delphi-Quellcode:
Da man die Anzahl der Elemente und alle Namen abfragen kann, ist es kein Problem die Datenconst list:array [0..8] of TVAitem = ( (name:'ArtikelNr'; vartype: varString), (name:'ArtikelName'; vartype: varString), (name:'EAN13'; vartype: VarString), (name:'Menge'; vartype: varDouble), (name:'MengeUnit'; vartype: varString), (name:'BruttoGewicht';vartype: varDouble), (name:'NettoGewicht'; vartype: varDouble), (name:'AuftragsNr'; vartype: varString), (name:'EquipmentNr'; vartype: varString) ); begin va := TTypedVariantArray.Create(list); va.ValueByName['ArtikelNr'] := '4711'; va.ValueByName['Menge'] := 150.0; in eine INI-Datei zu speichern. |
Re: Einer Routine einen beliebigen Record übergeben
Was spricht gegen den Einsatz von Klassen und der RTTI, so wie es der Streaming-Mechanismus von Delphi macht? Lösungen, wie Typen, Namen und Werte von published properties ermittelt und letztere gesetzt werden, solltest Du im Web finden.
Es ist dazu nicht notwendig, Deine Klasse von TPersistent erben zu lassen, das Kompilieren mit dem Schalter {$M+} Deiner jeweiligen Klasse, besser noch, einer schlanken Basisklasse, die Du dann auch für die Signatur von anderen Methoden verwenden könntest, reicht (auch für die Erben) vollkommen aus... |
Re: Einer Routine einen beliebigen Record übergeben
Delphi-Quellcode:
Obiges Klassenkonstrukt ist nichts anderes als ein Record, ein Record mit Properties, virtuellen Methoden, Events, Typsicherheit, Zugriffsmethoden etc.pp.
type
TAbstractSettings = class(TObject) protected procedure Save(Stream: TStream); virtual; abstract; procedure Load(Stream: TStream); vietual; abstract; end; TTestSettings = class(TAbstractSettings) private FLeftPos: Integer; FRightPos: Integer; public property LeftPos..... bla bla usw. end; Was spricht also für generische Records und was spricht gegen Klassen ? Falls du wirklich ganz ganz generische Records benutzen willst, also KEINE vollständigen Objecte bei denen man Methoden selber schreiben will so kann man denoch Klassen dazu benutzen. Man deklariert einfach eine X'beliebige Klasse abgeleitet von TObject und alle Felder als published. Die globale und procedurale Lade/Speicher Routine kann nun mit Hilfe der RTTI dieser Klasse dynamisch zur Laufzeit die Felder und deren Typen ermitteln und deren Inhalte laden und speichern. Gruß Hagen |
Re: Einer Routine einen beliebigen Record übergeben
Ich habe mich noch gar nicht irgendwie festgelegt. Das mit dem Record war nur zur Verdeutlichung gedacht.
Ich werde mir mal eure Vorschläge durch den Kopf gehen lassen. |
Re: Einer Routine einen beliebigen Record übergeben
Liste der Anhänge anzeigen (Anzahl: 1)
Ich hab mir die Sache mit dem RTTI und so mal angeschaut...
Benutz es, oder leite was draus ab, oder verbesser es, oder lass es :lol: Bei mir ist auf jeden Fall das hier herausgekommen : TSettings so deklarieren wie man es braucht :
Delphi-Quellcode:
und dann speichern oder laden...
type TSettings = class(TComponent)
private Ff: byte; Fg: char; Fb2: double; Fa1: integer; FPfad: string; Fe: word; Fd: string; Fh: boolean; protected public published property Pfad : string read FPfad write FPfad; property a1 : integer read Fa1 write Fa1; property b2 : double read Fb2 write Fb2; property d : string read Fd write Fd; property e : word read Fe write Fe; property f : byte read Ff write Ff; property g : char read Fg write Fg; property h : boolean read Fh write Fh; end;
Delphi-Quellcode:
uses SettingsVorlage;
procedure TForm1.BitBtn1Click(Sender: TObject); var t : TSettingsVorlage; begin t := TSettingsVorlage.Create(self); t.Settings.d := 'Hallo'; t.Settings.Pfad := 'Welt'; t.SaveToFile(Pfad+'Testfile.dat'); // t.SaveToINIFile(Pfad+'Testfile.ini'); // t.SaveToRegistry(HKEY_LOCAL_MACHINE ,'Software\YDB-Soft\Testfile'); t.free; end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 13:31 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