Board index » cppbuilder » Events on Client side?

Events on Client side?

Hi, all!

I have recieved a small VC++ com server appl. from a friend and have no
problems calling methods or getting / setting properties. I can, however,
not figure out how to use the events.

In my SERVERLib_TLB.h file I find this piece of code :

template <class T> HRESULT __fastcall
_IBWServerEventsDispT<T>::Even()
{
  static _TDispID _dispid(/* Even */ DISPID(1));
  return OleFunction(_dispid);

Quote
}

Question is; How do I use it??

All tips are welcome!

Regards;

Johan
--

  -----------------------------------------------------------------
  Johan Schrewelius / DAD Direct AB
  E-mail: johan.schrewel...@daddirect.se
  Phone: +46 418 450 511
  Mobile: +46 70 633 01 56
  URL: www.daddirect.se

 

Re:Events on Client side?


Johan,

I just posted a request for Client Event Sink feedback. A few days ago I
also posted a sample illustrating sinking events in C++Builder Client
application.

Your message, however, made me realize that the events-related templates in
xxxx_TLB.h is confusing. Here's the scoop:

Template DispWrappers of Source Interfaces and TEvents_xxxx templates in the
_TLB.H Files
=======================================================================
The xxxx_TLB.H file generated by the C++Builder IDE when importing a Server
or ActiveX Control uses exactly the same codegenerator used to create
xxxx_TLB.H files in an ActiveX Server project of C++Builder. Consequently,
the files exposes templates that are only useful if you are building a
Server. These templates are dispinterface wrappers of source interfaces and
templates named TEvents_CoClassName where CoClassName is replaced by the
name of a CoClass with source interfaces.

The dispinterface wrappers of source interfaces expose methods that invoke
particular events via IDispatch. These methods differ from the other
dispinterface wrappers exposed in the xxxx_TLB.H files in that they never
perform a 'GetIDsOfNames'. In other words, the _TDispID parameters that
caches the dispid of the event is never passed the name of the method. Note
that the name is still generated within comments for informational purposes.

The TEvents_CoClass templates utilize the dispinterface wrappers of source
interfaces. They are a simple template that expose methods named
'Fire_EventName' where event name is replaced by the name of indivual events
supported by the default source interface of the CoClass. This template is
used by the C++ class implementing the CoClass. For example, if you create a
new Automation Object and name the CoClass, MyObject, you'll end up with the
following C++ impelementation class:

class ATL_NO_VTABLE TMyObjectImpl :
  public CComObjectRootEx<CComSingleThreadModel>,
  public CComCoClass<TMyObjectImpl, &CLSID_MyObject>,
  public IConnectionPointContainerImpl<TMyObjectImpl>,
  public TEvents_MyObject<TMyObjectImpl>,
  public IDispatchImpl<IMyObject, &IID_IMyObject, &LIBID_Project1>
{

The relevant portion above is 'TEvents_MyObject<....>'.

You can then go to the Type Library Editor and add a method to the
'IMyObjectEvents' interface. Let's say that you add a method named
'Activate'. When the xxx_TLB.H file is refreshed, two things will have
changed. First, the dispinterface wrapper for IMyObjectEvents will contain a
method to simplify the invokation of the Activate method:

template <class T> HRESULT __fastcall
IMyObjectEventsDispT<T>::Activate()
{
  static _TDispID _dispid(/* Activate */ DISPID(1));
  return OleFunction(_dispid);

Quote
}

Second, the TEvents_MyObject template will expose a 'Fire_Activate' method:

template <class T>
class TEvents_MyObject : public IConnectionPointImpl<T,
                                                 &DIID_IMyObjectEvents,

CComUnkArray<CONNECTIONPOINT_ARRAY_SIZE> >
{
public:
  HRESULT         Fire_Activate(void);
protected:
  IMyObjectEventsDisp m_EventIntfObj;

Quote
};

Now, since the C++ class that implements your CoClass already derives form
the TEvents_MyObject template, your Server can easily fire that Activate
event. Let's assume the CoClass also exposes a 'WakeUp' method. The
implementation of that method could read:

STDMETHODIMP TMyObjectImpl::WakeUp()
{
  // Do whatever I need to do to wake up
  //...
  // Tell my clients that I'm aware
  Fire_Activate();

Quote
}

That is when the Server is asked to 'WakeUp' is informs all Clients that
it's now Awake (or Activated).

Now, it's true we could refrain from generating these classes when you
import a Server|ActiveXControl. They are only needed/used when you are
building a Server. However, so many of our users use the same xxxx_TLB.H
generated for their servers in their Client application. I we generated a
new xxxx_TLB.H when the Server is imported, we could be overwriting the
xxxx_TLB of the Server, making it not compile the next time the Server
project is loaded. So after much debate we opted to always generate these
classes [we did consider #ifdef'ing them out in non-Server projects but ran
into other problems: A Server application that's also a Client because it
imports other Servers; and there was backward compatibility issues also].

I realize that the above does not address your question about handling
events on the client side, but I thought I'd clarify why these classes are
in Client side generated headers and what they are used for. Please, see my
posts regarding Client side Event handling and don't hesitate to contact me
on the issue.

Regards,

Bruneau.

Quote
Johan Schrewelius wrote in message <7g1rff$g...@forums.borland.com>...
>Hi, all!

>I have recieved a small VC++ com server appl. from a friend and have no
>problems calling methods or getting / setting properties. I can, however,
>not figure out how to use the events.

>In my SERVERLib_TLB.h file I find this piece of code :

>template <class T> HRESULT __fastcall
>_IBWServerEventsDispT<T>::Even()
>{
>  static _TDispID _dispid(/* Even */ DISPID(1));
>  return OleFunction(_dispid);
>}

>Question is; How do I use it??

>All tips are welcome!

>Regards;

>Johan
>--

>  -----------------------------------------------------------------
>  Johan Schrewelius / DAD Direct AB
>  E-mail: johan.schrewel...@daddirect.se
>  Phone: +46 418 450 511
>  Mobile: +46 70 633 01 56
>  URL: www.daddirect.se

Other Threads