用户登录  |  用户注册
首 页源码下载网络学院最新源码源码排行屏蔽广告
当前位置:新兴网络 > 网络学院 > 编程开发 > VC/MFC

VC 下载指定文件(带进度条)实例

减小字体 增大字体 作者:九黎部落  来源:九黎部落  发布时间:2010-06-03 17:00:39

在项目中需要用到程序更新的功能,同事介绍说是curl中的开发库很不错,于是下载这个包测试了一下,确实不错。准备正式用到项目中,以下一个例子用于从互联网上抓取一个文件下载到本地,并加上进度条显示,做得挺简陋,不过功能差不多就这样了。
程序运行预览.

首先需要加入多线程的机制,因为程序一边在下载文件,一边在显示进度条,单线程的方式肯定不行,所以我用到了wxTimer来实现,在downloadMain.h 中定义了一个wxTimer,并做了事件申明.
DECLARE_EVENT_TABLE()

C/C++ code复制代码
/***************************************************************
 * Name:            downloadMain.h
 * Purpose:     Defines Application Frame
 * Author:         ()
 * Created:     2008-11-14
 * Copyright:    ()
 * License:
 **************************************************************/

#ifndef DOWNLOADMAIN_H
#define DOWNLOADMAIN_H

#include "downloadApp.h"

#include <wx/timer.h>
#include "GUIDialog.h"

class downloadDialog: public GUIDialog
{
        public:
                downloadDialog(wxDialog *dlg);
                ~downloadDialog();
                void .Timer(wxTimerEvent& event);
        private:
                virtual void .Close(wxCloseEvent& event);
                virtual void .Quit(wxCommandEvent& event);
                virtual void .About(wxCommandEvent& event);
                void downloadfile();
                wxTimer* m_timerdown;
                DECLARE_EVENT_TABLE()
};
#endif // DOWNLOADMAIN_H

下面是主程序的代码.

C/C++ code复制代码
/***************************************************************
 * Name:            downloadMain.cpp
 * Purpose:     Code for Application Frame
 * Author:         (alan)
 * Created:     2008-11-14
 * License:
 **************************************************************/

#ifdef WX_PRECOMP
#include "wx_pch.h"
#endif

#ifdef __BORLANDC__
#pragma hdrstop
#endif //__BORLANDC__

#include "downloadMain.h"
#include <curl/curl.h>
#include <curl/types.h>
#include <curl/easy.h>
#include "update.h"
#include <wx/msgdlg.h>
#include <wx/utils.h>
#define TIMER_ID 22222
//事件监听声明
BEGIN_EVENT_TABLE(downloadDialog, GUIDialog)
        EVT_TIMER(TIMER_ID, downloadDialog::OnTimer)
END_EVENT_TABLE()

enum wxbuildinfoformat
{
        short_f, long_f
};

wxString wxbuildinfo(wxbuildinfoformat format)
{
        wxString wxbuild(wxVERSION_STRING);

        if (format == long_f )
        {
#if defined(__WXMSW__)
                wxbuild << _T("-Windows");
#elif defined(__WXMAC__)
                wxbuild << _T("-Mac");
#elif defined(__UNIX__)
                wxbuild << _T("-Linux");
#endif

#if wxUSE_UNICODE
                wxbuild << _T("-Unicode build");
#else
                wxbuild << _T("-ANSI build");
#endif // wxUSE_UNICODE
        }

        return wxbuild;
}

//声明一个文件结构体
struct FtpFile
{
        char *filename;
        FILE *stream;
};

downloadDialog::downloadDialog(wxDialog *dlg)
                : GUIDialog(dlg)
{

        //创建一个定时器,制定TIMER_ID
        m_timerdown = new wxTimer(this, TIMER_ID);
        //定时器开始运行,这里会自动执行OnTimer函数
        m_timerdown->Start(100);
}

downloadDialog::~downloadDialog()
{

}
//定时器操作
void downloadDialog::OnTimer(wxTimerEvent &event)
{
        downloadfile();
}
//文件写入流
int my_fwrite(void *buffer, size_t size, size_t nmemb, void *stream)
{
        struct FtpFile *out=(struct FtpFile *)stream;
        if (out && !out->stream)
        {
                out->stream=fopen(out->filename, "wb");
                if (!out->stream)
                {
                        return -1;
                }
        }
        return fwrite(buffer, size, nmemb, out->stream);
}
//进度条显示函数
int wxcurldav_dl_progress_func(void* ptr, double rDlTotal, double rDlNow, double rUlTotal, double rUlNow)
{
                                wxGauge* pGauge = (wxGauge*) ptr;
                                if(pGauge)
                                //设置进度条的值
                                        pGauge->SetValue(100.0 * (rDlNow/rDlTotal));
                                return 0;
}
//下载文件函数
void downloadDialog::downloadfile()
{
        //创建curl对象
        CURL *curl;
        CURLcode res;
        m_staticText2->SetLabel(wxT("请耐心等待程序下载更新包..."));
        struct FtpFile ftpfile=
        {
                //定义下载到本地的文件位置和路径
                "tmp.exe",NULL
        };
        curl_global_init(CURL_GLOBAL_DEFAULT);

        //curl初始化
        curl = curl_easy_init();

        //curl对象存在的情况下执行操作
        if (curl)
        {
                //设置远端地址
                curl_easy_setopt(curl, CURLOPT_URL,"http://dl_dir.qq.com/minigamefile/QQGame2008ReleaseP2_web_setup.EXE");
                //执行写入文件流操作
                curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, my_fwrite);
                curl_easy_setopt(curl, CURLOPT_WRITEDATA, &ftpfile);
                //curl的进度条声明
                curl_easy_setopt(curl, CURLOPT_NOPROGRESS, FALSE);
                //回调进度条函数
                curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, wxcurldav_dl_progress_func);
                //设置进度条名称
                curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, m_gauge1);

                //进度条
                m_gauge1->SetValue(0);
                //写入文件
                res = curl_easy_perform(curl);
                m_gauge1->SetValue(100);
                //释放curl对象
                curl_easy_cleanup(curl);

                if (CURLE_OK != res)
                        ;
        }
        if (ftpfile.stream)
        {
                //关闭文件流
                fclose(ftpfile.stream);
        }
                //释放全局curl对象
                curl_global_cleanup();
                //这一步很重要,停止定时器,不然程序会无休止的运行下去
                m_timerdown->Stop();
                //执行刚下载完毕的程序,进行程序更新
                int pid = ::wxExecute(_T("tmp.exe"));
                wxMessageBox(wxT("下载完毕,程序开始执行更新操作......"));
}
void downloadDialog::OnClose(wxCloseEvent &event)
{
        Destroy();
}

void downloadDialog::OnQuit(wxCommandEvent &event)
{
        Destroy();
}

void downloadDialog::OnAbout(wxCommandEvent &event)
{

} 
  • 好的评价 如果您觉得此文章好,就请您
      75%(12)
  • 差的评价 如果您觉得此文章差,就请您
      25%(4)

网络学院评论评论内容只代表网友观点,与本站立场无关!

   评论摘要(共 0 条,得分 0 分,平均 0 分) 查看完整评论