Can anyone tell me why calling UpdateData(FALSE)
does not work until I call a messagebox in my VC++ dialog-based application? The runtime window remains unchanged until I call:
MessageBoxW(cDisp, L"!!!Data Count!!!", MB_OK | MB_ICONINFORMATION)
A part of my code snippet is like this...
for(int j=0;j<50;j++)
{
if(ferr==0)
{
double X[15][4],splusn[15],m_dBiasC,WOld[1][4],alpha,err,WNew[1][4],y[15][1],WTransOld[4][1];
//do
// {
int iGraphX,iGraphY;
CString cDisp1(""),cDisp;
m_dBiasC=m_dC;
err=m_dError;
alpha=m_dAlpha;
char ch;
double dummy1,dummy2;
cDisp.Format(L"%d",j);
m_sCount.Format(L"%d",m_iInterval);
UpdateData(FALSE);
BeginWaitCursor();
for(int i=0;i<15;i++)
{
f[0]>>dummy1>>ch>>dummy2;
Time[i]=dummy1;
m_dAccX[i]=dummy2;
if(!f[0].good())
{
MessageBox(L"The end of first data file encountered",L"Caution");
MessageBoxW(L"Quiting Program ",L"Caution");
ferr=2;
//break;
exit(1);
}
iGraphX=static_cast<int>(Time[i]*100.0);
iGraphY=static_cast<int>(m_dAccX[i]);
m_Graph[0].RemovePoint(0,0);
m_Graph[0].AddPoint(iGraphX,iGraphY);
cDisp.Format(L"%lf %lf",Time[i],m_dAccX[i]);
cDisp1+=cDisp;
cDisp1+="\r\n";
f[1]>>dummy1>>ch>>dummy2;
Time[i]=dummy1;
m_dAccY[i]=dummy2;
if(!f[1].good())
{
MessageBox(L"The end of second data file encountered",L"Caution");
MessageBoxW(L"Quiting Program ",L"Caution");
ferr=3;
//break;
exit(1);
}
iGraphX=static_cast<int>(Time[i]*50.0);
iGraphY=static_cast<int>(m_dAccY[i]*10);
m_Graph[1].RemovePoint(0,0);
m_Graph[1].AddPoint(iGraphX,iGraphY);
f[2]>>dummy1>>ch>>dummy2;
Time[i]=dummy1;
m_dAccZ[i]=dummy2;
if(!f[2].good())
{
MessageBox(L"The end of third data file encountered",L"Caution");
MessageBoxW(L"Quiting Program ",L"Caution");
ferr=4;
//break;
exit(1);
}
iGraphX=static_cast<int>(Time[i]*50.0);
iGraphY=static_cast<int>(m_dAccZ[i]);
m_Graph[2].RemovePoint(0,0);
m_Graph[2].AddPoint(iGraphX,iGraphY);
f[3]>>dummy1>>ch>>dummy2;
Time[i]=dummy1;
m_dECG[i]=dummy2;
if(!f[3].good())
{
MessageBox(L"The end of fourth data file encountered",L"Caution");
MessageBoxW(L"Quiting Program ",L"Caution");
ferr=5;
//break;
exit(1);
}
iGraphX=static_cast<int>(Time[i]*100.0);
iGraphY=static_cast<int>(m_dECG[i]*100);
m_Graph[3].RemovePoint(0,0);
m_Graph[3].AddPoint(iGraphX,iGraphY);
}
Sleep(500);
GetDlgItem(IDC_DISPLAYFILE)->SetWindowTextW(cDisp1);
UpdateData(FALSE);
EndWaitCursor();
cDisp.Format(L"Data Read till now: %d",((j+1)*15));
MessageBox(cDisp,L"!!!Data Count!!!",MB_OK|MB_ICONINFORMATION);
UpdateData(FALSE);
//This part is for adaptive filter calculations
for(int r=0;r<15;r++)
{
splusn[r]=static_cast<double>(m_dECG[r]);
X[r][0]=m_dBiasC;
X[r][1]=static_cast<double>(m_dAccX[r]*m_dScaleX);
X[r][2]=static_cast<double>(m_dAccY[r]*m_dScaleY);
X[r][3]=static_cast<double>(m_dAccZ[r]*m_dScaleZ);
}
WOld[0][0]=m_dW0;
WOld[0][1]=m_dW1;
WOld[0][2]=m_dW2;
WOld[0][3]=m_dW3;
for(int q=0;q<4;q++)
WNew[0][q]=WOld[0][q];
for(int p=0;p<15;p++)
{
for(int iRectCnt=0;iRectCnt<60;iRectCnt++)
{
f[4]<<setiosflags(ios::fixed)<<setw(8)<<setprecision(4)<<p<<" ";
for(int iWCnt=0;iWCnt<4;iWCnt++)
f[4]<<setw(8)<<setprecision(2)<<WOld[0][iWCnt];
f[4]<<endl;
y[p][0]=0.0;
for(int q=0;q<4;q++)
WTransOld[q][0]=WOld[0][q];
for(int r=0;r<4;r++)
{
y[p][0]=y[p][0]+(X[p][r]*WTransOld[r][0]);
}
err=splusn[p]-y[p][0];
for(int q=0;q<4;q++)
WNew[0][q]=WOld[0][q]+(2.0*alpha*err*X[p][q]);
for(int q=0;q<4;q++)
WOld[0][q]=WNew[0][q];
}
cDisp.Format(L"%lf",err);
GetDlgItem(IDC_ERROR)->SetWindowTextW(cDisp);
splusn[p]=splusn[p]-err;
}
for(int p=0;p<15;p++)
{
iGraphX=static_cast<int>(Time[p]*100.0);
iGraphY=static_cast<int>(splusn[p]*100);
m_Graph[4].RemovePoint(0,0);
m_Graph[4].AddPoint(iGraphX,iGraphY);
}
cDisp.Format(L"%lf",WNew[0][0]);
GetDlgItem(IDC_W0C)->SetWindowTextW(cDisp);
cDisp.Format(L"%lf",WNew[0][1]);
GetDlgItem(IDC_W1C)->SetWindowTextW(cDisp);
cDisp.Format(L"%lf",WNew[0][2]);
GetDlgItem(IDC_W2C)->SetWindowTextW(cDisp);
cDisp.Format(L"%lf",WNew[0][3]);
GetDlgItem(IDC_W3C)->SetWindowTextW(cDisp);
m_sCount.Format(L"%d",0);
// End of Adaptive filter
//close files here if already end of file is encountered
if((f[0].eof()||f[1].eof()||f[2].eof()||f[3].eo开发者_如何学Cf()))
{
MessageBox(L"End of File encountered");
ferr=1;
exit(1);
}
//}while(!(f[0].eof())&&!(f[1].eof())&&!(f[2].eof())&&!(f[3].eof()));
}
}
There are so many problems with that code that I'm not even sure where to begin. For starters:
Why are you calling
Sleep()
?? I can't possibly imagine a reason you would need to do this in a well-designed application. Especially not repeatedly, as you've shown in your code. TheSleep
function causes your thread to be suspended for the specified number of milliseconds. Try taking out the calls toSleep
altogether, and see if that doesn't solve your problem. If the thread is suspended, how is the UI going to update?Why are you mixing
UpdateData
withGetDlgItem
and a call toSetWindowText
? If you're letting MFC take care of coordinating the values of your member variables with the values displayed in the dialog's controls, you shouldn't need to set their properties yourself.
You also don't show us enough of your code to know what CDisp1
is, or what IDC_DISPLAYFILE
is. What are you ultimately trying to accomplish? Do you want a real-time update while data is processed? We could surely provide much better help on how to structure your code if we knew what the goal was, rather than just the code that doesn't work.
Update: Ahh, I see you've just added in a comment that the above code is in a for
loop. So your problem is actually simple: a for
loop puts the CPU into a tight loop where nothing else but your code gets executed. All message processing (in particular, updating the UI) is suspended while your loop executes the specified number of times.
Calling UpdateData
isn't having any result on the values of the controls in the dialog because your computer's processor is currently busy looping. Showing a message box temporarily blocks the execution of your for
loop by creating its own message pump, which allows the UI to be updated. Take the code out of the for
loop, and remove the calls to Sleep
, and your problems will go away.
From the comments, it looks like the best thing for you to do is create a worker thread and place your loop there instead, isolating it from your main (GUI) thread. The worker thread can then send a message to your main thread to update the controls in the dialog. Complete solutions and more information have already been provided as the answers to this question: How can I show a modeless dialog and display information in it immediately?
Probably because the call to MessageBox contains a message pump. Using Sleep as you're doing means the UI isn't going to be responsive.
精彩评论