通过IMAPIAdviseSink得到更改条目所在的Folder

来源:互联网 发布:淘宝店铺导航条 编辑:程序博客网 时间:2024/05/29 10:25

有时候我们不需要监视整个Outlook的改变

比如我们只需要监视邮件部分

这个时候我们就要判断该消息是否来自邮件部分

我最先想到的是监视EntryID,例如我要监视邮件部分的改变,则将邮件的EntryID记录下来,然后到Notify里面去比对

但是后来发现这样做不十分准确,在繁体中文系统上出问题了

看看代码

 

g_SyncFolderId是保存了ENTRYID的大小和ID两项(g_SyncFolderId.CalendarID , g_SyncFolderId.lIdsize)

 

 

for(int i = 0; i < (int)cNotif; ++i)
 {
   if (lpNotifications[i].info.obj.ulObjType != MAPI_MESSAGE)
  {
   continue;
  }

//如果不是MAPI_Message就不管


  switch (lpNotifications[i].ulEventType)
  {
  case fnevObjectCreated:
   if (lpNotifications[i].info.obj.lpParentID == NULL)

   //删除和move要使用lpOldParentID

   {
    break;
   }
   if (memcmp(lpNotifications[i].info.obj.lpParentID , &g_SyncFolderId.CalendarID , g_SyncFolderId.lIdsize) == 0)
   {
    ...
   }
   break;

 

.............

这是第一种做法

这种做法不是特别可靠,同事提供了另外一种做法:

for(int i = 0; i < (int)cNotif; i++)
 {
 

  if (lpNotifications[i].info.obj.ulObjType != MAPI_MESSAGE)
  {
   continue;
  }

//下面使用一个结构体保存这个ID以及其长度

  SBinary pCurBinary;
  pCurBinary.lpb = (LPBYTE)lpNotifications[i].info.obj.lpParentID;
  pCurBinary.cb = lpNotifications[i].info.obj.cbParentID;

  SBinary pOldBinary;
  pOldBinary.cb = lpNotifications[i].info.obj.cbOldParentID;
  pOldBinary.lpb = (LPBYTE)lpNotifications[i].info.obj.lpOldParentID;


 
  if (pCurBinary.lpb == NULL)
  {
   continue;
  }
  switch (lpNotifications[i].ulEventType)
  {
  case fnevObjectCreated:
   {
    if (IsSpecClassFolder(pCurBinary, LPCALENDAR))

//IsSpecClassFolder(pCurBinary, LPCALENDAR))  

//上面这个函数里面传入了消息带过来的ID,在得到LPMAPISESSION后,可以用这个ID去找到DisplayName

//我在这里要找的是日历里面的项目,所以有#define LPCALENDAR L"IPF.Appointment"
    {
     g_bOutlookChange = TRUE;
     PostMessage(g_hCalendar_MainWnd ,WM_OUTLOOKCHANGE,NULL ,NULL);
    }
   }
 
   break;

 

下面是这个函数的实现,我们假定已经得到LPMAPISESSION m_lpSession

函数内容比较好理解

不再解释了

如果不理解请移步http://blog.csdn.net/yzx0023/

 

BOOL IsSpecClassFolder( SBinary& sb, TCHAR* szClassName )
{
 if (!m_lpSession)
 {
  return FALSE;
 }

 if (!szClassName)
 {
  return FALSE;
 }

 LPSPropValue props=NULL;
 ULONG cValues=0;
 DWORD dwObjType;
 ULONG rgTags[]={ 2, PR_CONTAINER_CLASS ,PR_DISPLAY_NAME};
 LPMAPIFOLDER pFolder;
 if (m_lpSession->OpenEntry(sb.cb, (LPENTRYID)sb.lpb, NULL, MAPI_MODIFY, &dwObjType,(LPUNKNOWN*)&pFolder) != S_OK)
 {
  return FALSE;
 }

 if (pFolder->GetProps((LPSPropTagArray) rgTags, MAPI_UNICODE, &cValues, &props)!=S_OK)
 {
  pFolder->Release();
  return FALSE;
 }
 LPCTSTR TmpszClassName = NULL;
 if (props->Value.lpszW && !::IsBadStringPtr(props->Value.lpszW,(UINT_PTR)-1))
 {
  TmpszClassName =props->Value.lpszW;
 }
 if (_tcscmp(szClassName, TmpszClassName) == 0)
 {
  MAPIFreeBuffer(props);
  pFolder->Release();
  return TRUE;
 }

 MAPIFreeBuffer(props);
 pFolder->Release();
 return FALSE;

//以上方法二由Mars提供

如果各位测试后发现了问题,请联系我.

在XP+outlook测试过

原创粉丝点击