如何使用Windows API下载文件时创建进度条?

时间:2013-10-18 22:05:39

标签: c++ winapi visual-c++ progress-bar download

我正在使用Windows API处理MS Visual C ++中的应用程序,该应用程序必须下载文件并将其放在文件夹中。

我已经使用URLDownloadToFile函数实现了下载,但是我想在下载文件的同时创建一个带有选框样式的PROGRESS_CLASS进度条,但它似乎没有在此过程中获得动画。

这是我用于下载的功能:

BOOL SOXDownload()
{   
    HRESULT hRez = URLDownloadToFile(NULL,
        "url","C:\\sox.zip", 0, NULL);
    if (hRez == E_OUTOFMEMORY ) {
        MessageBox(hWnd, "Out of memory Error","", MB_OK);
        return FALSE;
    }
    if (hRez != S_OK) {
        MessageBox(hWnd, "Error downloading sox.", "Error!", MB_ICONERROR | MB_SYSTEMMODAL);
        return FALSE;
    }
    if (hRez == S_OK) {
        BSTR file = SysAllocString(L"C:\\sox.zip");
        BSTR folder = SysAllocString(L"C:\\");
        Unzip2Folder(file, folder);
        ::MessageBoxA(hWnd, "Sox Binaries downloaded succesfully", "Success", MB_OK);
    }
    return TRUE;
}

后来我在WM_CREATE内部调用(在我主窗口的消息处理器中):

if (!fileExists("C:\\SOX\\SOX.exe")) {
    components[7] = CreateWindowEx(0, PROGRESS_CLASS,
                                NULL, WS_VISIBLE | PBS_MARQUEE,
                                GetSystemMetrics(SM_CXSCREEN) / 2 - 80,
                                GetSystemMetrics(SM_CYSCREEN) / 2 + 25,
                                200, 50, hWnd, NULL, NULL, NULL);
    SetWindowText(components[7], "Downloading SoX");
    SendMessage(components[7], PBM_SETRANGE, 0, (LPARAM) MAKELPARAM(0, 50));
    SendMessage(components[7], PBM_SETMARQUEE, TRUE, MAKELPARAM( 0, 50));
    SOXDownload();
    SendMessage(components[7], WM_CLOSE, NULL, NULL);
}

正如我想的那样,我得到一个微小的进度条...但它没有动画,当我将光标放在条形图上时,光标指示程序正在忙着下载文件。

下载完成后,窗口会按照我的要求关闭:SendMessage(components[7], WM_CLOSE, NULL, NULL);

所以问题是如何在下载文件时移动栏?考虑到我希望它以简洁的方式完成。

提前致谢。

2 个答案:

答案 0 :(得分:4)

创建一个实现IBindStatusCallback接口的类,然后将其传递给URLDownloadToFile()的最后一个参数。然后,您将在下载过程中收到OnProgress个事件,您可以根据需要使用这些事件来更新UI,为待处理消息提取消息队列等等。

答案 1 :(得分:1)

我想我会使用InternetReadFile(或InternetReadFileEx)。这将允许您一次读取少量数据(例如,4千字节),以便您可以定期更新状态栏(并处理任何其他消息)。

要最大化UI响应,您可以执行异步读取。这将允许您在下载过程中立即处理消息,而不是等待下一个4K(或其他)块完成。通过快速连接,它可能不会产生明显的差异(4K通常不需要很长时间)但是在缓慢或不可靠的连接上,它可能是一个相当重要的帮助。如果花费太长时间,进行异步下载还可以让您彻底取消交易。