ActiveX Events and MFC State

http://www.codeproject.com/Articles/7128/ActiveX-Events-and-MFC-State




ATL ActiveX Event Sink

This approach involves creating an IDispEventSimpleImpl derived class. Once again, methods must be added to match the event source.

Unlike the MFC approach, in this case you are responsible for managing the MFC state yourself. To do this, you should make use of the AFX_MANAGE_STATE macro discussed earlier. In this case however, since the event sink object is instantiated in the main application, use the AfxGetAppModuleState() function to supply the pointer to theAFX_MODULE_STATE structure.

For example, a typical event sink function for an object constructed in the main application should start with the following code.

//
// Make sure the MFC state is correct.
//
         AFX_MANAGE_STATE(AfxGetAppModuleState())    
//
//       The rest of your code...
//

As mentioned earlier, when this function returns, the MFC state will be automatically restored.

The demo program illustrates the use of this technique in the CAtlEventSink class.


Note: there are some exceptions to the state management rules which make this topic even more confusing. Regular dlls that statically link to MFC and MFC extension dll's should not use AFX_MANAGE_STATE. See the MSDN article "Regular DLLs Dynamically Linked to MFC" for further details.



MFC中实现 EventSink 。 (1) 在MFC中,添加ATL简单对象 CFileMonitorSink (2) 添加继承父类 IDispEventImpl public IDispEventImpl (1) 0 唯一标识符, 用于区别 连接到 事件源的多个客户端 CFileMonitorSink, 当前类名 _IFun1Events, COM 中的事件源接口, 包含各种事件 __ATLEventLib, COM 中Lib类 具体查 MSDN --IDispEventImpl (2) 添加映射项 BEGIN_SINK_MAP(CFileMonitorSink) SINK_ENTRY_EX( 0, __uuidof(_IFun1Events), 1, OnNotify) //0 唯一标识符,用于区别 连接到 事件源的多个客户端 同上 , 1, 事件号 , 发生1号事件 由OnNotify来处理 SINK_ENTRY_EX( 0, __uuidof(_IFun1Events), 2, OnNotify2) //发生2号事件 由OnNotify2来处理 END_SINK_MAP() 并添加方法 STDMETHOD(OnNotify)(void); //事件处理类 STDMETHOD(OnNotify2)(CHAR* lszContent); (3) 连接到COM中的事件容器 添加变量 CComPtr m_Object; //COM 中的事件源对象 添加方法 STDMETHOD(Start)(IUnknown* pSinkThisObject, VARIANT_BOOL* succeeded) { AFX_MANAGE_STATE(AfxGetAppModuleState()); // TODO: 在此添加实现代码 if ( DispEventAdvise(pSinkThisObject) == S_OK ) { m_Object = pSinkThisObject; *succeeded = VARIANT_TRUE; } else { *succeeded = VARIANT_FALSE; } return S_OK; } STDMETHOD(Stop)(void) //解除连接 { AFX_MANAGE_STATE(AfxGetAppModuleState()); DispEventUnadvise(m_Object); return S_OK; } 在其他类中的 使用方法: CComPtr m_FileMonitorSink; CComPtr m_FileMonitor; //COM中导出接口 CoInitialize(0); HRESULT lRt = m_FileMonitorSink.CoCreateInstance( __uuidof(FileMonitorSink) ); lRt = m_FileMonitor.CoCreateInstance(__uuidof(Fun1)); //创建COM接口实例 VARIANT_BOOL succeeded; lRt = m_FileMonitorSink->Start(m_FileMonitor, &succeeded); //把 m_FileMonitorSink 连接到COM中的事件容器上 m_FileMonitor->HelloWorld(); //调用COM接口,接口中触发事件s m_FileMonitorSink->stop(); //从COM接口中解除连接 CoUninitialize(); // ################# CFileMonitorSink 类代码 ################# class ATL_NO_VTABLE CFileMonitorSink : public CComObjectRootEx, public CComCoClass, public IDispatchImpl, public IDispEventImpl { public: CFileMonitorSink() { } DECLARE_REGISTRY_RESOURCEID(IDR_FILEMONITORSINK) BEGIN_COM_MAP(CFileMonitorSink) COM_INTERFACE_ENTRY(IFileMonitorSink) COM_INTERFACE_ENTRY(IDispatch) END_COM_MAP() BEGIN_SINK_MAP(CFileMonitorSink) SINK_ENTRY_EX( 0, __uuidof(_IFun1Events), 1, OnNotify) SINK_ENTRY_EX( 0, __uuidof(_IFun1Events), 2, OnNotify2) END_SINK_MAP() DECLARE_PROTECT_FINAL_CONSTRUCT() HRESULT FinalConstruct() { return S_OK; } void FinalRelease() { } CComPtr m_Object; //COM 事件源对象 public: STDMETHOD(OnNotify)(void); STDMETHOD(Stop)(void); STDMETHOD(Start)(IUnknown* pSinkThisObject, VARIANT_BOOL* succeeded); STDMETHOD(OnNotify2)(CHAR* lszContent); };
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值