使用 ShellExecute 直接呼叫 mailto: 協定:
ShellExecute(NULL, NULL, "mailto:email@163.net", NULL, NULL, SW_SHOW);
適用於無需附件、主題、多收件人等進階需求的場景。
動態載入 MAPI32.DLL,取得 MAPISendMail 函式指標,填寫 MapiMessage、MapiRecipDesc、MapiFileDesc 結構體發送郵件。
#include "mapi.h"
void CSendEMailDlg::OnSendMapi() {
UpdateData(true);
// 1. 載入 MAPI32.DLL
HMODULE hMod = LoadLibrary("MAPI32.DLL");
if (!hMod) { AfxMessageBox(AFX_IDP_FAILED_MAPI_LOAD); return; }
// 2. 取得 MAPISendMail 位址
ULONG (PASCAL *lpfnSendMail)(ULONG, ULONG, MapiMessage*, FLAGS, ULONG);
(FARPROC&)lpfnSendMail = GetProcAddress(hMod, "MAPISendMail");
if (!lpfnSendMail) { AfxMessageBox(AFX_IDP_INVALID_MAPI_DLL); FreeLibrary(hMod); return; }
// 3. 準備附件資訊 (動態陣列)
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++) {
TCHAR* p = pTchPath + MAX_PATH * i;
m_list.GetText(i, szText);
_tcscpy(p, szText);
(pFileDesc + i)->nPosition = (ULONG)-1;
(pFileDesc + i)->lpszPathName = p;
(pFileDesc + i)->lpszFileName = p;
}
// 4. 收件人資訊
MapiRecipDesc recip = {0};
recip.lpszAddress = m_szEmailMAPI.GetBuffer(0);
recip.ulRecipClass = MAPI_TO;
// 5. 郵件主體
MapiMessage message = {0};
message.nFileCount = nFileCount;
message.lpFiles = pFileDesc;
message.nRecipCount = 1;
message.lpRecips = &recip;
message.lpszSubject = m_szSubject.GetBuffer(0);
message.lpszNoteText = m_szText.GetBuffer(0);
// 6. 保存父視窗指標,發送後回復焦點
CWnd* pParentWnd = CWnd::GetSafeOwner(NULL, NULL);
// 7. 發送郵件 (顯示對話框讓使用者確認)
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();
// 8. 釋放資源
free(pFileDesc);
free(pTchPath);
FreeLibrary(hMod);
}
| 錯誤碼 | 含義 |
|---|---|
| SUCCESS_SUCCESS | 發送成功 |
| MAPI_USER_ABORT | 使用者取消 |
| MAPI_E_LOGIN_FAILURE | 登入失敗 |
| MAPI_E_INSUFFICIENT_MEMORY | 記憶體不足 |
| MAPI_E_UNKNOWN_RECIPIENT | 收件人無法解析 |
ShellExecute:極簡、無依賴、功能受限。MAPI:功能完整、需動態載入 DLL、相容性佳(Outlook、Windows Mail、Foxmail 等均支援)。