[Webinar] Streamline your web hosting managementRegister Today

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 316
  • Last Modified:

array of COM object

I have two interfaces IList and IItem (as IDispatch interface). I would like to keep array of Items in List.
 Now I use COleSafeArray, but it's complicated to use.
Can you advise me better way (template ...).

IList have methods:
Add([in]IDispatch* pItem)
GetList([out,retval] VARIANT* pArrayOfItems)
0
mizera
Asked:
mizera
1 Solution
 
vachoohoCommented:
Use CTypedPtrList internaly
and do not forget to call AddRef() in Add([in] IDispatch * pItem) method

What to me OLESAFEARRAY is better
because it do much work for us.
0
 
talikCommented:
Hi mizera,

You can use an underlined C++ object that will be wrapped by your COM object.

For example, the prototype could be written as following:

class YourObjectListImpl
{
private:
    CList<IDispatch*, IDispatch*>  m_listItems;
    void CleanUp ();

public:
     (STDMETHOD)(Add) (IDispatch* pItem);
     (STDMETHOD)(GetList)(VARIANT* pArrayOfItems);
};

//---------- imlementation --------

STDMETHODIMP YourObjectListImpl::Add (IDispatch* pItem)
{
// skip error checking e.t.c ....

// notice the AddRef call - you're
// going to keep the object alive and
// therefore the list should be the
// "ownwer"

    pItem->AddRef ();
    m_listItems.AddTail (pItem);

    return S_OK;
}

STDMETHODIMP YourObjectListImpl::GetList(VARIANT* pArrayOfItems)
{
// skip error checking as well
   VariantInit (pArrayOfItems);

// AFAIK, the easy way to return variant
// array is still COleSafeArray

   COleSafeArray arRetArray;
   arRetArray.CreateOneDim (VT_DISPATCH, m_listItems.GetCount ());

   long lIndex = 0;
   for (POSITION pos = m_listItems.GetHeadPosition (); pos != NULL; lIndex++)
   {
        IDispatch* pItem = m_listItems.GetNext (pos);
// put element AddRef's each item      
        arRetArray.PutElement (&lIndex, pItem);
   }

   *pArrayOfItems = arRetArray.Detach ();

    return S_OK;
}

Don't forget to call Release for every item that's being removed from the list.

void YourObjectListImpl::CleanUp ()
{
    POSITION pos = m_listItems.GetHeadPosition();
    while(pos)
    {
      m_listItems.GetNext(pos)->Release();
    }
}

In this way you can implement wrappers for arrays, lists, maps e.t.c.
If you don't like MFC template collections, you can use STL using the same technique.

Last note: <afxtempl.h> required for MFC template collections by default is not included by ATL Wizard.
0

Featured Post

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now