如何获取一个outlook参会人的具体地址呢,我们要用到Outlook::Recipient这个对象,主要是用它的get_Address方法来获得参会人的邮件地址,这个很简单。麻烦的是对于exchange服务器,对exchange服务器来说,如果遇到ad域的情况,那么用get_Address获取到的,就不是正常的邮件地址,而是ad域在exchange中计算地址的字符串,例如/o=Organization/ou=First Administrative Group。
对于上述的ad域情况,又分好几种情况,这主要取决于Outlook::AddressEntry这个对象,AddressEntry有个OlAddressEntryUserType属性,是个枚举类型,定义如下:
enum OlAddressEntryUserType
{
olExchangeUserAddressEntry = 0,
olExchangeDistributionListAddressEntry = 1,
olExchangePublicFolderAddressEntry = 2,
olExchangeAgentAddressEntry = 3,
olExchangeOrganizationAddressEntry = 4,
olExchangeRemoteUserAddressEntry = 5,
olOutlookContactAddressEntry = 10,
olOutlookDistributionListAddressEntry = 11,
olLdapAddressEntry = 20,
olSmtpAddressEntry = 30,
olOtherAddressEntry = 40
};
我们遇到最多的是olExchangeUserAddressEntry和olExchangeDistributionListAddressEntry,这两个可以用对应的api函数get_PrimarySmtpAddress可以获得地址,其它的smtp的不用考虑,统一用get_Address来获取地址;我遇到过一种olExchangeAgentAddressEntry类型的,不能用api来获取,后来反复测试确认,最后用的是GetProperty来拿到地址的。
OlAddressEntryUserType中剩余的类型我没遇到过,估计大部分也可以用get_PrimarySmtpAddress来获取,如果不能,就只能用GetProperty来了,个人觉得这个函数是万能的,只要你能拿到对应属性的tag。
以下是该函数的代码:
void GetRecipientMails(CComQIPtr<Outlook::_AppointmentItem> &spApptmt)
{
CString strMails;
BSTR bstrRcvMail = NULL; // 保存参会人邮箱
// 保存主持人邮箱
CComPtr<Outlook::Recipients> spRcvPns; // 所有参会人
CComPtr<Outlook::Recipient> spRcvPn; // 一个参会人
CComPtr<Outlook::_NameSpace> spNameSpace;
CComPtr<Outlook::Recipient> spCrrentRcvPn; // 当前outlook用户
CComPtr<Outlook::UserProperties> spUserPro;
CString strRcvMails;
spApptmt->get_Recipients(&spRcvPns);
// 这个m_spApplication是个成员变量,表示一个outlook的application句柄,需要从别处获取
// 或者就用_AppointmentItem的get_Application来获取,我这里因为是现成的,所以直接用了
m_spApplication->GetNamespace(L"MAPI",&spNameSpace);
if (NULL != spRcvPns)
{
long lNum = 0; // 参会人个数
spRcvPns->get_Count(&lNum);
m_lMailCount = lNum;
VARIANT vIndex;
vIndex.vt = VT_I4;
for (long i = 1; i <= lNum; i++) // 这vIndex必须从1开始
{
vIndex.lVal = i;
spRcvPns->Item(vIndex,&spRcvPn);
if (NULL != spRcvPn)
{
CComQIPtr<Outlook::AddressEntry> spAddEntry;
CComQIPtr<Outlook::AddressEntry> spAddEntryBuffer;
OlAddressEntryUserType OlAddEntryUserType;
CComQIPtr<Outlook::_ExchangeUser> spExchangeUser;
spRcvPn->get_AddressEntry(&spAddEntry);
// 获取entrytype类型
BSTR bstrType = NULL;
spAddEntry->get_Type(&bstrType);
CString strEntryType(bstrType);
SysFreeString(bstrType);
// OlAddressEntryUserType特性是在2007开始添加的,如果是2003去获取,此处会崩溃退出。
// 非2003版本
if (!m_bOffice2k3OrBefore)
{
// 获取entryusertype类型
spAddEntry->get_AddressEntryUserType(&OlAddEntryUserType);
CString strEntryUserType;
strEntryUserType.Format(L"OlAddEntryUserType is %d", OlAddEntryUserType);
if (!strEntryType.Compare(L"EX"))
{
BSTR bstrEntryID = NULL;
spRcvPn->get_EntryID(&bstrEntryID);
// 作为olExchangeAgentAddressEntry的地址条目
if (OlAddEntryUserType == olExchangeAgentAddressEntry)
{
CComQIPtr<Outlook::_PropertyAccessor> spPropAccessor;
spAddEntry->get_PropertyAccessor(&spPropAccessor);
if (NULL != spPropAccessor)
{
CComVariant varAgentAddress = (L"");
BSTR bstrPropName = SysAllocString(L"http://schemas.microsoft.com/mapi/proptag/0x39FE001E");
HRESULT hr = spPropAccessor->GetProperty(bstrPropName, &varAgentAddress);
if (S_OK == hr)
{
CString strAddress = varAgentAddress.bstrVal;
bstrRcvMail = varAgentAddress.bstrVal;
}
SysFreeString(bstrPropName);
}
}
// 作为非Exchange通讯组列表的地址条目
else if (OlAddEntryUserType != olExchangeDistributionListAddressEntry)
{
spNameSpace->GetAddressEntryFromID(bstrEntryID,&spAddEntryBuffer);
spAddEntryBuffer->GetExchangeUser(&spExchangeUser);
spExchangeUser->get_PrimarySmtpAddress(&bstrRcvMail);
}
// 作为Exchange通讯组列表的地址条目
else
{
spNameSpace->GetAddressEntryFromID(bstrEntryID,&spAddEntryBuffer);
CComQIPtr<Outlook::_ExchangeDistributionList> spExchangeDisList;
spAddEntryBuffer->GetExchangeDistributionList(&spExchangeDisList);
spExchangeDisList->get_PrimarySmtpAddress(&bstrRcvMail);
}
}
else
{
spRcvPn->get_Address(&bstrRcvMail);
}
}
// 2003版本
else
{
spRcvPn->get_Address(&bstrRcvMail);
}
strMails += bstrRcvMail;
strMails += L";";
SysFreeString(bstrRcvMail);
}
spRcvPn = NULL;
}
}
}
|