AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein GUI-Design mit VCL / FireMonkey / Common Controls Delphi Einer Routine einen beliebigen Record übergeben
Thema durchsuchen
Ansicht
Themen-Optionen

Einer Routine einen beliebigen Record übergeben

Ein Thema von Luckie · begonnen am 28. Sep 2004 · letzter Beitrag vom 29. Sep 2004
Antwort Antwort
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#1

Einer Routine einen beliebigen Record übergeben

  Alt 28. Sep 2004, 02:04
Folgendes Szenario:
Um Einstellungen in eine Ini-Datei zu speichern erstelle ich mir immer einen Record:
Delphi-Quellcode:
TSettings = packed record
  ...: ...;
  ...: ...;
  ...: ...;
end;
Diesen Record fülle ich und übergeben ihn dann an eine Routine SaveSettings:
procedure SaveSettings(IniFile: String; Settings: TSettings); Das Gegenstück zum Laden dazu sieht folgendermaßen aus:
function LoadSettings(IniFile: String; var Settings: TSettings): Boolean; 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?
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Dax
(Gast)

n/a Beiträge
 
#2

Re: Einer Routine einen beliebigen Record übergeben

  Alt 28. Sep 2004, 07:27
Wenn du im Record nie Strings/Pointer (dazu zählen auch Klassen) benutzt, kannst du einfach
TFileStream.Write(MyRecord, sizeof(MyRecord)); schreiben.
  Mit Zitat antworten Zitat
Dax
(Gast)

n/a Beiträge
 
#3

Re: Einer Routine einen beliebigen Record übergeben

  Alt 28. Sep 2004, 13:49
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.
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#4

Re: Einer Routine einen beliebigen Record übergeben

  Alt 28. Sep 2004, 14:05
Das ist noch nicht so das, was ich mir vorstelle.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Nightshade

Registriert seit: 7. Jan 2003
Ort: Menden
192 Beiträge
 
Delphi 7 Enterprise
 
#5

Re: Einer Routine einen beliebigen Record übergeben

  Alt 28. Sep 2004, 14:26
Ich würd das Ini-File komplett in eine Stringliste laden.

Bei nur einer Section kannst du dann einfach mit

Pfad := Settings.Values['DatanbankPfad']; Auf die Variablen zugreifen.

Wenn du mehrere Sections hast Den String einfach
 String := Section + '#' + Name + '#' + Value; zusammen bauen und ne passende Function für bauen um das auszulesen.

Sonst mit Records fällt mir da nichts ein...
Christian
Killing for peace is like fucking for virginity

Nightshade
  Mit Zitat antworten Zitat
shmia

Registriert seit: 2. Mär 2004
5.508 Beiträge
 
Delphi 5 Professional
 
#6

Re: Einer Routine einen beliebigen Record übergeben

  Alt 28. Sep 2004, 18:08
Zitat von Luckie:
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?
Wenn du dich von normalen Records verabschiedest und stattdessen etwas komplizierteres verwendest, dann geht das.
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:
 
const
   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;
Da man die Anzahl der Elemente und alle Namen abfragen kann, ist es kein Problem die Daten
in eine INI-Datei zu speichern.
Angehängte Dateien
Dateityp: pas uvariantarray.pas (9,2 KB, 11x aufgerufen)
Andreas
  Mit Zitat antworten Zitat
choose

Registriert seit: 2. Nov 2003
Ort: Bei Kiel, SH
729 Beiträge
 
Delphi 2006 Architect
 
#7

Re: Einer Routine einen beliebigen Record übergeben

  Alt 28. Sep 2004, 21:13
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...
gruß, choose
  Mit Zitat antworten Zitat
Benutzerbild von negaH
negaH

Registriert seit: 25. Jun 2003
Ort: Thüringen
2.950 Beiträge
 
#8

Re: Einer Routine einen beliebigen Record übergeben

  Alt 28. Sep 2004, 22:39
Delphi-Quellcode:
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;
Obiges Klassenkonstrukt ist nichts anderes als ein Record, ein Record mit Properties, virtuellen Methoden, Events, Typsicherheit, Zugriffsmethoden etc.pp.
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
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#9

Re: Einer Routine einen beliebigen Record übergeben

  Alt 29. Sep 2004, 14:50
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.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Nightshade

Registriert seit: 7. Jan 2003
Ort: Menden
192 Beiträge
 
Delphi 7 Enterprise
 
#10

Re: Einer Routine einen beliebigen Record übergeben

  Alt 29. Sep 2004, 23:29
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

Bei mir ist auf jeden Fall das hier herausgekommen :


TSettings so deklarieren wie man es braucht :

Delphi-Quellcode:
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;
und dann speichern oder laden...

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;
Angehängte Dateien
Dateityp: rar settings.rar (18,5 KB, 8x aufgerufen)
Christian
Killing for peace is like fucking for virginity

Nightshade
  Mit Zitat antworten Zitat
Antwort Antwort


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:33 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