【发布时间】:2013-10-18 22:05:39
【问题描述】:
我正在使用 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);
所以问题是如何在下载文件时使栏移动?考虑到为了简单起见,我希望它使用选取框样式。
提前致谢。
【问题讨论】:
-
让下载进入不同的线程。即使没有进度条,您也不应该在下载内容时挂起窗口。
-
一句话:多线程。
-
您在 同步 SOXDownload 操作期间根本没有为消息提供服务。您将整个消息泵都挂在主线程上。
-
所以这意味着我必须使用另一个函数而不是
URLDownloadToFile? -
不,这意味着您需要将
URLDownloadToFile()代码移动到单独的工作线程,以便您的主线程可以继续为其消息队列提供服务。
标签: c++ winapi visual-c++ progress-bar download