小弟最近学习ATL编写Add-in,有2个困惑的地方,请高人指点:1, 创建了多个button,如果第一个button使用了 DispEventAdvise 建立连接,
然后创建了第二个button, 使用 DispEventAdvise 建立连接, 这个时候就会报错,
什么Cookie已经不为空。 我现在的解决办法是在第二个button调用 DispEventAdvise 前,先对前一个button调用
DispEventUnadvise , 这样就不会报错,而且第一个button尽管已经被调用 DispEventUnadvise
不过还是可以响应点击的,这是为什么?
2, 有多个事件源对应一个接收函数,而这个函数却一个参数也没有,比如很多控件的Close事件,(例如_Inspector的Close事件)
如果知道到底是哪个事件源发出的消息?有没有通用的方法?
请高人赐教!
谢谢!
然后创建了第二个button, 使用 DispEventAdvise 建立连接, 这个时候就会报错,
什么Cookie已经不为空。 我现在的解决办法是在第二个button调用 DispEventAdvise 前,先对前一个button调用
DispEventUnadvise , 这样就不会报错,而且第一个button尽管已经被调用 DispEventUnadvise
不过还是可以响应点击的,这是为什么?
2, 有多个事件源对应一个接收函数,而这个函数却一个参数也没有,比如很多控件的Close事件,(例如_Inspector的Close事件)
如果知道到底是哪个事件源发出的消息?有没有通用的方法?
请高人赐教!
谢谢!
建议你看看IDispEventSimpleImpl模板的原代码,在\MICROSOFT VISUAL STUDIO\VC98\ATL\Include\ATLCOM.H文件里。
其实学习ATL开发COM组件,最好看看微软对ATL的封装,在\MICROSOFT VISUAL STUDIO\VC98\ATL目录下可以找到所有ATL的封装代码,如能结合<<深入解析ATL>>那本书更好理解。
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CFPAnt, &CLSID_FPAnt>,
public ISupportErrorInfo,
public IConnectionPointContainerImpl<CFPAnt>,
public IDispatchImpl<IFPAnt, &IID_IFPAnt, &LIBID_OFFICEANTLib>,
public IDispatchImpl<AddInDesignerObjects::_IDTExtensibility2, &AddInDesignerObjects::IID__IDTExtensibility2, &AddInDesignerObjects::LIBID_AddInDesignerObjects>,
public IDispEventSimpleImpl<1,CFPAnt,&__uuidof(Office::_CommandBarButtonEvents)>,
public IDispEventSimpleImpl<2,CFPAnt,&__uuidof(Office::_CommandBarButtonEvents)>,
public IDispEventSimpleImpl<3,CFPAnt,&__uuidof(Office::_CommandBarButtonEvents)>
{
//type defination to avoid compilation 'ambigous call' errors
typedef IDispEventSimpleImpl</*nID =*/ 1,
CFPAnt, &__uuidof(Office::_CommandBarButtonEvents)> ExportCHMEvents;
typedef IDispEventSimpleImpl</*nID =*/ 2,
CFPAnt, &__uuidof(Office::_CommandBarButtonEvents)> ImportCHMEvents;
typedef IDispEventSimpleImpl</*nID =*/ 3,
CFPAnt, &__uuidof(Office::_CommandBarButtonEvents)> OptionEvents;
CFPAnt()
{
AfxSetResourceHandle(_Module.GetModuleInstance());
USES_CONVERSION;
UINT nResID[CommandIndexMax]={IDS_EXPORT_CHM,IDS_IMPORT_CHM,IDS_OPTION};
CString str,strsub;
for(int i=0;i<CommandIndexMax;i++)
{
str.LoadString(nResID[i]);
AfxExtractSubString(strsub,str,0,_T('\n'));
m_bstrCaption[i] =T2OLE((LPCTSTR)strsub);
AfxExtractSubString(strsub,str,1,_T('\n'));
m_bstrTipText[i] =T2OLE((LPCTSTR)strsub);
AfxExtractSubString(strsub,str,2,_T('\n'));
m_bstrTag[i] =T2OLE((LPCTSTR)strsub); }
}
STDMETHOD(OnDisconnection)(AddInDesignerObjects::ext_DisconnectMode RemoveMode, SAFEARRAY * * custom)
{
ExportCHMEvents::DispEventUnadvise((IDispatch*)m_spCmdButtons[CommandIndexExportCHM]);
ImportCHMEvents::DispEventUnadvise((IDispatch*)m_spCmdButtons[CommandIndexImportCHM]);
OptionEvents::DispEventUnadvise((IDispatch*)m_spCmdButtons[CommandIndexOption]);
for(int i=0;i<CommandIndexMax;i++)
{
m_spCmdButtons[i].Release();
}
m_spApp.Release();
return S_OK;
}
BEGIN_SINK_MAP(CFPAnt)
SINK_ENTRY_INFO(1, __uuidof(Office::_CommandBarButtonEvents),
/*dispid*/0x01, OnClickButtonExportCHM, &OnClickButtonInfo)
SINK_ENTRY_INFO(2, __uuidof(Office::_CommandBarButtonEvents),
/*dispid*/0x01, OnClickButtonImportCHM, &OnClickButtonInfo)
SINK_ENTRY_INFO(3, __uuidof(Office::_CommandBarButtonEvents),
/*dispid*/0x01, OnClickButtonOption, &OnClickButtonInfo)
END_SINK_MAP()
如果打开多个 inspector ,就有多个button。建立第一个button的时候,使用 DispEventAdvise 给button建立接收命令的连接
建立第二个button的时候,我先使用DispEventUnadvise 给第一个button断开连接,然后给第二个button用DispEventAdvise 建立事件连接。
这个时候,虽然第一个button看似已经断开连接,不过点击那个button,还是可以接受到消息的。请问这是为什么?ps ATL的书我一本都买不到,感觉ATL是不是过时了,我才刚刚开始学习!