Custom Resource Files Using Property Bags

Anders Nissen
Copyright Oct 11, 2004

URL: http://www.vbgamer.com/tutorial.asp?ndx=39


Page 1
Introduction

Have you ever wondered where the icons, pictures, cursors etc. from your forms are stored when Visual Basic isn't open? They are stored in form's .frx-file. All the infomation is stored in binary format using a method called property bags, and you can also use this extremely simple interface to store and extract multiple sources of data.

Text, numbers, boolean values, icons, pictures, fonts - you name it, it can handle them all! It's almost too simple, just read ahead.


The Property Bag

If you've ever made a user control, you will probably know that a property bag is, because that's where it's used the most.

Basicly a property bag is a virtuel container that can store almost any type of value. All infomation in the property bag is stored in Visual Basic's Variant-format. This allows for the user, that would be you, to add data to the property bag, and not worry about what kind of data it is. Be warned though, because the Variant-format can store any kind of data, you must carefully handle how you read the value that you've stored. You don't want to accidently try and sqeeze a picture-file into a Integer-variable.

The Variant-format is also the slowest variable-type due to its non-restrictive nature, but in most cases we only need to extract or store the values a few times during the programs execution so that won't be a problem.



Storing And Extracting Data From A Property Bag

To do anything involving a property bag, you need to first create a property bag object. The following code creates a new instance of a property bag, with the name objBag.

  1. Dim objBag As New PropertyBag

Not hard, huh? The property bag is part of the Visual Basic IDE so you don't even need a reference to it.
As with all instances of object, always remember to destroy the object, once you're done with it.

  1. Set objBag = Nothing

Doing so prevents those nasty memory leaks. But we don't want to destroy our property bag object just yet - we need to use it first!

Storing data in our property bag would be done like so:

  1. objBag.WriteProperty [Name ID], [Value], [Default Value]
  2. ' Example:
  3. objBag.WriteProperty "Str", "A string"

Here we're storing the string "A string" in the property bag using the string "Str" to tag it. We use that tag when we will extract data from the property bag. Here is how to read the written value.

  1. objBag.ReadProperty [Name ID], [Default Value]
  2. ' Example:
  3. Dim Str as String
  4. Str = objBag.ReadProperty "Str", "There is no value stored in the property bag"

Notice that you would store the property bag data in incompatible varible type without getting a compile-error, but first getting an error at run-time.



Saving And Reading A Property Bag From Disk

Storing data in a property bag internally at runtime could probably be useful on some occations, but what we're interested in is saving the data while the application is closed. Just like the .frx-files store the forms non-text contents when the project isn't opened.

Saving a property bag to disk can be done as the following method demonstrates:

  1. Private Sub SaveContents(Contents As Variant, FilePath As String)
  2.   Dim FileNum As Integer
  3.     FileNum = FileSystem.FreeFile()
  4.     Open FilePath For Binary As FileNum
  5.         Put #FileNum, , Contents
  6.     Close FileNum
  7. End Sub

The method would be called in the following manner:

  1. Dim objBag As New PropertyBag
  2.     With objBag
  3.     .WriteProperty "Str", "A string"
  4.     SaveContents .Contents, App.Path & "Things.bag"
  5. End With
  6. Set objBag = Nothing


Where objBag.Contents is all the data that the property bag stores, all packed into one messy Variant-variable.

Now we're got the property bag saved to disk - great! But we still need to be able to read it again, and here's how to do that:

  1. Private Function LoadContents(FilePath As String) As Variant
  2.   Dim FileNum As Integer
  3.   Dim tempContents As Variant
  4.     FileNum = FileSystem.FreeFile()
  5.     Open FilePath For Binary As FileNum
  6.         Get #FileNum, , tempContents
  7.     Close FileNum
  8.     LoadContents = tempContents
  9. End Function

The method would be called in the following manner:

  1.     Dim objBag As New PropertyBag
  2.     With objBag
  3.         .Contents = LoadContents(App.Path & "Things.bag")
  4.         Dim Str as String
  5.         Str = objBag.ReadProperty "Str", "There is no value stored in the property bag"
  6.     End With
  7.     
  8.     Set objBag = Nothing

That's really all there is to it!

You can, as mentioned, also store pictures, fonts, etc.. This without even changing the way you assign the data to the propertybag. Normally you would use Set [Object] = [Object], but you don't have to, because it of the way it's stored, so the object-files are just handled as Variant-type data.

But to extract object-data, such as picture-files, you need to use the Set ... =-syntax. Examine the example project to see how this is done.



Conclusion

Property bags let you store all kinds of data in a very simple and painless fasion. It's very usefull for applications where "real" custom resource files would be overkill. If you want to be able to store and retrive data from inside Class-objects, then take a look at the extended property bag class, which can be found here: www.paradoxes.info/code/PropertyBagClass.html.

A very simple example project using the techniques explained in this tutorial can be found here.

Tutorial written by Anders "Sion" Nissen, 11th October 2004.
Homepage: www.IcySoft.dk