mfc c++ 将带有 postmessage 的自定义用户消息从工作线程发送到主 ui 线程

Posted

技术标签:

【中文标题】mfc c++ 将带有 postmessage 的自定义用户消息从工作线程发送到主 ui 线程【英文标题】:mfc c++ send a custom user message with postmessage from a working thread to main ui thread 【发布时间】:2016-04-04 22:31:11 【问题描述】:

使用 Visual Studio 2015(社区版)和 MFC C++ 项目。我有一个工人 我希望使用 PostMessage() 函数将数据从该线程发送到主 UI 线程(我的 CDialog 所在的位置)但在同一个类中的线程,我 想收到这条消息。

在 MyComm.h 文件中,我有以下内容:

#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);
  ...
;

在我的 MyComm.cpp 文件中,我有以下内容:

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;
  ...

请注意,我对其中的一些内容进行了缩写以保持主题。

在调试这个(代码比这个多得多)时,我验证线程是否启动,我执行返回 true 的 PostMessage() 函数。我永远也达不到 打算作为接收者的 OnResponse() 函数。我不确定 为什么..(??)..

一些想法。确实,MyComm 类在同一个类中,但 不是对话线程,而是由它产生并派生自 CDialog。这 可能还不够??我承认,我对通过 MFC 的线程仍然有些陌生 编程范式。任何帮助表示赞赏。

疯狗

【问题讨论】:

虽然不会导致您的投递问题,但在投递邮件时字符串 's' 是否仍然存在? MyThreadProc() 返回时它不会被 RAII 删除吗? 抱歉,在实际代码中,线程永远不会返回(即 while (1)...)或直到被杀死。 在我的例子中,这个字符串是线程产生时创建的缓冲区。 Umm.. OK,所以这个缓冲区,在主线程处理之前不能被覆盖? 是否可以使用 SendMessage 代替?等待你等到处理程序使用缓冲区。然后你可以继续... 【参考方案1】:

今天,我确实找到了这个问题的答案。

这是因为启动线程的类不是绑定到一个 窗户,是由一个有窗户的人产生的。所以pMyHndl 上的细微差别 是必要的。如果在POSTMESSAGE() 我改用pMyHndl->m_pParent 代替 m_pParent 指向父类的位置(带有窗口的类)。 此代码正在接收消息,现在接收消息的代码 被搬到那里。感谢大家的帮助。

疯狗

【讨论】:

【参考方案2】: 变量string s在线程结束后将不存在。您显示的线程函数太小,很快就会退出。 理想情况下,您应该从OnInitDialog 开始新线程,而不是在构造函数中。消息循环不是在构造函数中创建的,而是在 OnInitDialog 的 while 中创建的。 检查消息代码是否正确。您的代码同时具有:WM_USBRDRESPONSEWM_USBRDRESPONSE

【讨论】:

正如我之前所说,我的代码中的线程在被杀死之前永远不会完成。我发现 SendMessage() 也没有收到。其次,我需要等待消息发布才能继续。我在link 的另一个问题中发现的东西建议我的 PostMessage() 将它的消息发送到一个窗口。除了在对话框类中生成之外,我当前的类是无窗口的。 所以这就解释了为什么 MyComm 类不执行 OnInitDialog() 方法。所以我可能需要在这里实际创建一个隐藏窗口。对信号本身表示歉意。在我的代码中,消息是 WM_USBRDRESPONSE。我在这里将其重命名为 WM_RESPONSE 只是为了简化。我不想把整个代码放在这里,因为它有 100 多页,而且涉及知识产权问题。

以上是关于mfc c++ 将带有 postmessage 的自定义用户消息从工作线程发送到主 ui 线程的主要内容,如果未能解决你的问题,请参考以下文章

MFC SendMessage和PostMessage 区别

C++:如何将 MessageBox 居中?

MFC中使用PostMessage和SendMessage函数

接收 MFC 对话框的 PostMessage 消息

MFC发送自定义消息-PostMessage和SendMessage

请问MFC中PostMessage()在此有啥作用呢?