Brigsoft wrote: But what I must to do if I do not know all events before a program start. Then you're in for a rough ride. COM events are either tied to a vtable entry (non-dispinterface source) or to a DISPID (dispinterace source). In both cases, the events are tied to an interface ID. You must know in advance what you're dealing with. Of course, one could devise a more dynamic homebrew event scheme - but alas, that's not the case here. COM events are as static as stone. Brigsoft wrote: But I want catch all to one function. You can do this quite easily if the source interface is a dispinterface. Simply implement the dispinterface "manually" in a separate class like this:
template <typename T, typename SourceInterface, int ID>
class CSourceInterfaceImpl {
public:
HRESULT Init() {
// Create type info stuff, preferably using CreateDispTypeInfo()
// based on the interface passed as template parameter. Feel
// free to use __uuidof(SourceInterface) if portability is of no
// concern
...
}
void Finalize() {
// Release type info
}
// Important. Do NOT implement the IUnknown part here. These
// methods must be implemented by the COM class so that we don't
// break any COM rules.
STDMETHOD(GetIDsOfNames)(...) {
// Implement this, preferably using DispGetIDsOfNames()
}
STDMETHOD(GetTypeInfo)(...) {
// pass back the type info object created in constructor
}
STDMETHOD(GetTypeInfoCount)(...) {
// Return 1
}
STDMETHOD(Invoke)(...) {
// this is where we dispatch the calls to "the one and only"
// function.
return static_cast<T>(this)->EventInvocation(
ID,
... // The rest of the parameters passed to this function
);
}
};
#define ID_FOR_EVENTS_X 1
#define ID_FOR_EVENTS_Y 2
#define ID_FOR_EVENTS_Z 3
class ATL_NO_VTABLE CMyCOMClass :
public ..., // boiler plate ATL code
// This is where we reuse the CSourceInterfaceImpl template
public CSourceInterfaceImpl<CMyCOMClass, ISourceX, ID_FOR_EVENTS_X>,
public CSourceInterfaceImpl<CMyCOMClass, ISourceY, ID_FOR_EVENTS_Y>,
public CSourceInterfaceImpl<CMyCOMClass, ISourceZ, ID_FOR_EVENTS_Z>
{
... // ATL boiler plate code
HRESULT FinalConstruct() {
HRESULT hr; // handling of errors omitted for brevity
hr = CSourceInterfaceImpl<CMyCOMClass, ISo