Geoff Chappell - Software Analyst
In addition to numerous creatable COM classes that SHDOCVW supports explcitly, each with its own CLSID, SHDOCVW also has a general type of class that is here called an instance class. An instance class acts as a sort of CLSID shortcut. The instance class is registered under one CLSID, but when a client creates an instance, what it actually gets is an instance of some other class, here called a host class. The host class may be any class that implements either an IPropertyBag or IPersistStream interface. The value of instance classes as a feature depends largely on the existence of host classes that usefully let their instances be configured from data loaded through these interfaces.
The details of the redirection are taken from the instance class’s registry key. In addition to the usual registry subkeys and values for a creatable COM class, there must be a subkey named Instance. This, in turn, must have a value named CLSID which points to the host class:
Key: | HKEY_CLASSES_ROOT\CLSID\{InstanceClassClsid}\Instance |
Value: | CLSID |
The data may be any type but is treated as a string (with an implied expansion of REG_EXPAND_SZ data). Specifically, the data is interpreted as the string representation, between curly braces, of the host class’s CLSID. When a client creates an instance of the class whose CLSID is InstanceClassClsid, it gets an instance of the host class, and this instance is initialised with data loaded from either of two expected subkeys.
If the host class implements an IPropertyBag interface, it gets initialised with properties loaded from the InitPropertyBag subkey:
Key: | HKEY_CLASSES_ROOT\CLSID\{InstanceClassClsid}\Instance\InitPropertyBag |
Value: | PropertyName |
Data: | PropertyValue |
Each value in this subkey names a property. Each value’s data, of whatever type, is the property’s value. The meaningfulness of these named properties is entirely a matter for the host class.
If properties cannot be loaded via the IPropertyBag interface but the host class has an IPersistStream interface, then initialisation is instead sought from the default value of the InitStream subkey:
Key: | HKEY_CLASSES_ROOT\CLSID\{InstanceClassClsid}\Instance\InitStream |
Value: | default |
Data: | InitialisationData |
The default value provides data, presumably meant to be stored as the REG_BINARY type, from which to initialise the host class. Again, the meaningfulness of this initialisation data is entirely a matter for the host class.
Though they may seem obscure, instance classes are used in the vast majority of real-world Windows sessions.
If nothing else, almost every user of Windows XP through Windows Vista starts their Windows experience with two instance classes in plain sight. When the new style of Start Menu is prepared for a new user, it ordinarily begins with pinned shortcuts to the default programs for the Internet and for E-mail. These shortcuts are hard-coded in SHELL32 as
respectively. The two CLSIDs in these shortcuts are set up in the registry as representing instance classes. Both have the same host class, namely ClientExtractIcon, which is implemented in SHELL32. But the InitPropertyBag subkey for each names different properties. These point SHELL32 to the default StartMenuInternet and Mail clients, respectively. Note the irony: even to have the pinned Start Menu shortcut for the Internet resolve to a browser that is not Internet Explorer, you must execute code from the main executable of Internet Explorer.
The many new-look folders that Windows Vista introduced to the Control Panel are set up as instance classes with LayoutFolder as the host class. It expects two properties, which tell it where to find an XML template for the layout.
The Fonts and Administrative Tools folders have long been set up as instance classes with FolderShortcut as the host class. (At least this class is documented.) In Windows Vista, folders such as Network, Printers and Public are instance classes with ShellFSFolder as the host class.
Instance classes are supported by SHDOCVW.DLL version 5.0 and higher and IEFRAME.DLL version 7.0 and higher.
Although there is no formal documentation from Microsoft, there is a Windows User Interface Technical Article called Creating Shell Extensions with Shell Instance Objects. It has perhaps not been updated since its creation in 2000. It talks specifically of “two shell objects that support being the host object of a shell instance object”, but there are many others, as noted above. Any creatable COM class, no matter who implements it, is suitable provided that it has either an IPropertyBag or IPersistStream interface.