dcsimg
 

Multithreaded Wait Dialog

Sunday Jun 6th 1999 by Todd Andrews

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

Home
Mobile Site | Full Site
Copyright 2018 © QuinStreet Inc. All Rights Reserved