Extending ArcObjects  

Component Categories

This topic is relevant for the following:
Product(s): ArcGIS Desktop: All
Version(s): 9.0, 9.1, 9.2, 9.3
Language(s): VB6, VC++
Experience level(s): Intermediate to advanced



In this section:

  1. COM and the registry
  2. Methods of registering to a component category

COM and the registry

The Windows system registry is used extensively to store information about COM systems. The HKEY_CLASSES_ROOT hive of a machine's registry contains information about all the COM classes, interfaces, type libraries, applications, and so on, registered on the system.

Each component is given a unique identifier (a GUID) that the COM runtime environment, called the Service Control Manager (SCM), uses to identify the component during execution. The details of COM's use of the registry can be found in the references included in the bibliography.

ArcObjects is a COM system, and therefore the standard information about the classes, interfaces, and so on that comprise ArcObjects can be found in the registry of any machine that has ArcGIS installed.

Developing software using COM offers the ability to update and customize an application incrementally—it is COM's use of the registry that helps achieve this.

Use of component categories

COM systems also often use another area of the registry, called component categories. Conceptually, a component category is a convenient way to logically group together classes that provide a certain type of functionality. Generally, all the classes in a particular category will support an agreed set of interfaces, although sometimes the classes simply conform to a semantic description of functionality.

Any application can read the contents of a component category at run time to gather information about which classes support certain functionality, without that application needing to know precise class names in advance.

ArcObjects makes extensive use of component categories to improve the extensibility of ArcGIS. You can also use the same component categories to help you extend ArcGIS.

Component categories support the extensibility of COM by allowing the developer of the client application to create and work with classes that belong to a particular category.

The client application does not need to know in advance the exact names of the coclasses in the category, as the coclasses in the category are found at run time.

About CATIDs

All the component categories on a machine can be found by opening the appropriate registry key.

HKEY_CLASSES_ROOT\Component Categories

Each subkey identifies a category; each subkey name is a unique identifier or GUID, which is referred to as a CATID. Each CATID key contains a descriptive name for the category as a string data value. The ESRI Workspace Factory component category is shown below, viewed using the Windows Regedit utility.

A CATID is a unique identifier for a particular component category.

You can see the CATID in the left pane, and the descriptive name in the right (the 409 value indicates the U.S. English locale ID, which is the locale of all the ESRI descriptive strings).

A CATID key does not contain subkeys of classes belonging to that category, as you may have expected. Instead, component category information for a specific class is stored along with the other class information for that class, under its Class ID (CLSID) registry entry, in a subkey called Implemented Categories. Each Implemented Categories key contains one or many subkeys, which contain the CATIDs of the categories the class takes part in.

A class indicates that it takes part in a component category by including the relevant CATID in the Implemented Categories subkey of the class's registry entry.

For example, the ArcInfoWorkspaceFactory coclass registry key is shown below. You can see that the Implemented Categories subkey contains three CATID subkeys. The first CATID is the ESRI Workspace Factory category; the other CATIDs indicate that the ArcInfoWorkspaceFactory is also part of the Automation Objects and Arkansas Objects categories.

All the component categories defined by ArcGIS can also be found in a Visual C++ header file, and a Visual Basic class module, which are part of the Developer Kit installed on your machine. These files can be found in the \Include\CatIDs subfolder of your installation.

The use of ESRI component categories in ArcGIS

Component categories are used in two different ways by ArcGIS: at application startup, also and as required throughout the framework.

Using ESRI component categories in custom components

When creating custom components for ArcGIS, you will often need to register your classes to component to a component category in order to work with your class in the same way as existing ArcObjects classes.

You will need to work out which category or categories to register your class to, and how best to go about the task of adding this information to the registry.

Bear in mind that a class may often be registered to more than one component category (to perform a task at different points of execution) or to no component categories at all (if a class is only referenced directly in code, the component category is superfluous). However, registering to appropriate categories is a useful technique, providing the flexibility for your own code to find classes at run time, and therefore to be updated more easily in the future. You could also create your own component category, if appropriate, to leverage this functionality further.


Methods of registering to a component category

The process of registering a component to a category depends largely on two factors.

As well as the standard methods of registration that may be available in your development environment, there are also methods of registration independent of your environment.

ESRI provides a number of ways to register classes to a component category, which may be particularly useful to VB programmers, as the VB environment provides little support for this.

You can register classes to a component category using one of several methods. The methods you can use may depend on your development environment.

Adding commands using the Customize dialog box

Using the Customize dialog box, you can register Commands and command bars to the appropriate category.

You can add classes that implement ICommand to a commands component categories using the Add From File button in the Customize dialog box.

Start by clicking the Tools menu and choosing Customize. Then click Add from file, and browse to your DLL. All classes in that DLL which implement ICommand are then added to the list of commands shown in the dialog box—the Categories list refers to the ICommand::Category property of the command classes.

These classes will also be registered to the appropriate commands component category; if you are using ArcMap, the classes will be registered to ESRI Mx Commands; for ArcCatalog the category will be ESRI Gx Commands; and for ArcScene the category will be ESRI Sx Commands.

Below you can see the Create Layer Files sample has been registered in ArcMap using the Customize dialog box. The left- and right-hand panes together list all components registered to ESRI Mx Commands.

This dialog box is most useful for registering sample commands and when testing.

You cannot remove a component from a category by using the Customize dialog box.

This functionality is ideal for use in an ad hoc testing environment for registering new commands and tools. It is also perfect for registering ESRI sample commands and tools.

However, this dialog box is limited in use, since it can only be used to register commands to the application commands component categories. Also, it is not possible to remove a class from a component category using this dialog box.

To remove a component registered in this way, you must first make sure any references to the class are removed from your documents by removing from toolbars, menus, and so on. The component category registry entry should then be removed manually, for example, by using one of the methods described in the following sections. Note that if you unregister your entire DLL using COMUnregisterServer, this process will also remove the component category registration for the class.

Using Component Category Manager

Distributed with ArcGIS is a utility called the Component Category Manager, that allows you to add and remove classes from any component category.

The Component Category Manager is a more flexible way of adding classes to, and removing classes from, component categories.

When you expand a component category in the tree view, Component Category Manager searches the registry and displays a list of all classes that are registered to that category. Use the Find button to find a category name that contains the search string, and reduce the amount of time you spend scrolling through the tree view.

Select a category, and then click the Add Object button, then in the Add Objects dialog box, browse to your DLL, and click Open. A checklist of all the classes in the server is then displayed, allowing you to register only the classes you want to the category.

The Remove Object button will remove the selected class from the category—it will not remove any other Implemented Categories from the class or unregister the class on the system.

This utility is ideal for registering noncommand items in an ad hoc testing environment, but it is unsuitable for deployment situations, as user interface interaction is always required.

Using the VB Compile and Register add-in

The VB Compile and Register add-in can be used to register any VB class to any component category at compile time; it can also be used to create registry scripts for later use.

The Visual Basic Compile and Register add-in allows you to register components to categories at compile time. It also creates registry scripts, which can be used to register components on other machines.

All the classes in your project are listed in the left-hand pane—select a class, and then select the categories to register the class to.

Commonly used categories are shown in the right-hand pane by default, but you can add to this list by choosing Components, then Select Component Categories.

Clicking the Compile button will save all the files in the project and also create a registry script containing the required registry entries. The project binary files are then compiled, and the component category information is added to the registry.

To unregister a class, select the class in the left-hand pane, uncheck the appropriate component category, and compile the project again.

If you are developing in VB, you may find the Compile and Register add-in an efficient way of registering your components at compile time. This method is ideal for a testing environment, where a component may need to be registered repeatedly. It also automatically generates a registry scripts, which can be used later when you want to deploy your component.

VB Debug Helper

When you run a VB application in Debug mode (by clicking the Run button), the VB Debug Process removes all the registry entries for the compiled component and replaces them with information pointing to the VB debug process itself.

This can lead to unexpected behavior when you are debugging a component which is registered to a component category, as the debugger does not replace component category information, and therefore client applications find your components are no longer registered to the component category.

The Compile and Register add-in provides the option to create a debug helper executable for your project. This executable registers the components in your project to the chosen component categories after the debug session has started, thus the client (for example, ArcMap) will find your components successfully. Your debug session will be unaffected.

To use the VB debug helper, open the Compile and Register dialog box and ensure the Support Visual Basic Debugger option is checked. Also, check the appropriate ArcGIS application.

