title: C++11 threads to update MFC application windows. SendMessage(), PostMessage() required?
body: <p>After spending a bit of time with simple UWP applications with C++/CX and ++/WinRT I have begun to enjoy some of the features of targeting that environment for Windows UI app development.</p>
  
  <p>Now having to go back to a more familiar MFC application development I want to change my approach to something that is similar to UWP app development. The idea is to use asynchronous C++11 threads to generate content and modify content that is displayed in the MFC UI.</p>
  
  <p>The main change I want to make is to use C++11 threads to offload some time-consuming tasks and have those threads communicate the results back to the main MFC UI.</p>
  
  <p>Some of the tasks that I am looking to offload onto C++11 threads, which are similar to what I would use with asynchronous tasks with C++/CX and C++/WinRT in UWP apps are:</p>
  
  <ul>
  <li>connect to and exchange data with another computer</li>
  <li>open a data file and parse it to update the UI view</li>
  <li>convert a data file to another format such as CSV and export to a file</li>
  <li>read a file in a format such as CSV and convert the content into a data file</li>
  <li>perform searches and filtering of the presentation of the data file in the UI</li>
  </ul>
  
  <p>The problem I am running into is similar to the problem described in <a href="https://stackoverflow.com/questions/17340285/can-i-have-multiple-gui-threads-in-mfc">Can I have multiple GUI threads in MFC?</a>, however, I am looking for a general approach rather than the specific progress bar update in that question.</p>
  
  <p>I have been trying a simple test with an experimental MFC app using the Visual Studio template which has a tree control docked on the left to build the tree in a worker thread.</p>
  
  <p>If I have a <code>CViewTree</code>, an MFC window that displays a tree view, which I want to update from a C++11 thread, I am currently using <code>::PostMessage()</code> to request that the tree control in the docked pane is updated.</p>
  
  <p>If I use a lambda with a global <code>std::thread</code> such as the following code:</p>
  
  <pre><code>std::thread t1;
  
  void CClassView::FillClassView()
  {
      // ::SendMessage() seems to deadlock so ::PostMessage() is required.
      t1 = std::thread([this]() { Sleep(5000);  ::PostMessage(this-&gt;m_hWnd, WM_COMMAND, ID_NEW_FOLDER, 0); });
  
  }
  </code></pre>
  
  <p>the message handler for the MFC docked pane which looks like:</p>
  
  <pre><code>void CClassView::OnNewFolder()
  {
      t1.join();   // this join seems to deadlock if ::SendMessage() is used.
  
      AddItemsToPane(m_wndClassView);
  }
  </code></pre>
  
  <p>does indeed update the MFC docked pane with the tree control content just as if the function <code>AddItemsToPane(m_wndClassView);</code> were called at the same place where the C++11 thread is created. The pane update is delayed by 5 seconds when the C++11 thread is used just to provide a visible indication that the thread approach is actually working.</p>
  
  <p>My problem is that I want the C++11 thread to create the content for the tree control and provide it to the docked pane rather than having the docked pane generate the content.</p>
  
  <p>Thus far the only approach I can think of is to develop my own class library that will provide C++11 thread analogues to the MFC library and controls using <code>::PostMessage()</code> to send the appropriate Windows messages to the designated MFC window or control.</p>
  
  <p>I am wondering if it is possible to have the C++11 threads have their own, shadowing MFC control which they update and then send a message to the UI asking the UI to update its displayed control with the contents of the shadow MFC control? Or is there some other approach that people are using?</p>
  
  <p>I am looking for some other, less arduous approaches to solving this problem of updating an MFC UI from C++11 threads.</p>
  
  <p><strong>By the way #1</strong> <code>::SendMessage()</code> appears to deadlock on the <code>join()</code> in <code>CClassView::OnNewFolder()</code> which I assume means that some kind of synchronization between the C+11 thread and the UI thread is blocking the C++11 thread from reaching its side of the <code>join()</code>?</p>
  
  <p>Yes there is a deadlock as the thread waits for <code>SendMessage()</code> to return while the message handler is waiting at the <code>join()</code> for the thread to finish. According to the <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/ms644950(v=vs.85).aspx" rel="nofollow noreferrer">Windows Dev Center SendMessage function</a>:</p>
  
  <blockquote>
    <p>Sends the specified message to a window or windows. The <code>SendMessage</code>
    function calls the window procedure for the specified window and <strong>does
    not return until the window procedure has processed the message</strong>.</p>
    
    <p>To send a message and return immediately, use the <code>SendMessageCallback</code>
    or <code>SendNotifyMessage</code> function. To post a message to a thread's message
    queue and return immediately, use the <code>PostMessage</code> or <code>PostThreadMessage</code>
    function.</p>
  </blockquote>
  
  <p><strong>By the way #2</strong> It would also seem that using the actual Window handle rather than the <code>this</code> pointer in the lambda for the C++11 thread would be safer. Just in case the <code>this</code> pointer becomes undefined for some reason such as the control is removed?</p>
  
  <p><strong>By the way #3</strong> The Microsoft <code>concurrency</code> namespace, provided via <code>#include &lt;ppltasks.h&gt;</code>, is an alternative to C++11 threads. The <code>concurrency</code> namespace functions are at a higher level of abstraction than C++11 threads and are easier to use.</p>
  
  <p>For instance the above use of <code>std:thread</code> could be rewritten as:</p>
  
  <pre><code>void CClassView::FillClassView()
  {
      concurrency::create_task([this]() { Sleep(5000);  ::SendMessage(this-&gt;m_hWnd, WM_COMMAND, ID_NEW_FOLDER, 0); });
  }
  </code></pre>
  
  <p>and this does not require the use of a <code>std::thread join()</code> to cleanly terminate the thread. Also <code>SendMessage()</code> or <code>PostMessage()</code> may be used to send the Windows message since we do not have the same deadlock issue as we have with C++11 threads.</p>
  
  <p><strong>Notes</strong></p>
  
  <p><em>Note #1:</em> <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/ms644927(v=vs.85).aspx" rel="nofollow noreferrer">About Messages and Message Queues</a> as well as <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/ms644928(v=vs.85).aspx" rel="nofollow noreferrer">Using Messages and Message Queues</a>.</p>
  
  <p>For MFC specific content see <a href="https://msdn.microsoft.com/en-us/library/70sw24a7.aspx" rel="nofollow noreferrer">Messages and Commands in the Framework</a>.</p>
  
  <p><em>Note #2:</em> <a href="https://msdn.microsoft.com/en-us/library/975t8ks0.aspx" rel="nofollow noreferrer">Multithreading with C++ and MFC</a> and specifically <a href="https://msdn.microsoft.com/en-us/library/h14y172e.aspx" rel="nofollow noreferrer">Multithreading: Programming Tips</a> which says.</p>
  
  <blockquote>
    <p>If you have a multithreaded application that creates a thread in a way
    other than using a CWinThread object, you cannot access other MFC
    objects from that thread. In other words, if you want to access any
    MFC object from a secondary thread, you must create that thread with
    one of the methods described in Multithreading: Creating
    User-Interface Threads or Multithreading: Creating Worker Threads.
    These methods are the only ones that allow the class library to
    initialize the internal variables necessary to handle multithreaded
    applications.</p>
  </blockquote>
  
  <p><em>Note #3:</em> <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/mt695951(v=vs.85).aspx" rel="nofollow noreferrer">UWP APIs callable from a classic desktop app</a> which says:</p>
  
  <blockquote>
    <p>With some notable exceptions, the general rule is that a Universal
    Windows Platform (UWP) API can be called from a classic desktop app.
    The two main areas of APIs that are an exception to this general rule
    are XAML UI APIs, and APIs that require the calling app to have a
    package identity. UWP apps have a well-defined app model, and they
    have a package identity. Classic desktop apps do not have a
    well-defined app model, and they do not have a package identity. A
    classic desktop app that has been converted to a UWP app does have a
    package identity.</p>
  </blockquote>
  
  <p>See as well the following blogs from Sep 2012 about WinRT with VS 2012 and Windows 8. Though C++/WinRT with VS 2017 seems more appropriate for Windows 10 than Windows Runtime template Library (WRL) used:</p>
  
  <ul>
  <li><a href="http://blogs.microsoft.co.il/pavely/2012/09/13/accessing-winrt-from-desktop-apps-part-1/" rel="nofollow noreferrer">Accessing WinRT From Desktop apps (Part 1)</a></li>
  <li><a href="http://blogs.microsoft.co.il/pavely/2012/09/24/accessing-winrt-from-desktop-apps-part-2/" rel="nofollow noreferrer">Accessing WinRT from Desktop Apps (Part 2)</a></li>
  </ul>
  
  <p><em>Note #4:</em> <a href="https://msdn.microsoft.com/en-us/library/d06h2x6e.aspx" rel="nofollow noreferrer">MFC Desktop Applications</a> which is a jumping off point with lots of links. See also <a href="https://msdn.microsoft.com/en-us/library/k851ext3.aspx" rel="nofollow noreferrer">MFC COM</a> which is a jumping off point with lots of links about MFC with COM along with this article <a href="https://msdn.microsoft.com/en-us/library/bwa2bx93.aspx" rel="nofollow noreferrer">Introduction to COM</a>. See as well <a href="https://msdn.microsoft.com/en-us/library/f2dch7fb.aspx" rel="nofollow noreferrer">MFC Macros and Globals</a>.</p>
  
  <p>As for using <code>AfxGetMainWnd()</code> to get the main application window, the Microsoft developer center has this to say in the article <a href="https://msdn.microsoft.com/en-us/library/waas15s1.aspx" rel="nofollow noreferrer">AfxGetMainWnd</a>:</p>
  
  <blockquote>
    <p>If AfxGetMainWnd is called from the application's primary thread, it
    returns the application's main window according to the above rules. If
    the function is called from a secondary thread in the application, the
    function returns the main window associated with the thread that made
    the call.</p>
  </blockquote>