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来实现剪切、复制和粘贴
| 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()函数,接收方在数据复制完成前不返回,这样发送方就不可能删除和修改数据。
例如:
| 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>
#include <cstdio>
#include <process.h>
#define MY_MSG WM_USER+100
const int MAX_INFO_SIZE = ;
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 ;
} while(true)
{
if(GetMessage(&msg,,,)) //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 ;
}
int main()
{
HANDLE hThread;
unsigned nThreadID;
hStartEvent = ::CreateEvent(,FALSE,FALSE,); //create thread start event
if(hStartEvent == )
{
printf("create start event failed,errno:%d\n",::GetLastError());
return ;
}
//start thread
hThread = (HANDLE)_beginthreadex( NULL, , &fun, NULL, , &nThreadID );
if(hThread == )
{
printf("start thread failed,errno:%d\n",::GetLastError());
CloseHandle(hStartEvent);
return ;
}
//wait thread start event to avoid PostThreadMessage return errno:1444
::WaitForSingleObject(hStartEvent,INFINITE);
CloseHandle(hStartEvent);
int count = ;
while(true)
{
char* pInfo = new char[MAX_INFO_SIZE]; //create dynamic msg
sprintf(pInfo,"msg_%d",++count);
if(!PostThreadMessage(nThreadID,MY_MSG,(WPARAM)pInfo,))//post thread msg
{
printf("post message failed,errno:%d\n",::GetLastError());
delete[] pInfo;
}
::Sleep();
}
CloseHandle(hThread);
return ;
}
MFC用PostMessage传递消息的更多相关文章
- MFC原理第五讲.消息映射.以及如何添加消息
MFC原理第五讲.消息映射.以及如何添加消息 一丶消息映射是什么 我们知道.Win32程序.都是通过消息去驱动的. 不断的在处理消息. 只要我们使用固定的宏.就可以让我们的框架知道一旦消息发生.该往哪 ...
- javascript跨域传递消息 / 服务器实时推送总结
参考文档,下面有转载[非常好的两篇文章]: http://www.cnblogs.com/loveis715/p/4592246.html [跨源的各种方法总结] http://kb.cnblogs. ...
- C# WPF 窗体传递消息
对于存在窗体的WPF程序(或者说,起码在任务栏上有个图标,即ShowInTaskbar = true),互相传递消息是很容易的. 步骤: 1,寻找窗体的句柄 2,运用windows API: Send ...
- Android消息传递之组件间传递消息
前言: 上篇学习总结了Android通过Handler消息机制实现了工作线程与UI线程之间的通信,今天来学习一下如何实现组件之间的通信.本文依然是为学习EventBus做铺垫,有对比才能进步,今天主要 ...
- <MFC_1>深入剖析MFC的WinMain和消息机制
一.开篇引论 熟悉Win32开发的朋友,应该非常了解它的基本组成和流程 1. WinMain:书写窗口类(WNDCLASS) -> 注册窗口类 -> 创建窗口 -> 显示窗口和更新窗 ...
- MFC模态对话框的消息循环
MFC模态对话框的消息循环 单线程程序, 当主窗口响应函数中弹出模态对话框时,为什么主窗口响应函数可能照常工作? 当弹出模态对话框时,线程的消息循环无法返回,父窗口的事件本应没人处理,应该处于卡死状态 ...
- MFC 中线程传递CString 是不安全的 转
MFC 中线程传递CString 是不安全的 在MFC中,向线程传递CString变量参数时,很容易犯一个错误,就是使用一个超出生存期的变量,在主函数中定义的CString变量是局部变量 ...
- Android为TV端助力:intent传递消息
我们都知道一个activity向另外一个activity传递消息可以用intent来传递 现在需求如下,一个不断接收消息服务的service,一个收到消息进行处理的activity service第一 ...
- Android开发--Service和Activity通过广播传递消息
Android的Service也运行在主线程,但是在服务里面是没法直接调用更改UI,如果需要服务传递消息给Activity,通过广播是其中的一种方法: 一.在服务里面发送广播 通过intent传送数据 ...
随机推荐
- [转载]AOP面向方面编程
1.引言 软件开发的目标是要对世界的部分元素或者信息流建立模型,实现软件系统的工程需要将系统分解成可以创建和管理的模块.于是出现了以系统模块化特性的面向对象程序设计技术.模块化的面向对象编程极度极地提 ...
- PHP5 session 详解
http协议是WEB服务器与客户端(浏览器)相互通信的协议,它是一种无状态协议.所谓无状态,指的是不会维护http请求数据,http请求是独立的,非持久的.而越来越复杂的WEB应用,需要保存一些用户状 ...
- Android支付接入(一):支付宝
原地址:http://blog.csdn.net/simdanfeg/article/details/9011603 转载之前我想深深地感谢屌丝哥 相信相同过App获取利润的都会需要接入计费SDK,下 ...
- DJANGO中filter_horizontal和raw_id_fields的作用
在作多项选择的操作方便性,及单项选择太多时,会有好一点的体验... class UserAuthorAdmin(admin.ModelAdmin): # raw_id_fields = ('group ...
- BZOJ 3123 SDOI2013 森林
首先对于查询操作就是裸的COT QAQ 在树上DFS建出主席树就可以了 对于连接操作,我们发现并没有删除 所以我们可以进行启发式合并,每次将小的树拍扁插入大的树里并重构即可 写完了之后第一个和第二个点 ...
- BZOJ 4311 向量
shallot+向量集 混合版? 首先我们考虑每个向量的存在时间为[L,R] 那么我们知道任意一个区间在线段树上最多被分解成logn个区间 那么我们可以像shallot一样进行区间覆盖 注意到本题的查 ...
- HDU1171——Big Event in HDU(母函数)
Big Event in HDU DescriptionNowadays, we all know that Computer College is the biggest department in ...
- PHP session过期时间
如何设置一个严格30分钟过期的Session 今天在我的微博(Laruence)上发出一个问题: 我在面试的时候, 经常会问一个问题: “如何设置一个30分钟过期的Session?”, 大家不要觉得看 ...
- Windows CE,你妈吗喊你在多核上玩玩
转自:http://hezongjian.com/blog/?p=9693 众所周知,CE的内核是完全重新写的,与9x根nt没有任何关系,这给CE带来了较好的实时性及灵活性.从诞生之日起,CE的内核改 ...
- 【HDOJ】4261 Estimation
挺不错的一道题,基本思路是dp.关键点是如何求区间内的Sigma|A_i-B_i|.线段树做TLE了,优先队列可以过. /* 4261 */ #include <iostream> #in ...