📄 urlfiledlg.cpp
字号:
// TODO: Add extra initialization here
return TRUE; // return TRUE unless you set the focus to a control
}
void CUrlFileDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}
// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.
void CUrlFileDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}
// The system calls this to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CUrlFileDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
//-----------------------------------------------------------------------------
// sent when the downloading thread ends
// wParam and lParam: not used
// return value: not used
LRESULT CUrlFileDlg::OnEndDownload(WPARAM, LPARAM)
{
ASSERT(m_pDownloadThread != NULL);
ASSERT_KINDOF(CWinThread, m_pDownloadThread);
TRACE(_T("OnEndDownload()\n"));
// wait until the thread terminates
DWORD dwExitCode;
if (::GetExitCodeThread(m_pDownloadThread->m_hThread, &dwExitCode) &&
dwExitCode == STILL_ACTIVE)
::WaitForSingleObject(m_pDownloadThread->m_hThread, INFINITE);
delete m_pDownloadThread;
m_pDownloadThread = NULL;
// display the result
if (m_downloadParam.strFileName.IsEmpty())
::AfxMessageBox(IDS_FAILED);
else
::AfxMessageBox(m_downloadParam.strFileName,
MB_OK | MB_ICONINFORMATION);
// change the UI
this->ChangeUIDownloading(false);
return 0;
}
//-----------------------------------------------------------------------------
// sent from the downloading thread to the dialog box to display the progress
// wParam: not used
// lParam: DOWNLOADSTATUS *, NULL if canceled
// {
// ULONG ulProgress - IN
// ULONG ulProgressMax - IN
// ULONG ulStatusCode - IN
// LPCWSTR szStatusText - IN
// }
// return value: not used
LRESULT CUrlFileDlg::OnDisplayStatus(WPARAM, LPARAM lParam)
{
const DOWNLOADSTATUS *const pDownloadStatus =
reinterpret_cast<DOWNLOADSTATUS *>(lParam);
// form the status text
CString strStatus;
if (pDownloadStatus != NULL)
{
ASSERT(::AfxIsValidAddress(pDownloadStatus, sizeof(DOWNLOADSTATUS)));
strStatus.LoadString(pDownloadStatus->ulStatusCode -
BINDSTATUS_FINDINGRESOURCE +
IDS_BINDSTATUS01);
strStatus += _T(" ");
strStatus += pDownloadStatus->szStatusText;
CString strProgress;
strProgress.Format(IDS_PROGRESS,
pDownloadStatus->ulProgress,
pDownloadStatus->ulProgressMax);
strStatus += strProgress + _T("\r\n");
}
else
{
strStatus.LoadString(IDS_CANCELED);
strStatus += _T("\r\n");
}
#if 1
// place a caret at the end of the text and append the text to the edit box
const int nLen = m_editProgress.GetWindowTextLength();
m_editProgress.SetSel(nLen, nLen);
m_editProgress.ReplaceSel(strStatus);
#else
// retrieve the status text
this->UpdateData();
// append the text
m_strProgress += strStatus;
// update the edit box
this->UpdateData(FALSE);
#endif
return 0;
}
//-----------------------------------------------------------------------------
// The current insertion has exceeded the specified number of characters
// for the edit control and has been truncated.
void CUrlFileDlg::OnMaxtextProgress()
{
// Simply empty the edit box
m_editProgress.SetWindowText(NULL);
}
//-----------------------------------------------------------------------------
// Download or Stop button pressed
void CUrlFileDlg::OnOK()
{
if (m_pDownloadThread == NULL)
{
// Download
// retrieve the URL
this->UpdateData();
// check if the URL is valid
USES_CONVERSION;
if (m_strURL.IsEmpty() ||
::IsValidURL(NULL, T2CW(m_strURL), 0) != S_OK)
{
::AfxMessageBox(IDS_ERRINVALIDURL, MB_OK | MB_ICONSTOP);
// change the UI
this->ChangeUIDownloading(false);
return;
}
// parameters to be passed to the thread
m_downloadParam.hWnd = this->GetSafeHwnd();
m_eventStop.ResetEvent(); // nonsignaled
m_downloadParam.hEventStop = m_eventStop;
m_downloadParam.strURL = m_strURL;
m_downloadParam.strFileName.Empty();
// create a thread to download, but don't start yet
m_pDownloadThread = ::AfxBeginThread(CUrlFileDlg::Download,
&m_downloadParam,
THREAD_PRIORITY_NORMAL,
0,
CREATE_SUSPENDED);
if (m_pDownloadThread != NULL)
{
TRACE(_T("AfxBeginThread: 0x%08lX\n"),
m_pDownloadThread->m_nThreadID);
/*
Set the m_bAutoDelete data member to FALSE. This allows
the CWinThread object to survive after the thread has been
terminated. You can then access the m_hThread data member
after the thread has been terminated. If you use this
technique, however, you are responsible for destroying the
CWinThread object as the framework will not automatically
delete it for you.
*/
m_pDownloadThread->m_bAutoDelete = FALSE;
// change the UI
this->ChangeUIDownloading();
// start
m_pDownloadThread->ResumeThread();
}
else
{
::AfxMessageBox(IDS_ERRCREATETHREAD, MB_OK | MB_ICONSTOP);
// change the UI
this->ChangeUIDownloading(false);
}
}
else
{
// Stop
m_eventStop.SetEvent(); // signaled
}
}
//-----------------------------------------------------------------------------
// Exit button, Alt-F4 key, Close menu or Close button
void CUrlFileDlg::OnCancel()
{
if (m_pDownloadThread != NULL)
return; // Don't exit while downloading
CDialog::OnCancel();
}
//-----------------------------------------------------------------------------
// change the user interface
// bDownloading: true - downloading, false - not downloading
void CUrlFileDlg::ChangeUIDownloading(bool bDownloading /* = true */)
{
// Download/Stop button
m_btnDownloadStop.SetWindowText
(CString(reinterpret_cast<LPCTSTR>(bDownloading
? IDS_BTNSTOP : IDS_BTNDOWNLOAD)));
// Exit button
m_btnExit.EnableWindow(!bDownloading);
// System menu - Close
CMenu *const pSysMenu = this->GetSystemMenu(FALSE);
if (pSysMenu != NULL)
pSysMenu->EnableMenuItem(SC_CLOSE,
MF_BYCOMMAND |
(bDownloading ? MF_GRAYED : MF_ENABLED));
// URL edit box
m_editURL.EnableWindow(!bDownloading);
if (bDownloading)
// Progress edit box
m_editProgress.SetWindowText(NULL); // clear the status text
else
{
// URL edit box
m_editURL.SetFocus();
m_editURL.SetSel(0, -1); // select all the text
}
}
//-----------------------------------------------------------------------------
// static member function - the controlling function for the worker thread
// pParam: DOWNLOADPARAM *
// {
// HWND hWnd - IN the window handle to display status
// HANDLE hEventStop - IN the event object to signal to stop
// CString strURL - IN the URL of the file to be downloaded
// CString strFileName - OUT the filename of the downloaded file
// }
// return value: not used
UINT CUrlFileDlg::Download(LPVOID pParam)
{
DOWNLOADPARAM *const pDownloadParam = static_cast<DOWNLOADPARAM *>(pParam);
ASSERT(pDownloadParam != NULL);
ASSERT(::AfxIsValidAddress(pDownloadParam, sizeof(DOWNLOADPARAM)));
/*
URLDownloadToCacheFile is a blocking function. Even though the data is
downloaded asynchronously the function does not return until all the
data is downloaded. If complete asynchronous downloading is desired,
one of the other UOS functions, such as URLOpenStream, or perhaps
general URL monikers would be more appropriate.
*/
CBSCallbackImpl bsc(pDownloadParam->hWnd, pDownloadParam->hEventStop);
const HRESULT hr = ::URLDownloadToCacheFile(NULL,
pDownloadParam->strURL,
pDownloadParam->strFileName.
GetBuffer(MAX_PATH),
URLOSTRM_GETNEWESTVERSION,
0,
&bsc);
/*
The resource from the cache is used for the second and subsequent
calls to URLDownloadToCacheFile during the session of the program
unless the following setting is selected, in which case, every call
to URLDownloadToCacheFile downloads the resource from the Internet.
Control Panel/Internet/General/Temporary Internet files/Settings/
Check for newer versions of stored pages -> Every visit to the page
*/
// empty the filename string if failed or canceled
pDownloadParam->strFileName.ReleaseBuffer(SUCCEEDED(hr) ? -1 : 0);
TRACE(_T("URLDownloadToCacheFile ends: 0x%08lX\nCache file name: %s\n"),
hr, pDownloadParam->strFileName);
// let the dialog box know it is done
::PostMessage(pDownloadParam->hWnd, WM_USER_ENDDOWNLOAD, 0, 0);
return 0;
}
//-----------------------------------------------------------------------------
//*****************************************************************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -