UI-Thread Demonstration

WEBINAR: On-demand webcast

How to Boost Database Development Productivity on Linux, Docker, and Kubernetes with Microsoft SQL Server 2017 REGISTER >

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


Comments

  • Can same technique be applied to MDI

    Posted by Legacy on 05/15/2002 12:00am

    Originally posted by: corremn

    Hi does anyone know if this technique of UI Threads be applied to a MDI UI? This is being a problem for some time now. I have not seen it mentioned anywhere
    Thanks

    Reply
  • Debug Version of the library crashes the app..

    Posted by Legacy on 12/11/2001 12:00am

    Originally posted by: Guruprasad

    When you debug the app, it crashes. Also, timer runs in a separate thread by itself. so there are three threads in the app now I guess.

    Reply
  • Source Code not updated

    Posted by Legacy on 10/16/2001 12:00am

    Originally posted by: John Brassard

    You have not corrected the source code that is available for download.

    Reply
  • You don't need to create an invisible button to update the data

    Posted by Legacy on 10/05/2001 12:00am

    Originally posted by: SSD

    Instead of create this button, you can use
    
    m_Dlg.UpdateData(FALSE) function directly.

    void CUIThread::SetString(CString &szString)
    {
    if(IsRunning())
    {
    m_Dlg.m_szMessage = szString;
    // m_Dlg.PostMessage(WM_COMMAND, IDC_BUTTON1);

    m_Dlg.UpdateData(FALSE);
    }
    else
    m_szMessage = szString;
    }

    void CUIThread::SetString(LPCTSTR szString)
    {
    if(IsRunning())
    {
    m_Dlg.m_szMessage = szString;
    // m_Dlg.PostMessage(WM_COMMAND, IDC_BUTTON1);
    m_Dlg.UpdateData(FALSE);
    }
    else
    m_szMessage = szString;
    }

    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • As all sorts of data becomes available for storage, analysis and retrieval - so called 'Big Data' - there are potentially huge benefits, but equally huge challenges...
  • The agile organization needs knowledge to act on, quickly and effectively. Though many organizations are clamouring for "Big Data", not nearly as many know what to do with it...
  • Cloud-based integration solutions can be confusing. Adding to the confusion are the multiple ways IT departments can deliver such integration...

Most Popular Programming Stories

More for Developers

RSS Feeds

Thanks for your registration, follow us on our social networks to keep up-to-date