MFC用PostMessage传递消息

1.自定义消息ID。

#define WM_MY_MESSAGE (WM_USER+100)         WM_USER为windows系统为非系统消息保留的ID,这里至少要用100,因为其它控件的消息会占用一部分。

2. 定义消息处理函数。

消息处理函数为消息目标类的成员函数。首先应该在.h 文件中声明。这里以主窗口类为例,主窗口类名 CMainDialog,则首先在CMainDialog.h声明消息处理函数。

protected:

afx_msg LRESULT OnMyMessage(WPARAM wParam, LPARAM lParam);

3.在CMainDialog.cpp中实现消息处理函数

LPESULT CMainDialog::OnMyMessage(WPARAM wParam, LPARAM lParam) 

// TODO: 处理用户自定义消息 
... 
return 0; 
}

4.在CMainDialog.cpp中映射消息ID和消息处理函数

BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWnd) 
ON_WM_CREATE() 
ON_WM_TIMER() 
ON_MESSAGE(WM_MY_MESSAGE, OnMyMessage) 
//}}AFX_MSG_MAP 
END_MESSAGE_MAP()

在创建线程的时候将主窗口句柄作为参数传入线程,就可以用 PostMessage传递消息了。

SendMessage函数功能描述:将指定的消息发送到一个或多个窗口。此函数为指定的窗口调用窗口过程,直到窗口过程处理完消息后才返回。

Postmessage函数则是将消息放入消息队列里,并立即返回。

常见问题

1)使用SendMessage来实现剪切、复制和粘贴

View Row Code

1 SendMessage(hwnd, WM_COPY, 0, 0);
2 SendMessage(hwnd, WM_CUT, 0, 0);
3 SendMessage(hwnd, WM_PASTE, 0, 0);

2)SendMessage与PostMessage的区别

PostMessage将消息放入消息队列后马上返回,而SendMessage直到窗口过程处理完消息后才返回。

3)SendMessage发送WM_COPYDATA消息在进程间传送数据

WM_COPYDATA消息主要目的是允许在进程间传递少量只读数据。SDK文档推荐用户使用SendMessage()函数,接收方在数据复制完成前不返回,这样发送方就不可能删除和修改数据。

例如:

View Row Code

1 std:string strData = "VC知识库 VCKBASE.COM";
2 COPYDATASTRUCT cds;
3 cds.dwData = 0;
4 cds.cbData = strData.Length();
5 cds.lpData = strData.c_str();
6 ::SendMessage(hwnd, WM_COPYDATA, NULL, (LPARAM)&cds);

3、PostThreadMessage有时会失败,报1444错误(Invalid thread identifier. ),其实这不一定是线程不存在的原因,也有可能是线程不存在消息队列(message queue)造成的。事实上,并不是每个thread都有message queue,那如何让thread具有呢? 答案是,至少调用message相关的function一次,比如GetMessage,PeekMessage。

4、如果是postthreadmessage动态分配的memory给另外一个thread,要注意内存的正确释放。并且PostThreadMessage不能够post WM_COPYDATE之类的同步消息,否则会报错!

5、最好不要使用PostThreadMessage post message给一个窗口,使用PostMessage替代。

