译自msdn(节选):http://msdn.microsoft.com/en-us/library/ms644946(v=vs.85).aspx

能接收消息的线程(即欲向其投递消息的线程),必须已经创建了一个消息队列,否则调用PostThreadMessage向其发送消息将失败。可使用如下方法处理这种情况。

  1. 首先(在源线程中)创建一个事件对象,然后创建新线程

  2. 在(源线程中)调用PostThreadMessage之前,使用WaitForSingleObject函数等待事件直至其被(目标投递线程)设置为激发状态

  3. 在目标投递线程中,以如下方式调用PeekMessage,从而强制系统为该线程创建消息队列:

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

  4. 在目标投递线程中,设置事件为激发状态,从而表明其已做好接收投递消息的准备

在目标投递线程中,可通过调用GetMessage或PeekMessage函数取回已投递的消息。函数返回的MSG结构中的hwnd成员值为NULL.

由PostThreadMessage发送的消息没有与一个窗口(对象句柄)相关联。一般来说,不与一个窗口(对象句柄)相关联的消息不能被函数DispatchMessage所派发。因此,如果接收者线程处于一个模态循环(如使用MessageBox或DialogBox)中时,消息将会丢失。在此情况下,为拦截线程消息,可使用线程特定的hook。

以下给出一个例子。

转自:http://www.cppblog.com/sandy/archive/2012/09/20/2320.html

#include <windows.h>
#include <cstdio>
#include <process.h>

#define MY_MSG WM_USER+100
const int MAX_INFO_SIZE = 20;

HANDLE hStartEvent; // thread start event

// thread function
unsigned __stdcall fun(void *param)
{
    printf("thread fun start\n");

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

if(!SetEvent(hStartEvent)) //set thread start event 
    {
        printf("set start event failed,errno:%d\n",::GetLastError());
        return 1;
    }
    
    while(true)
    {
        if(GetMessage(&msg,0,0,0)) //get msg from message queue
        {
            switch(msg.message)
            {
            case MY_MSG:
                char * pInfo = (char *)msg.wParam;
                printf("recv %s\n",pInfo);
                delete[] pInfo;
                break;
            }
        }
    };
    return 0;
}

int main()
{
    HANDLE hThread;
    unsigned nThreadID;

hStartEvent = ::CreateEvent(0,FALSE,FALSE,0); //create thread start event
    if(hStartEvent == 0)
    {
        printf("create start event failed,errno:%d\n",::GetLastError());
        return 1;
    }

//start thread
    hThread = (HANDLE)_beginthreadex( NULL, 0, &fun, NULL, 0, &nThreadID );
    if(hThread == 0)
    {
        printf("start thread failed,errno:%d\n",::GetLastError());
        CloseHandle(hStartEvent);
        return 1;
    }

//wait thread start event to avoid PostThreadMessage return errno:1444
    ::WaitForSingleObject(hStartEvent,INFINITE);
    CloseHandle(hStartEvent);

int count = 0;
    while(true)
    {
        char* pInfo = new char[MAX_INFO_SIZE]; //create dynamic msg
        sprintf(pInfo,"msg_%d",++count);
        if(!PostThreadMessage(nThreadID,MY_MSG,(WPARAM)pInfo,0))//post thread msg
        {
            printf("post message failed,errno:%d\n",::GetLastError());
            delete[] pInfo;
        }
        ::Sleep(1000);
    }

CloseHandle(hThread);
    return 0;
}

转载于:https://www.cnblogs.com/qinfengxiaoyue/archive/2013/04/25/3043818.html

