用simple mapi 发送一个带附件的邮件
使用 MAPI 實現郵件發送
原 作:deltacat,修改中
最后更新:2004.09.16
版權聲明:隨意轉載,敬請保持文檔及說明完整性
關鍵字: VC 郵件發送 MAPI
一、簡述
實際上,本文的設計,所使用的只是 Simple MAPI,可以把它看作是MAPI(Messaging Application Programming Interface)的一個子集。不過大多數時候,Simple MAPI提供的功能已經足夠使用。本文闡述了一個簡單的,用于發送一個帶附件的郵件的功能實現。如果需要更復雜的功能,我認為還是老老實實封裝SMTP和POP3比較好
??
二、Simple MAPI 介紹
Simple MAPI 包括一組很容易使用的函數以及相關的數據結構,可以在C/C++、VB等多種語言中使用。本文是基于VC設計的。
實現一個完整的郵件發送過程,只需要一個函數“MAPISendMail()”,完整函數表及相關介紹參查閱MSDN Library->Platform SDK->Messaging and Collaboration Services。
MAPI 與郵件系統關系密切,要能夠使用MAPI的功能,系統必須安裝有支持 MAPI 的郵件系統,比如Outlook、Outlook Express、Eudora、Netscape等. 在這里不得不提一下,使用非常廣泛的 FoxMail (5.0版本)似乎并不支持 MAPI,不過并沒有深入研究,如果有哪位高手發現實際上是支持的,麻煩告知我如何做。
Windows提供了一個文件 MAPI.H,包含所有的相關數據類型的定義。
三、功能的設計
我需要實現如下功能:可定制一封郵件,包括至少一個收件人,可選項目有標題、正文、若干抄送人、密件抄送人、附件。能夠根據需要選擇自動發送(無用戶干預),或彈出郵件編寫窗口。
為了便于使用和擴展,我用了一個class來實現。
1、MAPI庫的初始化
包括兩個步驟:裝載MAPI庫、得到函數入口地址。
?//-------------------------------------------------------------------------------------
?m_hLibrary = ::LoadLibrary(_T("MAPI32.DLL"));
?if(NULL == m_hLibrary)
?{
??return ::GetLastError();
?}
?// LPMAPISENDMAIL 等均定義在 <MAPI.H>
?m_lpfnMAPISendMail = (LPMAPISENDMAIL)::GetProcAddress(m_hLibrary, _T("MAPISendMail"));
?// 可以根據需要添加其他函數入口。我的做法是用了一個 InitMapi() 函數,一次性將所有函數入口得出,作為類的成員變量保存。隨時可以使用
?//-------------------------------------------------------------------------------------
2、發送郵件 MAPISendMail()
發送郵件功能就是對MAPISendMail()的封裝。下面解釋這個API函數的參數定義。
?ULONG FAR PASCAL MAPISendMail(LHANDLE lhSession, ULONG ulUIParam, lpMapiMessage lpMessage, FLAGS flFlags, ULONG ulReserved);
lhSession、ulUIParam和ulReserved這三個參數,簡單地設置為0就可以了。
flFlags有三個有效位,分別是 MAPI_DIALOG,MAPI_LOGON_UI,MAPI_NEW_SESSION。
重點是 lpMessage 這個參數,它指向一個MapiMessage類型的結構,詳細地定義了一個郵件的全部信息。
3、結構 MapiMessage
使用時首先定義一個MapiMessage類型的變量,將其清零。現在我們只要簡單地設定lpszSubject(標題)、lpszNoteText(正文)、lpOriginator(發件人)、nRecipCount(收件人計數,包含TO、CC、GCC),lpRecips(一個包含全部收件人的數組),nFileCount(附件計數)、lpFiles(包含每個附件信息的數組)。
nRecipCount 和 nFileCount 的值一定要與實際的收件人和附件數目相符。
4、結構 MapiRecipDesc
必須設置 ulRecipClass、lpszName、lpszAddress
5、結構 MapiFileDesc
必須設置的有lpszPathName、nPosiotion兩個參數
這里有個地方需要特別注意。我在實際編碼過程中,有幾次 Outlook 不能正確彈出窗口(自動發送也不行),但是同樣的過程,將郵件客戶設為 OutlookExpress 就沒有問題。但是十分頭痛。經過發付查找,發現 nPosiotion 這個參數十分重要。它指示附件在郵件中的位置。
對于一些郵件客戶端,比如OutlookExpress,也許忽略了這個參數,由客戶端自動安排。所以沒有問題。對于另一些客戶端,比如Outlook,總是按照這個值的指示來安排的。如果附件數多于一個,這個值如果相同,那么就會造成錯誤。但是自行計算挺麻煩而且沒什么意義。解決的方法是,將其設為 -1,指示客戶軟件自行安排。:)
四、如何工作?
MAPISendMail() 會調用系統默認的郵件客戶程序來發送郵件。對于彈出編輯窗的方式,它的行為和另一個函數MAPISendMail()差不多,只是可以定制標題、收件人等等,而MAPISendDocuments()只是簡單地準備一個空白的郵件(包含附件),有關MAPISendDocuments()的介紹參見MSDN。
對于自動發送。需要在Outlook Express的安全設置中,取消“當有其他應用程序試圖發送郵件時警告”這個選項。對于Outlook,還沒有找到方法。
我設計的類包括三個接口函數,Send(), AddFiles(), AddRecips(),其中只有Send()是必須的。使用時聲明一個對象,然后就直接調用Send()函數發送郵件。兩個Add函數只要根據需要在Send()之前調用即可。
五、遺留問題
我的開發環境是 Windows Xp Sp2 CHS,有如下幾個問題,希望有高手可以解決。
1、自動發送時的警告問題。
2、默認Outlook Express為系統郵件客戶端,可以立即發送,如果是Outlook,是先放到Outlook的發送隊列了,這時如果Outlook未運行,就一直不會發送。怎樣可以保證無論郵件客戶軟件是否在運行,我的程序都可以立即將郵件發送出去呢?
3、對于默認是“Hotmail”的情況,只有以 @hotmail.com 結尾的帳號可以正常發送,而 @msn.com 的則不行。同時,在發送時,hotmail會將硬盤上的附件改名(末尾添加“^”符號)并將文件屬性改為只讀。
六、結束語
本文是在給應用程序中添加郵件發送功能的心得。過程中遇到了很多問題,將他寫出來,主要是給自己一個記錄,也是我第一次將自己的編程過程整理成文檔。
若本文還能幫到有同樣需要的朋友,會令我很開心。也希望有這方面經驗的朋友可以解決我的遺留問題。
后篇?
?在VC中調用默認的電子郵件程序發送郵件
很多時候大家需要在程序中發送郵件,自己編又太麻煩,怎么辦,呵呵,有現成的!?
1、想省事兒的,用ShellExecute函數:?
ShellExecute(NULL,NULL,"mailto:email@263.net",NULL,NULL,SW_SHOW);?
2、如果想自己多處理一些東西的話,比如加上默認的帳號、密碼、附件等,就可以調用系統的Mapi函數。具體的用法大家可以去查MSDN都是以MAPI開頭的,如MAPILogon、MAPISendMail等。下面這段代碼演示如何調用默認的郵件程序發送郵件。?
#include "mapi.h"?
void CTestMapiDlg::OnSendMail()?
{?
HMODULE hMod = LoadLibrary("MAPI32.DLL");?
if (hMod == NULL)?
{?
AfxMessageBox(AFX_IDP_FAILED_MAPI_LOAD);?
return;?
}?
ULONG (PASCAL *lpfnSendMail)(ULONG, ULONG, MapiMessage*, FLAGS, ULONG);?
(FARPROC&)lpfnSendMail = GetProcAddress(hMod, "MAPISendMail");?
if (lpfnSendMail == NULL)?
{?
AfxMessageBox(AFX_IDP_INVALID_MAPI_DLL);?
return;?
}?
ASSERT(lpfnSendMail != NULL);?
TCHAR szPath[_MAX_PATH] = "C:\Winnt\setup.log";?
TCHAR szTitle[_MAX_PATH] = "setup.log";?
// prepare the file description (for the attachment)?
MapiFileDesc fileDesc;?
memset(&fileDesc, 0, sizeof(fileDesc));?
fileDesc.nPosition = (ULONG)-1;?
fileDesc.lpszPathName = szPath;?
fileDesc.lpszFileName = szTitle;?
// prepare the message (empty with 1 attachment)?
MapiMessage message;?
memset(&message, 0, sizeof(message));?
message.nFileCount = 1;?
message.lpFiles = &fileDesc;?
int nError = lpfnSendMail(0, 0,?
&message, MAPI_LOGON_UI¦MAPI_DIALOG, 0);?
// after returning from the MAPISendMail call, the window must?
// be re-enabled and focus returned to the frame to undo the workaround?
// done before the MAPI call.?
if (nError != SUCCESS_SUCCESS &&?
nError != MAPI_USER_ABORT && nError != MAPI_E_LOGIN_FAILURE)?
{?
AfxMessageBox(AFX_IDP_FAILED_MAPI_SEND);?
}?
}?
【轉】MAPI32::MAPISendMail以郵件附件形式發送文件
MAPISendMail
The MAPISendMail function sends a message, this function differs from the MAPISendDocuments function in that it allows greater flexibility in message generation.
Header file:MAPI.H
ULONG FAR PASCAL MAPISendMail(
LHANDLE?lhSession,
?ULONG?ulUIParam,
lpMapiMessage?lpMessage,
?FLAGS?flFlags,
ULONG?ulReserved?)
Parameters
lhSession
[in] handle to a simple MAPI session or zero.?If the value of? the lhSession parameter is zero, MAPI logs on the user and creates a session that exists only for the duration of the call.?This temporary session can be an existing shared session or a new one. If necessary, the logon dialog box is displayed.
ulUIParam
[in] Parent window handle or?zero.indicating that if a dialog box is displayed, it is application modal. If the ulUIParam contains a parent window handle, it is of type HWND (cast TO A ULONG).?If no dialog box is displayed during the call, ulUIParam is ignored.
lpMessage
[in] pointer to a MapiMessage structure containing the message to be sent.?If the MAPI_DIALOG flag is not set, the nRecipCount and lpRecips members must be valid for sucessful message delivery. Client application can set the flFlags member to MAPI_RECEIPT_REQUESTED to request a read report.?All other members are ignored and unused pointers should be NULL.
flFlags
[in] bitmark of option flags. The following flags can be set:
MAPI_DIALOG
A dialog box should be displayed to prompt the user for recipients and other sending options. When MAPI_DIALOG is not set, at least one recipient must be specified.
MAPI_LOGON_UI
A dialog box should be displayed to prompt the user to log on if required. When the MAPI_LOGON_UI is not set, the client application does not display a logon dialog box and returns an error value if the user is not logged on. MAPISendMail ignores this flag if the lpszMessageID parameter is empty.
MAPI_NEW_SEEEION
An attempt should be made to create a new session rather that acquire the environment's shared session. If the MAPI_SESSION flag is not set, MAPISendMail uses an existing share session.
ulReserved
Reserved; must be zero.
Return Values
MAPI_E_AMBIGUOUS_RECIPIENTRemarks
The MAPISendMail function sends a standard message, with or without any user interface. The profile must be configured so that MAPISendMail can open the default service paroviders without requiring user interface. However, if the flFlags parameter is set to MAPI_NEW_SESSION, disallowing the use of a shared session, and the profile requires a passsword, MAPI_LONON_UI must be set or? the function will fall. Client application can avoid this situation by using an explicit profile without a password or by using the default profile without a password.
Client application can provide a full or partial of recipient names, subject text,file attachments,or message text. If any information is missing, MAPISendMail can prompt the user for it. If no information is missing, either the message can be sent as if or the user can be prompted to verify the information, changing values if necessary.
A successful return form MAPISendMail does not necessarily imply recipient validation. The message might not have been sent to all recipients. Depending on the transport provider, recipient validation can be a lengthy process.
A NULL value for the lpszSubject member of the MapiMessage structure pointed to by the lpMessage parameter indicates that there is not text for the subject of the message.
A NULL value for the lpszNoteText member indicate that there is no message text. Some client application can truncate subject lines that are too long or contain carriage returns, line feeds, or form feeds.
Each paragraph should be terminated with a CR(OXOD), and LF(0X0a), or a CRLF(0X0D0A). MAPISendMail wraps lines as appropriate. If the text exceeds system limits, the function returns the MAPI_E_TEXT_TOO_LARGE values.
The lpszMessageType member of the MapiMessage structure pointed by lpMessage is used only by non_IPM applications. Applications that handle IPM message can set it to NULL or have it point to an empty string.
The number of attachments per message of the MapiMessage structure can be limited in some messaging systems. If the limit is exceeded, the MAPI_E_TOO_MANY_FILES value if returned. If no files are specified, a pointer value of NULL should be assigned to the files do not affect the contents of the message. The files must be closed when they are copied. Do not attempt to display attachments outside the range of the message text.
Some messaging systems can limit the number of recipients per message. A pointer value of NUL? for the lpRecipts member in the MapiMessage structure pointed by the lpMessage indicates no recipients. If the client application passes a non-NUll value indicating a number of recipients exceeding the system limit, MAPISendMail returns the MAPI_E_TOO_MANY_RECIPIENTS value. If the value of the nRecipCount member in the MapiMessage structure is 0, the MAPI_DAILOG flag must be present in the call to MAPISendMail.
Note that the lpRecips member in the MapiMessage structure can include either an entry identifier, the recipient's name, and address, or a name and address pair. The following table show how MAPISendMail handles the variety of information that can be specified:
| Information | Action |
| entry identifier | No name resolution; the name and address are ignored. |
| name | Name resolved using the Simple MAPI resolution rules. |
| address | No name resolution; address is used for both message delivery and for displaying the recipient name. |
| name and address | No name resolution; name used only for displaying the recipient name. |
Client applications that send messages to custom recipients can avoid name resolution. Such clients should set thelpszAddress?member of the?MapiRecipDesc?structure pointed to by the?lpRecips?member of the?MapiMessage?structure pointed to by the?lpMessage?parameter to the custom address.
MAPISendMail?does not require an originator-type recipient to send a message.
MapiMessage (simple MAPI)
A MapiMessage structure contains information about a message.
Header file: MAPI.H
typedef struct {
ULONG ulReserved;
LPTSTR lpszSubject;
LPTSTR lpszNoteText;
LPTSTR lpszMessageType;
LPTSTR lpszDateReceived;
LPTSTR lpszConversationID;
FLAGS flFlags;
lpMapiRecipDesc lpOriginator;
ULONG nRecipCount;
lpMapiRecipDesc lpRecips;
ULONG nFileCount;
lpMapiFileDesc lpFiles;
}MapiMessage, FAR *lpMapiMessage;
Members
ulReserved
Reserved,?must be zero.
lpszSubject
pointer to the text string describing the message subject, typically limited to 256 characters or less. If this member is empty or NULL, the user has not entered subject text.
lpszNoteText
pointer to a string containing the message text. If this member is empty or NULL, there is no message text.
lpszMessageType
Pointer to a string indicating a non-IPM type of message. Client application can select message types for their non_IPM messages.?Clients that only support IPM messages?can ignore the lpszMessageType member when reading messages andset it to empty or NULLwhen sending messages.
lpszDateReceived
Pointer to a string indicating the date when the message was received. The format is YYYY/MM/DD HH:MM, using a 24-hour clock.
lpszConversationID
pointer to a string identifying the conversation thread to which the message belongs. some messaging system can ignore and not return this member.
flFlagsBitmark of message status flags. The following flags can be set:
MAPI_RECEIPT_REQUESTEDlpOriginatorPointer to a?MapiRecipDescstructure containing information about the sender of the message.nRecipCountThe number of message recipient structures in the array pointed to by the?lpRecipsmember. A value of zero indicates no recipients are included.lpRecipsPointer to an array of?MapiRecipDescstructures, each containing information about a message recipient.nFileCountThe number of structures describing file attachments in the array pointed to by the?lpFiles?member. A value of zero indicates no file attachments are included.lpFilesPointer to an array ofMapiFileDesc?structures, each containing information about a file attachment.
?
MapiFileDesc (simple MAPI)
A MapiFileDesc structure contains information about a file containing a message attachment stored as a temporary file. That file can contain a static OLE object, an embedded OLE object, and embedded message, and other types of files.
typedef struct {
ULONG ulReserved;
ULONG flFlags;
ULONG nPosition;
LPTSTR lpszPathName;
LPTSTR lpszFileName;
LPVOID lpFileType;
} MapiFileDesc, FAR *lpMapiFileDesc;
Members
ulReservedIf neither flag is set, the attachment is treated as a data file.
?
?
Remarks
Simple MAPI works with three kinds of embedded attachments:
- Data file attachments
- Editable OLE object file attachments
- Static OLE object file attachments
Data file attachments are simply data files. OLE object file attachments are OLE objects that are displayed in the message text. If the OLE attachment is editable, the recipient can double-click it and its source application will be started to handle the edit session. If the OLE attachment is static, the object cannot be edited. The flag set in the?flFlags?member of the?MapiFileDesc?structure determines the kind of a particular attachment. Embedded messages can be identified by a .MSG extension in the?lpszFileNamemember.
OLE object files are file representations of OLE object streams. The client application can recreate an OLE object from the file by calling the OLE functionOleLoadFromStreamwith an OLESTREAM object that reads the file contents. If an OLE file attachment is included in an outbound message, the OLE object stream should be written directly to the file used as the attachment.
When using the?MapiFileDesc?member?nPosition, the client application should not place two attachments in the same location. Client applications might not display file attachments at positions beyond the end of the message text.
Example
/********************************************************************* * 函數名稱:CSendEMailDlg::OnSendMapi * 說明: 調用MAPI函數發送郵件。摘自 VC98/MFC/SRC/DOCMAPI.CPP * 作者: Geng * 時間 : 2003-04-22 20:08:30 *********************************************************************//* m_list 為ListControl的變量 ,程序將ListControl中列出的所有item以附近形式發送,如果你的系統安裝了Outlook發送郵件器,那么會啟動它來作為郵件發送默認程序*//* code 為非Unicode版本 */ void CSendEMailDlg::OnSendMapi() {UpdateData(true); //加載MAPI32.DLL動態庫 HMODULE hMod = LoadLibrary(_T("MAPI32.DLL")); if (hMod == NULL) //加載動態庫失敗 {AfxMessageBox(AFX_IDP_FAILED_MAPI_LOAD);return;} //獲取發送郵件的函數地址 ULONG (PASCAL *lpfnSendMail)(ULONG, ULONG, MapiMessage*, FLAGS, ULONG);(FARPROC&)lpfnSendMail = GetProcAddress(hMod, "MAPISendMail"); if (lpfnSendMail == NULL){AfxMessageBox(AFX_IDP_INVALID_MAPI_DLL);return;} int nFileCount = m_list.GetCount(); //有多少個附件需要發送 //分配內存保存附件信息 不能使用靜態數組,因為不知道要發送附件的個數 MapiFileDesc* pFileDesc = (MapiFileDesc*)malloc(sizeof(MapiFileDesc) * nFileCount);memset(pFileDesc,0,sizeof(MapiFileDesc) * nFileCount); //分配內存保存附件文件路徑 TCHAR* pTchPath = (TCHAR*)malloc(MAX_PATH * nFileCount); CString szText;for(int i = 0;i < nFileCount;i++){char* p = pTchPath + MAX_PATH * i;m_list.GetText(i,szText);strcpy(p,szText);(pFileDesc + i)->nPosition = (ULONG)-1;(pFileDesc + i)->lpszPathName = p;(pFileDesc + i)->lpszFileName = p;} //收件人結構信息 /*MapiRecipDesc recip;memset(&recip,0,sizeof(MapiRecipDesc));recip.lpszAddress = m_szEmailMAPI.GetBuffer(0);recip.ulRecipClass = MAPI_TO;*/ //郵件結構信息 MapiMessage message;memset(&message, 0, sizeof(message));message.nFileCount = nFileCount; //文件個數 message.lpFiles = pFileDesc; //文件信息//message.nRecipCount = 0; //收件人個數//message.lpRecips = NULL;//&recip; //收件人//message.lpszSubject = NULL; //m_szSubject.GetBuffer(0); //主題//message.lpszNoteText= NULL;//m_szText.GetBuffer(0); //正文內容 //保存本程序窗口指針,因為發完郵件后要返回本程序的窗口 CWnd* pParentWnd = CWnd::GetSafeOwner(NULL, NULL); //發送郵件 int nError = lpfnSendMail(0, 0,&message, MAPI_LOGON_UI|MAPI_DIALOG, 0); if (nError != SUCCESS_SUCCESS && nError != MAPI_USER_ABORT && nError != MAPI_E_LOGIN_FAILURE){AfxMessageBox(AFX_IDP_FAILED_MAPI_SEND);} //返回程序 pParentWnd->SetActiveWindow(); //不要忘了釋放分配的內存 free(pFileDesc);free(pTchPath);FreeLibrary(hMod); } //imapi.h================================ /* * $Header:$ * * $Log:$ */ //#include class CIMapi { public: CIMapi(); ~CIMapi(); enum errorCodes { IMAPI_SUCCESS = 0, IMAPI_LOADFAILED, IMAPI_INVALIDDLL, IMAPI_FAILTO, IMAPI_FAILCC, IMAPI_FAILATTACH }; // Attributes void Subject(LPCTSTR subject) { m_message.lpszSubject = (LPTSTR) subject; } void Text(LPCTSTR text) { m_text = text; } UINT Error(); void From(LPCTSTR from) { m_from.lpszName = (LPTSTR) from; } static BOOL HasEmail(); // Operations BOOL To(LPCTSTR recip); BOOL Cc(LPCTSTR recip); BOOL Attach(LPCTSTR path, LPCTSTR name = NULL); BOOL Send(ULONG flags = 0); private: BOOL AllocNewTo(); MapiMessage m_message; MapiRecipDesc m_from; UINT m_error; CString m_text; ULONG (PASCAL *m_lpfnSendMail)(ULONG, ULONG, MapiMessage*, FLAGS, ULONG); static HINSTANCE m_hInstMail; static BOOL m_isMailAvail; }; //imapi.cpp================================================== /* * $Header:$ * * $Log:$ */ #include "stdafx.h" #include <MAPI.H> #include "imapi.h" HINSTANCE CIMapi::m_hInstMail = (HINSTANCE) NULL; BOOL CIMapi::m_isMailAvail = (BOOL) -1; CIMapi::CIMapi() { m_error = 0; // Initially error free memset(&m_message, 0, sizeof(MapiMessage)); memset(&m_from, 0, sizeof(MapiRecipDesc)); m_message.lpOriginator = &m_from; m_from.ulRecipClass = MAPI_ORIG; if (m_hInstMail == (HINSTANCE) NULL) // Load the MAPI dll m_hInstMail = ::LoadLibraryA("MAPI32.DLL"); if (m_hInstMail == (HINSTANCE) NULL) { AfxMessageBox(AFX_IDP_FAILED_MAPI_LOAD); m_error = IMAPI_LOADFAILED; return; } ASSERT(m_hInstMail != (HINSTANCE) NULL); // Now get the pointer to the send function (FARPROC&) m_lpfnSendMail = GetProcAddress(m_hInstMail, "MAPISendMail"); if (NULL == m_lpfnSendMail) { AfxMessageBox(AFX_IDP_INVALID_MAPI_DLL); m_error = IMAPI_INVALIDDLL; return; } ASSERT(m_lpfnSendMail != NULL); } CIMapi::~CIMapi() { if (m_hInstMail != (HINSTANCE) NULL) ::FreeLibrary(m_hInstMail); m_hInstMail = (HINSTANCE) NULL; free(m_message.lpFiles); free(m_message.lpRecips); } BOOL CIMapi::HasEmail() { if (m_isMailAvail == (BOOL) -1) m_isMailAvail = ::GetProfileInt(_T("MAIL"), _T("MAPI"), 0) != 0 && SearchPath(NULL, _T("MAPI32.DLL"), NULL, 0, NULL, NULL) != 0; return m_isMailAvail; } UINT CIMapi::Error() { UINT temp = m_error; m_error = IMAPI_SUCCESS; return temp; } BOOL CIMapi::AllocNewTo() { // Allocate a new MapiRecipDesc structure and initialise it to all zeros m_message.lpRecips = (MapiRecipDesc *) realloc(m_message.lpRecips, (m_message.nRecipCount + 1) * sizeof(MapiRecipDesc)); memset(&m_message.lpRecips[m_message.nRecipCount], 0, sizeof(MapiRecipDesc)); ASSERT(m_message.lpRecips); return m_message.lpRecips != (MapiRecipDesc *) NULL; } BOOL CIMapi::To(LPCTSTR recip) { if (AllocNewTo()) { // We succeeded in allocating a new recipient record m_message.lpRecips[m_message.nRecipCount].lpszName = (LPTSTR) recip; m_message.lpRecips[m_message.nRecipCount].ulRecipClass = MAPI_TO; m_message.nRecipCount++; return TRUE; } m_error = IMAPI_FAILTO; return FALSE; } BOOL CIMapi::Cc(LPCTSTR recip) { if (AllocNewTo()) { // We succeeded in allocating a new recipient record m_message.lpRecips[m_message.nRecipCount].lpszName = (LPTSTR) recip; m_message.lpRecips[m_message.nRecipCount].ulRecipClass = MAPI_CC; m_message.nRecipCount++; return TRUE; } m_error = IMAPI_FAILCC; return FALSE; } BOOL CIMapi::Attach(LPCTSTR path, LPCTSTR name) { // Add a new attachment record m_message.lpFiles = (MapiFileDesc *) realloc(m_message.lpFiles, (m_message.nFileCount + 1) * sizeof(MapiFileDesc)); memset(&m_message.lpFiles[m_message.nFileCount], 0, sizeof(MapiFileDesc)); ASSERT(m_message.lpFiles); if (m_message.lpFiles == (MapiFileDesc *) NULL) { m_error = IMAPI_FAILATTACH; return FALSE; } m_message.lpFiles[m_message.nFileCount].lpszPathName = (LPTSTR) path; m_message.lpFiles[m_message.nFileCount].lpszFileName = (LPTSTR) name; m_message.nFileCount++; return TRUE; } BOOL CIMapi::Send(ULONG flags) { CWaitCursor wait; int offset = m_text.GetLength(); // Add 1 space per attachment at the end of the body text. m_text += CString(' ', m_message.nFileCount); // Set each attachment to replace one of the added spaces at the end of the body text. for (UINT i = 0; i < m_message.nFileCount; i++) m_message.lpFiles[i].nPosition = offset++; m_message.lpszNoteText = (LPTSTR) (LPCTSTR) m_text; // Set the body text // prepare for modal dialog box AfxGetApp()->EnableModeless(FALSE); HWND hWndTop; CWnd* pParentWnd = CWnd::GetSafeOwner(NULL, &hWndTop); // some extra precautions are required to use MAPISendMail as it // tends to enable the parent window in between dialogs (after // the login dialog, but before the send note dialog). pParentWnd->SetCapture(); ::SetFocus(NULL); pParentWnd->m_nFlags |= WF_STAYDISABLED; int nError = m_lpfnSendMail(0, (ULONG) pParentWnd->GetSafeHwnd(), &m_message, MAPI_LOGON_UI | flags, 0); // after returning from the MAPISendMail call, the window must // be re-enabled and focus returned to the frame to undo the workaround // done before the MAPI call. ::ReleaseCapture(); pParentWnd->m_nFlags &= ~WF_STAYDISABLED; pParentWnd->EnableWindow(TRUE); ::SetActiveWindow(NULL); pParentWnd->SetActiveWindow(); pParentWnd->SetFocus(); if (hWndTop != NULL) ::EnableWindow(hWndTop, TRUE); AfxGetApp()->EnableModeless(TRUE); if (nError != SUCCESS_SUCCESS && nError != MAPI_USER_ABORT && nError != MAPI_E_LOGIN_FAILURE) { AfxMessageBox(AFX_IDP_FAILED_MAPI_SEND); return FALSE; } return TRUE; } //在你的dlg.cpp #include imapi.h //你的dlg.cpp 的按鈕事件=================================== void 你的DLG::OnBnClickedButton1() { CIMapi mail;mail.To("Tofirst@qq.com"); mail.To("Tosecond@qq.com");mail.Cc("CCfirst@qq.com"); mail.From("aa@qq.com"); mail.Subject("Test Email"); // mail.Attach("somefilename"); // // mail.Attach("someotherfile", "different_name_for_recipient"); mail.Text("Body text for this email"); mail.Send(); }總結
以上是生活随笔為你收集整理的用simple mapi 发送一个带附件的邮件的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 设计模式(11)代理模式The Prox
- 下一篇: 临床医学计算机思维的应用情况,【临床医学