C/C++
CMapi - MFC класс для отправки почты при помощи Simple MAPI. | CMapi - MFC класс для отправки почты при помощи Simple MAPI. |
|
|
|
|
Simple MAPI это набор функций, экспортируемых MAPI32.dll, которые позволяют отправлять и получать почту. Simple MAPI присутствует во всех операционных системах Win32 начиная с Windows 95 (за исключением Windows CE). При отправке и получении почты будут использоваться настройки Outlook или Outlook Express. Simple MAPI это набор функций, экспортируемых MAPI32.dll, которые позволяют отправлять и получать почту. Simple MAPI присутствует во всех операционных системах Win32 начиная с Windows 95 (за исключением Windows CE). При отправке и получении почты будут использоваться настройки Outlook или Outlook Express.
///////////////////////////////// Includes //////////////////////////////////
#include "stdafx.h" #include "CMapi.h" #include <afxpriv.h>
//////////////////////////////// Statics / Macros /////////////////////////////
#ifdef _DEBUG #undef THIS_FILE static char BASED_CODE THIS_FILE[] = __FILE__; #define new DEBUG_NEW #endif
////////////////////////////////// Implementation /////////////////////////////
BOOL CMapiMessage::AddMultipleRecipients(const CString& sRecipients, RECIPIENT_TYPE RecipientType) { ASSERT(sRecipients.GetLength()); //An empty string is now allowed
//Loop through the whole string, adding recipients as they are encountered int length = sRecipients.GetLength(); TCHAR* buf = new TCHAR[length + 1]; // Allocate a work area (don't touch parameter itself) _tcscpy(buf, sRecipients); for (int pos=0, start=0; pos<=length; pos++) { //Valid separators between addresses are ',' or ';' if ((buf[pos] == _T(',')) || (buf[pos] == _T(';')) || (buf[pos] == 0)) { buf[pos] = 0; //Redundant when at the end of string, but who cares. CString sTemp(&buf[start]);
// Now divide the substring into friendly names and e-mail addresses CString To = sTemp;
//Finally add the new recipient to the array of recipients To.TrimRight(); To.TrimLeft(); if (To.GetLength()) { switch (RecipientType) { case TO: m_To.Add(To); break; case CC: m_CC.Add(To); break; case BCC: m_BCC.Add(To); break; default: ASSERT(FALSE); break; } }
//Move on to the next position start = pos + 1; } } delete[] buf; return TRUE; }
CMapiSession::CMapiSession() { m_hSession = 0; m_nLastError = 0; m_hMapi = NULL; m_lpfnMAPILogon = NULL; m_lpfnMAPILogoff = NULL; m_lpfnMAPISendMail = NULL; m_lpfnMAPIResolveName = NULL; m_lpfnMAPIFreeBuffer = NULL; Initialise(); }
CMapiSession::~CMapiSession() { //Logoff if logged on Logoff();
//Unload the MAPI dll Deinitialise(); }
void CMapiSession::Initialise() { //First make sure the MAPI32 dll is present on the system. Technically we should //be also testing by using the check "GetProfileInt(_T("MAIL"), _T("MAPI"), 0) != 0" //also, but some installs of MAPI screw this entry up. BOOL bMapiInstalled = (SearchPath(NULL, _T("MAPI32.DLL"), NULL, 0, NULL, NULL) != 0);
if (bMapiInstalled) { //Load up the MAPI dll and get the function pointers we are interested in m_hMapi = LoadLibrary(_T("MAPI32.DLL")); if (m_hMapi) { m_lpfnMAPILogon = (LPMAPILOGON) GetProcAddress(m_hMapi, "MAPILogon"); m_lpfnMAPILogoff = (LPMAPILOGOFF) GetProcAddress(m_hMapi, "MAPILogoff"); m_lpfnMAPISendMail = (LPMAPISENDMAIL) GetProcAddress(m_hMapi, "MAPISendMail"); m_lpfnMAPIResolveName = (LPMAPIRESOLVENAME) GetProcAddress(m_hMapi, "MAPIResolveName"); m_lpfnMAPIFreeBuffer = (LPMAPIFREEBUFFER) GetProcAddress(m_hMapi, "MAPIFreeBuffer");
//If any of the functions are not installed then fail the load if (m_lpfnMAPILogon == NULL || m_lpfnMAPILogoff == NULL || m_lpfnMAPISendMail == NULL || m_lpfnMAPIResolveName == NULL || m_lpfnMAPIFreeBuffer == NULL) { TRACE(_T("Failed to get one of the functions pointer in MAPI32.DLL\n")); Deinitialise(); } } } else TRACE(_T("Mapi is not installed on this computer\n")); }
void CMapiSession::Deinitialise() { if (m_hMapi) { //Unload the MAPI dll and reset the function pointers to NULL FreeLibrary(m_hMapi); m_hMapi = NULL; m_lpfnMAPILogon = NULL; m_lpfnMAPILogoff = NULL; m_lpfnMAPISendMail = NULL; m_lpfnMAPIResolveName = NULL; m_lpfnMAPIFreeBuffer = NULL; } }
BOOL CMapiSession::Logon(const CString& sProfileName, const CString& sPassword, CWnd* pParentWnd) { //For correct operation of the T2A macro, see MFC Tech Note 59 USES_CONVERSION;
ASSERT(MapiInstalled()); //MAPI must be installed ASSERT(m_lpfnMAPILogon); //Function pointer must be valid
//Initialise the function return value BOOL bSuccess = FALSE;
//Just in case we are already logged in Logoff();
//Setup the ascii versions of the profile name and password int nProfileLength = sProfileName.GetLength(); int nPasswordLength = sPassword.GetLength(); LPSTR pszProfileName = NULL; LPSTR pszPassword = NULL; if (nProfileLength) { pszProfileName = T2A((LPTSTR) (LPCTSTR) sProfileName); pszPassword = T2A((LPTSTR) (LPCTSTR) sPassword); }
//Setup the flags & UIParam parameters used in the MapiLogon call FLAGS flags = 0; ULONG nUIParam = 0; if (nProfileLength == 0) { //No profile name given, then we must interactively request a profile name if (pParentWnd) { nUIParam = (ULONG) pParentWnd->GetSafeHwnd(); flags |= MAPI_LOGON_UI; } else { //No CWnd given, just use the main window of the app as the parent window if (AfxGetMainWnd()) { nUIParam = (ULONG) AfxGetMainWnd()->GetSafeHwnd(); flags |= MAPI_LOGON_UI; } } }
//First try to acquire a new MAPI session using the supplied settings using the MAPILogon functio ULONG nError = m_lpfnMAPILogon(nUIParam, pszProfileName, pszPassword, flags | MAPI_NEW_SESSION, 0, &m_hSession); if (nError != SUCCESS_SUCCESS && nError != MAPI_E_USER_ABORT) { //Failed to create a create mapi session, try to acquire a shared mapi session TRACE(_T("Failed to logon to MAPI using a new session, trying to acquire a shared one\n")); nError = m_lpfnMAPILogon(nUIParam, NULL, NULL, 0, 0, &m_hSession); if (nError == SUCCESS_SUCCESS) { m_nLastError = SUCCESS_SUCCESS; bSuccess = TRUE; } else { TRACE(_T("Failed to logon to MAPI using a shared session, Error:%d\n"), nError); m_nLastError = nError; } } else if (nError == SUCCESS_SUCCESS) { m_nLastError = SUCCESS_SUCCESS; bSuccess = TRUE; }
return bSuccess; }
BOOL CMapiSession::SharedLogon() { ASSERT(MapiInstalled()); //MAPI must be installed ASSERT(m_lpfnMAPILogon); //Function pointer must be valid
//Initialise the function return value BOOL bSuccess = FALSE;
//Just in case we are already logged in Logoff();
//Try to acquire a shared mapi session ULONG nError = m_lpfnMAPILogon(0, NULL, NULL, 0, 0, &m_hSession); if (nError == SUCCESS_SUCCESS) { m_nLastError = SUCCESS_SUCCESS; bSuccess = TRUE; } else m_nLastError = nError;
return bSuccess; }
BOOL CMapiSession::LoggedOn() const { return (m_hSession != 0); }
BOOL CMapiSession::MapiInstalled() const { return (m_hMapi != NULL); }
BOOL CMapiSession::Logoff() { ASSERT(MapiInstalled()); //MAPI must be installed ASSERT(m_lpfnMAPILogoff); //Function pointer must be valid
//Initialise the function return value BOOL bSuccess = FALSE;
if (m_hSession) { //Call the MAPILogoff function ULONG nError = m_lpfnMAPILogoff(m_hSession, 0, 0, 0); if (nError != SUCCESS_SUCCESS) { TRACE(_T("Failed in call to MapiLogoff, Error:%d"), nError); m_nLastError = nError; bSuccess = TRUE; } else { m_nLastError = SUCCESS_SUCCESS; bSuccess = TRUE; } m_hSession = 0; }
return bSuccess; }
BOOL CMapiSession::Resolve(const CString& sName, lpMapiRecipDesc* lppRecip) { //For correct operation of the T2A macro, see MFC Tech Note 59 USES_CONVERSION;
ASSERT(MapiInstalled()); //MAPI must be installed ASSERT(m_lpfnMAPIResolveName); //Function pointer must be valid ASSERT(LoggedOn()); //Must be logged on to MAPI ASSERT(m_hSession); //MAPI session handle must be valid
//Call the MAPIResolveName function LPSTR lpszAsciiName = T2A((LPTSTR) (LPCTSTR) sName); ULONG nError = m_lpfnMAPIResolveName(m_hSession, 0, lpszAsciiName, 0, 0, lppRecip); if (nError != SUCCESS_SUCCESS) { TRACE(_T("Failed to resolve the name: %s, Error:%d\n"), sName, nError); m_nLastError = nError; }
return (nError == SUCCESS_SUCCESS); }
BOOL CMapiSession::Send(CMapiMessage& message, BOOL bResolve, BOOL bInteractive, CWnd* pParentWnd) { //For correct operation of the T2A macro, see MFC Tech Note 59 USES_CONVERSION;
ASSERT(MapiInstalled()); //MAPI must be installed ASSERT(m_lpfnMAPISendMail); //Function pointer must be valid ASSERT(m_lpfnMAPIFreeBuffer); //Function pointer must be valid
//Initialise the function return value BOOL bSuccess = FALSE;
//Create the MapiMessage structure to match the message parameter send into us MapiMessage mapiMessage; ZeroMemory(&mapiMessage, sizeof(mapiMessage)); mapiMessage.lpszSubject = T2A((LPTSTR) (LPCTSTR) message.m_sSubject); mapiMessage.lpszNoteText = T2A((LPTSTR) (LPCTSTR) message.m_sBody); mapiMessage.nRecipCount = message.m_To.GetSize() + message.m_CC.GetSize() + message.m_BCC.GetSize(); ASSERT(mapiMessage.nRecipCount); //Must have at least 1 recipient!
//Allocate the recipients array mapiMessage.lpRecips = new MapiRecipDesc[mapiMessage.nRecipCount];
//Setup the "To" recipients int nRecipIndex = 0; int nToSize = message.m_To.GetSize(); for (int i=0; i<nToSize; i++) { MapiRecipDesc& recip = mapiMessage.lpRecips[nRecipIndex]; ZeroMemory(&recip, sizeof(MapiRecipDesc)); recip.ulRecipClass = MAPI_TO; CString& sName = message.m_To.ElementAt(i);
if (bResolve) { //Try to resolve the name lpMapiRecipDesc lpTempRecip; if (Resolve(sName, &lpTempRecip)) { //Resolve worked, put the resolved name back into the sName sName = lpTempRecip->lpszName;
//Don't forget to free up the memory MAPI allocated for us m_lpfnMAPIFreeBuffer(lpTempRecip); } } recip.lpszName = T2A((LPTSTR) (LPCTSTR) sName);
++nRecipIndex; }
//Setup the "CC" recipients int nCCSize = message.m_CC.GetSize(); for (i=0; i<nCCSize; i++) { MapiRecipDesc& recip = mapiMessage.lpRecips[nRecipIndex]; ZeroMemory(&recip, sizeof(MapiRecipDesc)); recip.ulRecipClass = MAPI_CC; CString& sName = message.m_CC.ElementAt(i);
if (bResolve) { //Try to resolve the name lpMapiRecipDesc lpTempRecip; if (Resolve(sName, &lpTempRecip)) { //Resolve worked, put the resolved name back into the sName sName = lpTempRecip->lpszName;
//Don't forget to free up the memory MAPI allocated for us m_lpfnMAPIFreeBuffer(lpTempRecip); } } recip.lpszName = T2A((LPTSTR) (LPCTSTR) sName);
++nRecipIndex; }
//Setup the "BCC" recipients int nBCCSize = message.m_BCC.GetSize(); for (i=0; i<nBCCSize; i++) { MapiRecipDesc& recip = mapiMessage.lpRecips[nRecipIndex]; ZeroMemory(&recip, sizeof(MapiRecipDesc)); recip.ulRecipClass = MAPI_BCC; CString& sName = message.m_BCC.ElementAt(i);
if (bResolve) { //Try to resolve the name lpMapiRecipDesc lpTempRecip; if (Resolve(sName, &lpTempRecip)) { //Resolve worked, put the resolved name back into the sName sName = lpTempRecip->lpszName;
//Don't forget to free up the memory MAPI allocated for us m_lpfnMAPIFreeBuffer(lpTempRecip); } } recip.lpszName = T2A((LPTSTR) (LPCTSTR) sName);
++nRecipIndex; }
//Setup the attachments int nAttachmentSize = message.m_Attachments.GetSize(); int nTitleSize = message.m_AttachmentTitles.GetSize(); if (nTitleSize) { ASSERT(nTitleSize == nAttachmentSize); //If you are going to set the attachment titles then you must set //the attachment title for each attachment } if (nAttachmentSize) { mapiMessage.nFileCount = nAttachmentSize; mapiMessage.lpFiles = new MapiFileDesc[nAttachmentSize]; for (i=0; i<nAttachmentSize; i++) { MapiFileDesc& file = mapiMessage.lpFiles[i]; ZeroMemory(&file, sizeof(MapiFileDesc)); file.nPosition = 0xFFFFFFFF; CString& sFilename = message.m_Attachments.ElementAt(i); file.lpszPathName = T2A((LPTSTR) (LPCTSTR) sFilename); file.lpszFileName = file.lpszPathName; if (nTitleSize) { CString& sTitle = message.m_AttachmentTitles.ElementAt(i); file.lpszFileName = T2A((LPTSTR) (LPCTSTR) sTitle); } } }
//Setup the parameters into the function FLAGS flags = 0; ULONG uiParam = 0; if (!LoggedOn()) flags |= MAPI_LOGON_UI; if (bInteractive) { flags |= MAPI_DIALOG; if (pParentWnd) uiParam = (ULONG) pParentWnd->GetSafeHwnd(); else { ASSERT(AfxGetMainWnd()); uiParam = (ULONG) AfxGetMainWnd()->GetSafeHwnd(); } }
//Do the actual send using MAPISendMail ULONG nError = m_lpfnMAPISendMail(m_hSession, uiParam, &mapiMessage, flags, 0); if (nError == SUCCESS_SUCCESS) { bSuccess = TRUE; m_nLastError = SUCCESS_SUCCESS; } else { TRACE(_T("Failed to send mail message, Error:%d\n"), nError); m_nLastError = nError; }
//Tidy up the Attachements if (nAttachmentSize) delete [] mapiMessage.lpFiles;
//Free up the Recipients memory delete [] mapiMessage.lpRecips;
return bSuccess; }
ULONG CMapiSession::GetLastError() const { return m_nLastError; }
#include "stdafx.h" #include "Mail.h" #include "MailDlg.h" #include "CMapi.h"
#ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif
BEGIN_MESSAGE_MAP(CMailApp, CWinApp) //{{AFX_MSG_MAP(CMailApp) //}}AFX_MSG ON_COMMAND(ID_HELP, CWinApp::OnHelp) END_MESSAGE_MAP()
CMailApp::CMailApp() { }
CMailApp theApp;
BOOL CMailApp::InitInstance() { #ifdef _AFXDLL Enable3dControls(); // Call this when using MFC in a shared DLL #else Enable3dControlsStatic(); // Call this when linking to MFC statically #endif
//Settings will be stored in the registry SetRegistryKey(_T("PJ Naughter"));
//Check that Mapi is installed CMapiSession session; if (!session.MapiInstalled()) { AfxMessageBox(_T("Mapi is not installed on this machine"), MB_OK | MB_ICONSTOP); return FALSE; }
//Bring up the main dialog CMailDlg dlg; m_pMainWnd = &dlg; dlg.DoModal();
return FALSE; }
#ifndef __AFXWIN_H__ #error include 'stdafx.h' before including this file for PCH #endif
#include "resource.h" // main symbols
class CMailApp : public CWinApp { public: CMailApp();
protected: //{{AFX_VIRTUAL(CMailApp) virtual BOOL InitInstance(); //}}AFX_VIRTUAL
//{{AFX_MSG(CMailApp) //}}AFX_MSG DECLARE_MESSAGE_MAP() };
#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers
#include <afxwin.h> // MFC core and standard components #include <afxtempl.h> #include <mapi.h> #include <afxext.h> // MFC extensions
#ifndef __CMAPI_H__ #define __CMAPI_H__
#ifndef MAPI_H #include <mapi.h> #endif
//Class which encapsulates a MAPI mail message class CMapiMessage { public: //Enums enum RECIPIENT_TYPE { TO, CC, BCC };
//Methods BOOL AddMultipleRecipients(const CString& sRecipients, RECIPIENT_TYPE RecipientType);
//Member variables CStringArray m_To; //The To: Recipients CStringArray m_CC; //The CC: Recipients CStringArray m_BCC; //The BCC Recipients CString m_sSubject; //The Subject of the message CString m_sBody; //The Body of the message CStringArray m_Attachments; //Files to attach to the email CStringArray m_AttachmentTitles; //Titles to use for the email file attachments };
//The class which encapsulates the MAPI connection class CMapiSession { public: //Constructors / Destructors CMapiSession(); ~CMapiSession();
//Logon / Logoff Methods BOOL Logon(const CString& sProfileName, const CString& sPassword = CString(), CWnd* pParentWnd = NULL); BOOL SharedLogon(); BOOL LoggedOn() const; BOOL Logoff();
//Send a message BOOL Send(CMapiMessage& mesage, BOOL bResolve = FALSE, BOOL bInteractive = FALSE, CWnd* pParentWnd = NULL);
//General MAPI support BOOL MapiInstalled() const;
//Error Handling ULONG GetLastError() const;
protected: //Methods void Initialise(); void Deinitialise(); BOOL Resolve(const CString& sName, lpMapiRecipDesc* lppRecip);
//Data LHANDLE m_hSession; //Mapi Session handle ULONG m_nLastError; //Last Mapi error value HINSTANCE m_hMapi; //Instance handle of the MAPI dll LPMAPILOGON m_lpfnMAPILogon; //MAPILogon function pointer LPMAPILOGOFF m_lpfnMAPILogoff; //MAPILogoff function pointer LPMAPISENDMAIL m_lpfnMAPISendMail; //MAPISendMail function pointer LPMAPIRESOLVENAME m_lpfnMAPIResolveName; //MAPIResolveName function pointer LPMAPIFREEBUFFER m_lpfnMAPIFreeBuffer; //MAPIFreeBuffer function pointer };
#endif //__CMAPI_H__
|
| < Пред. | След. > |
|---|