1    #include <windows.h>
2    #include <cstdio>
3    #include <process.h>
4    #define MY_MSG WM_USER+100
5    const int MAX_INFO_SIZE = 20;
6    HANDLE hStartEvent; // thread start event
7    // thread function
8    unsigned __stdcall fun(void *param)
9    {
10        printf("thread fun start
11
12
13    \n");
14        MSG msg;
15        PeekMessage(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE);
16        if(!SetEvent(hStartEvent)) //set thread start event
17        {
18            printf("set start event failed,errno:%d\n",::GetLastError());
19            return 1;
20        }
21
22        while(true)
23        {
24            if(GetMessage(&msg,0,0,0)) //get msg from message queue
25            {
26                switch(msg.message)
27                {
28                case MY_MSG:
29                    char * pInfo = (char *)msg.wParam;
30                    printf("recv %s\n",pInfo);
31                    delete[] pInfo;
32                    break;
33                }
34            }
35        };
36        return 0;
37    }
38    int main()
39    {
40        HANDLE hThread;
41        unsigned nThreadID;
42        hStartEvent = ::CreateEvent(0,FALSE,FALSE,0); //create thread start event
43        if(hStartEvent == 0)
44        {
45            printf("create start event failed,errno:%d\n",::GetLastError());
46            return 1;
47        }
48        //start thread
49        hThread = (HANDLE)_beginthreadex( NULL, 0, &fun, NULL, 0, &nThreadID );
50        if(hThread == 0)
51        {
52            printf("start thread failed,errno:%d\n",::GetLastError());
53            CloseHandle(hStartEvent);
54            return 1;
55        }
56        //wait thread start event to avoid PostThreadMessage return errno:1444
57        ::WaitForSingleObject(hStartEvent,INFINITE);
58        CloseHandle(hStartEvent);
59        int count = 0;
60        while(true)
61        {
62            char* pInfo = new char[MAX_INFO_SIZE]; //create dynamic msg
63            sprintf(pInfo,"msg_%d",++count);
64            if(!PostThreadMessage(nThreadID,MY_MSG,(WPARAM)pInfo,0))//post thread msg
65            {
66                printf("post message failed,errno:%d\n",::GetLastError());
67                delete[] pInfo;
68            }
69            ::Sleep(1000);
70        }
71        CloseHandle(hThread);
72        return 0;
73    }
时间: 2024-11-03 05:35:05

MFC用PostMessage传递消息的相关文章

使用postMessage在不同iframe间跨域传递消息

iframe同源策略 如果父窗口访问一个不同域名的子窗口就会报错: Uncaught DOMException: Blocked a frame with origin "xxx" from accessing a cross-origin frame. 如何解决呢?一个简单的思路就是,既然是因为不同源,那么再建一个同源的窗口不久可以了吗?一个同源的子窗口能读取父窗口无法访问的子窗口的内容,然后通过postMessage传递给父窗口就可以了. //http://app1.test.lo

MFC框架剖析和消息机制

即便是基于MFC的应用程序,建立窗口类也是会遵循如下的过程: 设计窗口类->注册窗口类->生成窗口->显示窗口->更新窗口->消息循环->消息路由到窗口过程函数处理.下面就剖析一下在MFC中是如何完成上述过程的. (1)每个应用程序都有且仅有一个应用类的全局变量theApp,全局变量先于WinMain函数进行处理. (2)WinMain函数体在APPMODUL.CPP文件中,定义如下: extern "C" int WINAPI _tWinMain(

MFC 虚函数与消息映射区别

初学MFC添加函数时,总是纠结于是 Add  windows message handler or Add virtual function 说到底不理解MFC中虚函数与消息处理函数的设计区别 本人理解:虚函数是层层继承的,子类Add virtual function只是去改写相应功能.虚函数一般都是程序框架必须调用的,子类没有改写就会默认调用基类的. 而消息映射只在相应类中添加自己感兴趣的处理函数,不存在继承性.所以没必要把windows消息映射函数设计成虚函数.有需要时程序才会执行这些操作.

javascript重定向页面并用post方法传递消息

javascript中重定向页面得方法很多,同时能传递消息的也不少:但可用post方法传递的我只找到两种: 第一种方法:用document.write在 JavaScript函数中,用document.write("<input type="hidden" -- >"):在页面上输出几个hidden,name为要传递的参数名,value为要传递参数的值,最后 用"document.formname.submit"进行提交,formna

iOS页面间传递消息之Delegate

在开发应用的过程中,我们需要频繁地在界面之间传递消息,有时候是传递信息,有时候是传递一个信号即可.在iOS开发中,有多种传递信息的方式.比如最简单的,如果我们要在从一个界面进入另一个界面时给新界面传递一些消息,只需要给新界面定义一些属性,然后在创建新界面的时候设置其属性值即可. 那么如果要从新界面反过来传递信息给原先的界面怎么做呢,怎么建立起一个沟通的桥梁呢?iOS也提供了很多种方式,比如Notification.Block.UserDefault等等.本文就讲解最常见也是最常用的一种方式,几乎

Unity3D研究院之与Android相互传递消息

原地址:http://www.xuanyusong.com/archives/676 上一篇文章我们学习了Unity向Android发送消息,如果Android又能给Unity回馈消息那么这就玩美了.恰好Unity for Andoid 和 IOS一样都是可以相互与Unity发送与接收消息,这篇文章MOMO就和大家好好聊聊Android向Unity发送消息的方法.在读本片博文之前,建议大家读一下我上一篇文章Unity3D研究院之打开Activity与调用JAVA代码传递参数(十八),有关数据打包

2019.9.18 Unity3D与Android相互传递消息 &amp; unity与ios相互传递消息

unity与Android相互传递消息 参考1:http://www.xuanyusong.com/archives/667 参考2:http://www.xuanyusong.com/archives/676 参考3:https://www.douban.com/note/506767653/ unity与ios相互传递消息 参考1:http://www.xuanyusong.com/archives/517 参考2:http://www.xuanyusong.com/archives/521

简单、高效、易用的全平台(Windows/Linux/ARM/Android/iOS)web实现RTMP推送组件EasyRTMP-Android BUS传递消息过程介绍

背景分析 RTMP是Real Time Messaging Protocol(实时消息传输协议)的首字母缩写,该协议基于TCP,是一个协议族,包括RTMP基本协议及RTMP/RTMPS/RTMPE等多种变种.RTMP是一种设计用来进行实时数据通信的网络下ieyi,主要用来在Flash/AIR平台和支持RTMP协议的流媒体/交互服务器之间进行音视频和数据通信.RTMP推流,就是将直播内容推送到服务器的过程. EasyRTMP-Android BUS传递消息过程 提出问题EasyRTMP-Andro

深入MFC中WM_COMMAND命令消息的传递

MFC将windows消息系统进行了高度的抽象和封装,其根本原理是运用C++的高级特性并结合一定的设计模式(如工厂模式,模板方法等)来实现的.一般的windows消息(WM_XXX),则一定是由派生类流向基类,没有旁流的可能.如果是命令消息(WM_COMMAND),那就有比较奇特的路线了.下面就针对多文档/单文档(Document-View).对话框两种应用程序比较讨论WM_COMMAND消息的传递处理过程.讨论前首先得明确命令消息的来源,命令消息一般是用户选择某个菜单项,或一个加速键被翻译,或