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
- initializing and uninitializing COM,
- class factories,
- interface navigation,
- reference counting,
- in-process servers, and
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 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