How to code a responsive progress bar that uses callback functions?

1.4k views Asked by At

I have this progress bar that uses callback functions from a third party driver, to display a traditional progress bar in a window called CFProgress.

CFProgress *cFM=new CFProgress();
theApp.m_cFM = cFM;
cFM->Create(CFProgress::IDD);
cFM->ShowWindow(SW_SHOW);
thirdpartydriver->set_OnProgress(ProgressFuncC, (void *) cFM);
thirdpartydriver->DoReallyLongTask();

The ProgressFuncC is as follows:

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();
}

This used to work well on earlier OS'es, but Windows 7 keeps on complaining that the app is not responding while the progress bar window is displayed. The actual functionality is unaffected.

What would be a good way to make this more responsive to Windows?

Can I add this to the ProgressFuncC code and expect it to resolve the issue, or am I just being confused here :

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);
    }
}
1

There are 1 answers

4
karoberts On BEST ANSWER

Is thirdpartydriver->DoReallyLongTask(); running on the main UI thread?

If it is, then your windows won't respond until you return control to the Message Loop.

None of your windows will respond unless this loop is running, and if that long task is on the main thread, then it will block this loop.

while(GetMessage(&Msg, NULL, 0, 0) > 0)
{
    TranslateMessage(&Msg);
    DispatchMessage(&Msg);
}

Your best option is to move your thirdpartydriver->DoReallyLongTask(); into a separate thread, and have your callback function put a message into the message loop (via SendMessage or PostMessage) and then handle that message and update the progress bar.