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

📄 updatedlg.cpp

📁 本程序是VC为平台开发的股票资讯系统
💻 CPP
字号:
// UpdateDlg.cpp : implementation file
//

#include "stdafx.h"
#include "Resource.h"
#include "UpdateDlg.h"

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

const UINT WM_FTPTRANSFER_THREAD_FINISHED = WM_APP + 1;
const UINT WM_FTPTRANSFER_ASK_OVERWRITE_FILE = WM_APP + 2;

/////////////////////////////////////////////////////////////////////////////
// CUpdateDlg dialog
IMPLEMENT_DYNAMIC(CUpdateDlg, CDialog);

CUpdateDlg::CUpdateDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CUpdateDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CUpdateDlg)
	//}}AFX_DATA_INIT
	m_hInternetSession = NULL;
	m_hFTPConnection = NULL;
	m_hFTPFile = NULL;
	m_bAbort = FALSE;
	m_bSafeToClose = FALSE;
	m_pThread = NULL;
	m_bUsingAttached = NULL;
	m_bDownload = TRUE;
	m_nPort = INTERNET_DEFAULT_FTP_PORT;
	m_bBinary = TRUE;
	m_bOverwrite = FALSE;
}

void CUpdateDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CUpdateDlg)
	DDX_Control(pDX, IDC_PROGRESS1, m_ctrlProgress);
	DDX_Control(pDX, IDC_ANIMATE1, m_ctrlAnimate);
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CUpdateDlg, CDialog)
	//{{AFX_MSG_MAP(CUpdateDlg)
	ON_WM_CLOSE()
	ON_WM_DESTROY()
	//}}AFX_MSG_MAP
	ON_MESSAGE(WM_FTPTRANSFER_THREAD_FINISHED, OnThreadFinished)
	ON_MESSAGE(WM_FTPTRANSFER_ASK_OVERWRITE_FILE, OnAskOverwrite)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CUpdateDlg message handlers

void CUpdateDlg::AttachToExisitingHandles(HINTERNET hInternetSession, HINTERNET hFTPConnection)
{
	ASSERT(m_hInternetSession == NULL);
	ASSERT(m_hFTPConnection == NULL);
	m_hInternetSession = hInternetSession;
	m_hFTPConnection = hFTPConnection;
	m_bUsingAttached = TRUE;
}

LRESULT CUpdateDlg::OnAskOverwrite(WPARAM /*wParam*/, LPARAM /*lParam*/)
{
	CString sMsg;
	AfxFormatString1(sMsg, IDS_TRANSFER_OK_TO_OVERWRITE, m_sRemoteFile);
	return (AfxMessageBox(sMsg, MB_YESNO) == IDYES);
}

LRESULT CUpdateDlg::OnThreadFinished(WPARAM wParam, LPARAM /*lParam*/)
{
	//It's now safe to close since the thread has signaled us
	m_bSafeToClose = TRUE;

	//Stop the animation
	m_ctrlAnimate.Stop();

	//If an error occured display the message box
	if (m_bAbort)
		EndDialog(IDCANCEL);
	else if (wParam)
	{
		if (m_sError.GetLength())  
			AfxMessageBox(m_sError);
		EndDialog(IDCANCEL);
	}
	else
		EndDialog(IDOK);

	return 0L;
}

BOOL CUpdateDlg::OnInitDialog() 
{
	CDialog::OnInitDialog();
	
	// TODO: Add extra initialization here
	// Setup the animation control
	m_ctrlAnimate.Open(IDR_AVI_UPDATE);

	// Check to see if the file we are downloading exists and if
	// it does, then ask the user if they were it overwritten
	if (m_bDownload)
	{
		CFileStatus fs;
		ASSERT(m_sLocalFile.GetLength());
		if (!m_bOverwrite && CFile::GetStatus(m_sLocalFile, fs))
		{
			CString sMsg;
			AfxFormatString1(sMsg, IDS_OK_TO_OVERWRITE, m_sLocalFile);
			if (AfxMessageBox(sMsg, MB_YESNO) != IDYES)
			{
				TRACE(_T("Failed to confirm file overwrite, download aborted\n"));
				EndDialog(IDCANCEL);
				return TRUE;
			}
		}
	}

	//Try and open the file we will downloading into / uploading from
	if (m_bDownload)
	{
		if (!m_LocalFile.Open(m_sLocalFile, CFile::modeCreate | CFile::modeWrite | CFile::shareDenyWrite))
		{
			TRACE(_T("Failed to open the file to download into, Error:%d\n"), GetLastError());
			CString sError;
			sError.Format(_T("%d"), ::GetLastError());
			CString sMsg;
			AfxFormatString1(sMsg, IDS_FAIL_FILE_OPEN, sError);
			AfxMessageBox(sMsg);
			EndDialog(IDCANCEL);
			return TRUE;
		}
	}
	else
	{
		if (!m_LocalFile.Open(m_sLocalFile, CFile::modeRead | CFile::shareDenyWrite))
		{
			TRACE(_T("Failed to open the file to upload, Error:%d\n"), GetLastError());
			CString sError;
			sError.Format(_T("%d"), ::GetLastError());
			CString sMsg;
			AfxFormatString1(sMsg, IDS_FTPTRANSFER_FAIL_LOCALFILE_OPEN2, sError);
			AfxMessageBox(sMsg);
			EndDialog(IDCANCEL);
			return TRUE;
		}
	}

	//Spin off the background thread which will do the actual file transfer
	m_pThread = AfxBeginThread(_TransferThread, this, THREAD_PRIORITY_NORMAL, CREATE_SUSPENDED);
	if (m_pThread == NULL)
	{
		TRACE(_T("Failed to create transfer thread, dialog is aborting\n"));
		EndDialog(IDCANCEL);
		return TRUE;
	}
	m_pThread->m_bAutoDelete = FALSE;
	m_pThread->ResumeThread();
	
	return TRUE;  // return TRUE unless you set the focus to a control
	              // EXCEPTION: OCX Property Pages should return FALSE
}

