Niet-published properties van een component kun je in Delphi streamen door DefineProperties te overriden. Dat lukt allemaal prima voor eenvoudige properties zoals strings en integers. Maar nu wil ik een (protected) property streamen die een TComponent descendant is. Wat een gekloot
.
De property heet XMLDocument en is een TXMLDocument.
Het stomme is dat als ik in WriteXMLDocument een WriteBoolean() toevoeg, het schrijven wel lukt en er geen foutmelding volgt. Het probleem verplaatst zich dan echter naar het inlezen: ReadXMLDocument heeft er absoluut geen zin in.
Bovendien heb ik tijdens veel klooien gezien dat WriteComponent() de eigenschappen van XMLDocument wegschrijft alsof ze eigenschappen waren van TMijnComponent (en dat moet natuurlijk niet). De .dfm file van een TForm met daarop een TMijnComponent ziet er dan zo uit:
Er staat trouwens een voorbeeld in de helpfiles van Delphi 7 waarin een component wordt weggestreamd, maar zelfs dat voorbeeld werkt bij mij niet naar behoren
(zelfde klachten als hierboven aangegeven). Nog even voor de duidelijkheid, het probleem zit in ReadXMLDocument en WriteXMLDocument, niet in DefineProperties.
Ik sta op het punt het op te geven. Heeft iemand een geniale oplossing?
De property heet XMLDocument en is een TXMLDocument.
C++:
Nu loopt het al mis bij het wegschrijven in WriteXMLDocument - er volgt een 'Out of Memory' foutmelding. Aan het teruglezen kom ik niet eens toe.1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
| procedure TMijnComponent.DefineProperties(Filer: TFiler); function XMLDocumentStored: Boolean; begin if Assigned(Filer.Ancestor) then Result := XMLDocument <> TMijnComponent(Filer.Ancestor).XMLDocument else Result := Assigned(XMLDocument); end; begin inherited DefineProperties(Filer); Filer.DefineProperty('XMLDoc', ReadXMLDocument, WriteXMLDocument, XMLDocumentStored); end; procedure TMijnComponent.ReadXMLDocument(Reader: TReader); begin // Reader.ReadBoolean; XMLDocument := TXMLDocument(Reader.ReadComponent(nil)); end; procedure TMijnComponent.WriteXMLDocument(Writer: TWriter); begin // Writer.WriteBoolean(True); Writer.WriteComponent(XMLDocument); end; |
Het stomme is dat als ik in WriteXMLDocument een WriteBoolean() toevoeg, het schrijven wel lukt en er geen foutmelding volgt. Het probleem verplaatst zich dan echter naar het inlezen: ReadXMLDocument heeft er absoluut geen zin in.
Bovendien heb ik tijdens veel klooien gezien dat WriteComponent() de eigenschappen van XMLDocument wegschrijft alsof ze eigenschappen waren van TMijnComponent (en dat moet natuurlijk niet). De .dfm file van een TForm met daarop een TMijnComponent ziet er dan zo uit:
C++:
De property DOMVendorDesc (van TXMLDocument) wordt door WriteComponent dus weggeschreven alsof het een property van TMijnDocument was met daarboven de waarde van XMLDoc. Natuurlijk gaat het dan bij het inlezen helemaal mis: er volgt een stream error.1
2
3
4
5
6
7
8
9
10
11
12
| object Form1: TForm1 Left = 431 Top = 280 ... object MijnDocument1: TMijnDocument AutoSave = True Left = 88 Top = 184 XMLDoc = True DOMVendorDesc = 'MSXML' end end |
Er staat trouwens een voorbeeld in de helpfiles van Delphi 7 waarin een component wordt weggestreamd, maar zelfs dat voorbeeld werkt bij mij niet naar behoren
Ik sta op het punt het op te geven. Heeft iemand een geniale oplossing?
[ Voor 71% gewijzigd door Tomatoman op 03-11-2003 02:13 . Reden: Code maar even opgemaakt als 'C++' zodat de leestekens weer leesbaar zijn. ]
Een goede grap mag vrienden kosten.