1
0

docmapi.cpp 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. // This is a part of the Microsoft Foundation Classes C++ library.
  2. // Copyright (C) 1992-1998 Microsoft Corporation
  3. // All rights reserved.
  4. //
  5. // This source code is only intended as a supplement to the
  6. // Microsoft Foundation Classes Reference and related
  7. // electronic documentation provided with the library.
  8. // See these sources for detailed information regarding the
  9. // Microsoft Foundation Classes product.
  10. #include "stdafx.h"
  11. #pragma warning(disable: 4228)
  12. #include <mapi.h>
  13. #pragma warning(default: 4228)
  14. #ifdef AFX_MAPI_SEG
  15. #pragma code_seg(AFX_MAPI_SEG)
  16. #endif
  17. #ifdef _DEBUG
  18. #undef THIS_FILE
  19. static char THIS_FILE[] = __FILE__;
  20. #endif
  21. /////////////////////////////////////////////////////////////////////////////
  22. // MAPI implementation helpers and globals
  23. AFX_STATIC_DATA BOOL _afxIsMailAvail = (BOOL)-1; // start out not determined
  24. /////////////////////////////////////////////////////////////////////////////
  25. // _AFX_MAIL_STATE
  26. class _AFX_MAIL_STATE : public CNoTrackObject
  27. {
  28. public:
  29. HINSTANCE m_hInstMail; // handle to MAPI32.DLL
  30. virtual ~_AFX_MAIL_STATE();
  31. };
  32. _AFX_MAIL_STATE::~_AFX_MAIL_STATE()
  33. {
  34. if (m_hInstMail != NULL)
  35. ::FreeLibrary(m_hInstMail);
  36. }
  37. EXTERN_PROCESS_LOCAL(_AFX_MAIL_STATE, _afxMailState)
  38. /////////////////////////////////////////////////////////////////////////////
  39. // CDocument MAPI support
  40. void CDocument::OnFileSendMail()
  41. {
  42. ASSERT_VALID(this);
  43. ASSERT(_afxIsMailAvail); // update handler always gets called first
  44. CWaitCursor wait;
  45. _AFX_MAIL_STATE* pMailState = _afxMailState;
  46. if (pMailState->m_hInstMail == NULL)
  47. pMailState->m_hInstMail = ::LoadLibraryA("MAPI32.DLL");
  48. if (pMailState->m_hInstMail == NULL)
  49. {
  50. AfxMessageBox(AFX_IDP_FAILED_MAPI_LOAD);
  51. return;
  52. }
  53. ASSERT(pMailState->m_hInstMail != NULL);
  54. ULONG (PASCAL *lpfnSendMail)(ULONG, ULONG, MapiMessage*, FLAGS, ULONG);
  55. (FARPROC&)lpfnSendMail = GetProcAddress(pMailState->m_hInstMail, "MAPISendMail");
  56. if (lpfnSendMail == NULL)
  57. {
  58. AfxMessageBox(AFX_IDP_INVALID_MAPI_DLL);
  59. return;
  60. }
  61. ASSERT(lpfnSendMail != NULL);
  62. TCHAR szTempName[_MAX_PATH];
  63. TCHAR szPath[_MAX_PATH];
  64. BOOL bRemoveTemp = FALSE;
  65. if (m_strPathName.IsEmpty() || IsModified())
  66. {
  67. // save to temporary path
  68. VERIFY(GetTempPath(_countof(szPath), szPath) != 0);
  69. VERIFY(GetTempFileName(szPath, _T("afx"), 0, szTempName) != 0);
  70. // save it, but remember original modified flag
  71. BOOL bModified = IsModified();
  72. BOOL bResult = DoSave(szTempName, FALSE);
  73. SetModifiedFlag(bModified);
  74. if (!bResult)
  75. {
  76. TRACE0("Warning: file save failed during File.Send Mail.\n");
  77. return;
  78. }
  79. bRemoveTemp = TRUE;
  80. }
  81. else
  82. {
  83. // use actual file since it isn't modified
  84. lstrcpyn(szTempName, m_strPathName, _countof(szTempName));
  85. }
  86. #ifdef _UNICODE
  87. char szTempNameA[_MAX_PATH];
  88. _wcstombsz(szTempNameA, szTempName, _countof(szTempNameA));
  89. #endif
  90. // build an appropriate title for the attachment
  91. TCHAR szTitle[_MAX_PATH];
  92. if (!m_strPathName.IsEmpty())
  93. AfxGetFileName(m_strPathName, szTitle, _countof(szTitle));
  94. else
  95. {
  96. lstrcpyn(szTitle, m_strTitle, _countof(szTitle));
  97. if (m_strTitle.Find('.') == -1) // no extension
  98. {
  99. // append the default suffix if there is one
  100. CString strExt;
  101. CDocTemplate* pTemplate = GetDocTemplate();
  102. if (pTemplate != NULL &&
  103. pTemplate->GetDocString(strExt, CDocTemplate::filterExt))
  104. {
  105. lstrcat(szTitle, strExt);
  106. }
  107. }
  108. }
  109. #ifdef _UNICODE
  110. char szTitleA[_MAX_PATH];
  111. _wcstombsz(szTitleA, szTitle, _countof(szTitleA));
  112. #endif
  113. // prepare the file description (for the attachment)
  114. MapiFileDesc fileDesc;
  115. memset(&fileDesc, 0, sizeof(fileDesc));
  116. fileDesc.nPosition = (ULONG)-1;
  117. #ifdef _UNICODE
  118. fileDesc.lpszPathName = szTempNameA;
  119. fileDesc.lpszFileName = szTitleA;
  120. #else
  121. fileDesc.lpszPathName = szTempName;
  122. fileDesc.lpszFileName = szTitle;
  123. #endif
  124. // prepare the message (empty with 1 attachment)
  125. MapiMessage message;
  126. memset(&message, 0, sizeof(message));
  127. message.nFileCount = 1;
  128. message.lpFiles = &fileDesc;
  129. // prepare for modal dialog box
  130. AfxGetApp()->EnableModeless(FALSE);
  131. HWND hWndTop;
  132. CWnd* pParentWnd = CWnd::GetSafeOwner(NULL, &hWndTop);
  133. // some extra precautions are required to use MAPISendMail as it
  134. // tends to enable the parent window in between dialogs (after
  135. // the login dialog, but before the send note dialog).
  136. pParentWnd->SetCapture();
  137. ::SetFocus(NULL);
  138. pParentWnd->m_nFlags |= WF_STAYDISABLED;
  139. int nError = lpfnSendMail(0, (ULONG)pParentWnd->GetSafeHwnd(),
  140. &message, MAPI_LOGON_UI|MAPI_DIALOG, 0);
  141. // after returning from the MAPISendMail call, the window must
  142. // be re-enabled and focus returned to the frame to undo the workaround
  143. // done before the MAPI call.
  144. ::ReleaseCapture();
  145. pParentWnd->m_nFlags &= ~WF_STAYDISABLED;
  146. pParentWnd->EnableWindow(TRUE);
  147. ::SetActiveWindow(NULL);
  148. pParentWnd->SetActiveWindow();
  149. pParentWnd->SetFocus();
  150. if (hWndTop != NULL)
  151. ::EnableWindow(hWndTop, TRUE);
  152. AfxGetApp()->EnableModeless(TRUE);
  153. if (nError != SUCCESS_SUCCESS &&
  154. nError != MAPI_USER_ABORT && nError != MAPI_E_LOGIN_FAILURE)
  155. {
  156. AfxMessageBox(AFX_IDP_FAILED_MAPI_SEND);
  157. }
  158. // remove temporary file, if temporary file was used
  159. if (bRemoveTemp)
  160. CFile::Remove(szTempName);
  161. }
  162. void CDocument::OnUpdateFileSendMail(CCmdUI* pCmdUI)
  163. {
  164. ASSERT_VALID(this);
  165. if (_afxIsMailAvail == (BOOL)-1)
  166. {
  167. _afxIsMailAvail = ::GetProfileInt(_T("MAIL"), _T("MAPI"), 0) != 0 &&
  168. SearchPath(NULL, _T("MAPI32.DLL"), NULL, 0, NULL, NULL) != 0;
  169. }
  170. // enable the Send... menu item if available
  171. pCmdUI->Enable(_afxIsMailAvail);
  172. CMenu* pMenu = pCmdUI->m_pMenu;
  173. if (!_afxIsMailAvail && pMenu != NULL)
  174. {
  175. // remove the Send... menu and surrounding separators
  176. UINT nStateAbove = pMenu->GetMenuState(pCmdUI->m_nIndex-1, MF_BYPOSITION);
  177. UINT nStateBelow = pMenu->GetMenuState(pCmdUI->m_nIndex+1, MF_BYPOSITION);
  178. pMenu->RemoveMenu(pCmdUI->m_nIndex, MF_BYPOSITION);
  179. if (nStateAbove & nStateBelow & MF_SEPARATOR)
  180. {
  181. // a separator must be removed since the Send... is gone
  182. if (nStateAbove != (UINT)-1)
  183. pMenu->RemoveMenu(pCmdUI->m_nIndex-1, MF_BYPOSITION);
  184. else if (nStateBelow != (UINT)-1)
  185. pMenu->RemoveMenu(pCmdUI->m_nIndex, MF_BYPOSITION);
  186. }
  187. }
  188. }
  189. /////////////////////////////////////////////////////////////////////////////
  190. // COleDocument MAPI support
  191. void COleDocument::OnFileSendMail()
  192. {
  193. ASSERT_VALID(this);
  194. ASSERT(m_bRemember);
  195. LPSTORAGE lpOrigStg = m_lpRootStg;
  196. m_lpRootStg = NULL;
  197. TRY
  198. {
  199. m_bRemember = FALSE;
  200. CDocument::OnFileSendMail();
  201. }
  202. CATCH_ALL(e)
  203. {
  204. m_lpRootStg = lpOrigStg;
  205. m_bRemember = TRUE;
  206. THROW_LAST();
  207. }
  208. END_CATCH_ALL
  209. m_lpRootStg = lpOrigStg;
  210. m_bRemember = TRUE;
  211. }
  212. #ifdef AFX_INIT_SEG
  213. #pragma code_seg(AFX_INIT_SEG)
  214. #endif
  215. #pragma warning(disable: 4074)
  216. #pragma init_seg(lib)
  217. PROCESS_LOCAL(_AFX_MAIL_STATE, _afxMailState)
  218. /////////////////////////////////////////////////////////////////////////////