下载程序带进度条 [英] Downloader with progress bar

查看:146
本文介绍了下载程序带进度条的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

您好,伙计。



您能否提供一个很好的解决方案,将文件从URL下载到显示进度条的本地磁盘?



我尝试使用OpenURL和Read of CInternetSession,但如果我尝试下载大文件(> 60 MB),则会失败60MB。



谢谢。

Hello, Guys.

Could you please provide me with a good solution for downloading a file from URL to local disk showing progress bar?

I tried to use OpenURL and Read of CInternetSession, but it failed in 60MB if I try to download large files ( > 60 MB).

Thanks.

推荐答案

正如我在评论中提到的,我这样做的方法是在函数中调用一个回调函数来读取数据连接。此回调向主窗口发送通知,告知可用的更新下载进度。然后主窗口显示此信息。



这里是使用机制的简短示例:



1.在程序的主窗口中处理按钮单击的代码

As I mentioned in a comment, the way I do it is to call a callback function in the function that reads data from the connection. This callback sends notification to the main window that there is updated download progress available. The main window then displays this information.

Here''s a short example of the mechanism in use:

1. Code to handle button click in program''s main window
void onTestBtn()
{
    downloadHeader_t curDownload;
    char fileName[MAX_PATH];
    int i, numFiles;

    numFiles = sizeof(szUrls) / sizeof(*szUrls);

    ListView_DeleteAllItems(listWnd);
    for (i=0; i<numFiles; i++)
        addListViewItem(listWnd, szUrls[i]);

    downloadList.clear();
    for (i=0; i<numFiles; i++)
    {
        curDownload.szUrl = szUrls[i];
        curDownload.callback = (voidFuncPtr)fileDownloadedCallbackFunc;
        curDownload.progCallback = (voidFuncPtr)fileProgressCallbackFunc;
        curDownload.saveFilePath = getFilename(curDownload.szUrl);
        curDownload.lParam = (void*)i;
        curDownload.contentLen = 0;
        curDownload.bCancelled = false;
        downloadList.push_back(curDownload);
    }

    for (i=0; i<numFiles; i++)
    {
        _beginthread(DownloadThread, NULL, (void*)&(downloadList[i]));
    }
}





2.回调函数本身



2. The callback function itself

void fileProgressCallbackFunc(PVOID data)
{
    SendMessage(mainDlgWnd, WM_FILE_DOWNLOAD_PROGRESS_AVAILABLE, 0, (LPARAM)data);
}







3.调用回调(埋没在DownloadThread(* void)中)




3. Calling the callback (buried in DownloadThread(*void) )

if (hdr->progCallback)
    hdr->progCallback(hdr);





4.处理回调函数中发布的消息 - 在主窗口的windowProcedure中



4. Handling the message posted in the callback function - in the windowProcedure of the main window

case WM_FILE_DOWNLOAD_PROGRESS_AVAILABLE:
    progHdr = (downloadHeader_t*)lParam;

    if (progHdr->bComplete)
        sprintf(buffer, "Complete");
    else
    {
        if (progHdr->contentLen > 1024*1024)
            sprintf(buffer, "%.2f MB", (float)progHdr->contentLen / (1024*1024) );
        else if (progHdr->contentLen > 1024)
            sprintf(buffer, "%.1f KB", (float)progHdr->contentLen / (1024) );
        else
            sprintf(buffer, "%.1f B", (float)progHdr->contentLen);

    }

    setListViewItemDownloaded(listWnd, (int)progHdr->lParam, buffer);





5. downloadHeader_t的定义



5. The definition of downloadHeader_t

typedef void (*voidFuncPtr)(void*);
struct downloadHeader_t
{
    string szUrl;             /* in */
    voidFuncPtr callback;     /* in */
    voidFuncPtr progCallback;   /* in */
    string saveFilePath;     /* in */
    PVOID lParam;             /* in */

    SOCKET conn;
    char *readBuffer, *sendBuffer, *tmpBuffer, *result;
    string server, filepath, filename;
    long thisReadSize, headerLen, contentLen, totalLen;
    string statusTxt;
    bool bCancelled;
    bool bComplete;
};


这篇关于下载程序带进度条的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