A thread class downloading file

xiaoxiao2021-03-06  37

Sometimes, we need to download files through the Internet. In the process of file download, we also need to handle other things. To do this, we need to put the work downloaded in a thread to achieve it. In order to reflect the encapsulation of object-oriented programming, we'd better put the thread into a class, and we need one such thread in the future, we can instantiate the object of the class. If you do this kind of class, you should have a certain difficulty. Fortunately, MFC provides us with a base class, CWINTHREAD class, us as long as it is derived with the base class, it is possible. Now, I have a few files to download, and the file to be downloaded is saved in a list. During the download process, you want to display an error or download scheme to the interface. My program is a wizard program, the subclass of the wizard's CPROPERTYSHEET class, is managed each property page, so I will save the list of file information that will download the file information to the CWIZARDSHEET class, I will download it, I will download it. CWIZARDSHEET's pointer passes the thread, the thread reads its linked list member, sequentially downloads the files in the download, will send some messages to the main window to notify the main window file download status information. Thread class is defined as follows:! #If defined (AFX_CDownloadThread_H__1238AC8E_F397_4E8C_AC43_50170B789119__INCLUDED _) # define AFX_CDownloadThread_H__1238AC8E_F397_4E8C_AC43_50170B789119__INCLUDED_

#iF _MSC_VER> 1000 # pragma overce # endif // _msc_ver> 1000 // cdownloadthread.h: header file // # include "common.h"

Class cwizardsheet; /// cdownloadthread thread

