AGB  ·  Datenschutz  ·  Impressum  







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

TStringList(en) in DMF serialisieren

Ein Thema von stahli · begonnen am 30. Sep 2016 · letzter Beitrag vom 2. Okt 2016
Antwort Antwort
Benutzerbild von stahli
stahli

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.343 Beiträge
 
Delphi 11 Alexandria
 
#1

TStringList(en) in DMF serialisieren

  Alt 30. Sep 2016, 16:14
Seit längerer Zeit habe ich mal wieder eine Komponente erstellt (XE3).
Die published Properties werden in der DFM gespeichert.

Jetzt habe ich einige TStringList-Properties eingeführt.
Ich kann die über den OI zum bearbeiten öffnen.

Die IDE schmiert dann aber beim Schließen des Editors oder beim Speichern des Projektes ab.

Kann man vielleicht nur TStrings in die DFM serialisieren?
Sonst wüsste ich nicht, wo das Problem liegen soll.

Ich hatte in der Nacht nicht mehr die Zeit, das testweise umzustellen.

(Wenn das die Ursache wäre, sollte Emba vielleicht mal nachbessern und den Absturz absichern. Kann natürlich auch sein, dass ich da etwas verbockt hatte. War schon spät. )
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)
  Mit Zitat antworten Zitat
Benutzerbild von Zacherl
Zacherl

Registriert seit: 3. Sep 2004
4.629 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#2

AW: TStringList(en) in DMF serialisieren

  Alt 30. Sep 2016, 16:26
Ob TStringList wirklich buggt beim Serialisieren weiß ich nicht, aber deklariere die Property doch einfach als TStrings und behalte zur Initialisierung TStringList.Create bei Falls das auch nicht funktioniert, muss der Fehler noch an anderer Stelle liegen.
Projekte:
- GitHub (Profil, zyantific)
- zYan Disassembler Engine ( Zydis Online, Zydis GitHub)
  Mit Zitat antworten Zitat
Benutzerbild von stahli
stahli

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.343 Beiträge
 
Delphi 11 Alexandria
 
#3

AW: TStringList(en) in DMF serialisieren

  Alt 30. Sep 2016, 22:34
Also an TStringList liegt es nicht.

Es gibt aber alle möglichen Abbrüche.
Ich habe jetzt mal die IDE debuggt.

Jetzt erhalte ich aktuell die Fehlermeldung: Element '' hat kein übergeordnetes Fenster.
Ich habe aber gar kein sichtbares Control im Formular und auch keines dynamisch erzeugt.

Ich werde mal noch eine Testkomponente erstellen (obwohl ich die originale bis auf die primitiven Properties schon komplett entfrachtet habe) und die ggf. auch mal hier anhängen.

Zuvor werde ich mal noch ein Delphi-Repair versuchen und eine neue Formularanwendung versuchen. Vielleicht ist ja mit dem Projekt etwas faul...
Irgendwie scheint das am Delphi zu liegen.

Oder kann jemand vielleicht mit dem CallStack etwas anfangen?

