Multithreading 如何编写使用回调函数的响应进度条?
我有一个进度条,它使用来自第三方驱动程序的回调函数,在一个名为CFProgress的窗口中显示一个传统的进度条Multithreading 如何编写使用回调函数的响应进度条?,multithreading,mfc,windows-7,visual-c++,unresponsive-progressbar,Multithreading,Mfc,Windows 7,Visual C++,Unresponsive Progressbar,我有一个进度条,它使用来自第三方驱动程序的回调函数,在一个名为CFProgress的窗口中显示一个传统的进度条 CFProgress *cFM=new CFProgress(); theApp.m_cFM = cFM; cFM->Create(CFProgress::IDD); cFM->ShowWindow(SW_SHOW); thirdpartydriver->set_OnProgress(ProgressFuncC, (void *) cFM); thirdpartydr
CFProgress *cFM=new CFProgress();
theApp.m_cFM = cFM;
cFM->Create(CFProgress::IDD);
cFM->ShowWindow(SW_SHOW);
thirdpartydriver->set_OnProgress(ProgressFuncC, (void *) cFM);
thirdpartydriver->DoReallyLongTask();
progressfunc
如下所示:
void _stdcall ProgressFuncC(CallbackDataType UserData, LongWord Operation, LongWord Progress, LongWord Total, Bool CanStop, Bool *Stop)
{
char cMsg[100];
sprintf_s(cMsg, 100, "Task Progress (%d%% completed).", Progress * 100 / Total);
CFProgress *cFM;
cFM = theApp.m_cFM;
cFM->m_Prg1.SetPos(Progress * 100 / Total);
cFM->m_lblMsg.SetWindowText(cMsg);
cFM->UpdateWindow();
}
这在早期的操作系统上运行得很好,但Windows7一直抱怨在显示进度条窗口时应用程序没有响应。实际功能不受影响
有什么好方法可以让它对Windows更敏感
我是否可以将此添加到progressfunc
代码中,并期望它能够解决问题,或者我只是在这里感到困惑:
MSG msg;
if (::PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
if (msg.message == WM_QUIT)
{
::PostMessage(NULL, WM_QUIT, 0, 0L);
}
else
{
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
}
是
thirdpartydriver->doreally longtask()代码>在主UI线程上运行
如果是,则在您将控制权返回到消息循环之前,您的windows不会响应
除非此循环正在运行,否则所有窗口都不会响应,如果长任务位于主线程上,则它将阻止此循环
while(GetMessage(&Msg, NULL, 0, 0) > 0)
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
您最好的选择是移动thirdpartydriver->DoReallyLongTask()将>编码到一个单独的线程中,并让回调函数将消息放入消息循环(通过SendMessage
或PostMessage
),然后处理该消息并更新进度条。thirdpartydriver->DoReallyLongTask()确实在主UI线程上运行,因为代码中没有多线程。但是将进度条放在一个单独的线程中不是更简单吗?它可能更简单,但不会解决您的问题。要获得响应的UI,必须将控件返回到消息循环。这就是windows的工作方式。我对多线程技术还不熟悉-我在问题中添加了一些代码:“我可以将其添加到ProgressFuncC代码中吗…”您认为这可以解决无响应问题吗?是的,这会有帮助。将其设置为while循环而不是if,因为可能有多条消息。