Last Modification: May 28, 2003

How do I send/post a message to the main thread from another thread?

Posting or sending a user-defined message to the main thread is the best way to trigger something in the main thread from other threads. You start by defining the user-defined message itself. WM_APP is a windows constant that is higher than any message used by windows, so define your own windows message like this:


    #define MY_WM_MESSAGE1  (WM_APP + 1)

Your secondary thread will need an hwnd (not a CWnd*) to post to. You can pass the main hwnd when you create the thread. Then you are ready to send or post a message from the secondary thread:


    ::PostMessage(hwnd, MY_WM_MESSAGE1, (WPARAM)0, (LPARAM)0);
  or, 
    ::SendMessage(hwnd, MY_WM_MESSAGE1, (WPARAM)0, (LPARAM)0);

The lParam and wParam can be used to pass any parameters you like to the destination. PostMessage puts the message in the main thread's queue and returns quickly. The main thread processes it asynchronously. SendMessage does not return until the main thread actually gets and processes the message, so it provides interthread synchronization.

To receive and process the message in the main thread code, first declare your message hander function in the main window's h file. MFC does not route user-defined messages to views or docs, so the handler must be a member function of the CMainFrame class (or the main dialog class in a dialog-based app). The handler must have exactly this prototype:


    afx_msg LRESULT OnMyMessage1(UINT wParam, LONG lParam);

The next step is to enter your message handler into the message map, typing it in manually instead of using the wizard. Put in an ON_MESSAGE macro like the following after the "//}}AFX_MSG_MAP" line and before the "END_MESSAGE_MAP()" line.


        //}}AFX_MSG_MAP
        ON_MESSAGE(MY_WM_MESSAGE1, OnMyMessage1)
    END_MESSAGE_MAP()

This adds your message and function into the message mapping table. When the message comes in to the main window your function will be called:


    LRESULT CMainFrame::OnMyMessage1(UINT wParam, LONG lParam)
    {
        ... do something about the message from secondary thread
        return 0; // I handled this message
    }