UINT CUpdateDlg::_TransferThread(LPVOID pParam)
{
	//Convert from the SDK world to the C++ world
	CUpdateDlg* pDlg = (CUpdateDlg*) pParam;
	ASSERT(pDlg);
	ASSERT(pDlg->IsKindOf(RUNTIME_CLASS(CUpdateDlg)));
	pDlg->TransferThread();
	return 0;
}

void CUpdateDlg::SetProgressRange(DWORD dwFileSize)
{
	m_ctrlProgress.SetRange(0, (short)((dwFileSize+512)/1024));
}

void CUpdateDlg::SetProgress(DWORD dwBytesRead)
{
	m_ctrlProgress.SetPos(dwBytesRead/1024);
}

void CUpdateDlg::PlayAnimation()
{
	m_ctrlAnimate.Play(0, (UINT)-1, (UINT)-1);
}

void CUpdateDlg::HandleThreadErrorWithLastError(UINT nIDError, DWORD dwLastError)
{
	//Form the error string to report
	CString sError;

	DWORD dwErr = dwLastError;
	if (dwErr == 0)
		dwErr = ::GetLastError();
	if (dwErr == ERROR_INTERNET_EXTENDED_ERROR)
	{
		DWORD dwInetError;
		DWORD dwSize=0;
		::InternetGetLastResponseInfo(&dwInetError, NULL, &dwSize);
		TCHAR* pszResponse = new TCHAR[dwSize+1];
		::InternetGetLastResponseInfo(&dwInetError, pszResponse, &dwSize);
		pszResponse[dwSize] = _T('\0');
		sError = pszResponse;
		sError = _T("\n") + sError; //Add a line feed between the normal message
									//and the verbose error message
		delete [] pszResponse;	
	}
	else
		sError.Format(_T("%d"), dwErr);
	AfxFormatString1(m_sError, nIDError, sError);

	//Delete the file being downloaded to if it is present
	if (m_bDownload)
	{
		m_LocalFile.Close();
		::DeleteFile(m_sLocalFile);
	}

	PostMessage(WM_FTPTRANSFER_THREAD_FINISHED, 1);
}

void CUpdateDlg::HandleThreadError(UINT nIDError)
{
	m_sError.LoadString(nIDError);
	PostMessage(WM_FTPTRANSFER_THREAD_FINISHED, 1);
}

