If it weren’t for compatibility, programmers would live simpler, happier lives with only one annoying thorn in their sides—customers. In the case of the VBCore component, I’d have a lot less trouble if I simply made VBCore a requirement for all my samples. Instead of giving you the choice between UTILITY.BAS and the same procedures in VBCore, I would just make you use VBCore.
Perhaps that’s not such a bad idea, and probably I would have done it had I understood how much trouble it would be to maintain two different versions of each procedure module. But I started to give you a choice, and here it is—complete with a wizard that helps with the tedious dirty work. Figure 5-1 shows the Global Wizard in action.
Figure 5-1. The Global Wizard.
The Global Wizard handles the following tasks:
Let’s look at how I might use the wizard to convert the LotAbout program (the version that uses standard modules and private classes) to AllAbout (the version that uses VBCore). I’m going to use the global object technique for most of the modules in VBCore, but I’m going to use delegation for ERRORS.BAS (for reasons explained later) and for WINANY.BAS (because it uses AddressOf).
I start by running all the private classes and standard modules through the Global Wizard. The result is a matching global class for each module. But any of those global classes that call other global classes is going to fail because it doesn’t qualify inter-module calls. Visual Basic will give me compile-time errors for those problems, and I’ll be able to qualify them appropriately using the global objects created by the wizard in OBJECTS.BAS.
I’ll probably run into a few other problems due to the differences between classes and standard modules described in the next few sections. Some of these differences must be handled with conditional compilation. I define the compile-time constant fComponent in the project properties for VBCore so that it will always be True in the global class version and always False in the standard module version. You should add the same constant to any component you create that uses my modules. After I add all the qualifying objects and fix other differences, my global modules will be out of sync with the standard modules. I’ll have to run the Global Wizard again to convert the modified global classes back to standard modules.
You have to repeat this cycle every time you add add new procedures or modify the parameters of existing procedures.
Visual Basic knows a lot about your compile-time environment. It knows, for example, whether you’re in a component. It knows whether you’re compiling for an executable or for the IDE. It knows whether a module is global, public, or private. Most language compilers and interpreters share this kind of information with programmers through predefined constants. Visual Basic version 4 provided Win32 and Win16 as compile-time constants, but now they’re obsolete because everything is Win32 in version 5. It would be nice to get some useful predefined constants for information the compiler knows. Of course, you can define the appropriate constants yourself, but it’s better to have standard information shared in a standard way by the system rather than having every programmer come up with a different convention.