|
有时候,我们需要关心某条message的改变,需要做出及时的响应,我们当然不能主动的不断的QUERY MESSAGE的状态,好在系统提供了IMAPIAdviseSink,通过它我们可以获得Message移动、改变以及删除等等通知。 首先我们要做的是实现自己的IMAPIAdviseSink接口,原型是: class CAdviseSink : public IMAPIAdviseSink { public: CAdviseSink(); ~CAdviseSink(); MAPIMETHOD_(ULONG,OnNotify)(ULONG cNotif, LPNOTIFICATION lpNotifications); MAPIMETHOD(QueryInterface)(REFIID iid, void** ppvObject); MAPIMETHOD_(ULONG, AddRef)(); MAPIMETHOD_(ULONG, Release)(); private: ULONG m_cRef; }; 我们主要关注的是OnNotify,其他函数我们可以按照标准实现就可以了。我们先来看看OnNotify的一个简单的实现,关键地方我加了注释: ULONG CAdviseSink::OnNotify(ULONG cNotif, LPNOTIFICATION lpNotifications) { // cNotif : 指定有多少个Notification通知 // lpNotifications : Notification数组,个数为cNotif for(int i = 0; i < (int)cNotif; ++i) { //根据不同的Notification类型做不同的处理,类型有很多种,这里只是简单的列出的几种,要获取这些通知和注册AdviseSink密切相关,你需要告诉系统,你关心哪些方面的消息,比如消息的移动,删除等等,系统就会把这些相应的通知发给你,而其他你不关心的,就不会通知到你,这些我们会在后面注册部分讲到。 switch(lpNotifications[i].ulEventType) { case fnevObjectMoved: break; case fnevObjectModified: break; case fnevObjectDeleted: break; default: break; } } return 0; } 接下来是注册AdviseSink,它与每个Account的Store相对应,比如SMS、OUTLOOK等等。以下是注册步骤: A. 获取要监视的Message Store对象,从前面的文章里的我们已经知道如何获得指定的Message Store,这里我们拿SMS的Store来举例。 B. 创建我们自己的CAdviseSink对象 C. 调用IMsgStore::Advise注册 以下是注册示例代码: IMsgStore* pMsgStore = …… //获取SMS Message Store CAdviseSink* g_pAdviseSink = new CAdviseSink(); ULONG m_ulAdviseSink = 0; //用来标识AdviseSink,当取消注册时我们需要用到它。 // uEventMask : 它的作用是告诉系统,我们关心哪些方面的notification,没有列出来的事件在CAdviseSink::OnNotify里面就不会响应到。 ULONG uEventMask = fnevCriticalError | fnevNewMail | fnevObjectCreated | fnevObjectDeleted | fnevObjectModified | fnevObjectMoved | fnevObjectCopied | fnevSearchComplete | fnevTableModified | fnevStatusObjectModified | fnevReservedForMapi | fnevExtended; pMsgStore->Advise(0, NULL, uEventMask, g_pAdviseSink, &m_ulAdviseSink); 这样就注册成功了。 以下是取消注册的示例代码: if(m_ulAdviseSink) { pMsgStore->Unadvise(m_ulAdviseSink); } //记的释放对象 if(g_pAdviseSink) { delete g_pAdviseSink; g_pAdviseSink = NULL; } 前面只是简单的介绍了下AdviseSink的用法,在下一篇里,我会通过一个具体的例子来讲述在平时开发中AdviseSink的用途。 |