0
votes

The scenario is this:

  • I have a COM object to ask questions. Name it ICom.
  • The COM object requires me to implement an IDispatch , descendant of , say, IComEvents, that notifies me for events.
  • I implement an IDispatch and connect it to the COM interface.

So far so good. My IComEvents descentant's Invoke() is called when the events occur.

The point is now that I must manually parse Invoke() parameters. For example, if a notification function is HRESULT OnMouseHit(int x), I have to detect this function from the DispID, then call it manually, for example

if (dispIdMember == 0xfa)
 {
 OnMouseHit(pDispParams->rgvarg[0].pIntVal); 
 }

I would have to do it for all the functions I want to implement. However I saw the DispInvoke() function which presumably will automatically do this for me and call the appropriate overloaded method for the dispId, with the correct parameters:

DispInvoke(this,m_ptinfo,dispIdMember,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr);

How do I generate m_ptinfo? By calling LoadRegTypeLib with the libid of the COM object, and then ITypeLib::GetTypeInfoOfGuid() with the IID of IComEvents. However, DispInvoke() always returns "member not found".

What would be wrong? I expect DispInvoke to parse the type information, find the member function name from the DispID and then use the "this" pointer to get the function address from the vtbl.

What am I doing wrong?

Thanks a lot. Michael.

1

1 Answers

0
votes

Is IComEvents a dual interface or a dispinterface? If it is a pure dispinterface it doesn't have a vtable. DispInvoke requires the interface to have a vtable (ie that it is a dual interface).