title: Understanding MsgWaitForMultipleObjects
body: <p>I have a main gui thread that I want to remain responsive to the users action such as moving the dialog around, resizing, etc while I have a background thread doing some task.  In the past I've used WaitForSingleObject with a timeout in order to process gui events while waiting on the background thread to complete.  I recently read about  MsgWaitForMultipleObjects which looked to be solving the problem that I had a little bit cleaner.</p>
  
  <p>Can someone tell me the bugs in the following code &amp; where I'm going wrong here?  The gui is unresponsive when I click the button to start the thread.  I made a dialog app with an avi that is playing on the main ui thread.  I have a button to start a thread and use MsgWaitForMultipleObjects to wait on the thread handle but allow all messages through to be processed ultimately breaking when the thread is finished/signaled. </p>
  
  <p>Thanks.</p>
  
  <pre><code>UINT MyThreadProc( LPVOID pParam )
  {
      ThreadData* pObject = (ThreadData*)pParam;
  
      if (pObject == NULL ||
          !pObject-&gt;IsKindOf(RUNTIME_CLASS(ThreadData)))
      return 1;   
  
      // Do some processing.
      int x = 0; 
      while (x++ &lt; 5000)
      {
          for (int i=0; i&lt;50000; i++)
              double sum = sqrt((double)i+1) * sqrt((double)i+2); 
      }
  
      return 0;
  }
  </code></pre>
  
  <p>Button Handler </p>
  
  <pre><code>void Cmsgwait_demoDlg::OnBnClickedBtnStartThread()
  {
      m_pThreadData = new ThreadData;
      CWinThread* pWorkThread = AfxBeginThread(MyThreadProc, m_pThreadData);
  
      m_status.SetWindowText("Status: Waiting for thread to complete."); 
  
      HANDLE handles[] = { pWorkThread-&gt;m_hThread }; 
      DWORD ret = 0; 
  
      do 
      {
          ret = MsgWaitForMultipleObjects(1, handles, FALSE, INFINITE, QS_ALLINPUT); 
          if (ret == WAIT_OBJECT_0)
          {
              m_status.SetWindowText("Status: Thread completed."); 
          }
          else if (WAIT_IO_COMPLETION)
          {
              m_status.SetWindowText("Status: User mode APC queued."); 
          }
          else if (WAIT_FAILED)
          {
              m_status.SetWindowText("Status: Wait failed"); 
          }
      }
      while (ret != WAIT_OBJECT_0 &amp;&amp; ret != WAIT_FAILED);
  }
  </code></pre>