Introduction
Visual Basic has a very nice object called
Collection
, which is part of VBA type library. In VC++ we do not
have a similar object, which is a shame (in my opinion).
I searched MSDN and it turned out there is a sample called
ATLCollections. This project has 2 collections. First is a collection of
BSTR
s and second one is a VARIANT
collection which is
using CComBSTRa
as keys. I wanted to use only VARIANT
s
to be comparable with scripting languages so neither one was an option.
Next step was to search the Web. I found one on
www.widgetware.com written by Chris Brooks (clbrooks@micron.com) and another one
by Chris Sells (www.sellsbrothers.com). Both were template-based and I did not
want to use the templates. So I decided to write a collection object.
What is a collection?
According to MSDN a Collection object is an ordered set of items
that can be referred to as a unit. The Collection object provides a convenient way
to refer to a related group of items as a single object. The items, or members,
in a collection need only be related by the fact that they exist in the
collection. Members of a collection don't have to share the same data type.
A collection can be created the same way other objects are
created. For example:
Dim X As New Collection
Once a collection is created, members can be added using the
Add
method and removed using the Remove
method.
Specific members can be returned from the collection using the Item
method, while the entire collection can be iterated using the For
Each...Next
statement.
It means that a collection is a COM object that has 3
properties and 2 methods: Add
, Remove
,
Count
, Item
and _NewEnum
, though in
technical literature you may find that only Count
and
_NewEnum
are necessary for the object to be called the
collection.
My collection defines the interface IXCollection
implemented by the class CXCollection
.
The IDL looks like this:
interface IXCollection : IDispatch
{
[id(1), helpstring("Adds a member to a collection")]
HRESULT Add([in] VARIANT vItem, [in, optional] VARIANT vKey);
[id(2), helpstring("Removes a member from a collection")]
HRESULT Remove([in] VARIANT vIndex);
[propget, id(3),
helpstring("Returns the number of members in a collection")]
HRESULT Count([out, retval] long * plNumber);
[propget, id(DISPID_VALUE),
helpstring("Returns a specific member of a collection "
"either by position or key")]
HRESULT Item([in] VARIANT vIndex, [out, retval] VARIANT * pvItem);
[propget, restricted, id(DISPID_NEWENUM), helpstring("Method _NewEnum")]
HRESULT _NewEnum([out, retval] IUnknown ** ppUnk);
}
Now lets talk a little about each method and property.
Add
Adds items to the collection. You can add items to the collection
using the optional vKey parameter. If key is used the individual item can be
accessed using this key.
Remove
Removes items from the collection either by the index or by the
key.
Count
Returns the number of items in the collection.
Item
Returns an individual item either by the index or by the key. If
the index is a number it�s 1-based. This property is given the standard
DISPID DISPID_VALUE
to make it as the "default" property to
simplify its use in Visual Basic and scripting languages.
_NewEnum
Returns an enumerator object that contains collection items allowing the
client sequential access. This property is assigned the standard DISPID
DISPID_NEWENUM
, this DISPID
is used by Visual Basic to
implement its For-Each
syntax.
The _NewEnum
property returns an enumerator object that supports
standard IEnumVARIANT
interface. The IEnumVARIANT
interface is a collection of Variants. It allows clients to enumerate
heterogeneous collections of objects and intrinsic types when the clients cannot
or do not know the specific type(s) of elements in the collection.
Source Code
The source code contains ShoppingCart project that
implements the collection as well as C++ and VBScript test applications.
Environment
- VC++ 6.0 SP4, Win2000 SP2.
For detailed coverage of the collections and enumerators I refer you to
�ATL Internals� by B. Rector, C. Sells and �Professional ATL COM Programming� by
R. Grimes.
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.