home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tricks of the Windows Gam…ming Gurus (2nd Edition)
/
Disc2.iso
/
vc98
/
mfc
/
src
/
docmapi.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
1998-06-16
|
7KB
|
259 lines
// This is a part of the Microsoft Foundation Classes C++ library.
// Copyright (C) 1992-1998 Microsoft Corporation
// All rights reserved.
//
// This source code is only intended as a supplement to the
// Microsoft Foundation Classes Reference and related
// electronic documentation provided with the library.
// See these sources for detailed information regarding the
// Microsoft Foundation Classes product.
#include "stdafx.h"
#pragma warning(disable: 4228)
#include <mapi.h>
#pragma warning(default: 4228)
#ifdef AFX_MAPI_SEG
#pragma code_seg(AFX_MAPI_SEG)
#endif
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// MAPI implementation helpers and globals
AFX_STATIC_DATA BOOL _afxIsMailAvail = (BOOL)-1; // start out not determined
/////////////////////////////////////////////////////////////////////////////
// _AFX_MAIL_STATE
class _AFX_MAIL_STATE : public CNoTrackObject
{
public:
HINSTANCE m_hInstMail; // handle to MAPI32.DLL
virtual ~_AFX_MAIL_STATE();
};
_AFX_MAIL_STATE::~_AFX_MAIL_STATE()
{
if (m_hInstMail != NULL)
::FreeLibrary(m_hInstMail);
}
EXTERN_PROCESS_LOCAL(_AFX_MAIL_STATE, _afxMailState)
/////////////////////////////////////////////////////////////////////////////
// CDocument MAPI support
void CDocument::OnFileSendMail()
{
ASSERT_VALID(this);
ASSERT(_afxIsMailAvail); // update handler always gets called first
CWaitCursor wait;
_AFX_MAIL_STATE* pMailState = _afxMailState;
if (pMailState->m_hInstMail == NULL)
pMailState->m_hInstMail = ::LoadLibraryA("MAPI32.DLL");
if (pMailState->m_hInstMail == NULL)
{
AfxMessageBox(AFX_IDP_FAILED_MAPI_LOAD);
return;
}
ASSERT(pMailState->m_hInstMail != NULL);
ULONG (PASCAL *lpfnSendMail)(ULONG, ULONG, MapiMessage*, FLAGS, ULONG);
(FARPROC&)lpfnSendMail = GetProcAddress(pMailState->m_hInstMail, "MAPISendMail");
if (lpfnSendMail == NULL)
{
AfxMessageBox(AFX_IDP_INVALID_MAPI_DLL);
return;
}
ASSERT(lpfnSendMail != NULL);
TCHAR szTempName[_MAX_PATH];
TCHAR szPath[_MAX_PATH];
BOOL bRemoveTemp = FALSE;
if (m_strPathName.IsEmpty() || IsModified())
{
// save to temporary path
VERIFY(GetTempPath(_countof(szPath), szPath) != 0);
VERIFY(GetTempFileName(szPath, _T("afx"), 0, szTempName) != 0);
// save it, but remember original modified flag
BOOL bModified = IsModified();
BOOL bResult = DoSave(szTempName, FALSE);
SetModifiedFlag(bModified);
if (!bResult)
{
TRACE0("Warning: file save failed during File.Send Mail.\n");
return;
}
bRemoveTemp = TRUE;
}
else
{
// use actual file since it isn't modified
lstrcpyn(szTempName, m_strPathName, _countof(szTempName));
}
#ifdef _UNICODE
char szTempNameA[_MAX_PATH];
_wcstombsz(szTempNameA, szTempName, _countof(szTempNameA));
#endif
// build an appropriate title for the attachment
TCHAR szTitle[_MAX_PATH];
if (!m_strPathName.IsEmpty())
AfxGetFileName(m_strPathName, szTitle, _countof(szTitle));
else
{
lstrcpyn(szTitle, m_strTitle, _countof(szTitle));
if (m_strTitle.Find('.') == -1) // no extension
{
// append the default suffix if there is one
CString strExt;
CDocTemplate* pTemplate = GetDocTemplate();
if (pTemplate != NULL &&
pTemplate->GetDocString(strExt, CDocTemplate::filterExt))
{
lstrcat(szTitle, strExt);
}
}
}
#ifdef _UNICODE
char szTitleA[_MAX_PATH];
_wcstombsz(szTitleA, szTitle, _countof(szTitleA));
#endif
// prepare the file description (for the attachment)
MapiFileDesc fileDesc;
memset(&fileDesc, 0, sizeof(fileDesc));
fileDesc.nPosition = (ULONG)-1;
#ifdef _UNICODE
fileDesc.lpszPathName = szTempNameA;
fileDesc.lpszFileName = szTitleA;
#else
fileDesc.lpszPathName = szTempName;
fileDesc.lpszFileName = szTitle;
#endif
// prepare the message (empty with 1 attachment)
MapiMessage message;
memset(&message, 0, sizeof(message));
message.nFileCount = 1;
message.lpFiles = &fileDesc;
// 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 = lpfnSendMail(0, (ULONG)pParentWnd->GetSafeHwnd(),
&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.
::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);
}
// remove temporary file, if temporary file was used
if (bRemoveTemp)
CFile::Remove(szTempName);
}
void CDocument::OnUpdateFileSendMail(CCmdUI* pCmdUI)
{
ASSERT_VALID(this);
if (_afxIsMailAvail == (BOOL)-1)
{
_afxIsMailAvail = ::GetProfileInt(_T("MAIL"), _T("MAPI"), 0) != 0 &&
SearchPath(NULL, _T("MAPI32.DLL"), NULL, 0, NULL, NULL) != 0;
}
// enable the Send... menu item if available
pCmdUI->Enable(_afxIsMailAvail);
CMenu* pMenu = pCmdUI->m_pMenu;
if (!_afxIsMailAvail && pMenu != NULL)
{
// remove the Send... menu and surrounding separators
UINT nStateAbove = pMenu->GetMenuState(pCmdUI->m_nIndex-1, MF_BYPOSITION);
UINT nStateBelow = pMenu->GetMenuState(pCmdUI->m_nIndex+1, MF_BYPOSITION);
pMenu->RemoveMenu(pCmdUI->m_nIndex, MF_BYPOSITION);
if (nStateAbove & nStateBelow & MF_SEPARATOR)
{
// a separator must be removed since the Send... is gone
if (nStateAbove != (UINT)-1)
pMenu->RemoveMenu(pCmdUI->m_nIndex-1, MF_BYPOSITION);
else if (nStateBelow != (UINT)-1)
pMenu->RemoveMenu(pCmdUI->m_nIndex, MF_BYPOSITION);
}
}
}
/////////////////////////////////////////////////////////////////////////////
// COleDocument MAPI support
void COleDocument::OnFileSendMail()
{
ASSERT_VALID(this);
ASSERT(m_bRemember);
LPSTORAGE lpOrigStg = m_lpRootStg;
m_lpRootStg = NULL;
TRY
{
m_bRemember = FALSE;
CDocument::OnFileSendMail();
}
CATCH_ALL(e)
{
m_lpRootStg = lpOrigStg;
m_bRemember = TRUE;
THROW_LAST();
}
END_CATCH_ALL
m_lpRootStg = lpOrigStg;
m_bRemember = TRUE;
}
#ifdef AFX_INIT_SEG
#pragma code_seg(AFX_INIT_SEG)
#endif
#pragma warning(disable: 4074)
#pragma init_seg(lib)
PROCESS_LOCAL(_AFX_MAIL_STATE, _afxMailState)
/////////////////////////////////////////////////////////////////////////////