Klasse aus einer Datei laden ?

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
schnullerbacke
Beiträge: 1187
Registriert: Mi 13. Dez 2006, 10:58
OS, Lazarus, FPC: Winux (L 1.2.xy FPC 2.6.z)
CPU-Target: AMD A4-6400 APU
Wohnort: Hamburg

Beitrag von schnullerbacke »

Und wir können nicht verstehen, das du das nicht verstehst... :wink:

Mein Beispiel nennt man einen Scanner, der liest deine ASCII-Datei und sucht sich das Objekt, das gewünscht wird. Dann kannst du das Objekt wenn gefunden erzeugen und in AObject zurückgeben. Der Scanner dient nebenbei dazu die nötigen Parameter einzulesen (so denn welche da sind) und das Objekt gleich komplett zu initialisieren.

Und wenn du das einfacher haben willst machste das mit ner ini-Datei, da kannste das Objekt direkt über nen Schlüssel auswählen und die Parameter ebenfalls per Schlüssel einlesen.

Die ini-Kiste nützt nur dann nix, wenn die Dinger unsortiert in der ASCII-Datei liegen, also auch mehrfach vorkommen können. Dann bleibt nur der Weg über den Scanner.
Humor ist der Knopf, der verhindert, daß uns der Kragen platzt.

(Ringelnatz)

pluto
Lazarusforum e. V.
Beiträge: 7178
Registriert: So 19. Nov 2006, 12:06
OS, Lazarus, FPC: Linux Mint 19.3
CPU-Target: AMD
Wohnort: Oldenburg(Oldenburg)

Beitrag von pluto »

naja ich wollte gerne eine ASCI-Format haben wo ich ohne eine extra Programm drauf zugreifen kann. vielen Dank für eure Antworten. Ich werde es mir nochmal überlegen wie ich es machen !

ich glaube theo vorschlagt ist genau das was ich brauche !

was macht eigentlich RegisterClasses([TButton, TMemo]);
genau ? muss ich das mit angeben ? kann ich dort auch ein gobalen dynamischen array angeben ? weil dann währe das geeignet
MFG
Michael Springwald

schnullerbacke
Beiträge: 1187
Registriert: Mi 13. Dez 2006, 10:58
OS, Lazarus, FPC: Winux (L 1.2.xy FPC 2.6.z)
CPU-Target: AMD A4-6400 APU
Wohnort: Hamburg

Beitrag von schnullerbacke »

Das registriert halt Klassen in der Class-Lib damit sie der Umgebung bekannt sind. Wenn du die Dinger als Komponente installierst braucht man das nicht extra machen.
Humor ist der Knopf, der verhindert, daß uns der Kragen platzt.

(Ringelnatz)

Christian
Beiträge: 6079
Registriert: Do 21. Sep 2006, 07:51
OS, Lazarus, FPC: iWinux (L 1.x.xy FPC 2.y.z)
CPU-Target: AVR,ARM,x86(-64)
Wohnort: Dessau
Kontaktdaten:

Beitrag von Christian »

Was ist denn ne Class lib ?

Und warum muss man das für Komponenten nicht machen ? Klar muss man das auch für Klassen innerhalb der Komponenten machen.

Delphi/Lazarus führen eine Classlist über die TReader/TWriter die Klassen erkennen RegisterClass fügt eine von TPersistent abgeleitete Klasse in diese Classlist ein.
W.m.k.A.h.e.m.F.h. -> http://www.gidf.de/

pluto
Lazarusforum e. V.
Beiträge: 7178
Registriert: So 19. Nov 2006, 12:06
OS, Lazarus, FPC: Linux Mint 19.3
CPU-Target: AMD
Wohnort: Oldenburg(Oldenburg)

Beitrag von pluto »

von einer Class lib habe ich noch nie gehört.
MFG
Michael Springwald

schnullerbacke
Beiträge: 1187
Registriert: Mi 13. Dez 2006, 10:58
OS, Lazarus, FPC: Winux (L 1.2.xy FPC 2.6.z)
CPU-Target: AMD A4-6400 APU
Wohnort: Hamburg

Beitrag von schnullerbacke »