Zitat:
:759ea732 KERNELBASE.RaiseException + 0x62
:51a8733d ; c:\program files (x86)\embarcadero\rad studio\10.0\bin\exceptiondiag170.bpl
vcl.Vcl.Controls.TWinControl.CreateWnd
vcl.Vcl.StdCtrls.TCustomEdit.CreateWnd
vcl.Vcl.ComCtrls.TCustomRichEdit.CreateWnd
vcl.Vcl.Controls.TWinControl.CreateHandle
vcl.Vcl.Controls.TWinControl.HandleNeeded
vcl.Vcl.Controls.TWinControl.GetHandle
vcl.Vcl.ComCtrls.TRichEditStrings.GetCount
:504264a0 TWinControl.CreateHandle + $1C
rtl.System.Classes.TStrings.DefineProperties($A25B A70)
rtl.System.Classes.TWriter.WriteProperties($1CA6F6 90)
rtl.System.Classes.WriteObjectProp
rtl.System.Classes.TWriter.WriteProperty($A25B890, $5471D32)
rtl.System.Classes.TWriter.WriteProperties($A25B89 0)
rtl.System.Classes.TWriter.WriteData($A25B890)
rtl.System.Classes.TComponent.ValidateRename(nil,' ',???)
vcl.Vcl.Forms.TCustomForm.GetChildren((System.Clas ses.TWriter.WriteComponent,$A25BA70),???)
rtl.System.Classes.TWriter.WriteData($5E3F1A0)
rtl.System.Classes.TComponent.ValidateRename(nil,' ',???)
rtl.System.Classes.TWriter.WriteDescendent($29F508 ,???)
:21111f78 WriteStream + $D0
:21112045 TComponentRoot.WriteRootStream + $3D
:2110f241 TComponentRoot.GetRootStream + $85
:211143eb TComponentRoot.Save + $1F
:21cee08e delphicoreide170.@Delphimodule@TPascalCodeMgrModHa ndler@SaveFile$qqrv + 0x36
:206bd493 coreide170.@Sourcemodule@TCodeISourceModule@SaveFi le$qqrv + 0x67
:206baaff coreide170.@Sourcemodule@TSourceModule@SaveFile$qq rv + 0x73
:2084581e ; C:\Program Files (x86)\Embarcadero\RAD Studio\10.0\bin\coreide170.bpl
rtl.System.Rtti.RawInvoke(???,???)
:500e4990 RawInvoke + $44
rtl.System.Rtti.Invoke($208454F0,((($206B8A2C, Pointer($502A2860) as IValueData, 24, 42264, 417703192, $18E5A518, TClass($18E5A518), 24, -23272, 417703192, 5,93618146723173e-24, 2,0637279732543e-315, 0,00000000152261e-4933, 417703192, 41770,3192, 417703192, 417703192, ($18E5A518, nil), $18E5A518)), (($50051004, Pointer($502A2860) as IValueData, 0, 0, 0, nil, nil, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, (nil, nil), nil)), (($50051004, Pointer($502A2860) as IValueData, 1, 1, 1, $1, TClass($1), 1, 1, 1, 1,40129846432482e-45, 4,94065645841247e-324, 1e-4932, 1, 0,0001, 1, 1, ($1, nil), $1)), (($500510E8, Pointer($502A2860) as IValueData, 192, 8640, 481108416, $1CAD21C0, TClass($1CAD21C0), -64, 8640, 481108416, 1,14569038482569e-21, 2,37699140270699e-315, 0,00000000175374e-4933, 481108416, 48110,8416, 481108416, 481108416, ($1CAD21C0, nil), $1CAD21C0))),???,???,False)
rtl.System.Rtti.TRttiInstanceMethodEx.DispatchInvo ke((($206B8A2C, Pointer($502A2860) as IValueData, 24, 42264, 417703192, $18E5A518, TClass($18E5A518), 24, -23272, 417703192, 5,93618146723173e-24, 2,0637279732543e-315, 0,00000000152261e-4933, 417703192, 41770,3192, 417703192, 417703192, ($18E5A518, nil), $18E5A518)),(...))
rtl.System.Rtti.TRttiMethod.Invoke((($206B8A2C, Pointer($502A2860) as IValueData, 24, 42264, 417703192, $18E5A518, TClass($18E5A518), 24, -23272, 417703192, 5,93618146723173e-24, 2,0637279732543e-315, 0,00000000152261e-4933, 417703192, 41770,3192, 417703192, 417703192, ($18E5A518, nil), $18E5A518)),???)
:004bc0d1 ; C:\Program Files (x86)\Embarcadero\RAD Studio\10.0\bin\bds.exe
:2084549f coreide170.@Docmodul@TDocModule@Save$qqroo + 0xef
:206bbc5e ; C:\Program Files (x86)\Embarcadero\RAD Studio\10.0\bin\coreide170.bpl
:2084a3d2 ; C:\Program Files (x86)\Embarcadero\RAD Studio\10.0\bin\coreide170.bpl
:0041f762 ; C:\Program Files (x86)\Embarcadero\RAD Studio\10.0\bin\bds.exe
vcl.Vcl.Controls.TControl.Perform(???,???,655368)
vcl.Vcl.Controls.TWinControl.IsControlMouseMsg(??? )
vcl.Vcl.Controls.TWinControl.WndProc((514, 0, 655469, 0, 0, 0, (), 109, 10, (), 0, 0, ()))
vcl.Vcl.ComCtrls.TToolBar.WndProc((514, 0, 655469, 0, 0, 0, (), 109, 10, (), 0, 0, ()))
vcl.Vcl.Controls.TWinControl.MainWndProc(???)
rtl.System.Classes.StdWndProc(1771896,514,0,655469 )
:741dd273 user32.SetManipulationInputTarget + 0x53
:741be84a ; C:\WINDOWS\SysWoW64\user32.dll
:741be1a4 ; C:\WINDOWS\SysWoW64\user32.dll
:741bdf60 user32.DispatchMessageW + 0x10
vcl.Vcl.Forms.TApplication.ProcessMessage(???)

