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_USBRDRESPONSE
和 WM_USBRDRESPONSE
【讨论】:
正如我之前所说,我的代码中的线程在被杀死之前永远不会完成。我发现 SendMessage() 也没有收到。其次,我需要等待消息发布才能继续。我在link 的另一个问题中发现的东西建议我的 PostMessage() 将它的消息发送到一个窗口。除了在对话框类中生成之外,我当前的类是无窗口的。 所以这就解释了为什么 MyComm 类不执行 OnInitDialog() 方法。所以我可能需要在这里实际创建一个隐藏窗口。对信号本身表示歉意。在我的代码中,消息是 WM_USBRDRESPONSE。我在这里将其重命名为 WM_RESPONSE 只是为了简化。我不想把整个代码放在这里,因为它有 100 多页,而且涉及知识产权问题。以上是关于mfc c++ 将带有 postmessage 的自定义用户消息从工作线程发送到主 ui 线程的主要内容,如果未能解决你的问题,请参考以下文章
MFC SendMessage和PostMessage 区别
MFC中使用PostMessage和SendMessage函数