⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 magicdoc.cpp

📁 一个邮件客户端源代码,包括收发邮件,安排日程等很多内容
💻 CPP
字号:
// Copyright (C) 1997-2002 Valeriy Ovechkin
// 
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
// 
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
//
// MagicDoc.cpp : implementation of the CMagicDoc class
//
#include "stdafx.h"
#include "Magic.h"
#include "Mailbox.h"
#include "Excerpt.h"
#include "MagicFrame.h"
#include "GeneralPage.h"
#include "PlaybackPage.h"
#include "CommandPage.h"
#include "MessagePage.h"
#include "ServerPage.h"
#include "LogPage.h"

#include "MagicDoc.h"
#include "dpassword.h"
#include "tools.h"
#include "dnewimport.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CMagicDoc

IMPLEMENT_DYNCREATE(CMagicDoc, CDocument)

BEGIN_MESSAGE_MAP(CMagicDoc, CDocument)
	//{{AFX_MSG_MAP(CMagicDoc)
	ON_COMMAND(ID_TIMER_CHECK, OnTimerCheck)
	ON_COMMAND(ID_STOP_COMMAND_ALL, OnStopCommandAll)
	ON_COMMAND(ID_STOP_PLAYBACK_ALL, OnStopPlaybackAll)
	ON_UPDATE_COMMAND_UI(ID_STOP_PLAYBACK_ALL, OnUpdateStopPlaybackAll)
	ON_UPDATE_COMMAND_UI(ID_STOP_COMMAND_ALL, OnUpdateStopCommandAll)
	ON_COMMAND(ID_PASSWORD, OnPassword)
	ON_UPDATE_COMMAND_UI(ID_PASSWORD, OnUpdatePassword)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CMagicDoc construction/destruction

CMagicDoc::CMagicDoc()
{
	// TODO: add one-time construction code here

}

CMagicDoc::~CMagicDoc()
{
}

/////////////////////////////////////////////////////////////////////////////
// CMagicDoc serialization
static BYTE nVersion = 2;
void CMagicDoc::Serialize(CArchive& ar)
{
	m_listMailbox.Serialize( ar );
	if (ar.IsStoring())
	{
		ar << nVersion;
		theApp.m_Filters.Serialize( ar );
	}
	else
	{
		// old version does not have version number stored, so
		//  have to use exception handler
		try
		{
			BYTE bVer = 0;
			ar >> bVer;
			if (bVer <= nVersion)
			{
				theApp.m_Filters.Serialize( ar );
			}
		}
		catch(CArchiveException* e)
		{
			e->Delete();
			theApp.GenDefaultFilters();
		}
	}
}

/////////////////////////////////////////////////////////////////////////////
// CMagicDoc diagnostics

#ifdef _DEBUG
void CMagicDoc::AssertValid() const
{
	CDocument::AssertValid();
}

