[Previous] [Contents] [Next]

Obtaining Component Category Information

When you need to obtain information about available components from the registry, the Component Categories Manager can again be invaluable. In addition to the ICatRegister interface, the Component Categories Manager also implements the ICatInformation interface, through which you can get information about the categories of already registered components.

The ICatInformation Interface

Clients that want to locate one or more components that implement or require certain categories should use the ICatInformation interface. Visual Basic, for example, uses the ICatInformation::EnumClassesOfCategories method to populate the Components dialog box, which lists the available ActiveX controls. Here is the ICatInformation interface in IDL notation:

interface ICatInformation : IUnknown
{
// Get an enumerator for the registered categories.
HRESULT EnumCategories(
    [in] LCID lcid, 
    [out] IEnumCATEGORYINFO** ppenumCategoryInfo);

// Get the description of a registered component category.
HRESULT GetCategoryDesc(
    [in] REFCATID rcatid, 
    [in] LCID lcid, 
    [out] LPWSTR* pszDesc);

// Get an enumerator for the classes that support a 
// component category.
HRESULT EnumClassesOfCategories(
    [in] ULONG cImplemented,
    [in,size_is(cImplemented)] CATID rgcatidImpl[],
    [in] ULONG cRequired,
    [in,size_is(cRequired)] CATID rgcatidReq[],
    [out] IEnumCLSID** ppenumClsid);

// Determine whether a class supports a component category.
HRESULT IsClassOfCategories(
    [in] REFCLSID rclsid, 
    [in] ULONG cImplemented,
    [in,size_is(cImplemented)] CATID rgcatidImpl[],
    [in] ULONG cRequired,
    [in,size_is(cRequired)] CATID rgcatidReq[]);

// Get an enumerator for component categories implemented by 
// a class.
HRESULT EnumImplCategoriesOfClass(
    [in] REFCLSID rclsid, 
    [out] IEnumCATID** ppenumCatid);

// Get an enumerator for component categories required by 
// a class.
HRESULT EnumReqCategoriesOfClass(
    [in] REFCLSID rclsid, 
    [out] IEnumCATID** ppenumCatid);
}

The methods of this interface do not affect the information stored in the registry. You use the ICatInformation interface to retrieve component category information from the registry in a meaningful format. The following code instantiates the Component Categories Manager and retrieves a pointer to the ICatInformation interface:

// Instantiate COM+'s implementation of component categories.
// Notice that now we request the ICatInformation interface.
ICatInformation* pCatInformation;
CoCreateInstance(CLSID_StdComponentCategoriesMgr, NULL, 
    CLSCTX_INPROC_SERVER, IID_ICatInformation, 
    (void**)&pCatInformation);

The following code shows the ICatInformation::EnumClassesOfCategories method retrieving a pointer to an enumerator that contains the CLSIDs of the coclasses that implement the Arithmetic Objects component category:

// Get an enumerator for the CLSIDs of Arithmetic Objects.
IEnumCLSID* pEnumCLSID;
pCatInformation->EnumClassesOfCategories(1, &CATID_Math, 0, 
    NULL, &pEnumCLSID);
pCatInformation->Release();

Next, the code loops through the elements in the enumerator and displays the CLSIDs of all the Arithmetic Objects coclasses, as shown in the following code. At the very least, this display should include the CLSID of the InsideCOM coclass because it was previously registered as implementing the Arithmetic Objects component category.

// Loop through the CLSIDs in the enumeration.
CLSID clsid = CLSID_NULL;
DWORD fetched = 0;
while(true)
 {
    // Get the next CLSID.
    pEnumCLSID->Next(1, &clsid, &fetched);
    if(fetched == 0)
        break;

    // Convert the CLSID to a string.
    char buffer[39];
    OLECHAR ppsz[39];
    StringFromGUID2(clsid, ppsz, 39);
    WideCharToMultiByte(CP_ACP, 0, ppsz, 39, buffer, 39, 
        NULL, NULL);

    // Print the string form of CLSID.
    cout << 
        "CLSID that supports the Arithmetic Objects component " 
        << "category is " << buffer << endl;
}
pEnumCLSID->Release();

This code is similar to that executed by Visual Basic when it presents the user with a list of controls. Visual Basic, of course, enumerates classes that implement the ActiveX control CATID {40FC6ED4-2438-11CF-A3DB-080036F12502}. All COM+ components built with Microsoft Visual J++ are automatically labeled as supporting the Java Classes component category.