class CDownloadThread: public CWinThread {DECLARE_DYNCREATE (CDownloadThread) private: CDownloadThread (); // defined private definitions is to prevent an external thread and an array of calling the constructor with no arguments public: // Constructor passed a pointer to the parent window CDownloadThread ( CWIZARDSHEET * PWIZSHEET, AFX_THREADPROC PFNTHREADPROC); // AttributeSpublic:

// OperationSpublic: static uint threadfunc (lpvoid param); // thread function, will call the following function to download the file void getfile (newModuleInfo & newModuleInfo); // Really implement file download

// Overrides // ClassWizard Generated Virtual Function Overrides // {AFX_Virtual (cdownloadthread) Public: Virtual Bool InitInstance (); Virtual Int ExitInstance (); ///}} AFX_VIRTUAL

// ImplementationPublic: Virtual ~ cdownloadThread ();

// Generated message map functions // {{AFX_MSG (CDownloadThread) // NOTE - the ClassWizard will add and remove member functions here //}.} AFX_MSGDECLARE_MESSAGE_MAP () private: CWizardSheet * m_pWizSheet; // save the parent window pointers CString m_saveDir ; // File Save Path};

/

// {{AFX_INSERT_LOCATION}} // Microsoft Visual C Will Insert Additional Declarations Immediately Before The Previous Line.

#ndif //! defined (AFX_CDOWNLOADTHREAD_H__1238AC8E_F397_4E8C_AC43_50170B789119__INCLUDED _) // Download the thread implementation is as follows: // cdownloadthread.cpp: importation file //

#include "stdafx.h" #include #include "wiz2.h" #include "downloadthread.h" #include "wizardsheet.h"

#ifdef _debug # define new debug_new # undef this_filestatic char this_file [] = __file __; # ENDIF

// EXTERN WM_MSG_PROGRS = WM_USER 100; /// CDownloadThread

Implement_dyncreate (CDownloadThread, Cwinthread)

CDownloadthread :: cdownloadthread () {}

CDownloadThread :: CDownloadThread (CWizardSheet * pWizSheet, AFX_THREADPROC pfnThreadProc): CWinThread (pfnThreadProc, NULL) {m_pWizSheet = pWizSheet; // save the parent window pointer m_saveDir = pWizSheet-> GetSaveDir (); // get the file path to save m_bAutoDelete = TRUE ; // thread end will automatically clear m_pthreadparams = this; // thread parameters set to themselves} cdownloadthread :: ~ cdownloadthread () {}

Bool cdownloadthread :: InitInstance () {// Todo: Perform and per-thread initialization he Return True;}

Int cdownloadthread :: exitInstance () {// Todo: Perform Any Per-Thread Cleanup Here Return CWINTHREAD :: EXITINSTANCE ();

BEGIN_MESSAGE_MAP (CDownloadThread, CWinThread) // {{AFX_MSG_MAP (CDownloadThread) // NOTE - the ClassWizard will add and remove mapping macros here //}.} AFX_MSG_MAPEND_MESSAGE_MAP ()

/// cdownloadthread Message Handlers

UINT CDownloadThread :: ThreadFunc (LPVOID param) {CDownloadThread * pthread = (CDownloadThread *) param; NewModuleInfoList list = pthread-> m_pWizSheet-> GetNewModuleInfoList (); // get the list of files to be downloaded HWND hWnd = AfxGetApp () -> GetMainWnd () -> m_hwnd; newModuleInfolist :: item; waitforsingleObject (pthread-> m_pwizsheet-> m_hnewmoduleslistmutex, infinite); // Download each file for (item = list.begin (); item! = list.end (); item ) {if (item-> isFullFile == FALSE && item-> isSelected == TRUE) pthread-> GetFile (* item);} SendMessage (hWnd, WM_MSG_DOWNMODULE, NOTIFY_MSG, DOWNLOAD_FINISH); // send download completion message, ReleaseMutex (pthread-> m_pWizSheet-> m_hNewModulesListMutex); return 0;} // This is the real thread function, it will open the url the // caller supply, download the file specify by the url to the // specify dir, and send the statistics messge to the UI to // tell the user the progressvoid CDownloadThread :: GetFile (newModuleInfo & newModuleInfo) {HWND hWnd = AfxGetApp () -> GetMainWnd () -> m_hWnd; CInternetSession session; CStdioFile * p File = NULL; CStdioFile localFile; session.SetOption (INTERNET_OPTION_CONNECT_RETRIES, 10); try {pFile = session.OpenURL (newModuleInfo.URL, // open the URL 1, INTERNET_FLAG_TRANSFER_BINARY | INTERNET_FLAG_RELOAD | INTERNET_FLAG_DONT_CACHE | INTERNET_FLAG_PASSIVE); if (pFile == NULL) {// send connect failed message, notify the user an error encounter ReleaseMutex (m_pWizSheet-> m_hNewModulesListMutex); SendMessage (hWnd, WM_MSG_DOWNMODULE, NOTIFY_MSG, CONNECT_FAILED); return;}

CSTRING STRLEN; DWORD LEN = 0; if (newModuleInfo.serType == 0) // If it is http, get the file length {IF ((chttpfile *) pfile) -> queryinfo (http_query_content_length, strlen)! = 0) { LEN = atol (strlen);}} else if (newModuleinfo.serType == 1) {len = pfile-> getLength (); // If it is FTP, get the file length, but actual debugging found that the FTP file cannot be so long } IF (len m_hNewModulesListMutex); SendMessage (hWnd, WM_MSG_DOWNMODULE, NOTIFY_MSG, OPENFILE_FAILED); session.Close (); return;} localFile.Seek (0, CFile :: begin); // Read the Internet File to Buffer and Write To Loca L File Char BUF [4096]; MEMSET (BUF, 0, 4096); DWORD NTOTAL = 0; Double Der = 0; INT Per = 0; uint Ret = 0; CTIME STARTTIME = CTIME :: getCurrentTime (); CTimeSpan UsedTime;

Do {RET = Pfile-> Read (BUF, 4096); LOCALFILE.WRITE (BUF, RET); // Save File NTOTAL = RET; UsedTime = CTIME:: GetCurrentTime () - STARTTIME; // How long is it? statics * staticsPack = new statics; staticsPack-> length = len; staticsPack-> dwTotal = nTotal; staticsPack-> usedTime = usedTime.GetTotalSeconds (); // send the statistics infomation to the UI to show the progress SendMessage (hWnd, WM_MSG_DOWNMODULE , Statics_msg, (lparam); if (len> 0) {DPER = ((Double) NTOTAL) / ((Double) LEN); per = 100 * DPER; IF (Per <5) per = 5; //// Send The Download Percentage to Ui To Show The Progress SendMessage (HWND, WM_MSG_DOWNMODULE, PROGRS_MSG, PER); // Send Download Progress Give Main Window}} While (Ret! = 0); // Do Some Cleaning IF (Pfile! = Null ) {pFile-> Close (); delete pFile; pFile = NULL;} if (localFile.m_hFile = CFile :: hFileNull) {localFile.Close ();}!} catch (CInternetException InetEx) {ReleaseMutex (m_pWizSheet-> m_hNewModulesListMutex SendMessage (HW nd, WM_MSG_DOWNMODULE, NOTIFY_MSG, NETWORK_EXCEPTION); pFile = NULL; session.Close (); return;} catch (CFileException fileEx) {ReleaseMutex (m_pWizSheet-> m_hNewModulesListMutex); SendMessage (hWnd, WM_MSG_DOWNMODULE, NOTIFY_MSG, FILE_EXCEPTION); if (pFile ! = NULL) {pFile-> Close (); pFile = NULL;} session.Close (); return;} catch (...) {ReleaseMutex (m_pWizSheet-> m_hNewModulesListMutex); SendMessage (hWnd, WM_MSG_DOWNMODULE, NOTIFY_MSG, NETWORK_EXCEPTION ); Pfile = null; session.close (); return;}

转载请注明原文地址:https://www.9cbs.com/read-61898.html

New Post(0)