关于PostThreadMessage以及创建线程消息队列相关推荐

  1. 消息队列(定义、结构、如何创建、消息队列的发送与接收、发送与接收实例)

    一.定义 1.消息队列是一种先进先出的队列型数据结构,实际上是系统内核中的一个内部链表.消息被顺序插入队列中,其中发送进程将消息添加到队列末尾,接受进程从队列头读取消息. 2.多个进程可同时向一个消息 ...

  2. 关于创建zeromq消息队列,设置和更改IP地址,远程可以访问,不只是本地链接。python代码。

    关于zeromq的创建,绑定本地,和绑定其他客户端的方法. 网上一大堆关于zmq的通信模式的介绍,包括三种类型,具体我就不在描述. 但是他们给的demo,都是创建本地作为server服务端,也作为cl ...

  3. windows消息和消息队列详解

     windows消息和消息队列 与基于MS - DOS的应用程序不同,Windows的应用程序是事件(消息)驱动的.它们不会显式地调用函数(如C运行时库调用)来获取输入,而是等待windows向它们传 ...

  4. 关于windows操作系统之消息和消息队列

    关于消息和消息队列 不像基于MS-DOS的应用程序,基于Windows的程序是事件驱动的.他们不做任何显示调用来获取输入.而是通过等待系统传递给他们. 系统为应用程序传递所有输入到程序中的不同窗口.每 ...

  5. 操作系统-消息,消息队列

    消息,消息队列 1. 消息 在windows 程序中,消息是由MSG 结构体来表示的.MSG 结构体的定义如下: typedef struct tagMSG {HWND hwnd;UINT messa ...

  6. 【详解】消息队列和线程关系

    1.进程-线程-消息队列 简单的来说,什么是进程?什么是线程?打个比方,你的程序要执行,操作系统就会把你的exe文件加载到内存中,那就生成一个进程了(当然还包含分配到的资源等):对于线程,你可以理解成 ...

  7. UI线程和Windows消息队列

    在Windows应用程序中,窗体是由一种称为"UI线程(User Interface Thread)"的特殊类型的线程创建的. 首先,UI线程是一种"线程",所 ...

  8. 消息队列NetMQ 原理分析2-IO线程和完成端口

    目录 前言 介绍 目的 IO线程 初始化IO线程 Proactor 启动Procator线程轮询 处理socket IOObject 总结 前言 介绍 [NetMQ](https://github.c ...

  9. RTX5 | 消息队列01 - 创建消息队列

    文章目录 一.前言 二.实验的目的 三.API 3.1.osMessageQueueId_t 3.2.osMessageQueueAttr_t 3.3.osMessageQueueNew 四.代码 4 ...

  10. RT-Thread 线程同步及通信 -- 信号量、互斥量、事件、邮箱、消息队列

    目录 一  RT-Thread 信号量 二  RT-Thread 互斥量 三  RT-Thread 事件标志组 四  RT-Thread 邮箱 五  RT-Thread 消息队列 一  RT-Thre ...

最新文章

  1. Django中多种重定向方法使用
  2. golang中图片转base64_golang base64编码
  3. pl/sql developer导入导出
  4. ftp 上传文件夹_命令行连接FTP服务器
  5. BZOJ 1036: [ZJOI2008]树的统计Count
  6. 11.15scrum会议
  7. error: Program received signal SIGSEGV, Segmentation fault. (Codeblocks, C++)
  8. 华为 台积电 高通申请_华为表态愿意合作,台积电送来“神助攻”,高通:我太难了...
  9. LINUX任务栏上出现的小窗口是怎么回事
  10. 服务器lsass状态代码c0000005,提示lsass.exe失败状态代码c0000005
  11. 【iOS】iOS8 与以前版本比较,添加的新特性
  12. 保存numpy数组到excel
  13. Tr1 Function
  14. Windows10环境下Ruby安装和配置
  15. 高考数学95分能学计算机吗,数学模考5分到高考95分?
  16. 学习网络攻防,有什么渠道?
  17. 区块链技术在三角债清收领域的应用思考
  18. 【小知识】有趣代码注释图案【持续收集更新...】
  19. linux服务器上tcp有大量time_wait状态的解决方法和原因解释
  20. 麦克尼马尔检验(McNemar test)

热门文章

  1. dataframe数据按行做线性拟合
  2. Cesium加载GeoServer发布的SHP和GeoTIFF文件
  3. sublime跳转到函数定义
  4. ajax获取inputname值,jQuery - 获取ajax POST的表单值
  5. 字节跳动单点恢复功能及 Regional CheckPoint 优化实践
  6. 如何解决生产环境 Flink 应用的技术难题?
  7. 如何优化你的布局层级结构之RelativeLayout和LinearLayout及FrameLayout性能分析(二)...
  8. idea如何远端调试
  9. php和dart交互,Flutter 之和原生交互
  10. python 开发公众号sdk_「公众号开发」基于Serverless架构Python实现公众号图文搜索...