ccrpminilogo.gif (1886 bytes)  Knowledge Base
 KB Index    FAQ Index    Controls  
  
CCRP General Development Policies
Tuesday, January 06, 2004

INDEX
CCRP FAQ Index

CCRP Versioning Policy: New ProgIDs Used for Visual Basic Version Builds
25th November 1998
The CCRP Team
Copyright © 1998-2004 Common Controls Replacement Project

   
Overview
In order to allow developer's the ability to maintain References to both VB5 and VB6 versions of the library, the CCRP has decided that VB6-builds of our controls will sport a new ProgID assigned to the VB6 library. To ease the migration into the newer release, only the ProjectName will reflect the current VB version to which the control relates, i.e with a '6' appended to the name for the VB6 builds. The ObjectName will remain the same. This means that the VB6-compiled controls will be identified as:

VB5
VB6
VB7 (future versions)
CCRPager.ccrpPager CCRPager6.ccrpPager CCRPager7.ccrpPager
CCRTimers.ccrpTimer CCRTimers6.ccrpTimer CCRTimers7.ccrpTimer

... etc.



More Information

A Visual Basic ProgID is a unique identifier for every control which is constructed through the combination of the control's project and object names (ProjectName.ObjectName).

Prior to the release of Visual Basic 6-builds of our common controls and libraries, a typical CCRP control's ProgID was in the form:

CCRPager.ccrpPager
CCRTimers.ccrpTimer ... etc.

When referencing these control in a project, it was sufficient to reference the ObjectName - ccrpPager, or ccrpTimer.

In developing a standard for providing VB6 builds of the controls that meet specifications dictated by COM, yet provide the easiest migration for our users, our investigations took us deeper than we really wanted to go.

Controls or DLL objects added explicitly to a project (via the respective components or references dialog) are referenced by the libraries CLSID (for example, {D08328A8-7350-11D2-BBDC-0055003B26DE} ). But when objects within a control or DLL are referenced in code (with the CreateObject() function, for example) and without the explicit project references set, the objects are referenced not by their CLSID, but rather by their ProgID.

In the implementation of CreateObject() (which creates a new automation object and returns a pointer to the IDispatch of that object), and two out of the three ways GetObject() can be called, the OLE Automation 'CLSIDFromProgID()' method is called (ref: Microsoft Knowledge Base article Q122288). In calling CLSIDFromProgID, the method obtains the pointer to IDispatch of an Automation object in the pdisp variable.

In the registry, it is possible to have registered two objects with the same ProgID, yet supporting different runtime properties. Such a situation is to be discouraged, as attempting to maintain the same ProgID across different VB version builds of the same control violates the rules of COM. But should such an incident occur in Visual Basic, when attempting to resolve the object against the registered data will use either the object most recently registered, or the object higher in the References order, depending on the type of reference made.

If an explicit project reference was added via the Components or References dialogs, the object references become early bound, and are resolved via the object's CLSID at compile time. This situation is most common, and the method used in all CCRP demos.

On the other hand, if no explicit dialog reference was made, and the objects were late-bound referenced in code via the CreateObject() function, the objects are resolved via their ProgID. The last version of the control or DLL that was registered will be returned.

These behaviors posed a dilemma when deciding how to provide both VB5 and VB6-versions of our controls whereby we strived to provide a means by which both versions of a control could be registered on the same development machine, and both be used independently in different projects, without conflicts.

In order to allow developer's the ability to maintain References to both VB5 and VB6 versions of the library, the CCRP has decided that VB6-builds of our controls will sport a new ProgID assigned to the VB6 library. But to ease the migration into the newer release, only the ProjectName will be altered with a '6' appended to the name; the ObjectName will remain the same. This means that the controls will become:

VB5
VB6
CCRPager.ccrpPager CCRPager6.ccrpPager
CCRTimers.ccrpTimer CCRTimers6.ccrpTimer

... etc.

Since both the VB5 and VB6 versions expose objects with the same names, when using late-bound objects (such as occurs using CreateObject()), you *must* distinguish between the version desired by specifying the full ProgID when referencing the control. This is the only way to distinguish between the two.

Therefore, should you find that you need to maintain dual-References on your system, you must fully-qualify all object references from either library in order to insure that you're obtaining the reference you desired. In other words, use code such as the following in VB6:

Dim tmr As ccrpTimers6.ccrpTimer
Set tmr = New ccrpTimers6.ccrpTimer

or:

Dim tmr As Object
Set tmr = CreateObject("ccrpTimers6.ccrpTimer")

 

Likewise, to use the VB5 objects in this same project, refer to them as such:

Dim tmr As ccrpTimers.ccrpTimer
Set tmr = New ccrpTimers.ccrpTimer

or:

Dim tmr As Object
Set tmr = CreateObject("ccrpTimers.ccrpTimer")

 

This change was deemed superior to changing the names of all exposed objects, as it didn't require any source code changes for the vast majority of users. Where the migration to the newer VB6-build is to entirely replace the VB5-build, or on systems where the VB6-build is the only timer install, objects can continue to be referenced in the standard manner, as no conflict can arise:

Dim tmr As ccrpTimer
Set tmr = New ccrpTimer

or:

Dim tmr As Object
Set tmr = CreateObject("ccrpTimer")


The CCRP Team
November 25, 1998.