// und ein anderer

:759ea732 KERNELBASE.RaiseException + 0x62
:51a8733d ; c:\program files (x86)\embarcadero\rad studio\10.0\bin\exceptiondiag170.bpl
rtl.System.Classes.TPersistent.AssignError(???)
:50140fd2 ; C:\Program Files (x86)\Embarcadero\RAD Studio\10.0\bin\rtl170.bpl
:50140f05 TPersistent.Assign + $D
:2113db45 TStringsEditDlg.SetLines + $19
:20904f05 ; C:\Program Files (x86)\Embarcadero\RAD Studio\10.0\bin\coreide170.bpl
:2127284b vclide170.@Ideinsplistbox@TInspListBox@DoEditDblCl ick$qqrp14System@TObjecto + 0x1b
:50427416 TWinControl.WndProc + $5CA
:21271fac vclide170.@Ideinsplistbox@TPropInspEdit@WndProc$qq rr24Winapi@Messages@TMessage + 0x3c
:5015be3a StdWndProc + $1A
:741dd273 user32.SetManipulationInputTarget + 0x53
:741be84a ; C:\WINDOWS\SysWoW64\user32.dll
:741be1a4 ; C:\WINDOWS\SysWoW64\user32.dll
:741bdf60 user32.DispatchMessageW + 0x10
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)
  Mit Zitat antworten Zitat
Benutzerbild von stahli
stahli

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.343 Beiträge
 
Delphi 11 Alexandria
 
#4

AW: TStringList(en) in DMF serialisieren

  Alt 1. Okt 2016, 01:30


Also ich habe mal ein Delphi-Repair versucht. Das blieb hängen, da irgendwelche Dateien nicht wiederhergestellt und auch nicht aus dem Netz geladen werden konnte. Nach Abbruch war Delphi nicht mehr vorhanden.
Also habe ich ein Systembackup eingespielt.

Das Problem besteht hier auch.
Kann mal jemand die Komponente testen? Anbei ein XE3-Projekt.

Folgendes wäre auszuführen:
- Projektgruppe laden
- Install des Comp-Packages
- im Formularprojekt die Komponente in das Formular einsetzen
- Property SL_A öffnen und Text definieren
- Editor schließen
- Projekt speichern -> klappt das???

Ich mache doch da nichts falsch - oder?
Spinnt mein Delphi?
Ist das ein Bug?
Angehängte Dateien
Dateityp: zip ComponentTest.zip (11,8 KB, 3x aufgerufen)
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)
  Mit Zitat antworten Zitat
einbeliebigername

Registriert seit: 24. Aug 2004
140 Beiträge
 
Delphi XE8 Professional
 
#5

AW: TStringList(en) in DMF serialisieren

  Alt 1. Okt 2016, 09:03
Hallo,

so gehts
Delphi-Quellcode:
unit TestComp;

interface

uses
  System.Classes;

type

  TTestComp = class(TComponent)
  private
    fX1: String;
    fX2: Word;
    fX3: String;
    fSL_A: TStringList;
    fSL_B: TStringList;
    fSL_C: TStringList;
    fSL_D: TStringList;
    procedure SetSL_A(const Value: TStringList);
    procedure SetSL_B(const Value: TStringList);
    procedure SetSL_C(const Value: TStringList);
    procedure SetSL_D(const Value: TStringList);
  protected
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  published
    property X1: String read fX1 write fX1;
    property X2: Word read fX2 write fX2;
    property X3: String read fX3 write fX3;
    property SL_A: TStringList read fSL_A write SetSL_A;
    property SL_B: TStringList read fSL_B write SetSL_B;
    property SL_C: TStringList read fSL_C write SetSL_C;
    property SL_D: TStringList read fSL_D write SetSL_D;
  end;

procedure Register;

implementation

uses
  System.SysUtils;

procedure Register;
begin
  RegisterComponents('TestComp', [TTestComp]);
end;

{ TTestComp }

constructor TTestComp.Create(AOwner: TComponent);
begin
  inherited;
  fSL_A := TStringList.Create;
  fSL_B := TStringList.Create;
  fSL_C := TStringList.Create;
  fSL_D := TStringList.Create;
end;

destructor TTestComp.Destroy;
begin
  FreeAndNil(fSL_A);
  FreeAndNil(fSL_B);
  FreeAndNil(fSL_C);
  FreeAndNil(fSL_D);
  inherited;
end;