Wenn man Klasse als Komponente in der IDE installiert hat man das implizit schon miterledigt. Und ob nun List oder Library kommt wohl auf's Gleiche raus.
Humor ist der Knopf, der verhindert, daß uns der Kragen platzt.

(Ringelnatz)

Christian
Beiträge: 6079
Registriert: Do 21. Sep 2006, 07:51
OS, Lazarus, FPC: iWinux (L 1.x.xy FPC 2.y.z)
CPU-Target: AVR,ARM,x86(-64)
Wohnort: Dessau
Kontaktdaten:

Beitrag von Christian »

Ne Liste und ne Bibliothek ist für mich nicht das selbe worauf ich hinaus will ist das du immer Begriffe für irgendwas erfindest und man dich dann nicht verstehen kann.

Wenn du eine Komponente in der IDE installierst ist die Klasse innerhalb der IDE registriert lässt du deine Programme nur in der IDE laufen ?
W.m.k.A.h.e.m.F.h. -> http://www.gidf.de/

schnullerbacke
Beiträge: 1187
Registriert: Mi 13. Dez 2006, 10:58
OS, Lazarus, FPC: Winux (L 1.2.xy FPC 2.6.z)
CPU-Target: AMD A4-6400 APU
Wohnort: Hamburg

Beitrag von schnullerbacke »

Zitat:

Code: Alles auswählen

Beschreibung
 
Mit RegisterClass kann eine Klasse beim Streaming-System registriert werden. In einer Formulardeklaration enthaltene Formular- und Komponentenklassen (Instanzvariablen) werden automatisch registriert. Alle anderen in einer Anwendung verwendeten Klassen müssen mit RegisterClass explizit registriert werden, wenn Instanzen gespeichert werden sollen.


...also wohl nur für solche nötig, die nicht bereits in einem Formular implizit deklariert sind...

Code: Alles auswählen

type
 
  TMyForm = class(TForm)
     // von der IDE eingebaute Komponenten, automatisch registriert
  private
    FMyCircle: TMyCircle; // wird automatisch registriert weil Instanzvariable
  end;


...also nur für solche nötig, die nicht in einem beliebigen Formular der Anwendung bereits vorliegen, wie z.B. selten verwendete Klassen. TPopupMenue wenn es nicht auf einem vorhandenem Formular verwendet wird aber aus einem Stream eingelesen oder in einen Stream geschrieben werden soll. Dabei sind aber vornehmlich ResourceStreams (TReader, TWriter) gemeint, obwohl man das auch für einen beliebigen Stream anwenden kann.
Humor ist der Knopf, der verhindert, daß uns der Kragen platzt.

(Ringelnatz)

pluto
Lazarusforum e. V.
Beiträge: 7178
Registriert: So 19. Nov 2006, 12:06
OS, Lazarus, FPC: Linux Mint 19.3
CPU-Target: AMD
Wohnort: Oldenburg(Oldenburg)

Beitrag von pluto »

sehe ich das richtig ?

Instanzvariablen damit sind die Variablen gemeint die innerhalb einer klasse verwendet werden z.b. weitere klassen oder meinen die damit auch ganz normale Datentypen wie integer oder String ?
MFG
Michael Springwald

schnullerbacke
Beiträge: 1187
Registriert: Mi 13. Dez 2006, 10:58
OS, Lazarus, FPC: Winux (L 1.2.xy FPC 2.6.z)
CPU-Target: AMD A4-6400 APU
Wohnort: Hamburg

Beitrag von schnullerbacke »

Instanzvariablen meinen auch normale Datentypen, nur da die regelmäßig nicht von TPersistent abgeleitet sind, muß für solche Typen Objektintern die Parameterspeicherung gesondert vereinbart werden. Aber grundsätzlich sind auch die speicherbar.

#Edit

Code: Alles auswählen

procedure TMyObject.SaveToStream(Strm: TStream);
begin
   if (Strm <> nil) then begin
     Strm.Write(FMyVar, SizeOf(FMyVar));
     Strm.Write(FMyNextVar, SizeOf(FMyNextVar));
  end;
end;
 
