连续调用PostThreadMessage只能响应一次线程函数,若放置messagebox就没问题

倾城笑颜 2015-08-23 11:08:22
void MDDialog::OnButton4() //界面的一个普通按钮触发事件
{
int count = 0;

while (count < 5)
{
if(!PostThreadMessage(m_dwPrintId,0,0,0))//post thread msg向线程函数发出消息
{
AfxMessageBox("post message failed,errno:%d\n",::GetLastError());

}else
{
// AfxMessageBox("send success");//post成功则执行此处
// ::Sleep(500);

}

count++;
}
_-------------------------------------------------------------------------------------------------------------------
问题是,while循环5次,if判断后 每次都是执行到发送成功的,但是实际情况是线程响应函数只接受到一次消息,但我明明连续执行了5次,按道理线程函数里接受5次消息的呀,最后我在postThreadMessage之间加了弹出框,即每次post间加AfxMessageBox()后, 相对应的线程函数里的消息循环里就能循环5次了。why,加了弹出框就行,一开始以为是时间问题,将弹出框换成Sleep,还是执行一次。
----------------------------------------------------------------------------------------------------------------------
以下是线程函数,正常情况我postThreadMessage多少次,我的线程函数while循环
里就应该执行多少次,因为GetMessage(&msg,NULL,0,0)按道理是能捕获我post出去的消息的,现在的状况就是只执行一次while循环体,但是我若在多次PostThreadMessage间加MessageBox弹窗,就能保证我能GetMessage多少次,否则只能有一次效果,用Sleep间隔多个PostThreadMessage也没效果,线程函数也是只能捕获一次。
----------------------------------------------------------------------------------------------------------------------
DWORD WINAPI PrintOutMd(LPVOID lpParameter) //行情输出打印线程函数
{ AfxMessageBox("PrintOutMd");
int a = 0;
CString s ="";
MSG msg;
while(GetMessage(&msg,NULL,0,0))
{
BOOL bRes = PeekMessage(&msg, NULL, 0, 0, PM_REMOVE);
if (bRes)
{
//在这里处理本线程的消息。
s.Format("%d--有消息处理", a++);
AfxMessageBox(s);
}else
{
AfxMessageBox(_T("CThreadMsg::Run() 无消息处理/r/n"));
}

}

return 1 ;
}
...全文
266 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
阿源是少年 2015-08-26
  • 打赏
  • 举报
回复
引用 16 楼 u013255206 的回复:
[quote=引用 13 楼 pcradio 的回复:] [quote=引用 7 楼 u013255206 的回复:] [quote=引用 6 楼 pcradio 的回复:]
while(GetMessage(&msg,NULL,0,0))
你PostThreadMessage发送的uMsg 是0也就是WM_QUIT,看看你的while判断,接收到一个WM_QUIT就直接退出while了,你觉得呢
GetMessage(&msg,NULL,0,0)在这里只是判断PostThreadMessage有没有发送的uMsg,判断收到的是什么消息是 uMsg.message == (消息名) 。 我前面说过,在多个PostThreadMessage(post5次)之间放置MessageBox()弹窗,线程函数里的while(GetMessage(&msg,NULL,0,0))就循环了5次,这是肯定没有退出while的,但是没有弹窗就只有一次,用Seelp(1000)代替也只是接收到一次消息。[/quote] GetMessage收到WM_QUIT它还不会退出,你是在逗我么,AfxMessageBox会另起消息循环,你考虑到了么?![/quote] AfxMessageBox确实影响了,调试发现,没有弹窗,消息队列是可以接收到每次post过来的消息的,只不过用了弹窗,就不会接受每次的post消息[/quote] messagebox会阻塞原消息循环的while并另开消息循环,这样就拦截了消息
倾城笑颜 2015-08-26
  • 打赏
  • 举报
回复
引用 13 楼 pcradio 的回复:
[quote=引用 7 楼 u013255206 的回复:] [quote=引用 6 楼 pcradio 的回复:]
while(GetMessage(&msg,NULL,0,0))
你PostThreadMessage发送的uMsg 是0也就是WM_QUIT,看看你的while判断,接收到一个WM_QUIT就直接退出while了,你觉得呢
GetMessage(&msg,NULL,0,0)在这里只是判断PostThreadMessage有没有发送的uMsg,判断收到的是什么消息是 uMsg.message == (消息名) 。 我前面说过,在多个PostThreadMessage(post5次)之间放置MessageBox()弹窗,线程函数里的while(GetMessage(&msg,NULL,0,0))就循环了5次,这是肯定没有退出while的,但是没有弹窗就只有一次,用Seelp(1000)代替也只是接收到一次消息。[/quote] GetMessage收到WM_QUIT它还不会退出,你是在逗我么,AfxMessageBox会另起消息循环,你考虑到了么?![/quote] AfxMessageBox确实影响了,调试发现,没有弹窗,消息队列是可以接收到每次post过来的消息的,只不过用了弹窗,就不会接受每次的post消息
zhusg 2015-08-25
  • 打赏
  • 举报
回复
看下这个http://blog.csdn.net/thefutureisour/article/details/8155888
schlafenhamster 2015-08-25
  • 打赏
  • 举报
回复
uMsg 是0 ;也就是WM_NULL
阿源是少年 2015-08-24
  • 打赏
  • 举报
回复
while(GetMessage(&msg,NULL,0,0))
你PostThreadMessage发送的uMsg 是0也就是WM_QUIT,看看你的while判断,接收到一个WM_QUIT就直接退出while了,你觉得呢
阿源是少年 2015-08-24
  • 打赏
  • 举报
回复
你Post WM_QUIT消息吗?接收方如何处理的?
schlafenhamster 2015-08-24
  • 打赏
  • 举报
回复
通常 BOOL bRes = PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE);
schlafenhamster 2015-08-24
  • 打赏
  • 举报