procedure TTestComp.SetSL_A(const Value: TStringList);
begin
  fSL_A.Assign(Value);
end;

procedure TTestComp.SetSL_B(const Value: TStringList);
begin
  fSL_B.Assign(Value);
end;

procedure TTestComp.SetSL_C(const Value: TStringList);
begin
  fSL_C.Assign(Value);
end;

procedure TTestComp.SetSL_D(const Value: TStringList);
begin
  fSL_D.Assign(Value);
end;

end.
Problem ist der Designtime-Editor. Der gibt ein neues Objekt (vermutlich TMemo.Lines) ins Property und geht davon aus das die Componente die Referenz nicht übernimmt und gibt es anschliesend frei.

einbeliebigername.
  Mit Zitat antworten Zitat
Benutzerbild von stahli
stahli

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.343 Beiträge
 
Delphi 11 Alexandria
 
#6

AW: TStringList(en) in DMF serialisieren

  Alt 1. Okt 2016, 11:52
Vielen Dank!!!

Wie hast Du das heraus gefunden?
Ist das irgendwo dokumentiert? Oder ist das eher ein Bug?
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)
  Mit Zitat antworten Zitat
einbeliebigername

Registriert seit: 24. Aug 2004
140 Beiträge
 
Delphi XE8 Professional
 
#7

AW: TStringList(en) in DMF serialisieren

  Alt 1. Okt 2016, 13:45
Hallo,

Vielen Dank!!!

Wie hast Du das heraus gefunden?
Ist das irgendwo dokumentiert? Oder ist das eher ein Bug?
Erst mal fand ich das komisch, dass das nicht geht, da ich sowas schon öfters gemach habe. Da du so ein schönes Beispiel angehangen hattest, dachte ich mir Kopf noch nicht wach aber für klickibunti reicht es. Fehler ließ sich auch schnell reproduzieren. Beim Blick auf den Sourcecode fiel mir erst mal noch nichts auf. Also musste ein funktionierendes Beispiel her. TMemo.Lines ist so ein Beispiel. Im TCustomMemo fiel mir sofort der Setter auf und da war der Kopf wach. Es ist doch quasi ein Gesetz:

Alle Properties deren Typ von TPersistent aber nicht von TComponent erbt, werden per Setter und Assign gesetzt!

Habe das auch schon mal anders gemacht und hab dann später über mich selbst geflucht. Und dann fehlte nur noch eine Begründung, wieso man das bei diesem Beispiel auch nicht anders machen darf. Da half ein Haltepunkt im Setter. Angehalten wurde nur nach dem Ok im Propertyeditor und Value zeigt tatsächlich auf ein anderes Objekt. Und meine Vermutung, dass dort als Objekt eine TMemo.Lines übergeben wird, kommt daher das es nur zwei sinnvolle Wege gibt wie man mit Rtti so ein Proberty setzen kann.

1. Mit Rtti holt man sich die Objektreferenz aus dem Property, Castet diese nach TPersistent und ruf Assign auf. Dann würde aber der Setter nicht getriggert.
2. Man baut ein Objekt welches von TStrings erbt und schmeißt per Rtti die Referenz in den Setter. Und das wird im XE5 und XE8 (und vermutlich auch im XE10.2) so gemacht. TMemo war auch fast richtig. Der Typ von Value beim Ok im Propertyeditor ist tatsächlich TRichEditStrings.

Also aufgepasst bei published Properties mit Typen welche von TStrings erben.


einbeliebigername.
  Mit Zitat antworten Zitat
Benutzerbild von stahli
stahli

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.343 Beiträge
 
Delphi 11 Alexandria
 
#8

AW: TStringList(en) in DMF serialisieren

  Alt 1. Okt 2016, 14:30
Ok vielen Dank!
Dann muss man sich das halt merken oder beim nächsten Mal diesen Thread finden.
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#9

AW: TStringList(en) in DMF serialisieren

  Alt 2. Okt 2016, 00:48
Der DFM-Reader/Writer hat halt nur die Strings von "TStrings" serialisiert.
Strings.Objects wird ebenfalls nicht automatisch serialisiert ... wie auch.

Und da der TStrings-PropertyEditor "nur" eine TStringList für die Bearbeitung verwendet, kann und darf er seine Editor-Instanz auch garnicht rein geben.

PS: Ein TMemo hat ein TMemoStrings im Lines, da funktioniert dann garnichts mehr, wenn TMemo diese durch eine TStringList austauschen würde.
$2B or not $2B
  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 23:45 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