我在做一个视频解码的win32程序,主线程为winMain()函数。在此函数里又开了一个线程运行函数DisplayWinMain()在此函数里定义并注册视频显示窗口,并有消息循环得到消息并送给窗口主函数LRESULT APIENTRY MainWndProc ()。在MainWndProc 里要收到一个消息,然后SetEvent (vdWindow.hEvent);主线程里
/* Post message to drawing thread's window to draw frame */
PostMessage (null, VIDEO_DRAW_FRAME, (WPARAM) NULL, (LPARAM) NULL);
dwRetVal = WaitForSingleObject (vdWindow.hEvent, INFINITE);得到信息后会另取一帧图象。使程序运行下去。
VIDEO_DRAW_FRAME是用户自定义消息。
问题是:PostMessage 好像并没有把VIDEO_DRAW_FRAME传给副线程。副线程收不到消息,就不能把事件vdWindow.hEvent置有信号。故导致主线程阻塞。请问为什么possmessage的消息会没有被副线程收到那?

解决方案 »

  1.   

    你的postmessage的第一个参数为null,没有发送目标。如果要是向线成发送消息,可以使用postthreadmessage来实现。
    如果参数为空:
    The function behaves like a call to PostThreadMessage with the dwThreadId parameter set to the identifier of the current thread.
      

  2.   

    我改用PostThreadMessage()了。并把副线程的ID最为第一个参数。但也没什么效果。(没道理阿)。
    原来的函数为:
    PostMessage (vdWindow.hWnd, VIDEO_DRAW_FRAME, (WPARAM) NULL, (LPARAM) NULL);
    第一个参数就是窗口的ID。 我想知道的是:在那些情况下,postMessage()会失败。我做的咚咚本来是个c程序,现在我想把它封装成类。结果出问题了。
      

  3.   

    PostMessage应该是没错的,第一个参数是窗口句柄,不是ID。你确定窗口句柄是正确的,主窗口有没有收到消息呢,一步步调啦,如果没收到消息,再看看VIDEO_DRAW_FRAME有没有定义错误,是要WM_USER+n的。具体什么问题也不清楚,没法帮你调,不好意思啦
      

  4.   

    用PostThreadMessage()有三个要点:
    1.第一个参数是线程的ID;
    2.所寄送的消息必须是自定义消息
    3.副线程中要有消息循环,如果是工作线程要自己编写消息循环
      

  5.   

    我也是和你碰到一模一样的问题,改成SendMessage就可以,但SendMessage会阻塞线程,所以我现在都搞毛了,唉,哪位高手知道呀。
      

  6.   

    SendMessage的四个变种:
      1。SendMessageTimeout
      2。SendMessageCallBack
      3。SendNotifyMessage
      4。ReplyMessage 
    使用这四个函数中的任一个可以解决阻塞进程的问题
    (从Jeffrey Richter《Advanced Windows》中找到)
      

  7.   

    PostThreadMessage应该可以用. 大约是你消息循环的问题.
      

  8.   

    在Release版本下,线程中用PostMessage\SendMessage传递消息时回出错。而在Debug版本下没有问题。这是怎么回事?
      

  9.   

    我想你的情况可以这样解决:
    1 如果你的子线程有消息队列的话,PostThreadMessage肯定没有问题。PostThreadMessage函数要求该线程必须有一个消息队列
      具体的可以看MSDN中PostThreadMessage的帮助。
    2 如果你的子线程是WORKER线程的话,可以用以下的方法解决.当然你也可以创建一个带有消息队列的子线程。
    #define WM_YOURMESSAGE WM_USER + 100
    HANDLE eventHandle = NULL;
    DWORD WINAPID YourChildThreadFun(LPVOID lpParam)
    {
        MSG msg; 
        while(PeekMessage(&msg,NULL, WM_USER, WM_USER, PM_NOREMOVE))//这里强迫系统帮你产生一个消息队列。
       { 
        if(eventHandle != NULL) //通知主线程可以接受消息了。
           SetEvent(eventHandle);
        if(msg.message == WM_YOURMESSAGE) break;
       }
      return 0;
    }
    //////
    void CallChildThread()// 你的主线程中的任一函数
    {
      eventHandle = CreateEvent(NULL,TRUE, FALSE,NULL);//创建一个事件对象
      HANDLE hThread =  CreateThread(NULL,0,YourChildThreadFun,NULL,0);
      WaitForSingleObject(eventHandle,INFINITE); //等待子线程真的开始工作。 
      PostThreadMessage(hThread, WM_YOURMESSAGE,0,0);
      CloseHandle(eventHandle);
      eventHandle = NULL;
        
    }
    Good Luck!