COM Integration

Creating an extension with COM

The complete source and makefiles are located in the XMLFoundation Examples/c++/ExATLCOM directory

Create a basic ATL COM project with Visual Studio

.ExATLC1Visual Studio will write your IDL, and implementation header files.

The following code sample is the standard app wizard written implementation header file

with a few small additions (Highlighted in red) required for XML support.

public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CMyATLObj, &CLSID_MyATLObj>,
public IDispatchImpl<IMyATLObj, &IID_IMyATLObj, &LIBID_EXATLCOMLib> ,
public XMLObject

void MapXMLTagsToMembers();


In your implementation file you’ll need to add the macro at a global scope

and implement MapXMLTagsToMembers() to define the Object to XML mappings.

This example maps an integer, a string, and a list of COM objects.

void CMyATLObj::MapXMLTagsToMembers()
MapMember(&m_nInteger, “CustomerID”);
MapMember(&m_strString, “CustomerName”, &gGenericStrHandler);
MapMember(&m_lstCMyATLObj, CMyATLObj::GetStaticTag(), &gGListHandler,0);

In the ExATLCOM sample application several additional methods have been added to the COM Object.  Most notably put_XMLState() that has the ability to assign members variables and create COM objects when supplied well-formed XML as input.

This example specifies a unique object ID composed of element/member data in the object.  When an Object ID is specified put_XMLState() can then update COM object instances with new or more information.  A common usage of this feature is to “drill down” on a list of customers, adding more data detail to one of the customer object instances.  So for example given a customer that maps the attribute OID as the ObjectID:

<Customer oid=1>



The application may want more information on this customer.  More information is retrieved (generally from the DBMS) and it may look like this:

<Customer oid=1>



The new information does not create a new XML state object and a new COM interface object, rather it updates the existing state object and uses the same COM Interface object.  If however the oid of the new information was 2, then a new XML state object and a new COM interface would be created.

Visual Basic is the easiest way to demonstrate the functionality of this COM Object

From the “Project” menu add a “Reference”

ExATLC2Globally define the Object in VB like this:

     Dim MyO As IMyATLObj

Then assign it in fromLoad() like this:

     Set MyO = New MyATLObj

The application looks like this:


Buttons 1, 3, and 7 are all the same.  They get the state of the COM object in XML representation and display it in the large text box to the right.  The VB code to do that looks like this:

Text2 = MyO.XMLState

and that calls a method in the COM object in C++ that looks like this:

CComBSTR temp( ToXML() );
*pVal = temp.Copy();
return S_OK;

Button 2 directly modifies the COM object through Native COM accessors like this:

MyO.TheCount = 777
MyO.TheString = “Hello World”

they call into the COM object and execute the standard ATL member accessors like this:

STDMETHODIMP CMyATLObj::put_TheString(BSTR newVal)
_bstr_t b(newVal);
m_strString = (const char *)b;
return S_OK;

Button 3, like Button 1 shows the XML state.

Button 4 makes no COM call.  It only modifies the VB edit control to contain the following XML:

< /Container>

Button 5 takes the current value from the large edit control and stuffs it into the COM object.  If you use the value in the edit control by button 4, then the base object 777 will be modified and two new objects (and their interfaces) will be created (123 and 456).  The VB code looks like this:

MyO.XMLState = Text2

the ATL objects C++ code looks like this:

_bstr_t b(newVal);
FromXML((const char *)b);
return S_OK;

Button 6 clears the large text box.  VB code loos like this:

Text2 = “”

Button 7 displays the current state of the COM object in XML like buttons 1 & 3.

Button 8 retrieves a COM interface to one of the sub-objects (123 or 456) then displays the XML state of that object in a message box.  The VB code looks like this:

Dim MyO2 As IMyATLObj
Set MyO2 = MyO.GetMyInterface(txtCustID.Text)
If (MyO2 Is Nothing) Then
MsgBox (“Requested CustomerID Not found”)
‘ invoke a method on the interface returned by GetMyInterface()
MsgBox MyO2.XMLState
Set MyO2 = Nothing
End If

The COM object has to search it’s list for the specified CustomerID then return the associated COM Interface for that object.  The C++ code looks like this:

STDMETHODIMP CMyATLObj::GetMyInterface(long CustomerID, IUnknown **pIOResult)
GListIterator it(&m_lstCMyATLObj);
XMLObject *pO = (XMLObject *)it++;
CComObject<CMyATLObj>*pIO = (CComObject<CMyATLObj>*)pO->GetInterfaceObject();
if (pIO->GetCustomerID() == CustomerID)
*pIOResult = pIO;
return S_OK;

 © 2015 United Business Technologies, Inc. All Rights Reserved.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s