zoukankan      html  css  js  c++  java
  • 用户界面线程(含有消息泵的线程)主线程与用户界面线程的通信

    vckbase站点上,由一个多线程的demo,讲得是UI线程,如何开启一个UI界面线程.但是里面没有涉及到主线程如何和UI线程间通信.
    这个问题,我搞了好久.

    其实很简单,给一个线程发消息 PostThreadMessage().
      BOOL   PostThreadMessage(  
       
              DWORD   idThread, //   thread   identifier     {这个参数为线程ID,不是线程句柄}  
              UINT   Msg, //   message   to   post 
              WPARAM   wParam, //   first   message   parameter  
              LPARAM   lParam   //   second   message   parameter  
            );  

    eg:
     int ret = PostThreadMessage( pThread->m_nThreadID, WM_SPLASH_NOTIFY,0, 0   );
     if (ret == 0)    // :检查返回值,是否失败.
     {
      //AfxMessageBox("post thread msg error!");
      if ( ERROR_INVALID_THREAD_ID == GetLastError() )
      {
       AfxMessageBox("无效thread ID(你是否把线程句柄传了进去?:))! 或者线程里面没有消息泵!!!");
      }
     }

    WM_SPLASH_NOTIFY是自己定义的一个常量, 可以不用加入消息映射 呵呵. 直接在UI线程的PreTranslateMessage里面捕获处理就好了.:), 当然, 通过MFC的宏加入消息处理函数也可以, 不过原理是一样的.


       , 那么主线程如何知道UI界面线程的ID呢?
    答案是: 通过AfxBeginThread()函数创建线程时, 返回CWinThread* pThead指针.

    AfxBeginThread()返回一个CWinThread*对象指针,  
      CWinThread*   pThread   =   AfxBeginThread(...)   ;  
      pThread->m_nThreadID就是创建线程的ID.

    特别注意 , pThead->m_hThread是线程的句柄!!!! 不可以作为PostThreadMessage()的参数,否则会提示: error   C2664:   'PostThreadMessageA'   :   cannot   convert   parameter   1   from   'void   *'   to   'unsigned   long'   编译错误.
    具体参见如下帖子.

    http://topic.csdn.net/t/20040509/14/3045752.html

    那么我们发了消息后, 用户界面线程如何处理消息呢?

    重载PreTranslateMessage()函数.
    BOOL CUIThread::PreTranslateMessage(MSG* pMsg)
    {
     // TODO: Add your specialized code here and/or call the base class
     if (pMsg->message == WM_SPLASH_NOTIFY )
     {
      AfxMessageBox("catch!");
     }
     
     return CWinThread::PreTranslateMessage(pMsg);
    }

    补充说明两点
    1: 线程ID 不同于线程句柄, ID可用于给线程发消息.
    2: 线程句柄 可用于控制线程的执行,比如, 关闭线程, 暂停线程啥的.


    也就是通常意义上的UI界面线程, 可以给该线程发消息. 呼呼.
      3,4的说法可能有问题,已经测试过,对于工作线程, 已经测试过, 不可以在工作线程里面peekmessage.(peekmessage总是返回false, peek不到message ), .但是可以work thread成功发送消息, 但work thread里面 peekmessage老是失败.不知道CWinThread做了什么手脚.呼呼.


     MSG msg;
     PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE);

    参见msdn. PostThreadMessage的解释.

    下面文章是codeproject上详细讲解用户界面线程原理的文章.

    http://www.codeproject.com/KB/threads/usinguithreads.aspx

  • 相关阅读:
    原创《小白的Java自学课》第一课:Java是什么?Java到底能干嘛?
    谷歌chrome浏览器
    QT学习之QPair类
    char 与 signed char 和 unsigned char三者之间的关系
    QT学习之QT判断界面当前点击的按钮和当前鼠标坐标
    QT学习之QScript
    QT Creater 配色方案及下载
    QT学习之QString的arg方法
    QT创建与调用Dll方法(包括类成员)--显式调用
    C++学习之显式类型转换与运行时类型识别RTTI
  • 原文地址:https://www.cnblogs.com/tianlangshu/p/1989557.html
Copyright © 2011-2022 走看看