searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

PostMessage/SendMessage在不同线程的调用探究

2023-09-07 02:19:40
9
0

       PostMessage和SendMessage是我们比较常用的windows API,最近也探究这两个api在调用之后,执行的线程问题,发现如下结论:

  1.  仅仅是RegisterClass注册类之后,调用createwindow第一个参数通过:(const TCHAR*)baseClass.classAtom进行传参创建的窗口,并不执行消息循环,然后往这个窗口句柄进行PostMessage和SendMessage发现:PostMessage无效,Post的Message并不会被WndProc接收到,SendMessage可以正常被WndProc接收并处理,执行线程跟SendMessage当前线程为同一个线程。
  2. 在单独的线程RegisterClass注册类,然后createwindow,最后执行消息循环。然后往这个窗口句柄进行PostMessage和SendMessage发现:PostMessage和SendMessage可以正常被WndProc接收并处理,执行线程跟消息循环线程为同一个线程。
  3. 同时如果上面两个代码都同时执行,发现结果一样,也就是说创建的窗口(CreateWindow)在哪个线程,那么消息执行的线程也在该线程。也就是执行线程跟创建窗口的线程保持了一致,无论是SendMessage还是PostMessage。
  4. WM_COPYDATA消息必须是通过SendMessage,如果是PostMessage,消息队列也是收不到的,而且data里面的buffer必须是开辟的内存空间,连字符串常量也不行,否则接收到的是乱码:


    下面是相关Demo代码:
        std::wstring strLog = L"data msg";
        wchar_t* pBuffer = new wchar_t[strLog.length() + 2];
        memcpy(pBuffer, strLog.c_str(), 2 * strLog.length() + 2);
        pBuffer[strLog.length()] = 0;
     
        COPYDATASTRUCT cds;
        cds.dwData = 53; // any data
        cds.cbData = 2 * strLog.length() + 1;
        cds.lpData = pBuffer;
        ::SendMessage(MsgIPC.GetHandle(), WM_COPYDATA, 0, (LPARAM)&cds);
        delete pBuffer;
     
     
    // 下面是错误示范:
        LPCTSTR lpszString = L"Hello";
        COPYDATASTRUCT cds;
        cds.dwData = 1; // can be anything 
        cds.cbData = sizeof(TCHAR) * (wcslen(lpszString) + 1);
        cds.lpData = &lpszString;
     
        ::SendMessage(MsgIPC.GetHandle(), WM_COPYDATA, 0, (LPARAM)&cds); 
0条评论
0 / 1000
廖****龙
11文章数
2粉丝数
廖****龙
11 文章 | 2 粉丝
原创

PostMessage/SendMessage在不同线程的调用探究

2023-09-07 02:19:40
9
0

       PostMessage和SendMessage是我们比较常用的windows API,最近也探究这两个api在调用之后,执行的线程问题,发现如下结论:

  1.  仅仅是RegisterClass注册类之后,调用createwindow第一个参数通过:(const TCHAR*)baseClass.classAtom进行传参创建的窗口,并不执行消息循环,然后往这个窗口句柄进行PostMessage和SendMessage发现:PostMessage无效,Post的Message并不会被WndProc接收到,SendMessage可以正常被WndProc接收并处理,执行线程跟SendMessage当前线程为同一个线程。
  2. 在单独的线程RegisterClass注册类,然后createwindow,最后执行消息循环。然后往这个窗口句柄进行PostMessage和SendMessage发现:PostMessage和SendMessage可以正常被WndProc接收并处理,执行线程跟消息循环线程为同一个线程。
  3. 同时如果上面两个代码都同时执行,发现结果一样,也就是说创建的窗口(CreateWindow)在哪个线程,那么消息执行的线程也在该线程。也就是执行线程跟创建窗口的线程保持了一致,无论是SendMessage还是PostMessage。
  4. WM_COPYDATA消息必须是通过SendMessage,如果是PostMessage,消息队列也是收不到的,而且data里面的buffer必须是开辟的内存空间,连字符串常量也不行,否则接收到的是乱码:


    下面是相关Demo代码:
        std::wstring strLog = L"data msg";
        wchar_t* pBuffer = new wchar_t[strLog.length() + 2];
        memcpy(pBuffer, strLog.c_str(), 2 * strLog.length() + 2);
        pBuffer[strLog.length()] = 0;
     
        COPYDATASTRUCT cds;
        cds.dwData = 53; // any data
        cds.cbData = 2 * strLog.length() + 1;
        cds.lpData = pBuffer;
        ::SendMessage(MsgIPC.GetHandle(), WM_COPYDATA, 0, (LPARAM)&cds);
        delete pBuffer;
     
     
    // 下面是错误示范:
        LPCTSTR lpszString = L"Hello";
        COPYDATASTRUCT cds;
        cds.dwData = 1; // can be anything 
        cds.cbData = sizeof(TCHAR) * (wcslen(lpszString) + 1);
        cds.lpData = &lpszString;
     
        ::SendMessage(MsgIPC.GetHandle(), WM_COPYDATA, 0, (LPARAM)&cds); 
文章来自个人专栏
个人原创文章
11 文章 | 1 订阅
0条评论
0 / 1000
请输入你的评论
0
0