Sign in Join
Wiki copytemporary

Streaming components/de: what changed

Revision 1 to 2. Removed lines have a minus sign; added lines have a plus sign.

OldNewLine
1-\
21Zurück zu den [[Additional information/de|Zusätzlichen Informationen]].\
3-\
4-\
2+
53== Einleitung ==
64
75Normalerweise, wenn sie die Eigenschaftswerte eines Objekts speichern wollen, müssen sie Code schreiben für das Laden und Speichern jeder Eigenschaft. Dieses Tutorial beschreibt, wie man Klassen entwickelt, die ihre Eigenschaftswerte über einen Stream laden und speichern können ohne zusätzlichen Code dafür schreiben zu müssen. Dies geht unter Verwendung der RTTI.
86
97Es gibt ein Beispiel in den Lazarus Quelltexten, welches demonstriert, wie eine TGroupBox mit einer eingebetteten TCheckBox-Komponente über einen Stream gespeichert wird und durch lesen aus einem Stream neu erzeugt werden kann.
108
119` Siehe <lazaruspath>/examples/componentstreaming/`
1210
1311In Kombination mit [[RTTI controls/de|RTTI Bedienelementen]] können sie den Umfang des Codes, der für das Verbinden der Programmdaten mit dem GUI und der Platte / dem Netzwerk benötigt wird, auf ein Minimum reduzieren.
1412
1513## TComponent / TPersistent
1614
1715Die Klasse **TPersistent** ist definiert in der Unit Classes und verwendet den Compilerschalter **{\$M+}**. Dieser Schalter veranlasst den Compiler, Laufzeit-Typinformationen (engl. Run Time Type Information, **RTTI**) zu erzeugen. Das bedeutet, die Klasse und alle ihre Nachfahren erhalten einen neuen Klassenabschnitt **published**. 'Published'-Eigenschaften sind sichtbar wie 'public', aber zusätzlich ist ihre Struktur zur Laufzeit erreichbar. Alle published-Eigenschaften können zur Laufzeit gelesen und geschrieben werden, ohne dass ihr Name bekannt sein muss, während das Programm geschrieben wird. Lazarus kann damit alle Komponenten verwenden, ohne dass für jede Komponente neuer Code geschrieben werden muss.
1816
1917**TComponent** erweitert TPersistent durch die Möglichkeit, child components zu haben. Das ist wichtig für das streaming, wo eine Komponente die **root component** auch **lookup root** genannt ist mit einer Liste (list) von Child-Komponenten.
2018
2119## TReader / TWriter
2220
2321Diese Klassen erledigen die Arbeit und schreiben/lesen ein TComponent in den/aus dem Stream. (siehe: CreateLRSReader und CreateLRSWriter). Sie benutzen einen **Driver**, um ein spezielles Format zu lesen/schreiben. Momentan gibt es einen reader (TLRSObjectReader) und einen writer (TLRSObjectWriter) für das binary object format in der unit LResources und einen writer (TXMLObjectWriter) für TDOMDocument in der unit Laz_XMLStreaming. Die LResources Unit enthält auch Funktionen, um das binäre Format in Text zu konvertieren und umgekehrt (LRSObjectBinaryToText, LRSObjectTextToBinary). Die LCL bevorzugt UTF8 für Strings, während Delphi Widestrings bevorzugt. Daher gibt es auch einige Konvertierungsfunktionen.
2422
2523## Schreiben ihrer eigenen Komponente - Teil 1
2624
2725Eine maßgeschneiderte Komponente kann so einfach sein wie:
2826
2927```delphi
3028
3129type
3230 TMyComponent = class(TComponent)
3331 private
3432 FID: integer;
3533 published
3634 property ID: integer read FID write FID;
3735 end;
3836```
3937
4038## Schreiben einer Komponente in einen Stream
4139
4240Die Unit [[doc:lcl/lresources|LResources]] hat eine Funktion dafür:
4341
4442```delphi
4543procedure WriteComponentAsBinaryToStream(AStream: TStream; AComponent: TComponent);
4644```
4745
4846Sie schreibt eine Komponente im binären Format in den Stream. Zum Beispiel:
4947
5048```delphi
5149procedure TForm1.Button1Click(Sender: TObject);
5250var
5351 AStream: TMemoryStream;
5452begin
5553 AStream:=TMemoryStream.Create;
5654 try
5755 WriteComponentAsBinaryToStream(AStream,AGroupBox);
5856 // ... Stream weiterverarbeiten oder abspeichern ...
5957 finally
6058 AStream.Free;
6159 end;
6260end;
6361```
6462
6563## Lesen einer Komponente aus einem Stream
6664
6765Die Unit LResources hat eine Funktion dafür:
6866
6967```delphi
7068procedure ReadComponentFromBinaryStream(AStream: TStream;
7169 var RootComponent: TComponent; OnFindComponentClass: TFindComponentClassEvent; TheOwner: TComponent = nil);
7270```
7371
7472- AStream ist der Stream, der eine Komponente im binären Format enthält.
7573- RootComponent ist entweder eine existierende Komponente, deren Daten überschrieben werden, oder ist null und eine neue Komponente wird erzeugt.
7674- OnFindComponentClass ist eine Funktion, die von TReader verwendet wird, um die Klasse aus den Klassennamen im Stream zu erhalten. Zum Beispiel:
7775
7876```delphi
7977procedure TCompStreamDemoForm.OnFindClass(Reader: TReader;
8078 const AClassName: string; var ComponentClass: TComponentClass);
8179begin
8280 if CompareText(AClassName,'TGroupBox')=0 then
8381 ComponentClass:=TGroupBox
8482 else if CompareText(AClassName,'TCheckBox')=0 then
8583 ComponentClass:=TCheckBox;
8684end;
8785```
8886
8987- TheOwner is the component owner, when creating a new component.
9088
9189## Streambare Eigenschaften
9290
9391Es gibt einige Einschränkungen, welche Typen TReader/TWriter streamen kann:
9492
9593- Basistypen können gestreamt werden: string, integer, char, single, double, extended, byte, word, cardinal, shortint, method pointers, etc. .
9694- TPersistent und Nachfahren können gestreamt werden
9795
9896- Records, Objekte und Klassen, die nicht von TPersistent abstammen, können nicht gestreamt werden. um sie zu streamen muss man TReader/TWriter mitteilen wie. Siehe unten #Streaming custom Data - DefineProperties.
9997
10098## Streaming custom Data - DefineProperties
10199
102100Sie können zusätzlich beliebige Daten streamen, indem Sie **DefineProperties** überschreiben(=override). So können Sie alle Daten streamen, die keine passenden Grund-Typen haben. Beispiel : um eine Variable **FMyRect: TRect** Ihrer Komponente zu überschreiben, fügen sie die folgenden drei Methoden zu ihrer Komponente hinzu:
103101
104102```delphi
105103procedure DefineProperties(Filer: TFiler); override;
106104procedure ReadMyRect(Reader: TReader);
107105procedure WriteMyRect(Writer: TWriter);
108106```
109107
110108mit dem folgenden Code:
111109
112110```delphi
113111procedure TMyComponent.DefineProperties(Filer: TFiler);
114112var
115113 MyRectMustBeSaved: Boolean;
116114begin
117115 inherited DefineProperties(Filer);
118116 MyRectMustBeSaved:=(MyRect.Left<>0)
119117 or (MyRect.Top<>0)
120118 or (MyRect.Right<>0)
121119 or (MyRect.Bottom<>0);
122120 Filer.DefineProperty('MyRect',@ReadMyRect,@WriteMyRect,MyRectMustBeSaved);
123121end;
124122
125123procedure TMyComponent.ReadMyRect(Reader: TReader);
126124begin
127125 with Reader do begin
128126 ReadListBegin;
129127 FMyRect.Left:=ReadInteger;
130128 FMyRect.Top:=ReadInteger;
131129 FMyRect.Right:=ReadInteger;
132130 FMyRect.Bottom:=ReadInteger;
133131 ReadListEnd;
134132 end;
135133end;
136134
137135procedure TMyComponent.WriteMyRect(Writer: TWriter);
138136begin
139137 with Writer do begin
140138 WriteListBegin;
141139 WriteInteger(FMyRect.Left);
142140 WriteInteger(FMyRect.Top);
143141 WriteInteger(FMyRect.Right);
144142 WriteInteger(FMyRect.Bottom);
145143 WriteListEnd;
146144 end;
147145end;
148146```
149147
150148Dies wird MyRect als Eigenschaft 'MyRect' speichern.
151149
152150Falls Sie oft TRect streamen , dann wollen sie wahrscheinlich nicht jedes Mal den ganzen Code schreiben.
153151
154152Die Unit LResources enthält ein Beispiel, wie man eine Prozedur schreibt, um eine rect Eigenschaft zu definieren:
155153
156154```delphi
157155procedure DefineRectProperty(Filer: TFiler; const Name: string; ARect, DefaultRect: PRect);
158156```
159157
160158Auf diese Art kann der obige Code kurz gehalten werden :
161159
162160```delphi
163161procedure TMyComponent.DefineProperties(Filer: TFiler);
164162begin
165163 inherited DefineProperties(Filer);
166164 DefineRectProperty(Filer,'MyRect',@FMyRect,nil);
167165end;
168166```
169167
170168## Schreiben ihrer eigenen Komponente - Teil 2
171169
172170Jetzt kann das Beispiel erweitert werden und wir können beliebige Eigenschaften verwenden mit nur ein paar Zeilen Code:
173171
174172```delphi
175173type
176174 TMyComponent = class(TComponent)
177175 private
178176 FID: integer;
179177 FRect1: TRect;
180178 FRect2: TRect;
181179 protected
182180 procedure DefineProperties(Filer: TFiler); override;
183181 public
184182 property Rect1: TRect read FRect1 write FRect1;
185183 property Rect2: TRect read FRect2 write FRect2;
186184 published
187185 property ID: integer read FID write FID;
188186 end;
189187
190188procedure TMyComponent.DefineProperties(Filer: TFiler);
191189begin
192190 inherited DefineProperties(Filer);
193191 DefineRectProperty(Filer,'Rect1',@FRect1,nil);
194192 DefineRectProperty(Filer,'Rect2',@FRect2,nil);
195193end;
196194```
197195
198196Diese Komponente kann nun gespeichert, geladen oder von den [[RTTI controls/de|RTTI Bedienelementen]] verwendet werden. Sie müssen keinen weiteren Code schreiben.
199197
200198## Writing and Reading components from/to LFM
201199
202200Beispiele finden Sie in der unit **lresources** : function ReadComponentFromTextStream und writeComponentAsTextToStream
203201
204202## Writing and Reading components from/to XML
205203
206204Streaming components ist einfach: Siehe das Beispiel in lazarus/examples/xmlstreaming/.
207205
208206## Fazit
209207
210-<abbr title="Run Time Type Information">RTTI</abbr> ist ein leistungsstarker Mechanismus, der verwendet werden kann, um einfach ganze Klassen zu streamen, und er hilft das Schreiben von langweiligem Laden/Speichern Code zu vermeiden.
208+RTTI ist ein leistungsstarker Mechanismus, der verwendet werden kann, um einfach ganze Klassen zu streamen, und er hilft das Schreiben von langweiligem Laden/Speichern Code zu vermeiden.
211209
212210## Siehe auch
213211
214212- [[RTTI controls/de|RTTI controls]]
215213
216214---
217215*From the Free Pascal wiki, page "Streaming components/de", as it stood on 2014-05-07 after a change by Socke, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*
218216Category: Components/de
219217Category: Deutsch
220218Category: Tutorials/de

Back to history