I am trying to build Connection Points in existing COM component.
I derive the class from CCmdTarget and call MFC macros in class declaration and implementation as described in MSDN. Component is correctly build, linked, and run.
However, when I debug my client application I see the following issue:
Client locates the correct component, finds the connection point container, but fails on FindConnectionPoint with E_NOINTERFACE.
I suspect that I have to add or modify some MFC macros to include my connection point into container but not sure how to do this.
So, please help me to resolve this issue or give a hint where else to look for the issue.
Thanks in advance,
Hovo
[ uuid(xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx), version(1.0) ]
library SMC
{
importlib("stdole32.tlb");
importlib("stdole2.tlb");
[
uuid(xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx),
helpstring("_IAdHocPresenceEvents Interface")
]
interface _IAdHocPresenceEvents : IUnknown
{
[id(1), helpstring("method OnAdHocPresenceQuery")] HRESULT OnAdHocPresenceQuery();
};
#include "ISMCLink.idl"
[ uuid(xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx) ]
coclass SMCLink
{
dispinterface IDispSMCLink;
[default] interface ISMCLink;
interface ISMCLink2;
[default, source] interface _IAdHocPresenceEvents;
};
};
[
helpstring("Interface to control My Product"),
uuid(xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx),
dual,
oleautomation
]
interface ISMCLink : IDispatch
{
//...
/**
* RequestAdHocPresence
*
* Sends Ad Hoc Presence Query
*
* @param SIP address.
*
* @return S_OK if the In session window was opened successfully
*/
[id(0x00000001), helpstring("method Request for Ad Hoc Presence")]
HRESULT RequestAdHocPresence([in] BSTR user);
};
// Primary dispatch interface for SMC
[ uuid(xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx) ]
dispinterface IDispSMCLink
{
interface ISMCLink;
};
// Definition for the new interface ISMCLink2
// ------------------------------------------
[
helpstring("ISMCLink2, Interface to access My Product"),
uuid(xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx),
dual,
oleautomation
]
interface ISMCLink2 : ISMCLink
{
//...
};
namespace MYPROD {
class SMCLink : public CCmdTarget
{
//...
protected:
DECLARE_MESSAGE_MAP()
DECLARE_DISPATCH_MAP()
DECLARE_INTERFACE_MAP()
// Connection point for ISMCLink interface
BEGIN_CONNECTION_PART(SMCLink, AdHocPresenceEvents)
CONNECTION_IID(IID__IAdHocPresenceEvents)
END_CONNECTION_PART(AdHocPresenceEvents)
DECLARE_CONNECTION_MAP()
public:
SMCLink(void);
virtual ~SMCLink(void);
// to be OLE creatable, it must be DYNCREATE and OLECREATE
DECLARE_DYNCREATE(SMCLink)
DECLARE_OLECREATE(SMCLink)
//..
/**
* RequestAdHocPresence
*
* Sends Ad Hoc Presence Query
*
* @param SIP address.
*
* @return S_OK if the In session window was opened successfully
*/
afx_msg HRESULT RequestAdHocPresence(BSTR sipAddr);
BEGIN_DUAL_INTERFACE_PART(DualSMCLink, ISMCLink)
//...
STDMETHOD(RequestAdHocPresence)(THIS_ BSTR user);
END_DUAL_INTERFACE_PART(DualSMCLink)
};
} // namespace MYPROD
namespace MYPROD {
BEGIN_MESSAGE_MAP(SMCLink, CCmdTarget)
//{{AFX_MSG_MAP(CAutoProxy)
// NOTE - the ClassWizard will add and remove mapping macros here.
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
IMPLEMENT_DYNCREATE(SMCLink, CCmdTarget)
BEGIN_DISPATCH_MAP(SMCLink, CCmdTarget)
//{{AFX_DISPATCH_MAP(SMCLink)
//..
DISP_FUNCTION(SMCLink, "RequestAdHocPresence", RequestAdHocPresence, VT_ERROR, VTS_BSTR)
//}}AFX_DISPATCH_MAP
END_DISPATCH_MAP()
BEGIN_INTERFACE_MAP(SMCLink, CCmdTarget)
INTERFACE_PART(SMCLink, IID_ISMCLink, DualSMCLink)
INTERFACE_PART(SMCLink, IID_ISMCLink2, DualSMCLink)
INTERFACE_PART(SMCLink, IID_IConnectionPointContainer, ConnPtContainer)
END_INTERFACE_MAP()
BEGIN_CONNECTION_MAP(SMCLink, CCmdTarget)
CONNECTION_PART(SMCLink, IID_IConnectionPointContainer, AdHocPresenceEvents)
END_CONNECTION_MAP()
SMCLink::SMCLink(void)
{
EnableAutomation();
EnableConnections();
}
SMCLink::~SMCLink(void)
{
//..
if (registerCookie_ != 0)
RevokeActiveObject(registerCookie_, NULL);
}
void SMCLink::registerActive()
{
HRESULT hRes;
hRes = RegisterActiveObject(GetInterface(&IID_IUnknown),
SMCLink::guid, NULL, ®isterCookie_);
//..
}
//..
afx_msg HRESULT SMCLink::RequestAdHocPresence(BSTR sipAddr)
{
Sleep(1000);
::MessageBox(NULL, L"RequestAdHocPresence", L"RequestAdHocPresence", 0);
Fire_AdHocPresenceStatus(); // HOWTO ???
return S_OK;
}
STDMETHODIMP SMCLink::XDualSMCLink::RequestAdHocPresence(BSTR user)
{
METHOD_PROLOGUE(SMCLink, DualSMCLink)
return pThis->RequestAdHocPresence(user);
}
} // namespace MYPROD
CLSID clientCLSID;
if (FAILED(CLSIDFromProgID(A2BSTR("SMC.SMCLink"), &clientCLSID)))
{
clientCLSID = SMC::CLSID_SMCLink;
}
LPUNKNOWN lpUnk;
SMC::ISMCLink* m_pSMCLink = NULL;
if (m_pSMCLink == NULL)
{
if (GetActiveObject(clientCLSID, NULL, &lpUnk) == NOERROR)
{
hr = lpUnk->QueryInterface(SMC::IID_ISMCLink, (LPVOID*)&m_pSMCLink);
lpUnk->Release();
}
}
hr = m_pSMCLink->RequestAdHocPresence(A2BSTR("someuser@mydomain"));
// this returns S_OK
IConnectionPointContainer * pConnPtContainer = NULL;
IConnectionPoint * pCP2 = NULL; //these are declared as a member
//check if this interface supports connectable objects
hr = m_pSMCLink->QueryInterface(IID_IConnectionPointContainer,(void **)&pConnPtContainer);
// this returns S_OK
IEnumConnectionPoints* pEnum = NULL;
hr = pConnPtContainer->EnumConnectionPoints( &pEnum );
// this returns S_OK
hr = pConnPtContainer->FindConnectionPoint(IID__IAdHocPresenceEvents, &pCP2);
// this returns E_NOINTERFACE
// ..
Second argument should be an IID of connection pointer interface.