Consultor Eletrônico



Kbase P56004: COM object using IDispatch interface does not send events back to Progress
Autor   Progress Software Corporation - Progress
Acesso   Público
Publicação   06/04/2005
Status: Verified

FACT(s) (Environment):

Windows 32 Intel

SYMPTOM(s):

COM object (ActiveX automation server) does not send events back to Progress

The ENABLE-EVENTS method is used on the COM Object

COM object uses IDispatch event interface

COM object has it's own event interface defined that extends the IDispatch interface

CAUSE:

When the event sink is set up, a ConnectionPoint object is obtained for the COM object, on which Advise() is called. In response QueryInterface will be called on the Progress event sink object for a specific interface.
If any interface other than IDispatch is asked for, the event sink will report that interface is not supported and no events will be received by it.

A common cause is that the custom event interface of the COM object is asked for instead of the generic IDispatch interface. For example, a piece of C code from a typical Advise() function that calls the QueryInterface function will look like

QueryInterface(IID_IMsgQueueEvents, &pinterface);
if (pinterface != NULL)
{
/* Set up the parameters for IDispatch, which define the method name
and parameters, etc... (not shown here) */
pinterface->Invoke(<parameters>);
}One case in which this happens is when using Microsoft's ATL model - that model is defined to build enclosed applications, and will expect strong typing of the objects. It will therefore by default query the custom interface instead of the generic IDispatch.

FIX:

Modify the ActiveX/COM object so that the Advise() method calls QueryInterface on IDispatch if the event sink does not support the custom interface.

Following the C example above, this could be modified to read:
QueryInterface(IID_IMsgQueueEvents, &pinterface);
if (pinterface == NULL) QueryInterface(IID_IDispatch, &pinterface);
if (pinterface != NULL)
{
/* Set up the parameters for IDispatch, which define the method name
and parameters, etc... (not shown here) */
pinterface->Invoke();
}