Article ID: 138414
Article Last Modified on 11/21/2006
COleDispatchImpl dispatch;
ASSERT(*(DWORD*)&dispatch != 0); // null vtable ptr?
if (*(DWORD*)lpDispatch != *(DWORD*)&dispatch)
return NULL; // not our Idispatch*
The problem here is that classes derived from COleControl don't use the
COleDispatchImpl implementation of IDispatch directly. They have their own
implementation using BEGIN_INTERFACE_PART and END_INTERFACE_PART that
delegates to the COleDispatchImpl object in the CCmdTarget base class.
Because of this, the v-tables in the previous test won't match and the
function will return NULL.
COleControl * pCtrl = (COleControl*)
((BYTE*)lpDisp - m_xDispatch.m_nOffset);
In this formula, lpDisp is a valid LPDISPATCH, m_xDispatch is the XDispatch
object member of COleControl that contains the control's implementation of
IDispatch, and m_nOffset is the offset generated by the INIT_INTERFACE_PART
macro for IDispatch.
#define END_INTERFACE_PART(localClass) \
} m_x##localClass; \
friend class X##localClass; \
In this case, localClass is "Dispatch" so m_x##localClass becomes
m_xDispatch.
#ifndef _AFX_NO_NESTED_DERIVATION
#define INIT_INTERFACE_PART(theClass, localClass) \
size_t m_nOffset; \
INIT_INTERFACE_PART_DERIVE(theClass,localClass) \
#define INIT_INTERFACE_PART_DERIVE(theClass, localClass) \
X##localClass() \
{ m_nOffset = offsetof(theClass, m_x##localClass); } \
m_nOffset becomes offsetof(COleControl, m_xDispatch).
Additional query words: 2.00 2.10 1.50 1.51 1.52 1.52a
Keywords: kbprb KB138414