0
votes

Using Visual Studio 2015 (Community Edition) & MFC C++ project. I have a worker thread where I wish to use PostMessage() function to send data from this thread to the main UI thread (where my CDialog resides) yet in the same class, that I want to receive this message.

In the MyComm.h file, I have the following:

#define WM_USERRESPONSE WM_APP + 2000

class MyComm: public CDialog
{
  ...
  CWnd* m_pParent;
  static BOOL m_bThreadKill;
  static CWinThread* pThread;
  static CEvent* pEvent;
  static CEvent m_ThreadKillEvent;
  ...
  static UINT MyThreadProc(LPVOID pParam);
  ...
  afx_msg LRESULT OnResponse(WPARAM wParam, LPARAM lParam);
  ...
};

In my MyComm.cpp file, I have the following:

MyComm::MyComm(CWnd* pParent /*=NULL*/)
    : CDialog(IDD_PPAGE_COMMAND, pParent)
{
  m_pParent = pParent;

  pEvent = new CEvent(FALSE, FALSE);

  if ((pThread = AfxBeginThread(MyThreadProc, this)) == NULL)
    AfxMessageBox("Could not Create Read Thread!");

  pThread->m_bAutoDelete = FALSE;
  m_ThreadKillEvent.ResetEvent();
  m_ReadThreadDead.ResetEvent();
  running = 1;
}

UINT MyComm::MyThreadProc(LPVOID pParam)
{
  MyComm *pMyHndl = ((MyComm*)pParam);
  string s = "I would like this string posted";
  BOOL b = false;

  b = ::PostMessage(pMyHndl->GetSafeHwnd(), WM_USBRDRESPONSE, 0, 
       (LPARAM)&s);
}

BEGIN_MESSAGE_MAP(MyComm, CDialog)
    ON_MESSAGE(WM_USERRESPONSE, &MyComm::OnResponse)
END_MESSAGE_MAP()

afx_msg LRESULT MyComm::OnResponse(WPARAM wParam, LPARAM lParam)
{
  MyStruct* p = (MyStruct*)lParam;
  ...
}

Note I abbreviated some of this to stay on topic.

In debugging this (there is much more code than this), I verify that the thread starts, I execute this PostMessage() function which returns true. I never get to the OnResponse() function that is intended to be the recipient. I am not sure why..(??)..

Some thoughts. It is true that the class MyComm is in the the same class yet is not the dialog thread, yet is spawned by it and is derived from CDialog. This may not be sufficient?? I admit, I am still somewhat new to threads via MFC programming paradigm. Any help is appreciated.

Maddog

2
Although not causing your delivery issue, will the string 's' still exist when the message is delivered? Will it not be RAII'd away when MyThreadProc() returns?Martin James
Sorry, in the real code the thread never returns (i.e while (1)...) or until killed.Michael Murdock
In my case this string is a buffer created when the thread is spawned.Michael Murdock
Umm.. OK, so this buffer, it cannot be overwritten before the main thread handles it?Martin James
Is it possible to use SendMessage instead? That wait you wait until the buffer has been used by the handler. Then you can carry on ...Andrew Truckle

2 Answers

1
votes

Today, I did find the answer to this problem.

It is because the class where the thread is started is not a class tied to a window yet, is spawned by one with a window. So a subtle nuance on pMyHndl is necessary. If in the POSTMESSAGE() I instead use pMyHndl->m_pParent in place of where m_pParent points to the Parent class (one with window). This code was receiving the message now that the code to receive the message was moved there. Thanks for all the help everyone.

maddog

0
votes
  • The variable string s will not exist after thread finishes. The thread function you've shown is too small, and would exit soon.
  • You should ideally start new thread from OnInitDialog not in the constructor. The message loop is not created in constructor, but in while in OnInitDialog.
  • Check that message code is correct. Your code has both: WM_USBRDRESPONSE and WM_USBRDRESPONSE