![]() |
Platforms, Frameworks & Libraries »
COM / COM+ »
General
Intermediate
License: The Code Project Open License (CPOL)
Component Category Manager wrapper classesBy Len HolgateCOM objects can be categorised using the Component Category Manager. The code here makes it easier to use these categories in your code. |
VC6, MFC, COM, Dev
|
|
Advanced Search |
|
|
|
||||||||||||||||
There are two interfaces to the Component Category Manager: the registration interface and the information interface. The registration interface is used by COM objects during their registration, or by setup programs to register an object as belonging to, or requiring a particular category. The information interface is then used by the application needing to use a category of objects. I wrote two classes to wrap these interfaces up.
CComCatRegister wraps an ICatRegister interface and provides a
thin wrapper around the standard functionality. The advantages of using the wrapper class
are that for the simplest registration requirements you can just instantiate it and call
a single function to register your object...
CComCatRegister catMgr; catMgr.RegisterClassImplCategories(myGUID, myCATID);
If you also need to register the category, the above becomes...
CComCatRegister catMgr; catMgr.RegisterCategory(myCATID, _T("This is a category")); catMgr.RegisterClassImplCategories(myGUID, myCATID);
You can also register the class as belonging to multiple categories, or register categories that the class requires, rather than implements.
That's about all there is to using the registration category manager. Compare this to
the boiler-plate code required to initialise COM, get an ICatRegister
interface, manage its lifetime, provide the locale ID for the category descriptions,
etc, etc... It's easier!
ICatInformation.
This is used by applications that want to discover which objects belong to which
categories, which categories an object requires, which categories it implements, etc.
As with CComCatRegister, CComCatInformation wraps the standard
COM interface in a thin wrapper. This class adds more value that CComCatRegister
as the underlying interface is more complex. Using the IEnumXXXX iterator
wrappers that are explained
here it neatly
wraps all of the IEnum interfaces available from ICatInformation
and makes them easier to use.
If you wanted to display a list of objects implementing a particular category then all you need do is something like this...
CComCatInformation catMgr; CIterateGUID start = catMgr.IterateClassesOfCategory(myCATID); CIterateGUID end = CIterateGUID::End(); for (CIterateGUID &it = begin; it != end; ++it) { LPOLESTR lpGUIDString; if (S_OK == StringFromIID(it, &lpGUIDString)) { std::wcout << L" " << lpGUIDString << std::endl; CoTaskMemFree(lpGUIDString); } }
Compare this code to that found in the
IEnum
sample that doesn't use the Component Category Manager.
IEnumCATID that is supplied
with the standard component category manager. I have version 4.71 of ComCat.dll
on my machine and calling Clone() on an IEnumCATID interface
pointer which was obained from a call to either EnumImplCategoriesOfClass()
or EnumReqCategoriesOfClass() gives you a pointer which appears to be linked
to the original pointer you called Clone() on. Calling Release() on
either the cloned pointer or the original appears to invalidate the other... This is
certainly not the case with the other IEnum interfaces presented by the
component category manager.
The problem can be seen with the code below (there's a complete test program available for from the download page).
IEnumCATID *pIEnumCatid = 0; hr = pICatInfo->EnumImplCategoriesOfClass(guid, &pIEnumCatid); if (SUCCEEDED(hr)) { IEnumCATID *pIEnumCatidClone = 0; hr = pIEnumCatid->Clone(&pIEnumCatidClone); if (SUCCEEDED(hr)) { pIEnumCatid->Release(); pIEnumCatidClone->Release(); // Doesn't matter which order these are // the second release causes an access // violation... } }
Apparantly a new version of the component category manager is available with VB6.0 the version of ComCat.dll should be 5.0. I would be intestested to know if this bug is still present in the latest version. Version 5.0 is also supposedly part of IE4sr1 but I have that installed and still have 4.71
EnumImplCategoriesOfClass() and EnumReqCategoriesOfClass()
are probably the least used functions on the ICatInformation interface, and
for most uses you wouldn't need to call Clone() on an interface pointer obtained
from them. However, it causes problems with my wrapper class as the iterators are returned
by value and this causes the interface pointer to be Clone()d in the copy
constructor of the IEnumIterator...
If the test program fails on your machine, do not use
CComCatInformation::IterateImplCategoriesOfClass() or
CComCatInformation::IterateReqCategoriesOfClass().
See the article on Len's homepage for the latest updates.
| You must Sign In to use this message board. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
General
News
Question
Answer
Joke
Rant
Admin
|
PermaLink |
Privacy |
Terms of Use
Last Updated: 24 Feb 2000 Editor: Valerie Bradley |
Copyright 2000 by Len Holgate Everything else Copyright © CodeProject, 1999-2009 Web11 | Advertise on the Code Project |