回复
DWORD WINAPI PrintOutMd(LPVOID lpParameter) //行情输出打印线程函数 { AfxMessageBox("PrintOutMd"); 应该使用 afxDump << "PrintOutMd\n"; 以避免 MessageBox 打扰 消息 处理
二班的码农 2015-08-24
  • 打赏
  • 举报
回复
The PostThreadMessage function places (posts) a message in the message queue of the specified thread and then returns without waiting for the thread to process the message. 也就是说调用PostThreadMessage函数,该函数会把一个消息放在指定线程的消息对列里,只要线程存在,一般都返回非零 当你用while循环5次时,已经向指定线程发送了五个这样的消息,只不过指定线程来不及处理,只处理了一个
阿源是少年 2015-08-24
  • 打赏
  • 举报
回复
引用 7 楼 u013255206 的回复:
[quote=引用 6 楼 pcradio 的回复:]
while(GetMessage(&msg,NULL,0,0))
你PostThreadMessage发送的uMsg 是0也就是WM_QUIT,看看你的while判断,接收到一个WM_QUIT就直接退出while了,你觉得呢
GetMessage(&msg,NULL,0,0)在这里只是判断PostThreadMessage有没有发送的uMsg,判断收到的是什么消息是 uMsg.message == (消息名) 。 我前面说过,在多个PostThreadMessage(post5次)之间放置MessageBox()弹窗,线程函数里的while(GetMessage(&msg,NULL,0,0))就循环了5次,这是肯定没有退出while的,但是没有弹窗就只有一次,用Seelp(1000)代替也只是接收到一次消息。[/quote] GetMessage收到WM_QUIT它还不会退出,你是在逗我么,AfxMessageBox会另起消息循环,你考虑到了么?!
schlafenhamster 2015-08-24
  • 打赏
  • 举报
