我正在使用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);
所以问题是如何在下载文件时移动栏?考虑到我希望它以简洁的方式完成。
提前致谢。
答案 0 :(得分:4)
创建一个实现IBindStatusCallback
接口的类,然后将其传递给URLDownloadToFile()
的最后一个参数。然后,您将在下载过程中收到OnProgress
个事件,您可以根据需要使用这些事件来更新UI,为待处理消息提取消息队列等等。
答案 1 :(得分:1)
我想我会使用InternetReadFile
(或InternetReadFileEx
)。这将允许您一次读取少量数据(例如,4千字节),以便您可以定期更新状态栏(并处理任何其他消息)。
要最大化UI响应,您可以执行异步读取。这将允许您在下载过程中立即处理消息,而不是等待下一个4K(或其他)块完成。通过快速连接,它可能不会产生明显的差异(4K通常不需要很长时间)但是在缓慢或不可靠的连接上,它可能是一个相当重要的帮助。如果花费太长时间,进行异步下载还可以让您彻底取消交易。