Click here to Skip to main content
Licence 
First Posted 23 Sep 2003
Views 28,973
Bookmarked 23 times

Extending COM object with runtime properties through custom interface

By | 23 Sep 2003 | Article
How to propogate non COM properties to COM client through custom interface

Introduction

This article explains how to extend COM object properties at run time with properties that are not declared in IDL file.

The method explained here is to use custom interface IRtProperties, this method is only aplicable if you are the owner of both the COM server and the COM client since both need to know of existance of the IRtProperties interface.

Usage

Server side

Suppose you have some COM object that will generate custom properties at runtime and you have a COM client that you want to recognize those properties and manage them.

First you have to include the header file IRtProperties.h in your COM object's header.
Than you have to derrive your object from this interface:

class ATL_NO_VTABLE CSomeCOMObject : 
 public CComObjectRootEx<CComSingleThreadModel>,
 public CComCoClass<CSomeCOMObject , &CLSID_SomeCOMObject >,
 public IRtProperties  // << Add this line
BEGIN_COM_MAP(CMdnBlockCom)
 COM_INTERFACE_ENTRY(ISomeCOMObject )
 COM_INTERFACE_ENTRY(IDispatch)
 COM_INTERFACE_ENTRY(IRtProperties) // << Add this line
END_COM_MAP()

Next step is to override all of the interface's functions. Here is the list:

// *** IRtProperties ***
    
 STDMETHOD(GetRtPropertiesCount)(THIS_ 
  /* [out] */ LONG* pCount) PURE;

  STDMETHOD(GetRtPropertyName)(THIS_ 
  /* [in]  */ LONG propid,
  /* [out] */ BSTR* pbstrName) PURE;
    
  STDMETHOD(GetRtPropertyCategory)(THIS_
  /* [in]  */ LONG propid,
  /* [out] */ BSTR* pbstrName,
  /* [out] */ PROPCAT* ppropcat) PURE;
 STDMETHOD(GetRtPropertyType)(THIS_
  /* [in]  */ LONG propid,
  /* [out] */ VARTYPE* vt) PURE;
 STDMETHOD(IsRtPropertyEnabled)(THIS_
  /* [in]  */ LONG propid,
  /* [out] */ BOOL* isEnabled) PURE;
 STDMETHOD(SetRtPropertyValue)(THIS_
  /* [in]  */ LONG propid,
  /* [in] */ VARIANT newVal) PURE;
 STDMETHOD(GetRtPropertyValue)(THIS_
  /* [in]  */ LONG propid,
  /* [out] */ VARIANT* pVal) PURE;
 STDMETHOD(GetRtPredefinedStrings)(THIS_
  /* [in]  */ LONG propid,
  /* [out] */ CALPOLESTR *pcaStringsOut,
  /* [out] */ CADWORD *pcaCookiesOut) PURE; 

Explanation

Suppose your runtime properies is an array of PROPERTY declared as follows:

struct PROPERTY{
       CString name;
       CString value;
}

CArray <PROPERTY,PROPERTY> m_myRtProperties;

GetRtPropertiesCount : returns the total count of runtime properties.

Example

STDMETHODIMP CSomeCOMObject ::GetRtPropertiesCount(
 /* [out] */ LONG* pCount)
{
 *pCount = m_myRtProperties.GetSize();
 return S_OK;
}

GetRtPropertyName : returns property name by index.

Example

STDMETHODIMP CMdnBlockCom::GetRtPropertyName(
 /* [in]  */ LONG propid,
    /* [out] */ BSTR* pbstrName)
{

   *pbstrName=::SysAllocString(m_myRtProperties[propid].name);
   return S_OK;
}

Continue to override all of the functions.

Client side

From the client side when you aquire the IDispatch or IUnknown interface of the object quiry it for the IRtProperies inteface:

hr = pUnk->QueryInterface(IID_IRtProperties, (void**)&irtp);
 if (FAILED(hr) || irtp == NULL)
  return;
When you have the IRtProperties interface just use its functions to manipulate the object's runtime properties.

Example

long propCount;
 irtp->GetRtPropertiesCount(&propCount);
 CComBSTR bstrName, bstrCategory;
 PROPCAT catId;
 for (int i = 0; i < propCount; i++)
 {
  irtp->GetRtPropertyName(i,&bstrName);
  irtp->GetRtPropertyCategory(i,&bstrCategory,&catId);
  VARTYPE vt;
  irtp->GetRtPropertyType(i,&vt);
  if (vt == VT_ARRAY)
  {
   CALPOLESTR     castr; 
   CADWORD        cadw;
   hr = irtp->GetRtPredefinedStrings(i,&castr,&cadw);
   if (hr == S_OK)
   {
    for (ULONG j = 0; j < castr.cElems; j++)
    {
     CString szVal(castr.pElems[j]);
     int index = otiCombo->AddString(szVal);
     otiCombo->CComboBox::SetItemData(j,cadw.pElems[j]);
    }
    CoTaskMemFree((void *)cadw.pElems); 
    CoTaskMemFree((void *)castr.pElems); 
   }
  }

  BOOL bReadOnly;
  irtp->IsRtPropertyEnabled(i,&bReadOnly);

}
if (irtp)
  irtp->Release();

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Alex Hazanov

Software Developer (Senior)
RDV Systems
Israel Israel

Member



Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board. (secure sign-in)
 
Search this forum  
 FAQ
    Noise  Layout  Per page   
  Refresh
-- There are no messages in this forum --
Permalink | Advertise | Privacy | Mobile
Web03 | 2.5.120517.1 | Last Updated 24 Sep 2003
Article Copyright 2003 by Alex Hazanov
Everything else Copyright © CodeProject, 1999-2012
Terms of Use
Layout: fixed | fluid