Creating Global Objects


Have you ever wondered exactly what the App object is? Have you ever wanted to create something similar to the Screen object? With Visual Basic version 4, you could create a global instance of a class but you couldn’t stop others from using the class to create additional objects at different scopes. This would defeat the purpose. You want one and only one System object because there’s only one system.


With Visual Basic, you can create a System object in a component and be sure that there is one and only one instance of it for the outside world. The technique is Byzantine, to say the least, so we’ll have to step through it slowly.


First we need a CSystem class. I have one, and many of its features will be described in Chapter 11. (Readers of the first edition are already familiar with my System object.) For now, it doesn’t matter what the System object does, just that one and only one instance of it exists for clients of VBCore. To prevent outsiders from creating unauthorized instances of CSystem, we set its Instancing property to PublicNotCreatable. That means that we (the royal We who created VBCore) are the only ones who can create instances of the class, and if we create just one, that’s the only one. Those who want to use CSystem as a private class outside VBCore are still stuck with nothing but the honor system to keep them from creating multiple System objects.


One way to make the System object available to the world is to make it a read-only property of a global module. We could define it like this in the instance data module, INSTANCE.CLS:

Private sys As New CSystem
§
Property Get System()
Set System = sys
End Property

The problem with this is that each user of VBCore gets a separate copy of the System object. If you study the code of the CSystem class, you’ll see that this probably wouldn’t cause any problems. Each System object would be separate but identical. Nevertheless, it’s more efficient and correct for the System object to be shared data. There’s only one system, so there should be only one System object. When you create your own system-wide objects, think carefully about the clients. In some cases, instance data might be more appropriate.


To make the System object shared data, simply move the data declaration to
the shared data module, SHARED.BAS. Of course, you’ll still need to make the object public through a global class. You can do this with a property procedure in SHARED.CLS that delegates to the real object in SHARED.BAS:

Property Get System() As CSystem
Set System = MShared.System
End Property

The System object and its cousin, the Video object, can be used by outside ­clients indirectly through global properties in SHARED.CLS. The objects are also used by one inside client. The CAbout class gets some of the information for its About dialog box from the System and the Video objects, but it accesses them directly through the properties in SHARED.BAS.