回复
Remarks The thread to which the message is posted must have created a message queue, or else the call to PostThreadMessage fails. Use one of the following methods to handle this situation: Call PostThreadMessage. If it fails, call theSleep function and call PostThreadMessage again. Repeat until PostThreadMessage succeeds. Create an event object, then create the thread. Use theWaitForSingleObject function to wait for the event to be set to the signaled state before calling PostThreadMessage. In the thread to which the message will be posted, call PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE) to force the system to create the message queue. Set the event, to indicate that the thread is ready to receive posted messages. The thread to which the message is posted retrieves the message by calling the GetMessage or PeekMessage function. The hwnd member of the returned MSG structure is NULL.
二班的码农 2015-08-24
  • 打赏
  • 举报
回复
楼主,你有给线程创建消息队列么 调用PeekMessage(&msg,NULL,WM_USER,WM_USER,PM_NOREMOVE)消息将寄送到的线程通过调用GetMesssge或PeekMesssge来取得消息。
倾城笑颜 2015-08-24
  • 打赏
  • 举报
回复
我窗体初始化时就创建了线程,已经调用了线程函数一次,AfxMessageBox("PrintOutMd");弹窗也弹出来了,线程函数会阻塞在 while(GetMessage(&msg,NULL,0,0)){} 一直等待消息,也就是说有消息线程函数才会while循环一次,这就跟我加了 AfxMessageBox("PrintOutMd")没啥关系吧,毕竟这个语句是在while(GetMessage(&msg,NULL,0,0))外面,只在线程创建时执行过一次,线程函数一旦遇到PostThreadMessage发过来的消息,都是从·while(GetMessage(&msg,NULL,0,0)里执行的了。
倾城笑颜 2015-08-24
  • 打赏
  • 举报
回复
这是我窗体一开始初始化就创建线程语句 ----------------------------------------------------------------- BOOL MDDialog::OnInitDialog() { //创建行情输出线程 m_hPrintThread = CreateThread( NULL,0,PrintOutMd,(LPVOID)this,0,&m_dwPrintId); if (m_hPrintThread == NULL) { MessageBox("创建线程失败!"); } ****** }
二班的码农 2015-08-24
  • 打赏
  • 举报
回复
DWORD WINAPI PrintOutMd(LPVOID lpParameter) //行情输出打印线程函数 { AfxMessageBox("PrintOutMd"); int a = 0; CString s =""; MSG msg; while(GetMessage(&msg,NULL,0,0)) { BOOL bRes = PeekMessage(&msg, NULL, 0, 0, PM_REMOVE); if (bRes) { //在这里处理本线程的消息。 s.Format("%d--有消息处理", a++); AfxMessageBox(s); }else { AfxMessageBox(_T("CThreadMsg::Run() 无消息处理/r/n")); } } return 1 ; } 你的响应函数里不是有 AfxMessageBox么,会不会弹出消息框后,引发该线程阻塞
倾城笑颜 2015-08-24
  • 打赏
  • 举报
回复
引用 2 楼 ant2012 的回复:
The PostThreadMessage function places (posts) a message in the message queue of the specified thread and then returns without waiting for the thread to process the message. 也就是说调用PostThreadMessage函数,该函数会把一个消息放在指定线程的消息对列里,只要线程存在,一般都返回非零 当你用while循环5次时,已经向指定线程发送了五个这样的消息,只不过指定线程来不及处理,只处理了一个
我用Sleep(1000)为什么还不能保证线程来处理接受的消息呢,这跟用messagebox阻塞延时有什么区别吗,还有其他可能原因吗
倾城笑颜 2015-08-24
  • 打赏
  • 举报
回复
引用 6 楼 pcradio 的回复:
while(GetMessage(&msg,NULL,0,0))
你PostThreadMessage发送的uMsg 是0也就是WM_QUIT,看看你的while判断,接收到一个WM_QUIT就直接退出while了,你觉得呢
GetMessage(&msg,NULL,0,0)在这里只是判断PostThreadMessage有没有发送的uMsg,判断收到的是什么消息是 uMsg.message == (消息名) 。 我前面说过,在多个PostThreadMessage(post5次)之间放置MessageBox()弹窗,线程函数里的while(GetMessage(&msg,NULL,0,0))就循环了5次,这是肯定没有退出while的,但是没有弹窗就只有一次,用Seelp(1000)代替也只是接收到一次消息。

15,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