在基于MFC的COM客户中创建Sink接口

  • 概要

Microsoft Foundation Classes (MFC)有wizard支持添加sink到ActiveX 控制的界面. 但是, 这技术支持不延伸到其它COM服务器. 这文章描绘怎样在MFC客户中添加sink界面。请注意,本文应用到源接口,它是一个disp接口,或一个双接口。

  • 更多信息

这里是向COM客户添加sink接口的步骤:

使用Class Wizard,加CCmdTarget有自动化支持的派生对象(例如, CMySink)。在Class Wizard中, 选择Automation选项,而不使用"Createable by type ID"。在界面图中,改变IID (在INTERFACE_PART宏中第二参数),让它指定源接口的IID。.idl文件能通过查看OLE/COM Object Viewer中的typelib。在CMySink的DISPATCH_MAP中,添加一DISP_FUNCTION_ID宏,它用于定义希望处理的事件的定义。例如:

BEGIN_DISPATCH_MAP(CMySink, CCmdTarget)
DISP_FUNCTION_ID(CMySink,"Quit",2,OnObjQuit,VT_EMPTY,VTS_I4 VTS_I4)
END_DISPATCH_MAP()

在上方的代码一因为处理离开事件入口的,它使用DISPID=2。现在就可以准备连接接口了,在服务器对象创建时调用AfxConnectionAdvise()。例如:

//初始化对象,并保存对象指针。
m_pSink = new CMySink();

//得到sinks IUnknown接口的指针, 不用AddRef.
LPUNKNOWN pUnkSink = m_pSink->GetIDispatch(FALSE);

//建立来源和sink之间关系,其中m_pUnkSrc是经过CoCreateInstance的调用而得到服务器IUnknown的。
//m_dwCookie是标记连接用的,将来使用这中止连接。
AfxConnectionAdvise(m_pUnkSrc, IID_MYEVENT, pUnkSink, FALSE, &m_dwCookie);

当你已完成用服务器对象时,在释放服务器对象之前,你需要停止连接. 你通过调用AfxConnectionUnadvise完成。例如:

//得到sinks IUnknown接口的指针, 不用AddRef.
LPUNKNOWN pUnkSink = m_pSink->GetIDispatch(FALSE);

//中止连接。其中m_pUnkSrc是经过CoCreateInstance的调用而得到服务器IUnknown的,m_dwCookie是AfxConnectionAdvise()得到的。
AfxConnectionUnadvise(m_pUnkSrc, IID_MYEVENT, pUnkSink, FALSE, m_dwCookie);

因为CMySink是在堆上被建立,确保你删除它以避免内存漏洞。