Once you have compiled your project with the add-in, open the Project Properties dialog box in VB, select the Debugging tab, and set the Start Program to the EXE generated by the add-in—this will be called EsriVBDebugHelper.exe and will be located in the project folder.

Using registry scripts

Components can also be registered by entering information directly to the registry. This is most commonly done by running a registry script. A registry script is simply a plain text file with the extension .reg. Running the script (for example, by double-clicking the file in Windows Explorer or by running from a batch file) will enter the contained information to the registry.

The first line of the file specifies the intended version of the registry editor. After a blank line, the required registry entries are listed, each separated by a blank line. A registry entry is specified by enclosing the required registry path in square brackets. Comments are preceded by a semicolon.

For example, the Create Layer Files sample you saw previously could be registered to the ESRI Mx Commands category by executing the following script.

; CoClass: CreateLayerfiles.clsCreateLayerfile
; CLSID: {AEFC673B-17D7-11D4-B77E-0080C71C4226}
; Component Category: ESRI Mx Commands
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{AEFC673B-17D7-11D4-B77E-0080C71C4226}\Implemented Categories\{B56A7C42-83D4-11D2-A2E9-080009B6F22B}]

(Note that the last two lines of this registry script should be one continuous line in the .reg file).

Registry scripts can be used to add information to the registry.

Using registry scripts

To see examples of registry scripts, you can use the VB Compile and Register add-in, or you can export existing registry entries to a .reg file using the Regedit utility.

Registry scripts are useful if you are developing in VB and need to distribute your application, as the script can then be run as part of an installation program on the target machines. If you are developing in VC++, you would generally place registration code into the COMRegisterServer function (see Registering components built with VC++ and ATL below).

Registry scripts may be useful when deploying a component to other machines.

Programming with the ComponentCategoryManager coclass

The ComponentCategoryManager class is provided by ESRI to help you register your components to component categories programmatically.

ESRI provides this class as an alternative to the COM standard component category manager class, which has interfaces that aren't VB friendly. In addition, the ESRI class optimizes the process of searching the registry for component category information by caching category information.

Using IComponentCategoryManager, you can create a new component category, register classes to any component category, and also remove classes from a category. The following VB code adds all the classes that implement ICommand in the specified MyCommands.dll to the ESRI Mx Commands category.

[Visual Basic 6]
Dim pInterfaceUID As New UID, pCatUID As New UID
pInterfaceUID.Value = "{36B06538-4437-11D1-B970-080009EE4E51}" ` ICommand
pCatUID.Value = "{B56A7C42-83D4-11D2-A2E9-080009B6F22B}" ` ESRI Mx Commands
 
Dim pCategoryMan As IComponentCategoryManager
Set pCategoryMan = New ComponentCategoryManager
pCategoryMan.Setup sMyPath & "\MyCommands.dll", pInterfaceUID, pCatUID, True

ComponentCategoryManager may be useful to both VB and VC++ developers, for runtime component category editing, or can be used to create a program to run as part of an install.

Registering components built with VC++ and ATL

If you have used the ATL COM Object Wizard to create your component, your project will include a registry script file (.rgs) for each class. This registry script is executed when the server is registered or unregistered on a machine.

You can add code to register your class to a component category here, although it is generally easier and more appropriate to register to a component category by using the ATL category map macros.

Visual C++ offers a number of ways to register components to a component category. You can use the ATL category map macros, registry scripts, or alternatively, the ComponentCategoryManager coclass, adding code to the DLLRegisterServer method.

Use these macros in the header file of your component. Whenever your server is registered (in the COMRegisterServer and COMUnregisterServer functions), the components will be registered to the specified component categories. As an example, this code registers a zoom-in class to the ESRI Mx Commands category.

[Visual C++]
BEGIN_CATEGORY_MAP(__uuidof(CATID_MxCommands))
  IMPLEMENTED_CATEGORY(__uuidof(CATID_MxCommands))
END_CATEGORY_MAP()

You can obtain the CATIDs of the standard ESRI component categories from the ArcCATIDs.h header file provided as part of the ArcGIS installation. Include this header file in your project:

#include "C:\Program Files\ArcGIS\include\CatIDs\ArcCATIDs.h"

Alternatively, you can add to the self-registration code of the server to register a class to a category. This can be done either using the Microsoft Component Category Manager coclass or the ESRI ComponentCategoryManager coclass.


Back to top