通过IMAPIAdviseSink得到更改条目所在的Folder
2009-02-23 15:03
453 查看
有时候我们不需要监视整个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测试过
比如我们只需要监视邮件部分
这个时候我们就要判断该消息是否来自邮件部分
我最先想到的是监视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测试过
相关文章推荐
- [Windows编程] 通过GetModuleHandleEx 得到函数调用者所在的DLL/EXE
- VB6: 通过窗口句柄得到窗口所在程序的名称和路径(实例)
- 得到字符所在的位置,,通过位置得到该位置所在的字符
- 通过GetModuleHandleEx 得到函数调用者所在的DLL/EXE(转)
- 通过GetModuleHandleEx 得到函数调用者所在的DLL/EXE
- Java通过class文件得到所在jar包
- 示例演示通过rowid得到数据块的相关信息(所在对象,文件,数据块)
- 通过GetModuleHandleEx 得到函数调用者所在的DLL/EXE
- 通过uiview 得到所在的viewcontroller
- javascript日期处理-通过一个字符串的日期得到所在周、上周及下周的第一天和最后一天
- [Windows编程] 通过GetModuleHandleEx 得到函数调用者所在的DLL/EXE
- CE MAPI实例讲解 --- IMAPIAdviseSink的一个例子(四)
- 通过某日期得到该日期所在的一周的周一和周日的日期
- [Windows编程] 通过GetModuleHandleEx 得到函数调用者所在的DLL/EXE
- 前端通过获取广域网ip然后根据ip得到所在的城市
- windows mobile 短信拦截IMAPIAdviseSink代码下载
- 如何让你的站点可以通过配置进行更改
- 对于"容量分别为A与B的两个水桶,是否能够通过互相倒水可以得到1~MAX(A,B)所有容量的水"问题的分析
- 通过查询系统表得到纵向的表结构
- DrawTool多重笔之前奏 => 通过InkAnalyzer实现图形识别