一个自定义的消息,发送给UI线程的。打算是:用PostThreadMessage发,用ON_THREAD_MESSAGE消息宏收,然后把该消息发来的数据添加到UI线程类的成员数据列表里,然后在UI线程的Run()函数里处理。结果死活收不到消息(消息的发送和接受宏等都没有任何问题,已确认)。尝试在Run()里用GetMessage收,可以收到消息!当下不解。调试了半天,发现问题出在Run函数里的CWinThread::Run();这句话。默认情况下,新建一个派生自CWinThread的线程,Run这个虚函数中只有这句话:return CWinThread::Run()只要这句话被运行,则消息立马可以收到了。但是,问题来了,这句话一倍运行,Run函数的控制权就不在我这里了,想对收到的消息进行处理就无法实现了。请问,这种情况应该怎么解决。附修改的Run函数代码:
Run()
{
  while (事件列表里有事件)
  {
      做相应操作;
  }  return CWinThread::run();
}原本以为InitInstance()虚函数返回TRUE后,消息队列就已经建立了,现在这样看来是不是并非如此?还是因为我这个Run函数while循环是个阻塞型的操作,所以消息被阻塞了,完全收不到消息。如果是后者,那有什么好的做法没? 可能有人会说,既然让它运行了基类的Run函数后,可以收到消息了,直接收到消息后就处理了不就完了。的确如此,只是为了搞明白这个机制,所以有这样的疑问,纯属研究,请大家不吝指教。

解决方案 »

  1.   

    PostThreadMessage不是用在线程间通讯的么?
      

  2.   

    消息队列可能还没建立,就会丢失消息。你可以在InitInstance开始调用一次下面的代码强制建立消息队列:
    MSG msg;
    PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE);
      

  3.   

    jameshooo:你想的这点我一开始也想到过,也尝试过强制建立消息队列,结果一样是收不到消息。感觉应该可以排除消息队列不存在导致收不到消息。
    现在,我的理解更倾向于:UI线程如果想收到消息,其实一样是要把控制权交给操作系统(运行CWinThread::Run()其实就是把控制权交给了操作系统,以后只能靠消息来驱动该线程继续自己的运作了,Run函数中的后续语句已经无法被执行了),让它派发消息。如果想在保持自己控制(类似Run函数中那样的阻塞型的while语句)的前提下,响应消息,无法办到。除非显式地调用GetMessage去人为的搜索消息队列操作和派发消息。 就像工作线程,其实如果这样做,一样可以收到消息。 
    不知道我的理解有没有问题。
      

  4.   

    把ON_THREAD_MESSAGE的相关代码贴上。
      

  5.   

    ON_THREAD_MESSAGE(WM_MYMSG,OnMyMsg)afx_msg LRESULT OnMyMsg(WPARAM, LPARAM);不会是这里的问题,因为我在个空的app里试验过,没问题,也仔细检查过...
      

  6.   

    搞不懂,你不让thread去跑消息循环,还想收到消息?
      

  7.   

    Run 就是用来运行消息泵的,不断地GetMessage和DispatchMessage。 继承于CWinThread 类的线程类,都从父类中集成了一个窗体,这个窗体含有消息泵。用来接收外部消息。线程的工作是以事件为驱动的,当外界给线程发送消息后,线程对应的消息响应函数做对应的动作。http://www.vckbase.com/document/viewdoc/?id=1706 这是一个典型的例子。一般情况下,后台线程,如执行下载、压缩/解压缩 的线程,都不需要这个窗体。直接声明一个全局或者静态函数通过__BeginThread获得AfxBeginThread启动就好。
      

  8.   

      while (事件列表里有事件) 
      { 
          做相应操作; 
      } 
    程序在这个循环里面的时候是不能响应消息的,要在return CWinThread::Run();之后才能响应。