Q142415: PRB: MFC Message Handler Not Called with PostThreadMessage()

Article: Q142415
Product(s): Microsoft C Compiler
Version(s): winnt:1.0,2.0,2.1,2.2,4.0,4.1
Operating System(s): 
Keyword(s): kbMFC kbThread kbVC100 kbVC200 kbVC400 kbVC410 kbWndwMsg kbGrpDSMFCATL
Last Modified: 07-MAY-2001

-------------------------------------------------------------------------------
The information in this article applies to:

- Microsoft Visual C++, versions 1.0, 2.0, 2.1, 2.2, 4.0, 4.1 
-------------------------------------------------------------------------------

SYMPTOMS
========

When code uses the PostThreadMessage() Win32 function, the MFC message handlers
are not called.


CAUSE
=====

When you call PostThreadMessage(), the message is placed in the thread's message
queue. However, because messages posted this way are not associated with a
window, MFC will not dispatch them to message or command handlers. In order to
handle these messages, override the PreTranslateMessage() function of your
CWinApp-derived class, and handle the messages manually.

RESOLUTION
==========

The following code demonstrates how to call PostThreadMessage() in the
InitInstance() of the CWinApp-derived class using a single-threaded application.
The principle is the same for secondary threads except that the code shown here
would be put in your alternate CWinThread-derived class.

Visual C++ 4.2 does support handling messages posted to threads. For more
information, see ON_THREAD_MESSAGE in the Visual C++ 4.2 documentation.

NOTE: MFC worker threads do not have a message loop/pump associated with them so
you must use a user-interface thread.

Sample Code
-----------

  /* Compile options needed:

     standard MFC project generated by AppWizard */ 

  BOOL CThreadMsgApp::PreTranslateMessage(MSG* pMsg)
  {
      // Is it the Message you want?
      // You can use a switch statement but because this is
      // only looking for one message, you can use the if/else
      if (pMsg->message == WM_USER+2268)
      {
          // Call the function to handle this message
     OnReceivedCommand(pMsg->wParam,pMsg->lParam);
          // Tell MFC no more processing is needed
          return TRUE;
      }
      else
          // Call MFC to have it continue processing the message
          return CWinThread::PreTranslateMessage(pMsg);
  }

  BOOL CThreadMsgApp::InitInstance()
  {
      WPARAM wParam;
      LPARAM lParam;
      wParam = MAKEWPARAM(0,0); // We can put whatever we
      lParam = MAKELPARAM(0,0); // want in wParam & lParam

      // Send the user-defined Thread Message
      // m_nThreadID is a member of CWinThread that holds the thread ID
      PostThreadMessage(m_nThreadID, WM_USER+2268, wParam, lParam);

      return TRUE;
  }

  void CThreadMsgApp::OnReceivedCommand(WPARAM wParam, LPARAM lParam)
  {
      // You can do whatever you want in here, this is simply
      // sending output to the debug window
      TRACE0("Received WM_USER+2268!!\n");
  }

REFERENCES
==========

For more information on the CWinThread object, please see the following: MFC
Encyclopedia, Multithreading: Creating User-Interface Threads.

Additional query words: 1.00 2.00 2.10 2.20 4.00 4.10

======================================================================
Keywords          : kbMFC kbThread kbVC100 kbVC200 kbVC400 kbVC410 kbWndwMsg kbGrpDSMFCATL 
Technology        : kbVCsearch kbVC400 kbAudDeveloper kbvc100 kbVC220 kbVC410 kbVC200 kbVC210
Version           : winnt:1.0,2.0,2.1,2.2,4.0,4.1
Issue type        : kbprb

=============================================================================