procedure TMyObject.ReadFromStream(Strm: TStream);
begin
   if (Strm <> nil) and (Strm.Size - Strm.Pos >= SizeOf(FMyVar) + SizeOf(FMyNextVar)) then begin
     Strm.Read(FMyVar, SizeOf(FMyVar);
     Strm.Read(FMyNextVar, SizeOf(FMyNextVar));
  end;
end;


Der Datentyp muß im Beispiel nicht angegeben werden, weil die jeweilige Variable einfach als Folge von Bytes gespeichert wird. Allerdings ist die Reihenfolge genau einzuhalten. Strings sind allerdings gesondert zu behandeln. Hier muß zunächst die Länge gespeichert werden und dann über eine Hilfsvariable einzulesen. Etwa so:

Code: Alles auswählen

procedure TMyObject.SaveToStream(Strm: TStream);
begin
   if (Strm <> nil) then begin
     Strm.Write(FMyVar, SizeOf(FMyVar));
     Strm.Write(FMyStr[0], SizeOf(integer));
     Strm.Write(FMyStr[1], length(FMyStr);
  end;
end;
 
procedure TMyObject.ReadFromStream(Strm: TStream);
var
  len: integer;
  str: string;
begin
   if (Strm <> nil) and (Strm.Size - Strm.Pos > 0) then begin
     Strm.Read(FMyVar, SizeOf(FMyVar));
     Strm.Read(len, SizeOf(len));
     SetLength(s, len);
     Strm.Read(s[1], len);
     FMyStr:= s;
     {auch erlaubt
        SetLength(FMyStr, len);
        Strm.Read(FMyStr[1], len));
     }

  end;
end;
Humor ist der Knopf, der verhindert, daß uns der Kragen platzt.

(Ringelnatz)

pluto
Lazarusforum e. V.
Beiträge: 7178
Registriert: So 19. Nov 2006, 12:06
OS, Lazarus, FPC: Linux Mint 19.3
CPU-Target: AMD
Wohnort: Oldenburg(Oldenburg)

Beitrag von pluto »

Vielen Dank für dein Beispiel ! mit Stream kenne ich mich aus !

Habe auch schon überlegt ob ich Stream nutzen sollte für mein vorhaben.
Aber ich glaube das eignet sich dafür nicht !
MFG
Michael Springwald

pluto
Lazarusforum e. V.
Beiträge: 7178
Registriert: So 19. Nov 2006, 12:06
OS, Lazarus, FPC: Linux Mint 19.3
CPU-Target: AMD
Wohnort: Oldenburg(Oldenburg)

Beitrag von pluto »

Code: Alles auswählen

function TmyList.AddObj(toolindex:String;var inserindex:Integer;objlist:TObjectList = nil):TPaint2Object;
var
  paint2obj:TPaint2Object;
  index:Integer;
  AClass:TControlClass;
  AControl:TControl;
begin
  fvt.Clear;
  if (oldItemindex > -1) and (AktivDocument.objlist.count > 0 ) and (oldItemindex <=AktivDocument.objlist.Count-1) then begin
    TPaint2BasesObj(AktivDocument.objlist[oldItemindex]).isfocus:=false;
  end;
 
  fBuffer.Canvas.Brush.color:=clBlue;
  paint2obj:=nil;
  AClass:=TControlClass(GetClass(toolindex));
  if AClass<>nil then begin
//    AControl:=
    Writeln('A1');
    paint2obj:=TPaint2Object(AClass).Create;
    Writeln('A2');
//    if paint2obj <> NIL then
      WriteLN(paint2obj.ClassName);
    //else
  //    writeln('<> paint2obj');
    Writeln('A3');
//    paint2obj:=TPaint2BasesObj(AClass.Create);
  end
  else
      writeln('<> NIL');

ich habe alles versucht, es geht nicht er kommt nur bis a1 d.h. der Fehler liegt bei paint2obj:=TPaint2Object(AClass).Create;
und ich weiß leider nicht warum :cry:
MFG
Michael Springwald

pluto
Lazarusforum e. V.
Beiträge: 7178
Registriert: So 19. Nov 2006, 12:06
OS, Lazarus, FPC: Linux Mint 19.3
CPU-Target: AMD
Wohnort: Oldenburg(Oldenburg)

Beitrag von pluto »

bin jetzt etwas weiter gekommen:

Code: Alles auswählen

function TmyList.AddObj(toolindex:String;var inserindex:Integer;objlist:TObjectList = nil):TPaint2Object;
var
  paint2obj:TPaint2Object;
  index:Integer;
  AClass:TClass;
  AControl:TControl;
begin
  fvt.Clear;
  if (oldItemindex > -1) and (AktivDocument.objlist.count > 0 ) and (oldItemindex <=AktivDocument.objlist.Count-1) then begin
    TPaint2BasesObj(AktivDocument.objlist[oldItemindex]).isfocus:=false;
  end;
  fBuffer.Canvas.Brush.color:=clBlue; paint2obj:=nil;
  AClass:=TControlClass(FindClass(toolindex));
 
  if AClass <> nil then paint2obj:=TPaint2Object(AClass.Create);
 
  if toolindex <> 'tImageListB' then begin
    if paint2obj <> NIL then begin
 
      if objlist = nil then begin
 
        AktivDocument.objlist.Add(paint2obj);
        index:=Documentlist[documentindex].objlist.Count-1;
        result:=TPaint2Object(AktivDocument.objlist[index]);
      end
      else begin
        if inserindex = -1 then begin
          objlist.Add(paint2obj);
          index:=objlist.Count-1;
        end
        else begin
          if inserindex < objlist.count-1 then begin
            objlist.Items[inserindex]:=paint2obj;
            index:=inserindex+1;
          end
          else begin
            objlist.Add(paint2obj);
            index:=objlist.Count-1;
          end;
        end;
        inserindex:=index;
        result:=TPaint2Object(objlist.items[index]);
      end;
 
    end
    else
      result:=nil;
  end
  else begin
    usrListBox.Items.AddObject(paint2obj.Name,tImageListB(TPaint2Object(AControl)));
    result:=TPaint2Object(usrListBox.Items.Objects[usrListBox.items.Count-1]);
  end;
 
  if Documentindex > -1 then
    AktivDocument.isMod:=true;
 
end; // AddObj


ich habe das gefühl er ruft den Constructur der entsprechende klasse nicht auf !
denn es kommt eine AV und ich weiß nicht genau wo !
ich vermute es nur !
kann das sein ? und wenn ja warum ?
z.b. TRechteck ist jetzt abgeleitet von TPaint2BaseObj was wiederum von TPaint2Objekt stammt und alle haben ihr eigene Create und Trecheck soll jetzt natürlich das Create von Tpaint2BaseObj aufrufen und soweiter !

Das hat auch prima funktniert bevor ich es umgestellt habe !
MFG
Michael Springwald

pluto
Lazarusforum e. V.
Beiträge: 7178
Registriert: So 19. Nov 2006, 12:06
OS, Lazarus, FPC: Linux Mint 19.3
CPU-Target: AMD
Wohnort: Oldenburg(Oldenburg)

Beitrag von pluto »

das Problem scheint hier zu sein:

Code: Alles auswählen

writeln(AClass.ClassName);
  if AClass <> nil then paint2obj:=TPaint2Object(AClass).Create;


und zwar ruft er hier nicht den constructor von TRechteck auf bzw. ruft gar kein constructor auf(das haben meine Nachforschungen ergeben).

Die Frage ist jetzt wie rufe ich jetzt den Constructor der Entsprechende klasse auf?
MFG
Michael Springwald

Benutzeravatar
theo
Beiträge: 10467
Registriert: Mo 11. Sep 2006, 19:01

Beitrag von theo »

pluto hat geschrieben:das Problem scheint hier zu sein:

Code: Alles auswählen

writeln(AClass.ClassName);
  if AClass <> nil then paint2obj:=TPaint2Object(AClass).Create;


und zwar ruft er hier nicht den constructor von TRechteck auf bzw. ruft gar kein constructor auf(das haben meine Nachforschungen ergeben).

Die Frage ist jetzt wie rufe ich jetzt den Constructor der Entsprechende klasse auf?


paint2obj:=AClass.Create;

Antworten