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:

COM clients: Coding a client
1) The first 3 steps give us an instance of COM object 01 and an interface pointer to IF1
The first 3 steps give us an instance of COM object 01 and an interface pointer to IF1

2) Step 4 is application specific since you make COM calls into IF1 to perform application tasks
Step 4 is application specific since you make COM calls into IF1 to perform application tasks

3) Step 5, the call into IF1::QueryInterface gives us a second interface pointer into COM object01 - a pointer to IF2
Step 5, the call into IF1::QueryInterface gives us a second interface pointer into COM object01 - a pointer to IF2


4) Step 6 is application specific, requires you make COM calls into IF2 to perform application tasks
Step 6 is application specific, requires you make COM calls into IF2 to perform application tasks

5)Step 7 is required of all COM clients. You must call Release on all COM interface pointers when you are finished using them.
Step 7 is required of all COM clients. You must call Release on all COM interface pointers when you are finished using them.

6) Step 8 tells COM that the current thread is no longer going to use COM services and objects
Step 8 tells COM that the current thread is no longer going to use COM services and objects


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

SEMrush Software