Multithreaded Wait Dialog

Environment: Window95/98, NT

Well, this project actually started as an effort to do multithreaded DAO.  I had
some calculations that were running *much* too long on user’s machines and there was some
concern that people might actually reboot their machines, thinking they had locked up.
  The calculations in question involved going back and forth to a Jet database, so my
first thought was to isolate the calculations in a thread of their own and show a little
modal dialog letting the user know that the program was still running.

Needless to say, placing Jet in a worker thread did not work (at least, I couldn’t get
it to work…).  So, as a secondary option, I created a class that would start a
worker thread and manage a dialog with an animation on it.  It works more or less
like CWaitCursor, all you need to do is declare a variable of type CWaitDialog and call
the Show function and the modal dialog will show until you call the Close function.  
As a secondary option, you can create a dialog with an abort button on it.   This
might be useful for printing or other operations, although a little extra work is required
to get the class to respond to the button event.

The WaitDialog itself requires 3 classes: cWaitDialog, which is derived from CCmdTarget
so it can use a message map.  cWaitDialog contains a cWaitDlgThread member, which is
the worker thread derived from CWinThread.  Lastly is cWaitDlg, which is derived from
CDialog.  This could really be any CDialog derivative, as long as you include the
code in the OnTimer, OnCancel and OnOK functions.  The dialog in the sample project
also includes 2 other classes, cAnimWnd and cMemDC.  cAnimWnd is a simple class that
displays a series of bitmaps on a timer, and cMemDC is used by the cAnimWnd (from Keith
Rule’s CMemDC – thanks, Keith!).



// Creating a cWaitDialog without an abort button:
void CWaitDialogView::OnViewWaitDlg()
{
   long i,x;
   cWaitDialog dlg;

   dlg.m_Text = "Calculating...please wait";

   dlg.Show();

// Do lengthy task here....

   dlg.Close();
}

//////////////////////////////////////////////
// Creating a cWaitDialog with an abort button, and creating an event to respond to:
void CWaitDialogView::OnViewAbortDlg()
{
   HANDLE event;
   event = CreateEvent(NULL, TRUE, FALSE, "CONEVENTTEST");
// can't use a cWaitDialog here because we have to be able to wait for the event to fire,
// so create a cWaitDlgThread instead.  This is essentially what the cWaitDialog class is doing 
// internally anyhow.

   cWaitDlgThread *thread = (cWaitDlgThread *)AfxBeginThread(RUNTIME_CLASS(cWaitDlgThread), THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED);

   thread->m_Eventname = "CONEVENTTEST";
   thread->m_bShowCancelButton = true;
   thread->m_Text = "Calculating...please wait";

   thread->ResumeThread();

      long i,x;

      x = 0;
   while ((WaitForSingleObject(event, 0)==WAIT_TIMEOUT) && (x < 10000000))
      {
// Do lengthy task here....
      }

   thread->m_Event->SetEvent();
   CloseHandle(event);

}

Download source & demo project – 22 Kb

History

More by Author

Must Read