How to show a "Wait" dialog?

I want to show a wait dialog while the program is doing a long job (compacting the database). I have written a dialog which has an animated control with a moving clock. When I tested it with the following it works:

CWaitDlg *pWD = new CWaitDlg;

pWD->Create(IDD_WAIT, 0);
pWD->ShowWindow(SW_SHOW);

//To hold for showing the effect of the animated control

AfxMessageBox("Stop");

pWD->DestroyWindow();
delete pWD;

;; But when I change to :

CWaitDlg *pWD = new CWaitDlg;

pWD->Create(IDD_WAIT, 0);
pWD->ShowWindow(SW_SHOW);

//To do the long job.
pDaoDatabase->Compact(szOldDB, szNewDB);

pWD->DestroyWindow();
delete pWD;

;;The Dialog appears, but was frozen (the clock does not move)

??What is the problem and how to solve it?
hshliangAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Vinayak KumbarSr Program ManagerCommented:
Hi,
I yhink the Compact(...) is taking all CPU time and resources, so the clock is not getting updated. For that U may have to spawn a thread for timer updation.In the OnInitDialog() of CWaitDlg, spawn a thread using AfxBeginThread(...). And in the thread procedure, animate the timer.

Try it out.
VinExpert
0
chensuCommented:
This is because your Compact function does not yield control. Thus, the animate control does not have a chance to run. Check out the following article that implements the CWaitDialog class.

http://www.microsoft.com/msj/defaultframe.asp?page=/msj/0297/wicked/wicked0297.htm
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
chensuCommented:
Another method to achieve it is to use a worker thread. Check out my article at CodeGuru.

Download a File Using URLDownloadToCacheFile
http://www.codeguru.com/internet/urlfile.shtml
0
Get expert help—faster!

Need expert help—fast? Use the Help Bell for personalized assistance getting answers to your important questions.

hshliangAuthor Commented:
I started looking for the ways to do it by a different thread. My work come to a few questions:
1) The Jet engine is not multi-Thread compatible, so I must keep the database compacting in the original application.
2) This leaves me the only option to call and display a wait dialog in a different thread.
3) That means the urlfileDlg by chensu using Worker thread is not feasible.
4) Hence I have to use a User-Interface thread. I studied the example by Todd Andrews of a WaitDialog. It passes the messages by CEvent. But it runs out of a Doc/View application. My original program is a dialog-based application. This becomes a problem. The waitdlg created by DoModal is not deleted after the thread is closed. I tried to create the dialog indirectly, but again, no luck. I do not know how to tell the thread that the task is done. If I call AfxBeginThread, the dialog is displayed. But when do I close it?

see below codes:

//////////// the calling function //////////////
void CSimWaitDlg::OnGo()
{
      // TODO: Add your control notification handler code here

      Start();

      long i,x,y;

      for(x=0;x<100000;x++)
            for(y=0;y<10000;y++)
                  i = x * y;

            TRACE("Finish work\n");
      End();
      
}

//////////// Start /////////
void CSimWaitDlg::Start()
{


      m_pThread = (CSimThread *)AfxBeginThread(RUNTIME_CLASS(CSimThread), THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED);

//      m_pThread->m_bAutoDelete = FALSE;  ///Should I use autoDelete or not???

      TRACE("To Start Thread 0x%08lX\n",m_pThread->m_nThreadID);

      m_pThread->ResumeThread();

}

///////////// End ///////////////
void CSimWaitDlg::End()
{
      ASSERT(NULL != m_pThread);
      ASSERT_KINDOF(CWinThread, m_pThread);

      TRACE("To End Thread\n");
      
      TRACE("m_pThread->m_hThreadID = 0x%08lX\n",m_pThread->m_nThreadID);

      GetExitCodeThread(m_pThread->m_hThread,&dwExitCode);
      
      TRACE("Exit Code is %d and STILL_ACTIVE is %d\n",dwExitCode,STILL_ACTIVE);
      
      ///The exit code return STILL_ACTIVE

//////////???? should I call ExitInstance here??
///////// If I do not, there is no way to close the Thread
////////  Please suggest ways I can close the thread here and to delete the CWaitDlg object
      
      m_pThread->ExitInstance();
      
      delete m_pThread;
      
      m_pThread = NULL;


}
/////////// The Thread's functions ///////////////////
BOOL CSimThread::InitInstance()
{
      // TODO:  perform and per-thread initialization here

    m_pMainWnd = new CWaitDlg;

    TRACE("Creating Wait dialog\n");

    ((CWaitDlg *)m_pMainWnd)->Create(IDD_WAITDLG,NULL);

    TRACE("Showing Wait dialog m_pMainWnd is 0x%08X\n",m_pMainWnd);

    m_pMainWnd->ShowWindow(SW_SHOW);

 
   return      TRUE;
}

int CSimThread::ExitInstance()
{
      // TODO:  perform any per-thread cleanup here
      TRACE("Exiting Thread m_pMainWnd is 0x%08X\n",m_pMainWnd);
      
/////////////////???????????? Big question ??????????????///////////////
//////Problem here, the WaitDlg does not get destroyed immediately
//////  and NB  when I MOVE the MOUSE, the following errors occur
/////   at winecore.cpp line 304 (see Debug message below)
/////      otherwise the dialog just keeps going
////    that is I cannot destroy the dialog here.

      m_pMainWnd->DestroyWindow();
      delete m_pMainWnd;
      m_pMainWnd = NULL;

      return CWinThread::ExitInstance();
}




//////////////////Debug messages//////////////////
To Start Thread 0xFFF8ADD1
Creating Wait dialog
Showing Wait dialog m_pMainWnd is 0x00781970
Finish work
To End Thread
m_pThread->m_hThreadID = 0xFFF8ADD1
Exit Code is 259 and STILL_ACTIVE is 259
Exiting Thread m_pMainWnd is 0x00781970
Second Chance Assertion Failed: File wincore.cpp, Line 304
The program 'C:\BillVC\SimWait\Debug\SimWait.exe' has exited with code 0 (0x0).

Please HELP
0
chensuCommented:
Don't call ExitInstance, which will be called by the framework. To terminate a user-interface thread, call ::PostQuitMessage from within the user-interface thread. You may need to use a CEvent object to notify it to terminate. urlfileDlg.cpp shows how to use CEvent.
0
hshliangAuthor Commented:
I did try ::PostQuitMessage(), the problem is the parent dialog is closed also. Any ways to avoid this?
THANKS
0
chensuCommented:
The parent dialog is in the different thread, isn't it? Then, the parent dialog should not be closed.
0
hshliangAuthor Commented:
I do this and seems to work:
instead of creating the dialog indirectly, I create it directly like
In the Thread:
CWaitDlg WD;
m_pMainWnd = &WD;

WD.DoModal();

On End:

((CDialog *)m_pThread->m_pMainWnd)->EndDialog(0);

However, when I tested it in Release mode, it fails with assertion errors.
I am not sure why.
0
chensuCommented:
I would suggest you take a look at some MFC UI thread samples that come with Visual C++.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
System Programming

From novice to tech pro — start learning today.