15.02.2015 Views

C# 4 and .NET 4

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

Using a .neT Component from a CoM Client ❘ 721<br />

The name of the event must be the same as the name of the method inside the source<br />

interface. Otherwise, the events cannot be mapped for COM clients.<br />

Creating a Client with a sink object<br />

After you ’ ve built <strong>and</strong> registered the .<strong>NET</strong> assembly <strong>and</strong> installed it into the global assembly cache, you can<br />

build a client application by using the event sources. Implementing a callback or sink object that implements<br />

the IDispatch interface was — using Visual Basic 6.0 — just a matter of adding the With Events keyword,<br />

very similar to how Visual Basic deals with .<strong>NET</strong> events today. It ’ s more work with C++, but here the Active<br />

Template Library helps.<br />

Open the C++ Console application created in the section “ Creating a COM Client Application ” <strong>and</strong> add the<br />

following includes to the fi le stdafx.h :<br />

#include < atlbase.h ><br />

extern CComModule _Module;<br />

#include < atlcom.h ><br />

The fi le stdafx.cpp requires an include of the ATL implementation fi le atlimpl.cpp :<br />

#include < atlimpl.cpp ><br />

code snippet COMClient/stdafx.h<br />

code snippet COMClient/stdafx.cpp<br />

Add the new class CEventH<strong>and</strong>ler to the fi le COMClient.cpp . This class contains the implementation of<br />

the IDispatch interface to be called by the component. The implementation of the IDispatch interface<br />

is done by the base class IDispEventImpl . This class reads the type library to match the dispatch IDs<br />

of the methods <strong>and</strong> the parameters to the methods of the class. The template parameters of the class<br />

IDispatchEventImpl requires an ID of the sink object (here the ID 4 is used), the class that implements the<br />

callback methods ( CEventH<strong>and</strong>ler ), the interface ID of the callback interface ( DIID_IMathEvents ), the ID<br />

of the type library ( LIBID_DotnetComponent ), <strong>and</strong> the version number of the type library. You can fi nd the<br />

named IDs DIID_IMathEvents <strong>and</strong> LIBID_DotnetComponent in the fi le dotnetcomponent.tlh that was<br />

created from the #import statement.<br />

The sink map that is surrounded by BEGIN_SINK_MAP <strong>and</strong> END_SINK_MAP defi nes the methods that are<br />

implemented by the sink object. SINK_ENTRY_EX maps the method OnCalcCompleted to the dispatch<br />

ID 46200. This dispatch ID was defi ned with the method CalculationCompleted of the IMathEvents<br />

interface in the .<strong>NET</strong> component.<br />

class CEventH<strong>and</strong>ler: public IDispEventImpl < 4, CEventH<strong>and</strong>ler,<br />

& DIID_IMathEvents, & LIBID_DotnetComponent, 1, 0 ><br />

{<br />

public:<br />

BEGIN_SINK_MAP(CEventH<strong>and</strong>ler)<br />

SINK_ENTRY_EX(4, DIID_IMathEvents, 46200, OnCalcCompleted)<br />

END_SINK_MAP()<br />

HRESULT __stdcall OnCalcCompleted()<br />

{<br />

cout < < "calculation completed" < < endl;<br />

return S_OK;<br />

}<br />

};<br />

code snippet COMClient/COMClient.cpp<br />

www.it-ebooks.info

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!