Ab Visual Basic 6 ist es möglich, PropertyBag-Objekte
selbst zu instanzieren, ihren gesamten Inhalt als Byte-Array
auszulesen, und das Byte-Array wieder in ein neu instanziertes
PropertyBag-Objekt einzulesen. Wie ich Ihnen bereits in mehreren
Artikeln gezeigt habe (siehe "Verschachtelte
Schachteln", "OLE-Drag&Drop
mit Objekten", "Clones
von der Stange" und "Bilder
zu Bytes"), sind PropertyBag-Objekte recht
nützliche und vielfältig verwendbare Gesellen. Sie haben
allerdings den Nachteil, dass sie selbst keine Persistenz
unterstützen - Sie können nur den Inhalt eines PropertyBag-Objekts
(Contents-Eigenschaft) nur als Byte-Array in ein anderes
PropertyBag-Objekt schreiben:
PropBag1.WriteProperty "Name", PropBag2.Contents
Das Wiederherstellen eines PropertyBag-Objekts kann auch nur
indirekt erfolgen:
Dim PropBag2 As PropertyBag
Set PropBag2 = New PropertyBag
PropBag2.Contents = PropBag1.ReadProperty("Name")
Wäre es nicht interessant, ein PropertyBag-Objekt direkt in ein
anderes Propertybag-Objekt schreiben, und umgekehrt direkt mit dem
Auslesen instanzieren zu können, wie beispielsweise bei einem
Picture-Objekt oder bei Klassen mit Persistenz?
Also etwa zum Schreiben:
PropBag1.WriteProperty "Name", PropBag2
und zum Auslesen:
Dim PropBag2 As PropertyBag
Set PropBag2 = PropBag1.ReadProperty("Name")
Es geht, auch wenn Sie dazu nicht das originale
PropertyBag-Objekt verwenden können, sondern - das Stichwort ist
bereits gefallen - dieses in eine Klasse mit Persistenz verpacken.
Glücklicherweise gehört das PropertyBag-Objekt zu den wenigen
Objekten aus Visual Basic, die eine Implements-taugliche
Schnittstelle haben. Probieren Sie zum Beispiel einmal, in einer
Klasse eine TextBox-Schnittstelle zu implementieren:
Implements TextBox
Erstens werden Sie daraufhin diese Schnittstelle nicht in der
Objekt-Liste des Editor-Fensters finden, und zweitens wird sich
Visual Basic darüber beschweren, dass das eine "schlechte
Schnittstelle..." wäre. Die Zeile
Implements PropertyBag
funktioniert hingegen anstandslos. Sie können die
Schnittstellen-Prozeduren anlegen und Visual Basic wird die
Schnittstelle anstandslos "für gut befinden".
Nun brauchen Sie nichts weiter zu tun, als ein in der Klasse in
einer privaten Objekt-Variablen gehaltenes PropertyBag-Objekt eins
zu eins mit den Schnittstellen-Prozeduren zu verbinden:
Implements PropertyBag
Dim pPropBag As PropertyBag
Private Property Get PropertyBag_Contents() As Variant
PropertyBag_Contents = pPropBag.Contents
End Property
Private Property Let PropertyBag_Contents _
(ByVal New_Contents As Variant)
pPropBag.Contents = New_Contents
End Property
Private Function PropertyBag_ReadProperty(ByVal Name As String, _
Optional ByVal DefaultValue As Variant) As Variant
PropertyBag_ReadProperty = pPropBag.ReadProperty(Name, _
DefaultValue)
End Function
Private Sub PropertyBag_WriteProperty(ByVal Name As String, _
ByVal Value As Variant, Optional ByVal DefaultValue As Variant)
pPropBag.WriteProperty Name, Value, DefaultValue
End Sub
Das private PropertyBag-Objekt instanzieren Sie im
Class_Initialize-Ereignis und geben es im Class_Terminate-Ereignis
wieder frei:
Private Sub Class_Initialize()
Set pPropBag = New PropertyBag
End Sub
Private Sub Class_Terminate()
Set pPropBag = Nothing
End Sub
Setzen Sie die Eigenschaft Persistable der Klasse auf "1
- Persistable", stehen die weiteren Ereignisse
Class_ReadProperties und Class_WriteProperties zur Verfügung, in
denen Sie das indirekte ein- und auslesen des Byte-Array-Inhalts des
privaten PropertyBag-Objekts vornehmen:
Private Sub Class_ReadProperties(PropBag As PropertyBag)
pPropBag.Contents = PropBag.ReadProperty("Contents")
End Sub
Private Sub Class_WriteProperties(PropBag As PropertyBag)
PropBag.WriteProperty "Contents", pPropBag.Contents
End Sub
Die Verwendung dieses PropertyBag-Objekts mit Persistenz ist
denkbar einfach. Es sind keinerlei zusätzliche Deklarationen
notwendig und auch keinerlei Objekt-Konvertierungen (siehe auch "Schnittstellen
'chamäleonieren'"). Sie instanzieren lediglich die
neue Klasse PropertyBagPersistable anstelle eines originalen
PropertyBag-Objekts, weisen diese Instanz aber einer
Objekt-Variablen zu, die Sie als originales PropertyBag-Objekt
deklariert haben.
Das kleine Beispiel-Projekt zu diesem Artikel zeigt Ihnen, wie
das konkret aussieht (hier ein Auszug aus dessen Code):
Private mBytes() As Byte
Private Sub cmdSave_Click()
Dim nPropBag As PropertyBag
Dim nPropBagPersistable As PropertyBag
Set nPropBagPersistable = New PropertyBagPersistable
nPropBagPersistable.WriteProperty "Text", txt.Text
Set nPropBag = New PropertyBag
nPropBag.WriteProperty "PropBag", nPropBagPersistable
mBytes = nPropBag.Contents
End Sub
Private Sub cmdRestore_Click()
Dim nPropBag As PropertyBag
Dim nPropBagPersistable As PropertyBag
Set nPropBag = New PropertyBag
nPropBag.Contents = mBytes
Set nPropBagPersistable = nPropBag.ReadProperty("PropBag")
txt.Text = nPropBagPersistable.ReadProperty("Text")
End Sub
Da Klassen mit Persistenz allerdings nur als öffentliche Klassen
angelegt werden können, müssen Sie diese PropertyBag-Umhüllung in
ein ActiveX-Projekt verpacken. Grundsätzlich eignet sich zwar jeder
ActiveX-Typ. Doch wenn Sie diese Klasse in einem ActiveX-DLL-Projekt
anlegen, dieses kompilieren und installieren bzw. auf Ihrem
Entwicklungsrechner registrieren, können Sie diese als Verweis in
jedes beliebige Projekt einbinden und dort das PropertyBag-Objekt
mit Persistenz anstelle des VB-Originals verwenden.
|