void CUpdateDlg::TransferThread()
{
	//Create the Internet session handle (if needed)
	if (!m_bUsingAttached)
	{
		ASSERT(m_hInternetSession == NULL);
		m_hInternetSession = ::InternetOpen(NULL, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
		if (m_hInternetSession == NULL)
		{
			TRACE(_T("Failed in call to InternetOpen, Error:%d\n"), ::GetLastError());
			HandleThreadErrorWithLastError(IDS_FTPTRANSFER_GENERIC_ERROR);
			return;
		}

		//Should we exit the thread
		if (m_bAbort)
		{
			PostMessage(WM_FTPTRANSFER_THREAD_FINISHED);
			return;
		} 
	} 
	ASSERT(m_hInternetSession);  

	//Should we exit the thread
	if (m_bAbort)
	{
		PostMessage(WM_FTPTRANSFER_THREAD_FINISHED);
		return;
	}  

	//Make the connection to the FTP server (if needed)
	if (!m_bUsingAttached)
	{
		ASSERT(m_hFTPConnection == NULL);
		ASSERT(m_sServer.GetLength());
		if (m_sUserName.GetLength())
			m_hFTPConnection = ::InternetConnect(m_hInternetSession, m_sServer, m_nPort, 
				m_sUserName, m_sPassword, INTERNET_SERVICE_FTP, 0, (DWORD) this);
		else
			m_hFTPConnection = ::InternetConnect(m_hInternetSession, m_sServer, 
				m_nPort, NULL, NULL, INTERNET_SERVICE_FTP, 0, (DWORD) this);
		if (m_hFTPConnection == NULL)
		{
			TRACE(_T("Failed in call to InternetConnect, Error:%d\n"), ::GetLastError());
			HandleThreadErrorWithLastError(IDS_FAIL_CONNECT_SERVER);
			return;
		}

		//Should we exit the thread
		if (m_bAbort)
		{
			PostMessage(WM_FTPTRANSFER_THREAD_FINISHED);
			return;
		} 
	}
	ASSERT(m_hFTPConnection); 

	//Start the animation to signify that the download is taking place
	PlayAnimation();

	// Get the length of the file to transfer            
	DWORD dwFileSize = 0;
	BOOL bGotFileSize = FALSE;
	if (m_bDownload)
	{
		WIN32_FIND_DATA wfd;
		HINTERNET hFind = ::FtpFindFirstFile(m_hFTPConnection, 
			m_sRemoteFile, &wfd, INTERNET_FLAG_RELOAD | INTERNET_FLAG_DONT_CACHE, (DWORD) this); 
		if (hFind)
		{
			//Set the progress control range
			bGotFileSize = TRUE;
			dwFileSize = (DWORD) wfd.nFileSizeLow;
			SetProgressRange(dwFileSize);

			//Destroy the enumeration handle now that we are finished with it
			InternetCloseHandle(hFind);
		}
	}
	else
	{
		bGotFileSize = TRUE;
		dwFileSize = m_LocalFile.GetLength();
		SetProgressRange(dwFileSize);
	}

	//Should we exit the thread
	if (m_bAbort)
	{
		PostMessage(WM_FTPTRANSFER_THREAD_FINISHED);
		return;
	}  

	//check to see if the file already exists on the server  
	if (!m_bDownload)
	{
		WIN32_FIND_DATA wfd;
		HINTERNET hFind = ::FtpFindFirstFile(m_hFTPConnection, m_sRemoteFile, &wfd, INTERNET_FLAG_RELOAD | 
			INTERNET_FLAG_DONT_CACHE, (DWORD) this); 
		BOOL bFound = FALSE;
		if (hFind)
		{
			bFound = TRUE;
      
			//Destroy the enumeration handle now that we are finished with it
			InternetCloseHandle(hFind);
		}

		if (bFound && !m_bOverwrite && SendMessage(WM_FTPTRANSFER_ASK_OVERWRITE_FILE) == 0)
		{
			PostMessage(WM_FTPTRANSFER_THREAD_FINISHED, 1);
			return;
		}
	}

	//Should we exit the thread
	if (m_bAbort)
	{
		PostMessage(WM_FTPTRANSFER_THREAD_FINISHED);
		return;
	}  

	//Open the remote file
	ASSERT(m_hFTPFile == NULL);
	if (m_bDownload)
	{
		if (m_bBinary)
			m_hFTPFile = FtpOpenFile(m_hFTPConnection, m_sRemoteFile, GENERIC_READ, FTP_TRANSFER_TYPE_BINARY | 
				INTERNET_FLAG_RELOAD | INTERNET_FLAG_DONT_CACHE, (DWORD) this);
		else
			m_hFTPFile = FtpOpenFile(m_hFTPConnection, m_sRemoteFile, GENERIC_READ, FTP_TRANSFER_TYPE_ASCII | 
				INTERNET_FLAG_RELOAD | INTERNET_FLAG_DONT_CACHE, (DWORD) this);
	}
	else
	{
		if (m_bBinary)  
			m_hFTPFile = FtpOpenFile(m_hFTPConnection, m_sRemoteFile, GENERIC_WRITE, FTP_TRANSFER_TYPE_BINARY | 
				INTERNET_FLAG_RELOAD | INTERNET_FLAG_DONT_CACHE, (DWORD) this);
		else
			m_hFTPFile = FtpOpenFile(m_hFTPConnection, m_sRemoteFile, GENERIC_WRITE, FTP_TRANSFER_TYPE_ASCII | 
				INTERNET_FLAG_RELOAD | INTERNET_FLAG_DONT_CACHE, (DWORD) this);
	}
	if (m_hFTPFile == NULL)
	{
		TRACE(_T("Failed in call to FtpOpenFile, Error:%d\n"), ::GetLastError());
		HandleThreadErrorWithLastError(IDS_FTPTRANSFER_FAIL_OPEN_FILE);
		return;
	}

	//Should we exit the thread
	if (m_bAbort)
	{
		PostMessage(WM_FTPTRANSFER_THREAD_FINISHED);
		return;
	}  

	//Now do the actual reading / writing of the file
	DWORD dwStartTicks = ::GetTickCount();
	DWORD dwCurrentTicks = dwStartTicks;
	DWORD dwBytesRead = 0;
	DWORD dwBytesWritten = 0;
	char szReadBuf[1024];
	DWORD dwBytesToRead = 1024;
	DWORD dwTotalBytesRead = 0;
	DWORD dwTotalBytesWritten = 0;
	DWORD dwLastTotalBytes = 0;
	DWORD dwLastPercentage = 0;
	
	do
	{
		if (m_bDownload)
		{
			//Read from the remote file
			if (!::InternetReadFile(m_hFTPFile, szReadBuf, dwBytesToRead, &dwBytesRead))
			{
				TRACE(_T("Failed in call to InternetReadFile, Error:%d\n"), ::GetLastError());
				HandleThreadErrorWithLastError(IDS_ERROR_READFILE);
				return;
			}
			else if (dwBytesRead && !m_bAbort)
			{
				//Write the data to file
				TRY
				{
					m_LocalFile.Write(szReadBuf, dwBytesRead);
				}
				CATCH(CFileException, e);                                          
				{
					TRACE(_T("An exception occured while writing to the download file\n"));
					HandleThreadErrorWithLastError(IDS_ERROR_READFILE, e->m_lOsError);
					e->Delete();
					return;
				}
				END_CATCH

				//Increment the total number of bytes read
				dwTotalBytesRead += dwBytesRead;  
				UpdateControlsDuringTransfer(dwTotalBytesRead, dwLastPercentage, bGotFileSize, dwFileSize);
			}
		}
		else
		{
			//Read the data from the local file
			TRY
			{
				dwBytesRead = m_LocalFile.Read(szReadBuf, 1024);
			}
			CATCH(CFileException, e);                                          
			{
				TRACE(_T("An exception occured while reading the local file\n"));
				HandleThreadErrorWithLastError(IDS_ERROR_READFILE, e->m_lOsError);
				e->Delete();
				return;
			}
			END_CATCH

			//Write to the remote file
			if (dwBytesRead)
			{
				if (!::InternetWriteFile(m_hFTPFile, szReadBuf, dwBytesRead, &dwBytesWritten))
				{
					TRACE(_T("Failed in call to InternetWriteFile, Error:%d\n"), ::GetLastError());
					HandleThreadErrorWithLastError(IDS_FTPTRANSFER_ERROR_WRITEFILE);
					return;
				}
				else if (dwBytesWritten && !m_bAbort)
				{
					//Increment the total number of bytes read
					dwTotalBytesWritten += dwBytesWritten;  
					UpdateControlsDuringTransfer(dwTotalBytesWritten, dwLastPercentage, bGotFileSize, dwFileSize);
				}
			}
		}
	} 
	while (dwBytesRead && !m_bAbort);

	//Delete the file being downloaded, if it is present and the download was aborted
	m_LocalFile.Close();
	if (m_bAbort && m_bDownload)
		::DeleteFile(m_sLocalFile);

	//We're finished
	PostMessage(WM_FTPTRANSFER_THREAD_FINISHED);
}

void CUpdateDlg::UpdateControlsDuringTransfer(DWORD dwTotalBytesRead, 
		DWORD& dwLastPercentage, BOOL bGotFileSize, DWORD dwFileSize)
{
	if (bGotFileSize)
	{
		//Update the percentage downloaded in the caption
		DWORD dwPercentage = (DWORD) (dwTotalBytesRead * 100.0 / dwFileSize);
		if (dwPercentage != dwLastPercentage)
		{
			//Update the progress control bar
			SetProgress(dwTotalBytesRead);
		}
	}
}

void CUpdateDlg::OnClose() 
{
  if (m_bSafeToClose)	
	  CDialog::OnClose();
  else
  {
    //Just set the abort flag to TRUE and
    //disable the cancel button
    m_bAbort = TRUE;	
  }
}

void CUpdateDlg::OnDestroy() 
{
	//Wait for the worker thread to exit
	if (m_pThread)
	{
		WaitForSingleObject(m_pThread->m_hThread, INFINITE);
		delete m_pThread;
		m_pThread = NULL;
	}

	//Free up the internet handles we may be using
	::InternetCloseHandle(m_hFTPFile);
	m_hFTPFile = NULL;

	if (!m_bUsingAttached)
	{
		::InternetCloseHandle(m_hFTPConnection);
		::InternetCloseHandle(m_hInternetSession);
	}
	m_hFTPConnection = NULL;
	m_hInternetSession = NULL;

	//Let the parent class do its thing
	CDialog::OnDestroy();
}

⌨️ 快捷键说明

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