[Webinar] Streamline your web hosting managementRegister Today

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 425
  • Last Modified:

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?
0
hshliang
Asked:
hshliang
  • 5
  • 3
1 Solution
 
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
 
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
Keep up with what's happening at Experts Exchange!

Sign up to receive Decoded, a new monthly digest with product updates, feature release info, continuing education opportunities, and more.

 
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

Featured Post

Get your problem seen by more experts

Be seen. Boost your question’s priority for more expert views and faster solutions

  • 5
  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now