UI-Thread Demonstration

Environment: VC6, Win98, Win2K, WinNT
 

Introduction

Hi, according to the documentation of the MSDN for MFC, we can create either worker thread or UI thread. As the name implies, the worker thread is normally spawned off to work on some sort of background task while the UI thread would be used for user interface.

As there ain't many examples of UI thread example, I would like to take this opportunity to demonstrate on how UI thread can be created and used to display a modal dialog box. This program was written to display a count down message in the dialog box. When the timer reaches zero, the dialog box will be closed automatically.

Creating and Starting the UI-Thread

The key of writing a UI-thread is by using CWinThread class. When the UI-Thread object is created, the member variable m_bAutoDelete's default value is TRUE which means that the thread object will be automatically deleted when the thread terminates. However, there may be situation that we need to keep track of multiple threads and therefore need to delete the object ourselves.

Next, to start the thread of the UI-Thread object, use the CreateThread() function of CWinThread. If the dwCreateFlag is set to CREATE_SUSPENDED, the thread will not execute until ResumeThread() is called.

Writing the UI-Thead

The two main methods of CWinThread are InitInstance() and Run().

When the CWinThread object is being created and run, the first function to be executed will be InitInstance(). This member function is normally used to initialization before the normal operation commence. If initialization is performed without any error, this function should return TRUE. On the other hand, if error occurs during initialization, this function should return FALSE so as to stop the thread object from execution.

The next function is Run(), this is the function that performs normal operation where is the thread loops endlessly until it is being informed to break out from it. One way to do this is by using a while loop as show below:

int CThread::Run() // CThread is derived from CWinThread.
{
   while(!m_bKill)
   {
      // Do some work.
      .
      .
      .
   }
   return 0;
}

When the thread breaks out from the loop, the thread will be automatically killed gracefully. Besides using a continuous loop to perform some task, this example shows that we can display a dialog box.

int CUIThread::Run()
{
   ...
   m_Dlg.DoModal();
   ...
}

The advantage of doing so is that the main program's thread will be blocked while displaying the dialog box but also at the same time performs other operations. For this example, counting down through WM_TIMER window message.

Manipulating the UI-Threaded Dialog Box

To manipulate the dialog box, this example shows that we can simply do so by PostMessage() to the Dialog box.
void CUIThread::Kill()
{
   // Kill the interface thread by posting a 
   // message to the close dialog box.
   if(m_bKill) return;

   m_Dlg.PostMessage(WM_COMMAND, IDCANCEL);
}

void CUIThread::SetString(CString &szString)
{
   if(IsRunning())
   {
      // Updating the displayed message
      m_Dlg.m_szMessage = szString;
      m_Dlg.PostMessage(WM_COMMAND, IDC_BUTTON1);
   }
   else
      m_szMessage = szString;
}

Download

Download demo project - 24 Kb
Download source - 71 Kb