如何设置收件人信息
发布网友
发布时间:2022-05-07 04:46
我来回答
共2个回答
热心网友
时间:2023-10-15 22:30
发件人和收件人是邮件和消息很常用的几个属性之一,关于发件人的设置和获取是很简单的,只需要处理PR_SENDER_EMAIL_ADDRESS属性即可,下面主要讲述的收件人的设置和获取。
MAPI收件人结构如图(摘自MSDN):
每一个Entry代表了一个收件人信息组,每个信息组又可以有多项信息组成,举个例子,下面的代码代表了一个收件人的信息:
aEntries[0].rgPropVals[0].ulPropTag = PR_RECIPIENT_TYPE; //类型,MAPI_TO代表是设置到TO字段上的,相应的还有MAPI_CC和MAPI_BCC。
aEntries[0].rgPropVals[0].Value.ul = MAPI_TO;
aEntries[0].rgPropVals[1].ulPropTag = PR_ADDRTYPE; //设置地址类型,一般为SMTP
aEntries[0].rgPropVals[1].Value.LPSZ = _T("SMTP");
aEntries[0].rgPropVals[2].ulPropTag = PR_EMAIL_ADDRESS; //收件人地址
aEntries[0].rgPropVals[2].Value.LPSZ = _T("1234567");
设置收件人是通过IMessage:: ModifyRecipients来实现的,以下的代码举例说明了如何设置TO、CC和BCC属性:
INT nRecipientCount = 3; //表示有3个联系人信息
INT nListBufSize = CbNewADRLIST(nRecipientCount); //计算3个联系人需要的存储空间
LPADRLIST pAddressList = NULL;
MAPIAllocateBuffer(nListBufSize, (LPVOID FAR *)&pAddressList)); //分配空间
memset(pAddressList, 0, nBufSize);
pAddressList->cEntries = 3; //表明一共有3个联系人信息
//设置To
INT nCurIndex = 0;
MAPIAllocateBuffer(sizeof(SPropValue) * 3, (LPVOID FAR *)&pAddressList->aEntries[nCurIndex].rgPropVals)); //分配空间 memset(pAddressList->aEntries[nCurIndex].rgPropVals, 0, sizeof(SPropValue) * 3);
pAddressList->aEntries[nCurIndex].rgPropVals[0].ulPropTag = PR_RECIPIENT_TYPE;
pAddressList->aEntries[nCurIndex].rgPropVals[0].Value.ul = MAPI_TO; //表明是写到To
pAddressList->aEntries[nCurIndex].rgPropVals[1].ulPropTag = PR_ADDRTYPE;
pAddressList->aEntries[nCurIndex].rgPropVals[1].Value.LPSZ = _T("SMTP");
pAddressList->aEntries[nCurIndex].rgPropVals[2].ulPropTag = PR_EMAIL_ADDRESS;
pAddressList->aEntries[nCurIndex].rgPropVals[2].Value.LPSZ = _T("1234567");
pAddressList->aEntries[nCurIndex].cValues = 3; //表明改联系人有3个属性要设置
//同上,现在设置CC
nCurIndex = 1;
MAPIAllocateBuffer(sizeof(SPropValue) * 3, (LPVOID FAR *)&pAddressList->aEntries[nCurIndex].rgPropVals)); //分配空间 memset(pAddressList->aEntries[nCurIndex].rgPropVals, 0, sizeof(SPropValue) * 3);
pAddressList->aEntries[nCurIndex].rgPropVals[0].ulPropTag = PR_RECIPIENT_TYPE;
pAddressList->aEntries[nCurIndex].rgPropVals[0].Value.ul = MAPI_CC; //表明是写到CC
pAddressList->aEntries[nCurIndex].rgPropVals[1].ulPropTag = PR_ADDRTYPE;
pAddressList->aEntries[nCurIndex].rgPropVals[1].Value.LPSZ = _T("SMTP");
pAddressList->aEntries[nCurIndex].rgPropVals[2].ulPropTag = PR_EMAIL_ADDRESS;
pAddressList->aEntries[nCurIndex].rgPropVals[2].Value.LPSZ = _T("7654321");
pAddressList->aEntries[nCurIndex].cValues = 3; //表明改联系人有3个属性要设置
//同上,现在设置BCC
nCurIndex = 2;
MAPIAllocateBuffer(sizeof(SPropValue) * 3, (LPVOID FAR *)&pAddressList->aEntries[nCurIndex].rgPropVals)); //分配空间 memset(pAddressList->aEntries[nCurIndex].rgPropVals, 0, sizeof(SPropValue) * 3);
pAddressList->aEntries[nCurIndex].rgPropVals[0].ulPropTag = PR_RECIPIENT_TYPE;
pAddressList->aEntries[nCurIndex].rgPropVals[0].Value.ul = MAPI_BCC; //表明是写到CC
pAddressList->aEntries[nCurIndex].rgPropVals[1].ulPropTag = PR_ADDRTYPE;
pAddressList->aEntries[nCurIndex].rgPropVals[1].Value.LPSZ = _T("SMTP");
pAddressList->aEntries[nCurIndex].rgPropVals[2].ulPropTag = PR_EMAIL_ADDRESS;
pAddressList->aEntries[nCurIndex].rgPropVals[2].Value.LPSZ = _T("88888888");
pAddressList->aEntries[nCurIndex].cValues = 3; //表明改联系人有3个属性要设置
//调用ModifyRecipients添加联系人,完了记的释放申请的内存,pMsg为你想操作的Message的对象实例,关于如何获取可以参考以前的文章。 pMsg->ModifyRecipients(MODRECIP_ADD, pAddressList)
for(INT i = 0; i < nRecipientCount; i++)
MAPIFreeBuffer(pAddressList->aEntries[i].rgPropVals);
MAPIFreeBuffer(pAddressList);
(六)如何获取收件人信息
接下来开始讲讲如何获取联系人信息,它与设置信息比较相近,以下举例说明:
IMAPITable* pTable = NULL;
//通过GetRecipientTable获取联系人信息列表
pMsg->GetRecipientTable( NULL, &pTable );
LPADRLIST pRecipentRows = NULL;
//获取每个联系人信息,这里的做法可以看出和枚举Folder等都相似
while(!FAILED(hr = pTable->QueryRows(1, 0, (LPSRowSet*)&pRecipentRows)))
{
if( pRecipentRows->cEntries == 0 )
break;
for(int n = 0; n < pRecipentRows->cEntries; n++ )
{
//每个Entry代表一个联系人信息,每个联系人信息又有多个属性组成
for(int i = 0; i < pRecipentRows->aEntries[n].cValues ; i++)
{
//判断如果是PR_EMAIL_ADDRESS属性,那么就找到了联系人地址
if( PR_EMAIL_ADDRESS == pRecipentRows->aEntries[n].rgPropVals[i].ulPropTag )
{
//联系人地址
CString strContact = pRecipentRows->aEntries[n].rgPropVals[i].Value.lpszW;
//后续操作
}
}
}
//完了记得要释放pRecipentRows和它里面的内容,释放方法见上一篇关于设置联系人信息的介绍。
……
}
上面的代码片段只简单演示了获取联系人信息的基本操作步骤,通过这个例子也可以熟悉IMAPITable的用法,MAPI里面还是有很多地方会用到这个接口,用处还是比较大的。
(七)设置Message附件
本篇主要介绍如何设置Message的附件内容,下一篇会介绍如何获取附件。长话短说,下面的例子将完成如下的事情:
1) 准备工作,在Temp目录下先放上几张图片,在这个例子里面,我在Temp目录放两张JPG图片,1.jpg,2.jpg,我将把这两张图片放到一个Message里面,生成两个附件。
2) 在Outlook草稿箱里面创建出一条新的Message。
3) 为Message添加附件。
如何在Outlook草稿箱里面创建一条新的Message,我想通过前面的文章已经解释清楚了,这里就不罗嗦了,以下假设我们已经获取了IMessage*对象指针。首先提出一个帮助函数:MAPIHelp_AddAttachment,该函数作用是为指定的Message添加指定文件作为附件,定义如下:
BOOL MAPIHelp_AddAttachment( IMessage* pMsg, LPCTSTR szFilePath, LPCTSTR szFileName );
pMsg : Message目标对象指针
szFilePath : 需要作为附件添加的文件全路径
szFileName : 需要作为附件添加的文件名称,作为附件的名称
以下是函数具体实现:
BOOL MAPIHelp_AddAttachment( IMessage* pMsg, LPCTSTR szFilePath, LPCTSTR szFileName )
{
if( NULL == pMsg || NULL == szFilePath )
return FALSE;
BOOL bRet = FALSE;
ULONG ulAttachNum = 0;
LPATTACH pAttach = NULL;
IStream* pStream = NULL;
HANDLE hFile = NULL;
SPropValue rgpropsTo[1] = {0};
DWORD dwChunkSize = 4096;
DWORD dwSizeRead = 0;
//预备BUFFER,用来读写文件内容
LPBYTE pData = new BYTE[dwChunkSize];
if( NULL == pData )
return FALSE;
//创建附件,返回IAttach对象,每个IAttach对象对应于一个附件, ulAttachNum是这个对象的标识,我们可以通过IMessage:: OpenAttach时传入这个ID来读取这个附件,具体的方法会在下篇时介绍。
if( FAILED(pMsg->CreateAttach( NULL, NULL, &ulAttachNum, &pAttach )) )
goto Exit;
//设置附件名称
rgpropsTo[0].ulPropTag = PR_ATTACH_FILENAME;
rgpropsTo[0].Value.lpszW = (LPTSTR)szFileName;
if( FAILED(pAttach->SetProps(1, rgpropsTo, NULL)) )
goto Exit;
//通过OpenProperty获取IStream对象,有了IStream对象,我们就可以读写数据。对于IAttach:: OpenProperty,CE上只支持PR_ATTACH_DATA_BIN属性。
if( FAILED(pAttach->OpenProperty( PR_ATTACH_DATA_BIN, NULL, NULL, MAPI_MODIFY, (LPUNKNOWN *)&pStream )) )
goto Exit;
//下面部分是文件读写部分,从原始文件里读出数据,再写到附件里面去
hFile = ::CreateFile( szFilePath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
if( INVALID_HANDLE_VALUE == hFile )
goto Exit;
while( ReadFile( hFile, pData, dwChunkSize, &dwSizeRead, NULL ) )
{
if( 0 >= dwSizeRead )
break;
pStream->Write( pData, dwSizeRead, &dwSizeRead );
}
bRet = TRUE;
Exit:
//完毕以后记的释放获取的对象。
RELEASE_OBJ(pStream);
RELEASE_OBJ(pAttach);
DELETE_OBJ(pData);
if( INVALID_HANDLE_VALUE != hFile )
::CloseHandle( hFile );
return bRet;
}
有了上面的帮助函数,当我们想为一条Message添加附件时,可以按照如下调用:
MAPIHelp_AddAttachment( pMsg, _T("//Temp//1.jpg"), _T("1.jpg") );
MAPIHelp_AddAttachment( pMsg, _T("//Temp//2.jpg"), _T("2.jpg") );
(八)读取Message附件
在上一篇里面讲述了如何为一条MESSAGE设置附件,下面将继续关于附件的话题,利用上一个例子,我们接下来来看看如何获取一条MESSAGE的附件信息。下面将通过两个帮助函数来完成:
BOOL MAPIHelp_SaveAttachFile( LPATTACH pAttach, LPCTSTR szFile )
作用:读取单个附件文件内容,并保存到指定位置
pAttach: 附件对象
szFile: 保存文件名
BOOL MAPIHelp_GetAttachment( IMessage* pMsg, LPCTSTR szFilePath )
作用:获取一条Message的全部附件,并保存到指定目录下
pMsg: 目标消息对象
szFilePath: 目标目录
下面来看看具体实现:
BOOL MAPIHelp_SaveAttachFile( LPATTACH pAttach, LPCTSTR szFile )
{
if( NULL == pAttach || NULL == szFile )
return FALSE;
HANDLE hFile = INVALID_HANDLE_VALUE;
IStream* pstmAttachment = NULL;
char * pBuffer = NULL;
int i = 0;
DWORD dwWrite = 0;
BOOL bRet = FALSE;
ULONG ulRead = 0;
//打开附件,获取IStream对象,用于获取文件内容,根据MSDN的解释,这里只支持PR_ATTACH_DATA_BIN属性。
if(FAILED(pAttach->OpenProperty (PR_ATTACH_DATA_BIN, NULL, STGM_READ, MAPI_MODIFY,
reinterpret_cast <IUnknown **> (&pstmAttachment))))
{
goto EXIT;
}
//创建目标文件
hFile = ::CreateFile(szFile, GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if(INVALID_HANDLE_VALUE == hFile)
{
goto EXIT;
热心网友
时间:2023-10-15 22:30
什么东西上的收件人信息啊,说清楚点啊,要不然怎么说方法啊。
热心网友
时间:2023-10-15 22:30
发件人和收件人是邮件和消息很常用的几个属性之一,关于发件人的设置和获取是很简单的,只需要处理PR_SENDER_EMAIL_ADDRESS属性即可,下面主要讲述的收件人的设置和获取。
MAPI收件人结构如图(摘自MSDN):
每一个Entry代表了一个收件人信息组,每个信息组又可以有多项信息组成,举个例子,下面的代码代表了一个收件人的信息:
aEntries[0].rgPropVals[0].ulPropTag = PR_RECIPIENT_TYPE; //类型,MAPI_TO代表是设置到TO字段上的,相应的还有MAPI_CC和MAPI_BCC。
aEntries[0].rgPropVals[0].Value.ul = MAPI_TO;
aEntries[0].rgPropVals[1].ulPropTag = PR_ADDRTYPE; //设置地址类型,一般为SMTP
aEntries[0].rgPropVals[1].Value.LPSZ = _T("SMTP");
aEntries[0].rgPropVals[2].ulPropTag = PR_EMAIL_ADDRESS; //收件人地址
aEntries[0].rgPropVals[2].Value.LPSZ = _T("1234567");
设置收件人是通过IMessage:: ModifyRecipients来实现的,以下的代码举例说明了如何设置TO、CC和BCC属性:
INT nRecipientCount = 3; //表示有3个联系人信息
INT nListBufSize = CbNewADRLIST(nRecipientCount); //计算3个联系人需要的存储空间
LPADRLIST pAddressList = NULL;
MAPIAllocateBuffer(nListBufSize, (LPVOID FAR *)&pAddressList)); //分配空间
memset(pAddressList, 0, nBufSize);
pAddressList->cEntries = 3; //表明一共有3个联系人信息
//设置To
INT nCurIndex = 0;
MAPIAllocateBuffer(sizeof(SPropValue) * 3, (LPVOID FAR *)&pAddressList->aEntries[nCurIndex].rgPropVals)); //分配空间 memset(pAddressList->aEntries[nCurIndex].rgPropVals, 0, sizeof(SPropValue) * 3);
pAddressList->aEntries[nCurIndex].rgPropVals[0].ulPropTag = PR_RECIPIENT_TYPE;
pAddressList->aEntries[nCurIndex].rgPropVals[0].Value.ul = MAPI_TO; //表明是写到To
pAddressList->aEntries[nCurIndex].rgPropVals[1].ulPropTag = PR_ADDRTYPE;
pAddressList->aEntries[nCurIndex].rgPropVals[1].Value.LPSZ = _T("SMTP");
pAddressList->aEntries[nCurIndex].rgPropVals[2].ulPropTag = PR_EMAIL_ADDRESS;
pAddressList->aEntries[nCurIndex].rgPropVals[2].Value.LPSZ = _T("1234567");
pAddressList->aEntries[nCurIndex].cValues = 3; //表明改联系人有3个属性要设置
//同上,现在设置CC
nCurIndex = 1;
MAPIAllocateBuffer(sizeof(SPropValue) * 3, (LPVOID FAR *)&pAddressList->aEntries[nCurIndex].rgPropVals)); //分配空间 memset(pAddressList->aEntries[nCurIndex].rgPropVals, 0, sizeof(SPropValue) * 3);
pAddressList->aEntries[nCurIndex].rgPropVals[0].ulPropTag = PR_RECIPIENT_TYPE;
pAddressList->aEntries[nCurIndex].rgPropVals[0].Value.ul = MAPI_CC; //表明是写到CC
pAddressList->aEntries[nCurIndex].rgPropVals[1].ulPropTag = PR_ADDRTYPE;
pAddressList->aEntries[nCurIndex].rgPropVals[1].Value.LPSZ = _T("SMTP");
pAddressList->aEntries[nCurIndex].rgPropVals[2].ulPropTag = PR_EMAIL_ADDRESS;
pAddressList->aEntries[nCurIndex].rgPropVals[2].Value.LPSZ = _T("7654321");
pAddressList->aEntries[nCurIndex].cValues = 3; //表明改联系人有3个属性要设置
//同上,现在设置BCC
nCurIndex = 2;
MAPIAllocateBuffer(sizeof(SPropValue) * 3, (LPVOID FAR *)&pAddressList->aEntries[nCurIndex].rgPropVals)); //分配空间 memset(pAddressList->aEntries[nCurIndex].rgPropVals, 0, sizeof(SPropValue) * 3);
pAddressList->aEntries[nCurIndex].rgPropVals[0].ulPropTag = PR_RECIPIENT_TYPE;
pAddressList->aEntries[nCurIndex].rgPropVals[0].Value.ul = MAPI_BCC; //表明是写到CC
pAddressList->aEntries[nCurIndex].rgPropVals[1].ulPropTag = PR_ADDRTYPE;
pAddressList->aEntries[nCurIndex].rgPropVals[1].Value.LPSZ = _T("SMTP");
pAddressList->aEntries[nCurIndex].rgPropVals[2].ulPropTag = PR_EMAIL_ADDRESS;
pAddressList->aEntries[nCurIndex].rgPropVals[2].Value.LPSZ = _T("88888888");
pAddressList->aEntries[nCurIndex].cValues = 3; //表明改联系人有3个属性要设置
//调用ModifyRecipients添加联系人,完了记的释放申请的内存,pMsg为你想操作的Message的对象实例,关于如何获取可以参考以前的文章。 pMsg->ModifyRecipients(MODRECIP_ADD, pAddressList)
for(INT i = 0; i < nRecipientCount; i++)
MAPIFreeBuffer(pAddressList->aEntries[i].rgPropVals);
MAPIFreeBuffer(pAddressList);
(六)如何获取收件人信息
接下来开始讲讲如何获取联系人信息,它与设置信息比较相近,以下举例说明:
IMAPITable* pTable = NULL;
//通过GetRecipientTable获取联系人信息列表
pMsg->GetRecipientTable( NULL, &pTable );
LPADRLIST pRecipentRows = NULL;
//获取每个联系人信息,这里的做法可以看出和枚举Folder等都相似
while(!FAILED(hr = pTable->QueryRows(1, 0, (LPSRowSet*)&pRecipentRows)))
{
if( pRecipentRows->cEntries == 0 )
break;
for(int n = 0; n < pRecipentRows->cEntries; n++ )
{
//每个Entry代表一个联系人信息,每个联系人信息又有多个属性组成
for(int i = 0; i < pRecipentRows->aEntries[n].cValues ; i++)
{
//判断如果是PR_EMAIL_ADDRESS属性,那么就找到了联系人地址
if( PR_EMAIL_ADDRESS == pRecipentRows->aEntries[n].rgPropVals[i].ulPropTag )
{
//联系人地址
CString strContact = pRecipentRows->aEntries[n].rgPropVals[i].Value.lpszW;
//后续操作
}
}
}
//完了记得要释放pRecipentRows和它里面的内容,释放方法见上一篇关于设置联系人信息的介绍。
……
}
上面的代码片段只简单演示了获取联系人信息的基本操作步骤,通过这个例子也可以熟悉IMAPITable的用法,MAPI里面还是有很多地方会用到这个接口,用处还是比较大的。
(七)设置Message附件
本篇主要介绍如何设置Message的附件内容,下一篇会介绍如何获取附件。长话短说,下面的例子将完成如下的事情:
1) 准备工作,在Temp目录下先放上几张图片,在这个例子里面,我在Temp目录放两张JPG图片,1.jpg,2.jpg,我将把这两张图片放到一个Message里面,生成两个附件。
2) 在Outlook草稿箱里面创建出一条新的Message。
3) 为Message添加附件。
如何在Outlook草稿箱里面创建一条新的Message,我想通过前面的文章已经解释清楚了,这里就不罗嗦了,以下假设我们已经获取了IMessage*对象指针。首先提出一个帮助函数:MAPIHelp_AddAttachment,该函数作用是为指定的Message添加指定文件作为附件,定义如下:
BOOL MAPIHelp_AddAttachment( IMessage* pMsg, LPCTSTR szFilePath, LPCTSTR szFileName );
pMsg : Message目标对象指针
szFilePath : 需要作为附件添加的文件全路径
szFileName : 需要作为附件添加的文件名称,作为附件的名称
以下是函数具体实现:
BOOL MAPIHelp_AddAttachment( IMessage* pMsg, LPCTSTR szFilePath, LPCTSTR szFileName )
{
if( NULL == pMsg || NULL == szFilePath )
return FALSE;
BOOL bRet = FALSE;
ULONG ulAttachNum = 0;
LPATTACH pAttach = NULL;
IStream* pStream = NULL;
HANDLE hFile = NULL;
SPropValue rgpropsTo[1] = {0};
DWORD dwChunkSize = 4096;
DWORD dwSizeRead = 0;
//预备BUFFER,用来读写文件内容
LPBYTE pData = new BYTE[dwChunkSize];
if( NULL == pData )
return FALSE;
//创建附件,返回IAttach对象,每个IAttach对象对应于一个附件, ulAttachNum是这个对象的标识,我们可以通过IMessage:: OpenAttach时传入这个ID来读取这个附件,具体的方法会在下篇时介绍。
if( FAILED(pMsg->CreateAttach( NULL, NULL, &ulAttachNum, &pAttach )) )
goto Exit;
//设置附件名称
rgpropsTo[0].ulPropTag = PR_ATTACH_FILENAME;
rgpropsTo[0].Value.lpszW = (LPTSTR)szFileName;
if( FAILED(pAttach->SetProps(1, rgpropsTo, NULL)) )
goto Exit;
//通过OpenProperty获取IStream对象,有了IStream对象,我们就可以读写数据。对于IAttach:: OpenProperty,CE上只支持PR_ATTACH_DATA_BIN属性。
if( FAILED(pAttach->OpenProperty( PR_ATTACH_DATA_BIN, NULL, NULL, MAPI_MODIFY, (LPUNKNOWN *)&pStream )) )
goto Exit;
//下面部分是文件读写部分,从原始文件里读出数据,再写到附件里面去
hFile = ::CreateFile( szFilePath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
if( INVALID_HANDLE_VALUE == hFile )
goto Exit;
while( ReadFile( hFile, pData, dwChunkSize, &dwSizeRead, NULL ) )
{
if( 0 >= dwSizeRead )
break;
pStream->Write( pData, dwSizeRead, &dwSizeRead );
}
bRet = TRUE;
Exit:
//完毕以后记的释放获取的对象。
RELEASE_OBJ(pStream);
RELEASE_OBJ(pAttach);
DELETE_OBJ(pData);
if( INVALID_HANDLE_VALUE != hFile )
::CloseHandle( hFile );
return bRet;
}
有了上面的帮助函数,当我们想为一条Message添加附件时,可以按照如下调用:
MAPIHelp_AddAttachment( pMsg, _T("//Temp//1.jpg"), _T("1.jpg") );
MAPIHelp_AddAttachment( pMsg, _T("//Temp//2.jpg"), _T("2.jpg") );
(八)读取Message附件
在上一篇里面讲述了如何为一条MESSAGE设置附件,下面将继续关于附件的话题,利用上一个例子,我们接下来来看看如何获取一条MESSAGE的附件信息。下面将通过两个帮助函数来完成:
BOOL MAPIHelp_SaveAttachFile( LPATTACH pAttach, LPCTSTR szFile )
作用:读取单个附件文件内容,并保存到指定位置
pAttach: 附件对象
szFile: 保存文件名
BOOL MAPIHelp_GetAttachment( IMessage* pMsg, LPCTSTR szFilePath )
作用:获取一条Message的全部附件,并保存到指定目录下
pMsg: 目标消息对象
szFilePath: 目标目录
下面来看看具体实现:
BOOL MAPIHelp_SaveAttachFile( LPATTACH pAttach, LPCTSTR szFile )
{
if( NULL == pAttach || NULL == szFile )
return FALSE;
HANDLE hFile = INVALID_HANDLE_VALUE;
IStream* pstmAttachment = NULL;
char * pBuffer = NULL;
int i = 0;
DWORD dwWrite = 0;
BOOL bRet = FALSE;
ULONG ulRead = 0;
//打开附件,获取IStream对象,用于获取文件内容,根据MSDN的解释,这里只支持PR_ATTACH_DATA_BIN属性。
if(FAILED(pAttach->OpenProperty (PR_ATTACH_DATA_BIN, NULL, STGM_READ, MAPI_MODIFY,
reinterpret_cast <IUnknown **> (&pstmAttachment))))
{
goto EXIT;
}
//创建目标文件
hFile = ::CreateFile(szFile, GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if(INVALID_HANDLE_VALUE == hFile)
{
goto EXIT;
热心网友
时间:2023-10-15 22:30
什么东西上的收件人信息啊,说清楚点啊,要不然怎么说方法啊。
热心网友
时间:2023-10-15 22:30
发件人和收件人是邮件和消息很常用的几个属性之一,关于发件人的设置和获取是很简单的,只需要处理PR_SENDER_EMAIL_ADDRESS属性即可,下面主要讲述的收件人的设置和获取。
MAPI收件人结构如图(摘自MSDN):
每一个Entry代表了一个收件人信息组,每个信息组又可以有多项信息组成,举个例子,下面的代码代表了一个收件人的信息:
aEntries[0].rgPropVals[0].ulPropTag = PR_RECIPIENT_TYPE; //类型,MAPI_TO代表是设置到TO字段上的,相应的还有MAPI_CC和MAPI_BCC。
aEntries[0].rgPropVals[0].Value.ul = MAPI_TO;
aEntries[0].rgPropVals[1].ulPropTag = PR_ADDRTYPE; //设置地址类型,一般为SMTP
aEntries[0].rgPropVals[1].Value.LPSZ = _T("SMTP");
aEntries[0].rgPropVals[2].ulPropTag = PR_EMAIL_ADDRESS; //收件人地址
aEntries[0].rgPropVals[2].Value.LPSZ = _T("1234567");
设置收件人是通过IMessage:: ModifyRecipients来实现的,以下的代码举例说明了如何设置TO、CC和BCC属性:
INT nRecipientCount = 3; //表示有3个联系人信息
INT nListBufSize = CbNewADRLIST(nRecipientCount); //计算3个联系人需要的存储空间
LPADRLIST pAddressList = NULL;
MAPIAllocateBuffer(nListBufSize, (LPVOID FAR *)&pAddressList)); //分配空间
memset(pAddressList, 0, nBufSize);
pAddressList->cEntries = 3; //表明一共有3个联系人信息
//设置To
INT nCurIndex = 0;
MAPIAllocateBuffer(sizeof(SPropValue) * 3, (LPVOID FAR *)&pAddressList->aEntries[nCurIndex].rgPropVals)); //分配空间 memset(pAddressList->aEntries[nCurIndex].rgPropVals, 0, sizeof(SPropValue) * 3);
pAddressList->aEntries[nCurIndex].rgPropVals[0].ulPropTag = PR_RECIPIENT_TYPE;
pAddressList->aEntries[nCurIndex].rgPropVals[0].Value.ul = MAPI_TO; //表明是写到To
pAddressList->aEntries[nCurIndex].rgPropVals[1].ulPropTag = PR_ADDRTYPE;
pAddressList->aEntries[nCurIndex].rgPropVals[1].Value.LPSZ = _T("SMTP");
pAddressList->aEntries[nCurIndex].rgPropVals[2].ulPropTag = PR_EMAIL_ADDRESS;
pAddressList->aEntries[nCurIndex].rgPropVals[2].Value.LPSZ = _T("1234567");
pAddressList->aEntries[nCurIndex].cValues = 3; //表明改联系人有3个属性要设置
//同上,现在设置CC
nCurIndex = 1;
MAPIAllocateBuffer(sizeof(SPropValue) * 3, (LPVOID FAR *)&pAddressList->aEntries[nCurIndex].rgPropVals)); //分配空间 memset(pAddressList->aEntries[nCurIndex].rgPropVals, 0, sizeof(SPropValue) * 3);
pAddressList->aEntries[nCurIndex].rgPropVals[0].ulPropTag = PR_RECIPIENT_TYPE;
pAddressList->aEntries[nCurIndex].rgPropVals[0].Value.ul = MAPI_CC; //表明是写到CC
pAddressList->aEntries[nCurIndex].rgPropVals[1].ulPropTag = PR_ADDRTYPE;
pAddressList->aEntries[nCurIndex].rgPropVals[1].Value.LPSZ = _T("SMTP");
pAddressList->aEntries[nCurIndex].rgPropVals[2].ulPropTag = PR_EMAIL_ADDRESS;
pAddressList->aEntries[nCurIndex].rgPropVals[2].Value.LPSZ = _T("7654321");
pAddressList->aEntries[nCurIndex].cValues = 3; //表明改联系人有3个属性要设置
//同上,现在设置BCC
nCurIndex = 2;
MAPIAllocateBuffer(sizeof(SPropValue) * 3, (LPVOID FAR *)&pAddressList->aEntries[nCurIndex].rgPropVals)); //分配空间 memset(pAddressList->aEntries[nCurIndex].rgPropVals, 0, sizeof(SPropValue) * 3);
pAddressList->aEntries[nCurIndex].rgPropVals[0].ulPropTag = PR_RECIPIENT_TYPE;
pAddressList->aEntries[nCurIndex].rgPropVals[0].Value.ul = MAPI_BCC; //表明是写到CC
pAddressList->aEntries[nCurIndex].rgPropVals[1].ulPropTag = PR_ADDRTYPE;
pAddressList->aEntries[nCurIndex].rgPropVals[1].Value.LPSZ = _T("SMTP");
pAddressList->aEntries[nCurIndex].rgPropVals[2].ulPropTag = PR_EMAIL_ADDRESS;
pAddressList->aEntries[nCurIndex].rgPropVals[2].Value.LPSZ = _T("88888888");
pAddressList->aEntries[nCurIndex].cValues = 3; //表明改联系人有3个属性要设置
//调用ModifyRecipients添加联系人,完了记的释放申请的内存,pMsg为你想操作的Message的对象实例,关于如何获取可以参考以前的文章。 pMsg->ModifyRecipients(MODRECIP_ADD, pAddressList)
for(INT i = 0; i < nRecipientCount; i++)
MAPIFreeBuffer(pAddressList->aEntries[i].rgPropVals);
MAPIFreeBuffer(pAddressList);
(六)如何获取收件人信息
接下来开始讲讲如何获取联系人信息,它与设置信息比较相近,以下举例说明:
IMAPITable* pTable = NULL;
//通过GetRecipientTable获取联系人信息列表
pMsg->GetRecipientTable( NULL, &pTable );
LPADRLIST pRecipentRows = NULL;
//获取每个联系人信息,这里的做法可以看出和枚举Folder等都相似
while(!FAILED(hr = pTable->QueryRows(1, 0, (LPSRowSet*)&pRecipentRows)))
{
if( pRecipentRows->cEntries == 0 )
break;
for(int n = 0; n < pRecipentRows->cEntries; n++ )
{
//每个Entry代表一个联系人信息,每个联系人信息又有多个属性组成
for(int i = 0; i < pRecipentRows->aEntries[n].cValues ; i++)
{
//判断如果是PR_EMAIL_ADDRESS属性,那么就找到了联系人地址
if( PR_EMAIL_ADDRESS == pRecipentRows->aEntries[n].rgPropVals[i].ulPropTag )
{
//联系人地址
CString strContact = pRecipentRows->aEntries[n].rgPropVals[i].Value.lpszW;
//后续操作
}
}
}
//完了记得要释放pRecipentRows和它里面的内容,释放方法见上一篇关于设置联系人信息的介绍。
……
}
上面的代码片段只简单演示了获取联系人信息的基本操作步骤,通过这个例子也可以熟悉IMAPITable的用法,MAPI里面还是有很多地方会用到这个接口,用处还是比较大的。
(七)设置Message附件
本篇主要介绍如何设置Message的附件内容,下一篇会介绍如何获取附件。长话短说,下面的例子将完成如下的事情:
1) 准备工作,在Temp目录下先放上几张图片,在这个例子里面,我在Temp目录放两张JPG图片,1.jpg,2.jpg,我将把这两张图片放到一个Message里面,生成两个附件。
2) 在Outlook草稿箱里面创建出一条新的Message。
3) 为Message添加附件。
如何在Outlook草稿箱里面创建一条新的Message,我想通过前面的文章已经解释清楚了,这里就不罗嗦了,以下假设我们已经获取了IMessage*对象指针。首先提出一个帮助函数:MAPIHelp_AddAttachment,该函数作用是为指定的Message添加指定文件作为附件,定义如下:
BOOL MAPIHelp_AddAttachment( IMessage* pMsg, LPCTSTR szFilePath, LPCTSTR szFileName );
pMsg : Message目标对象指针
szFilePath : 需要作为附件添加的文件全路径
szFileName : 需要作为附件添加的文件名称,作为附件的名称
以下是函数具体实现:
BOOL MAPIHelp_AddAttachment( IMessage* pMsg, LPCTSTR szFilePath, LPCTSTR szFileName )
{
if( NULL == pMsg || NULL == szFilePath )
return FALSE;
BOOL bRet = FALSE;
ULONG ulAttachNum = 0;
LPATTACH pAttach = NULL;
IStream* pStream = NULL;
HANDLE hFile = NULL;
SPropValue rgpropsTo[1] = {0};
DWORD dwChunkSize = 4096;
DWORD dwSizeRead = 0;
//预备BUFFER,用来读写文件内容
LPBYTE pData = new BYTE[dwChunkSize];
if( NULL == pData )
return FALSE;
//创建附件,返回IAttach对象,每个IAttach对象对应于一个附件, ulAttachNum是这个对象的标识,我们可以通过IMessage:: OpenAttach时传入这个ID来读取这个附件,具体的方法会在下篇时介绍。
if( FAILED(pMsg->CreateAttach( NULL, NULL, &ulAttachNum, &pAttach )) )
goto Exit;
//设置附件名称
rgpropsTo[0].ulPropTag = PR_ATTACH_FILENAME;
rgpropsTo[0].Value.lpszW = (LPTSTR)szFileName;
if( FAILED(pAttach->SetProps(1, rgpropsTo, NULL)) )
goto Exit;
//通过OpenProperty获取IStream对象,有了IStream对象,我们就可以读写数据。对于IAttach:: OpenProperty,CE上只支持PR_ATTACH_DATA_BIN属性。
if( FAILED(pAttach->OpenProperty( PR_ATTACH_DATA_BIN, NULL, NULL, MAPI_MODIFY, (LPUNKNOWN *)&pStream )) )
goto Exit;
//下面部分是文件读写部分,从原始文件里读出数据,再写到附件里面去
hFile = ::CreateFile( szFilePath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
if( INVALID_HANDLE_VALUE == hFile )
goto Exit;
while( ReadFile( hFile, pData, dwChunkSize, &dwSizeRead, NULL ) )
{
if( 0 >= dwSizeRead )
break;
pStream->Write( pData, dwSizeRead, &dwSizeRead );
}
bRet = TRUE;
Exit:
//完毕以后记的释放获取的对象。
RELEASE_OBJ(pStream);
RELEASE_OBJ(pAttach);
DELETE_OBJ(pData);
if( INVALID_HANDLE_VALUE != hFile )
::CloseHandle( hFile );
return bRet;
}
有了上面的帮助函数,当我们想为一条Message添加附件时,可以按照如下调用:
MAPIHelp_AddAttachment( pMsg, _T("//Temp//1.jpg"), _T("1.jpg") );
MAPIHelp_AddAttachment( pMsg, _T("//Temp//2.jpg"), _T("2.jpg") );
(八)读取Message附件
在上一篇里面讲述了如何为一条MESSAGE设置附件,下面将继续关于附件的话题,利用上一个例子,我们接下来来看看如何获取一条MESSAGE的附件信息。下面将通过两个帮助函数来完成:
BOOL MAPIHelp_SaveAttachFile( LPATTACH pAttach, LPCTSTR szFile )
作用:读取单个附件文件内容,并保存到指定位置
pAttach: 附件对象
szFile: 保存文件名
BOOL MAPIHelp_GetAttachment( IMessage* pMsg, LPCTSTR szFilePath )
作用:获取一条Message的全部附件,并保存到指定目录下
pMsg: 目标消息对象
szFilePath: 目标目录
下面来看看具体实现:
BOOL MAPIHelp_SaveAttachFile( LPATTACH pAttach, LPCTSTR szFile )
{
if( NULL == pAttach || NULL == szFile )
return FALSE;
HANDLE hFile = INVALID_HANDLE_VALUE;
IStream* pstmAttachment = NULL;
char * pBuffer = NULL;
int i = 0;
DWORD dwWrite = 0;
BOOL bRet = FALSE;
ULONG ulRead = 0;
//打开附件,获取IStream对象,用于获取文件内容,根据MSDN的解释,这里只支持PR_ATTACH_DATA_BIN属性。
if(FAILED(pAttach->OpenProperty (PR_ATTACH_DATA_BIN, NULL, STGM_READ, MAPI_MODIFY,
reinterpret_cast <IUnknown **> (&pstmAttachment))))
{
goto EXIT;
}
//创建目标文件
hFile = ::CreateFile(szFile, GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if(INVALID_HANDLE_VALUE == hFile)
{
goto EXIT;
热心网友
时间:2023-10-15 22:30
什么东西上的收件人信息啊,说清楚点啊,要不然怎么说方法啊。