Basic COM   «Prev  Next»
Lesson 11 COM clients: Coding a Client
Objective Write COM client code

COM clients: Coding a Client

The client code described in this lesson builds on the previous lessons on
  1. initializing and uninitializing COM,
  2. class factories,
  3. interface navigation,
  4. reference counting,
  5. in-process servers, and
  6. CoCreateInstance.

COM object definitions

Following are definitions for COM object O1 and interfaces IF1 and IF2. These definitions are shared between the client and the server.
The client uses them to get class ids, interface ids, and interface definitions.

// {80C5FEF2-614A-11d2-85DB-08001700C57F}
DEFINE_GUID(CLSID_O1, 0x80c5fef2,
  0x614a, 0x11d2, 0x85, 0xdb,
  0x8, 0x0, 0x17, 0x0, 0xc5, 0x7f);

// {80C5FEF3-614A-11d2-85DB-08001700C57F}
DEFINE_GUID(IID_IF1, 0x80c5fef3,
  0x614a, 0x11d2, 0x85, 0xdb,
  0x8, 0x0, 0x17, 0x0, 0xc5, 0x7f);'

struct IF1 : public IUnknown {
   virtual HRESULT __stdcall X1(INT x);
   virtual HRESULT __stdcall X2();
};

// {80C5FEF4-614A-11d2-85DB-08001700C57F}
DEFINE_GUID(IID_IF2, 0x80c5fef4,
  0x614a, 0x11d2, 0x85, 0xdb,
  0x8, 0x0, 0x17, 0x0, 0xc5, 0x7f);

class IF2 : public IUnknown {
public:
   virtual HRESULT __stdcall Z1(FLOAT x);
};

Using COM Objects

To use COM object O1 and interfaces IF1 and IF2, we do the following:
1) COM Object Interface 1 2) COM Object Interface 2 3) COM Object Interface 3 4) COM Object Interface 4 5) COM Object Interface 5 6) COM Object Interface 6
Program 1 Program 2 Program 3 Program 4 Program 5 Program 6
COM Instance Object Interface Pointer

Error messages

COM interface and API calls return an HRESULT. Macros FAILED and SUCCEEDED take in an HRESULT and return a Boolean value that can be used to check the return status of a COM method.
Win32 API function FormatMessage can take in an HRESULT returned from a COM API call (for example, CoCreateInstance) or a COM interface method and return a string message that provides a short description of the error.

Using FormatMessage

Win32 API function FormatMessage can take in an HRESULT returned from a COM API call (for example, CoCreateInstance) or a COM interface method and return a string message that provides a short description of the error.

DWORD FormatMessage(  DWORD dwFlags,      
  LPCVOID lpSource,   
  DWORD dwMessageId,  
  DWORD dwLanguageId, 
  LPTSTR lpBuffer,    
  DWORD nSize,        
  va_list *Arguments);

The following code fragment demonstrates basic usage of FormatMessage:
#define EBUF_SIZ 2048

void ComErrorMsg(HRESULT hr) {
   TCHAR ebuf[EBUF_SIZ];

   FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
      NULL,
      hr,
      0,
      ebuf,
      EBUF_SIZ * sizeof(TCHAR),
      NULL);

   ::MessageBox(NULL, ebuf, ...);
}      

Function ComErrorMsg could be used as follows:
hr = CoCreateInstance(...);
if (FAILED(hr)) {
   ComErrorMsg(hr);
  ...
}

FormatMessage can also handle other (i.e., non-COM) Win32 API calls. Normally, you must call GetLastError to get the error code before calling FormatMessage.
See the Microsoft Platform SDK documentation for more details.

Com ClientCode - Exercise

Click the Exercise link below to apply what you have learned about writing client code.
COM Client Code - Exercise