|Installing, Registering, COM and VB|
|What is a ProgID and How Do I Change It?|
|Information about ProgIDs, CLSIDs and a little about COM object registration|
If you are modifying an ActiveX EXE, DLL or OCX you have downloaded from this site and want to distribute it with your project, I specify two requirements:
All About ProgIDs and a Little About COM
VB implements non-private Classes and UserControls as COM objects (I suppose I should mention that UserDocuments are also done this way too, but who uses them?) To allow access to a COM object regardless of where it is located, COM implements a mechanism to identify where the executable implementing a given COM object is. This mechanism means COM is not restricted to any given path for storing an object, and with the DCOM extensions the COM object can actually be held on another computer on the network.
To do this, COM requires that every non-private object has a unique identifier. This identifier is called a GUID (Globally Unique Identifier). This is a 128bit number (thus potentially allowing for a maximum of 2128 possible COM objects, which is an undescribably large number. Read about how GUIDs are generated here). To make it easier to write a GUID, it is normally expressed as a hexadecimal number with some formatting applied. This form of a GUID is also referred to as a CLSID when the GUID is the identification number for a COM object. An example CLSID looks like this (this is the CLSID for the Microsoft Common Dialog control shipped with Service Pack 2 of VB5):
The formatting shown corresponds to the COM GUID type:
Even with this formatting, a GUID is hardly an easy thing to remember. In addition to this,
COM supports the concept of Binary Compatibility where two objects with different
GUIDs can be used interchangeably.
When you request an instance of the cFlatControl class, COM looks up the ProgID "vbalFCtl.cFlatControl" which
gives it the GUID of the object. COM can then locate the GUID and therefore the path to the object.
This is where the problem arises with two objects with the same ProgID. If you create a new
version of the Flat Control DLL, say it either has with different methods or it is compiled
in VB6 instead of VB5, you will automatically generate
a new GUID. However, if you
don't change either the project name or the class name, you will overwrite the existing ProgID
with your own version. Anyone else's code which expects to get an instance of the object
suddenly gets routed to the new version, and their code may then fail depending on what you've
done to the existing class.
For controls, however, this isn't so easy. Controls can persist a great quantity of information entered at design time in your form's FRX files. Removing the control and adding the new one throws away all of this information. You can see this particularly with the ImageList control. If you have an ImageList control with 90 icons in it, to migrate to a new version of the component means you have to somehow get all 90 icons from the previous version to the new one. Often you can make this change quite easily by adjustment of VB's Project and Form files. Say for example you were migrating the pre-release demo of the S-Grid control from a VB5 version to the VB6 version.
In the Project file you will have something like this:
You should find you can migrate from one version to another by replacing the CLSIDs in
both files (see above for how to determine the new CLSID) and changing the ProgID in
the form file from the old version to the new one you have compiled
(from vbAcceleratorGrid.vbalGrid to, say, vbAcceleratorGrid6.vbalGrid). Of course here
I am assuming the the StdFont object used to persist the font information hasn't
changed its CLSID as well. To make sure you have your CLSIDs correct, you can create a
blank project, add the new control and put some dummy design time data in. Then open
up the test project's .vbp and .frm files - you will be able to see the new CLSIDs and
ProgIDs and should be able to swap them over!
Back to top
Back to Installation
Back to Home