Fixed issue #2507: Support keyboard shortcuts in yes/no prompts
[TortoiseGit.git] / src / Utils / MailMsg.cpp
blob3c33c5543ea07b16013d0fe796ae5dfaa0a7c9d4
1 /*************************************************************************************
2 This file is a part of CrashRpt library.
4 Copyright (c) 2003, Michael Carruth
5 All rights reserved.
7 Adjusted by Sven Strickroth <email@cs-ware.de>, 2011
8 * make it work with no attachments
9 * added flag to show mail compose dialog
10 * make it work with 32-64bit inconsistencies (http://msdn.microsoft.com/en-us/library/dd941355.aspx)
11 * auto extract filenames of attachments
12 * added AddCC
14 Redistribution and use in source and binary forms, with or without modification,
15 are permitted provided that the following conditions are met:
17 * Redistributions of source code must retain the above copyright notice, this
18 list of conditions and the following disclaimer.
20 * Redistributions in binary form must reproduce the above copyright notice,
21 this list of conditions and the following disclaimer in the documentation
22 and/or other materials provided with the distribution.
24 * Neither the name of the author nor the names of its contributors
25 may be used to endorse or promote products derived from this software without
26 specific prior written permission.
29 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
30 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
31 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
32 SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
34 TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
35 BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
36 STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
37 OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38 ***************************************************************************************/
40 ///////////////////////////////////////////////////////////////////////////////
42 // Module: MailMsg.cpp
44 // Desc: See MailMsg.h
46 // Copyright (c) 2003 Michael Carruth
48 ///////////////////////////////////////////////////////////////////////////////
50 #include "stdafx.h"
51 #include "MailMsg.h"
52 #include "UnicodeUtils.h"
54 CMailMsg::CMailMsg()
56 m_hMapi = NULL;
57 m_lpMapiSendMail = NULL;
58 m_bReady = FALSE;
59 m_bShowComposeDialog = FALSE;
62 CMailMsg::~CMailMsg()
64 if (m_bReady)
65 MAPIFinalize();
69 void CMailMsg::SetFrom(CString sAddress)
71 m_from = CUnicodeUtils::GetUTF8(sAddress);
74 void CMailMsg::SetTo(CString sAddress)
76 m_to = CUnicodeUtils::GetUTF8(sAddress);
79 void CMailMsg::SetSubject(CString sSubject)
81 m_sSubject = CUnicodeUtils::GetUTF8(sSubject);
84 void CMailMsg::SetMessage(CString sMessage)
86 m_sMessage = CUnicodeUtils::GetUTF8(sMessage);
89 void CMailMsg::SetShowComposeDialog(BOOL showComposeDialog)
91 m_bShowComposeDialog = showComposeDialog;
94 void CMailMsg::AddCC(CString sAddress)
96 m_cc.push_back((std::string)CUnicodeUtils::GetUTF8(sAddress));
99 void CMailMsg::AddAttachment(CString sAttachment, CString sTitle)
101 if (sTitle.IsEmpty())
103 int position = sAttachment.ReverseFind(_T('\\'));
104 if(position >=0)
106 sTitle = sAttachment.Mid(position+1);
108 else
110 sTitle = sAttachment;
113 m_attachments[(LPCSTR)CUnicodeUtils::GetUTF8(sAttachment)] = CUnicodeUtils::GetUTF8(sTitle);
116 BOOL CMailMsg::DetectMailClient(CString& sMailClientName)
118 CRegKey regKey;
119 TCHAR buf[1024] = _T("");
120 ULONG buf_size = 0;
121 LONG lResult;
123 lResult = regKey.Open(HKEY_CURRENT_USER, _T("SOFTWARE\\Clients\\Mail"), KEY_READ);
124 if(lResult!=ERROR_SUCCESS)
126 lResult = regKey.Open(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Clients\\Mail"), KEY_READ);
129 if(lResult==ERROR_SUCCESS)
131 buf_size = 1023;
132 #pragma warning(disable:4996)
133 LONG result = regKey.QueryValue(buf, _T(""), &buf_size);
134 #pragma warning(default:4996)
135 if(result==ERROR_SUCCESS)
137 sMailClientName = buf;
138 return TRUE;
140 regKey.Close();
142 else
144 sMailClientName = "Not Detected";
147 return FALSE;
150 BOOL CMailMsg::MAPIInitialize()
152 // Determine if there is default email program
154 CString sMailClientName;
155 if(!DetectMailClient(sMailClientName))
157 m_sErrorMsg = _T("Error detecting E-mail client");
158 return FALSE;
160 else
162 m_sErrorMsg = _T("Detected E-mail client ") + sMailClientName;
165 // Load MAPI.dll
167 m_hMapi = AtlLoadSystemLibraryUsingFullPath(_T("mapi32.dll"));
168 if (!m_hMapi)
170 m_sErrorMsg = _T("Error loading mapi32.dll");
171 return FALSE;
174 m_lpMapiSendMail = (LPMAPISENDMAIL)::GetProcAddress(m_hMapi, "MAPISendMail");
176 m_bReady = !!m_lpMapiSendMail;
178 if(!m_bReady)
180 m_sErrorMsg = _T("Not found required function entries in mapi32.dll");
183 return m_bReady;
186 void CMailMsg::MAPIFinalize()
188 ::FreeLibrary(m_hMapi);
191 CString CMailMsg::GetEmailClientName()
193 return m_sEmailClientName;
196 BOOL CMailMsg::Send()
198 if(m_lpMapiSendMail==NULL)
199 return FALSE;
201 TStrStrMap::iterator p;
202 int nIndex = 0;
203 MapiRecipDesc* pRecipients = NULL;
204 int nAttachments = 0;
205 MapiFileDesc* pAttachments = NULL;
206 ULONG status = 0;
207 MapiMessage message;
209 if(!m_bReady && !MAPIInitialize())
210 return FALSE;
212 pRecipients = new MapiRecipDesc[2 + m_cc.size()];
213 if(!pRecipients)
215 m_sErrorMsg = _T("Error allocating memory");
216 return FALSE;
219 nAttachments = (int)m_attachments.size();
220 if (nAttachments)
222 pAttachments = new MapiFileDesc[nAttachments];
223 if(!pAttachments)
225 m_sErrorMsg = _T("Error allocating memory");
226 delete[] pRecipients;
227 return FALSE;
231 // set from
232 pRecipients[0].ulReserved = 0;
233 pRecipients[0].ulRecipClass = MAPI_ORIG;
234 pRecipients[0].lpszAddress = (LPSTR)m_from.c_str();
235 pRecipients[0].lpszName = "";
236 pRecipients[0].ulEIDSize = 0;
237 pRecipients[0].lpEntryID = NULL;
239 // set to
240 pRecipients[1].ulReserved = 0;
241 pRecipients[1].ulRecipClass = MAPI_TO;
242 pRecipients[1].lpszAddress = (LPSTR)m_to.c_str();
243 pRecipients[1].lpszName = (LPSTR)m_to.c_str();
244 pRecipients[1].ulEIDSize = 0;
245 pRecipients[1].lpEntryID = NULL;
247 // add cc receipients
248 nIndex = 2;
249 for (size_t i = 0; i < m_cc.size(); ++i)
251 pRecipients[nIndex].ulReserved = 0;
252 pRecipients[nIndex].ulRecipClass = MAPI_CC;
253 pRecipients[nIndex].lpszAddress = (LPSTR)m_cc.at(i).c_str();
254 pRecipients[nIndex].lpszName = (LPSTR)m_cc.at(i).c_str();
255 pRecipients[nIndex].ulEIDSize = 0;
256 pRecipients[nIndex].lpEntryID = NULL;
257 nIndex++;
260 nIndex=0;
261 // add attachments
262 for (p = m_attachments.begin(), nIndex = 0;
263 p != m_attachments.end(); p++, nIndex++)
265 pAttachments[nIndex].ulReserved = 0;
266 pAttachments[nIndex].flFlags = 0;
267 pAttachments[nIndex].nPosition = 0xFFFFFFFF;
268 pAttachments[nIndex].lpszPathName = (LPSTR)p->first.c_str();
269 pAttachments[nIndex].lpszFileName = (LPSTR)p->second.c_str();
270 pAttachments[nIndex].lpFileType = NULL;
273 message.ulReserved = 0;
274 message.lpszSubject = (LPSTR)m_sSubject.c_str();
275 message.lpszNoteText = (LPSTR)m_sMessage.c_str();
276 message.lpszMessageType = NULL;
277 message.lpszDateReceived = NULL;
278 message.lpszConversationID = NULL;
279 message.flFlags = 0;
280 message.lpOriginator = pRecipients;
281 message.nRecipCount = (ULONG)(1 + m_cc.size());
282 message.lpRecips = &pRecipients[1];
283 message.nFileCount = nAttachments;
284 message.lpFiles = nAttachments ? pAttachments : NULL;
286 status = m_lpMapiSendMail(NULL, 0, &message, (m_bShowComposeDialog?MAPI_DIALOG:0)|MAPI_LOGON_UI, 0);
288 if(status!=SUCCESS_SUCCESS)
290 m_sErrorMsg.Format(_T("MAPISendMail has failed with code %lu."), status);
293 if (pRecipients)
294 delete [] pRecipients;
296 if (nAttachments)
297 delete [] pAttachments;
299 return (SUCCESS_SUCCESS == status);