0

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].eof()))
                            {
                                MessageBox(L"End of File encountered");
                                ferr=1;
                                exit(1);
                            }


                     //}while(!(f[0].eof())&&!(f[1].eof())&&!(f[2].eof())&&!(f[3].eof()));
       }

    }
ddbiomed
  • 37
  • 1
  • 7
  • We're all-seeing and all-knowing, so yes, we can tell you what is wrong with your code without seeing any snippet of it. – user541686 Feb 17 '11 at 06:16
  • ... we can tell you, but we don't do this, because we are really bad guys! – Alex F Feb 17 '11 at 06:18
  • Sorry Mehrdad do you mean that I should add a snippet of my code with the question? If yes I can do that... – ddbiomed Feb 17 '11 at 06:19
  • Interesting reading: [Avoiding UpdateData](http://www.flounder.com/updatedata.htm). The proposed alternative is accessing the values from *control variables*, instead of using the `UpdateData` function. – Cody Gray - on strike Feb 17 '11 at 06:22
  • @sspdd: Haha yeah, I meant you should've added a snippet of your code, so we see how things interact. (In general, it's better to put a snippet of code even if it seems obvious, just so people can see a more real picture of what's happening.) Thanks for posting it. :) – user541686 Feb 17 '11 at 06:24
  • @sspdd: By the way, what exactly do you mean by "does not work"? – user541686 Feb 17 '11 at 06:25
  • well the code snippet I have shown here is inside a for loop...when the program runs..I expect that the dialog screen chould be updated all the time the loop index is incremented..But the problem I am facing is that if I don't add the line MessageBox(cDisp,L"!!!Data Count!!!",MB_OK|MB_ICONINFORMATION); the dialog window does not get updated...and if I add the messagebox it gets updated just after I click OK button of the Messagebox...this is not desired..I need the loop to run without the messagebox and the dialog to get updated all the time. – ddbiomed Feb 17 '11 at 06:30

2 Answers2

4

There are so many problems with that code that I'm not even sure where to begin. For starters:

  1. 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. The Sleep function causes your thread to be suspended for the specified number of milliseconds. Try taking out the calls to Sleep altogether, and see if that doesn't solve your problem. If the thread is suspended, how is the UI going to update?

  2. Why are you mixing UpdateData with GetDlgItem and a call to SetWindowText? 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?

Community
  • 1
  • 1
Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
  • I am sure you can help, because already you have given enough information...you are rightI need a real time update while data is processed..actually my code snippet is very large...if you people don't have any objection then only I can post it with my question.. – ddbiomed Feb 17 '11 at 06:39
  • 1
    @sspdd: The real point is probably that you shouldn't be trying to run the loop in the GUI thread in the first place. Spin off a separate thread and do your processing there. Anything else is a hack, plain and simple. If you're not opposed to that, you can pump the message loop yourself, but I can't say enough how much I strongly *disagree* with that choice. See [this thread](http://www.codeguru.com/forum/showthread.php?t=337851) for sample code. – Cody Gray - on strike Feb 17 '11 at 06:42
  • Well if I take the code out of the for loop then how can I process my data continously? Actually I am reading 4 files containing voltage variations with time and plotting them on the screen. for each loop index the file pointers move down in the files and read 15 more data..and then plots them on the screen. – ddbiomed Feb 17 '11 at 06:44
  • Do you allow me to add the full code snippet with my question? – ddbiomed Feb 17 '11 at 06:46
  • @sspdd: Sure, you can add the code. Is it not letting you do so? – Cody Gray - on strike Feb 17 '11 at 06:47
  • @sspdd: It looks to me like your question is already answered [here](http://stackoverflow.com/questions/385928/question-about-modeless-dialog-in-mfc). There's some good advice given about how to create a worker thread to do your looping, which then sends a message to your main (UI) thread to update the controls in the dialog. – Cody Gray - on strike Feb 17 '11 at 06:49
0

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.

Steve
  • 1,760
  • 10
  • 18
  • Then Please tell me How to avoid the MessageBox while still using the Sleep(), cause I need to give the user to view the change on the screen? – ddbiomed Feb 17 '11 at 06:36
  • @sspdd You need to understand how message queues work and you never need `Sleep` for this type of program – David Heffernan Feb 17 '11 at 07:45