void CMagicDoc::Dump(CDumpContext& dc) const
{
	CDocument::Dump(dc);
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CMagicDoc commands

void CMagicDoc::DeleteContents() 
{
	POSITION pos = GetFirstViewPosition();
	while( pos ) VERIFY( ( (CListView*) GetNextView( pos ) )->GetListCtrl().DeleteAllItems() );	
	while( !m_listMailbox.IsEmpty() ) delete m_listMailbox.RemoveHead(); 
	
	CDocument::DeleteContents();
}

void CMagicDoc::NewMailbox()
{
	DNewImport dlg;
	if (dlg.DoModal() == IDCANCEL)
		return;

	CMailbox *pMailbox = new CMailbox();
	if (dlg.m_nSel == 1)
	{
		pMailbox->m_strAlias = dlg.m_sAlias;
		pMailbox->m_strUser = dlg.m_sUser;
		pMailbox->m_strHost = dlg.m_sServer;
		pMailbox->m_intPort = dlg.m_nPort;
	}
	CTypedPtrArray < CPtrArray, CMailbox* > arrayMailbox;
	arrayMailbox.Add( pMailbox );

	CGeneralPage pageG; 
	CCommandPage pageC; 
	CPlaybackPage pageP; 
	CMessagePage pageM;

	pageG.Attach( &arrayMailbox );
	pageC.Attach( &arrayMailbox );
	pageP.Attach( &arrayMailbox );
	pageM.Attach( &arrayMailbox );

	CPropertySheet sheet( IDP_MAILBOX_PROPERTIES_TITLE, AfxGetMainWnd() );
	sheet.AddPage( &pageG );
	sheet.AddPage( &pageC );
	sheet.AddPage( &pageP );
	sheet.AddPage( &pageM );

	if( IDOK == sheet.DoModal() )
	{
		m_listMailbox.AddHead( pMailbox );
		SetModifiedFlag();
	}
	else
	{
		delete pMailbox;
	}
}

void CMagicDoc::DeleteMailbox( CMailbox* pMailbox ) 
{
	ASSERT( pMailbox && m_listMailbox.Find( pMailbox ) );
	m_listMailbox.RemoveAt( m_listMailbox.Find( pMailbox ) );
	delete pMailbox;
	SetModifiedFlag();
}

void CMagicDoc::OnTimerCheck() 
{
	POSITION pos = m_listMailbox.GetHeadPosition();

	while( pos )
	{
		CMailbox &mbox = *m_listMailbox.GetNext( pos );
		mbox.SetElapsed();
		if (mbox.IsDisabled())
			continue;
		if( !theApp.bIsSuspended && mbox.m_intPoll )
		{
			if( ( mbox.m_intElapsed && 
					!( mbox.m_intElapsed % mbox.m_intPoll ) ) ||
				( mbox.m_intElapsed < 0 && STATE_FINAL( mbox.m_intState ) ) )
			{
				mbox.Check();
			}
		}
	}
}

void CMagicDoc::EndResolveHostByName( WPARAM wParam, LPARAM lParam )
{
	for( POSITION pos = m_listMailbox.GetHeadPosition(); pos; m_listMailbox.GetNext( pos ) )
	{
		m_listMailbox.GetAt( pos )->EndResolveHostByName( wParam, lParam );
	}
}

void CMagicDoc::MailboxProperties( CTypedPtrArray < CPtrArray, CMailbox* > &arrayMailbox ) 
{
	CGeneralPage pageG; 
	CCommandPage pageC; 
	CPlaybackPage pageP; 
	CMessagePage pageM;
	CServerPage pageS;
	CLogPage pageL;

	pageG.Attach( &arrayMailbox );
	pageC.Attach( &arrayMailbox );
	pageP.Attach( &arrayMailbox );
	pageM.Attach( &arrayMailbox );
	pageS.Attach( &arrayMailbox );
	pageL.Attach( &arrayMailbox );

	CPropertySheet sheet( IDP_MAILBOX_PROPERTIES_TITLE, AfxGetMainWnd() );
	sheet.AddPage( &pageG );
	sheet.AddPage( &pageC );
	sheet.AddPage( &pageP );
	sheet.AddPage( &pageM );
	sheet.AddPage( &pageS );
	sheet.AddPage( &pageL );

	sheet.DoModal();
}

void CMagicDoc::OnStopCommandAll() 
{
	if( theApp.m_hCmdID )
	{
		TerminateProcess( theApp.m_hCmdID, 0 );
		theApp.m_hCmdID = 0;
	}

	POSITION pos = m_listMailbox.GetHeadPosition();
	while( pos )
	{
		CMailbox &mbox = *m_listMailbox.GetNext( pos );
		if( mbox.m_hCmdID )
		{
			TerminateProcess( mbox.m_hCmdID, 0 );
			mbox.m_hCmdID = 0;
		}
	}
}

void CMagicDoc::OnUpdateStopCommandAll(CCmdUI* pCmdUI) 
{
	BOOL bEnable = FALSE;
	DWORD dwExitCode = 0;

	if( theApp.m_hCmdID )
	{
		if( !GetExitCodeProcess( theApp.m_hCmdID, &dwExitCode ) || STILL_ACTIVE != dwExitCode )
		{
			theApp.m_hCmdID = 0;
		}
		else bEnable = TRUE;
	}


	POSITION pos = m_listMailbox.GetHeadPosition();
	while( pos )
	{
		CMailbox &mbox = *m_listMailbox.GetNext( pos );
		if( mbox.m_hCmdID )
		{
			if( !GetExitCodeProcess( mbox.m_hCmdID, &dwExitCode ) || STILL_ACTIVE != dwExitCode )
			{
				mbox.m_hCmdID = 0;
			}
			else bEnable = TRUE;
		}
	}

	if( pCmdUI ) pCmdUI->Enable( bEnable );		  
}

void CMagicDoc::OnStopPlaybackAll() 
{
	if( theApp.m_uMciID )
	{
		mciSendCommand( theApp.m_uMciID, MCI_STOP, MCI_WAIT, NULL );
		mciSendCommand( theApp.m_uMciID, MCI_CLOSE, 0, NULL);
		theApp.m_uMciID = 0;
	}

	POSITION pos = m_listMailbox.GetHeadPosition();
	while( pos )
	{
		CMailbox &mbox = *m_listMailbox.GetNext( pos );
		if( mbox.m_uMciID ) 
		{
			mciSendCommand( mbox.m_uMciID, MCI_STOP, MCI_WAIT, NULL );
			mciSendCommand( mbox.m_uMciID, MCI_CLOSE, 0, NULL);
			mbox.m_uMciID = 0;
		}
	}

}

void CMagicDoc::OnUpdateStopPlaybackAll(CCmdUI* pCmdUI) 
{
	BOOL bEnable = FALSE;

	if( theApp.m_uMciID ) bEnable = TRUE;
	else
	{
		POSITION pos = m_listMailbox.GetHeadPosition();
		while( pos )
		{
			CMailbox &mbox = *m_listMailbox.GetNext( pos );
			if( mbox.m_uMciID )
			{
				bEnable = TRUE;
				break;
			}
		}
	}

	if( pCmdUI ) pCmdUI->Enable( bEnable );
}

void CMagicDoc::MciNotify( UINT uMciID )
{
	mciSendCommand( uMciID, MCI_STOP, MCI_WAIT, NULL );
	mciSendCommand( uMciID, MCI_CLOSE, 0, NULL);

	if( theApp.m_uMciID == uMciID ) theApp.m_uMciID = 0;
	else
	{
		POSITION pos = m_listMailbox.GetHeadPosition();
		while( pos )
		{
			CMailbox &mbox = *m_listMailbox.GetNext( pos );
			if( mbox.m_uMciID == uMciID ) 
			{
				mbox.m_uMciID = 0;
				break;
			}
		}
	}
}

void CMagicDoc::Check()
{
	POSITION pos = m_listMailbox.GetHeadPosition();
	while( pos )
	{
		CMailbox &mbox = *m_listMailbox.GetNext( pos );
		if( mbox.m_bitSelected && !mbox.IsDisabled()) mbox.Check();
	}
}

void CMagicDoc::StopChecking()
{
	POSITION pos = m_listMailbox.GetHeadPosition();
	while( pos )
	{
		CMailbox &mbox = *m_listMailbox.GetNext( pos );
		if( mbox.m_bitSelected ) mbox.StopChecking();
	}
}

void CMagicDoc::UpdateItem( CObject *pObject )
{
	ASSERT( pObject );

	if( pObject->IsKindOf( RUNTIME_CLASS( CMailbox ) ) )
	{
		CMailbox &mbox = *(CMailbox*) pObject;
		int intChanged = mbox.m_intChanged;
		if( !intChanged ) return;

		UpdateAllViews( 0, 0, &mbox );
	
		if( mbox.IsChanged( COLUMN_MAIL ) && STATE_FINAL( mbox.m_intState ) )
		{
			int intNewMailCount = 0;

			for( int i = 0; i < mbox.m_arrayExcerpt.GetSize(); ++i )
			{
				if( !mbox.m_arrayExcerpt[i]->m_bitWasReported )
				{
					++intNewMailCount;
					mbox.m_arrayExcerpt[i]->m_bitWasReported = 1;
				}
			}

			int intTotalMailCount = 0;

			POSITION pos = m_listMailbox.GetHeadPosition();
			while( pos ) intTotalMailCount += m_listMailbox.GetNext( pos )->m_arrayExcerpt.GetSize();

			CMagicFrame *wnd = (CMagicFrame*) AfxGetMainWnd();
			if( wnd )
			{
				wnd->UpdateMailCount( intTotalMailCount, intNewMailCount );
				if( intNewMailCount )
				{
					wnd->PostMessage( VM_START_COMMAND, intNewMailCount, (LPARAM) &mbox ); 
					wnd->PostMessage( VM_START_PLAYBACK, intNewMailCount, (LPARAM) &mbox ); 
					wnd->PostMessage( VM_START_MESSAGE, intNewMailCount, (LPARAM) &mbox ); 
				}
			}
		}

		mbox.m_bitCreated = 0;
		mbox.m_intChanged ^= intChanged;
	}
	else if( pObject->IsKindOf( RUNTIME_CLASS( CExcerpt ) )	)
	{
		CExcerpt &xrpt = *(CExcerpt*) pObject;
		int intChanged = xrpt.m_intChanged;
		if( !intChanged ) return;
		UpdateAllViews( 0, 0, &xrpt );
		xrpt.m_bitCreated = 0;
		xrpt.m_intChanged ^= intChanged;
	}
}

void CMagicDoc::UpdateIdle()
{
	UpdateAllViews( 0, HINT_DISABLE_SORT, 0 );

	POSITION pos = m_listMailbox.GetHeadPosition(); 
	while( pos )
	{	
		CMailbox &mbox = *m_listMailbox.GetNext( pos );
		UpdateItem( &mbox );
		int i = mbox.m_arrayExcerpt.GetSize(); 
		while( i ) UpdateItem( mbox.m_arrayExcerpt[--i] );
	}

	UpdateAllViews( 0, HINT_ENABLE_SORT, 0 );
}


BOOL CMagicDoc::OnOpenDocument(LPCTSTR lpszPathName) 
{
	LPBYTE pData = NULL;
	BOOL bOK = TRUE;
	CWaitCursor wait;
	try
	{
		CFile file;
		CFileException fe;
		if (!file.Open(lpszPathName, CFile::modeRead, &fe))
		{
			ReportSaveLoadException(lpszPathName, &fe, 
				FALSE, AFX_IDP_FAILED_TO_OPEN_DOC);
			return FALSE;
		}
		DeleteContents();
		SetModifiedFlag();  // dirty during de-serialize

		DWORD dwLen = file.GetLength();
		pData = new BYTE[dwLen+5];
		DWORD dwRead = file.Read(pData, dwLen);

		// check signiture - encrypted?
		if (IsEncrypted(pData, dwRead))		// decrypt data
		{
			// prompt for password
			do 
			{
				DPassword dlg(FALSE);
				if (dlg.DoModal() != IDOK)
				{
					delete pData;
					SetModifiedFlag(FALSE);
					// can not return FALSE, due to bugs in reinit
					if (AfxGetMainWnd())
						AfxGetMainWnd()->PostMessage(WM_COMMAND, ID_FILE_NEW);
					else
						((CMagicApp*)AfxGetApp())->m_bReset = TRUE;
					return TRUE;
				}
				m_sPassword = dlg.m_sPassword;
			}
			while (!DecryptData(pData, dwRead, m_sPassword));
		}
		else
			m_sPassword.Empty();

		CMemFile mf;
		mf.Attach(pData, dwRead);
		CArchive ar(&mf, CArchive::load);
		ar.m_pDocument = this;
		Serialize(ar);     // load me
		ar.Close();
		mf.Detach();
	}
	catch (CException* e)
	{
		ReportSaveLoadException(lpszPathName, e, 
				FALSE, AFX_IDP_FAILED_TO_OPEN_DOC);
		e->Delete();
		bOK = FALSE;
	}
	catch(...)
	{
		ReportSaveLoadException(lpszPathName, NULL, 
				FALSE, AFX_IDP_FAILED_TO_OPEN_DOC);
		bOK = FALSE;
	}
	delete pData;
	if (!bOK)
	{
		DeleteContents();
		return FALSE;
	}
	
	SetModifiedFlag(FALSE);
	
	CMagicFrame *wnd = (CMagicFrame*) AfxGetMainWnd();
	if( wnd )
	{
		wnd->UpdateMailCount( 0, 0 );
	}

	return TRUE;
}

BOOL CMagicDoc::OnNewDocument() 
{
	CMagicFrame *wnd = (CMagicFrame*) AfxGetMainWnd();
	if( wnd )
	{
		wnd->UpdateMailCount( 0, 0 );
	}
	
	return CDocument::OnNewDocument();
}

BOOL CMagicDoc::OnSaveDocument(LPCTSTR lpszPathName) 
{
	LPBYTE pData = NULL;
	BOOL bOK = TRUE;
	try
	{
		CMemFile mf;
		CArchive ar(&mf, CArchive::store | CArchive::bNoFlushOnDelete);
		ar.m_pDocument = this;
		CWaitCursor wait;
		Serialize(ar);     // save me
		ar.Close();
		DWORD dwLen = mf.GetLength();
		pData = mf.Detach();
		if (!m_sPassword.IsEmpty())
		{
			EncryptData(pData, dwLen, m_sPassword);
		}
		CFile file;
		CFileException fe;
		if (file.Open(lpszPathName, CFile::modeWrite|CFile::modeCreate, &fe))
		{
			file.Write(pData, dwLen);
			file.Close();
		}
		else
		{
			ReportSaveLoadException(lpszPathName, &fe, 
				TRUE, AFX_IDP_FAILED_TO_SAVE_DOC);
			bOK = FALSE;
		}
	}
	catch (CException* e)
	{
		ReportSaveLoadException(lpszPathName, e, 
			TRUE, AFX_IDP_FAILED_TO_SAVE_DOC);
		e->Delete();
		bOK = FALSE;
	}
	catch(...)
	{
		ReportSaveLoadException(lpszPathName, NULL, 
			TRUE, AFX_IDP_FAILED_TO_SAVE_DOC);
		bOK = FALSE;
	}
	
	if (bOK)
		SetModifiedFlag(FALSE);
	delete pData;

	return bOK;
}

void CMagicDoc::OnPassword() 
{
	DPassword dlg(TRUE);
	dlg.m_sPassword = m_sPassword;
	if (dlg.DoModal()!=IDOK)
		return;
	m_sPassword = dlg.m_sPassword;
	SetModifiedFlag(TRUE);
}

void CMagicDoc::OnUpdatePassword(CCmdUI* pCmdUI) 
{
	pCmdUI->SetCheck(!m_sPassword.IsEmpty());
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -