PostThreadMessage和SendMessage用法+结合CreateThread多线程讲解
来源:互联网 发布:gre网络课程 编辑:程序博客网 时间:2024/06/05 11:45
提示:有关函数及其参数介绍大家直接百科就行了,这里只介绍具体用法。
一、SendMessage
首先我们来学习一下如何使用SendMessage函数,这个函数在线程中调用后,消息发出到消息接收函数,
该线程必须等到消息接收函数执行完毕才能继续向下执行。这也是它和PostThreadMessage最大的区别。
后者只需要抛出消息,然后继续执行,不需等待接受消息函数执行完。
比较完整的做法,六步就可执行完毕,希望读者有些耐心,并且能真正理解其用法的含义。
1.
//首先要自定义一个用户消息,我们一般用WM_USER +n来定义消息ID,n要大于100,小于100的已经被系统消息ID占用。
该操作一般位于头文件中。
#define WM_USERLOGIN_RSP WM_USER+102 //账号登录响应
2.
//声明一个函数用于接收消息。一般也放在头文件中
afx_msg LRESULT OnUserLogin(WPARAM wParam,LPARAM lParam);
3.
//给消息绑定接收函数
ON_MESSAGE(WM_USERLOGIN_RSP,OnUserLogin)
如果是基于MFC编程,在
//将消息和函数绑定
BEGIN_MESSAGE_MAP(CTraVariety, CDialog)
//{{AFX_MSG_MAP(CTraVariety)
、、、、、、、、
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
里面添加这句代码即可
4.
//定义消息接收函数,该函数位于下面的第5步中 句柄所代表的区域
LRESULT CTraVariety::OnUserLogin(WPARAM wParam,LPARAM lParam)//登录成功消息
{
CString *nameMsg = (CString *)wParam;
/*********/
}
5.该句柄要包含上述第4步中的消息接收函数
//确定一个用来接收消息的句柄,
比如我们可以这样做:
HWND m_hMainWnd;//句柄变量
//给句柄赋值
void CTraVariety::CTPInitWnd(CTraderSpi* UserSpi)
{
// 将pUserSpi的消息响应窗口设置为本窗口 //传递主窗口句柄:
UserSpi->SetHwnd(this->m_hWnd);
}
SetHwnd()函数定义如下:
void CTraderSpi::SetHwnd(HWND hWnd)
{
m_hMainWnd = hWnd;
}
6.最后,你就可以随意使用SendMessage了,第一个参数是你想让这个消息发送到哪个句柄,第二个参数是消息的名,
第三个参数是发送的数据
//发送自定义消息
::SendMessage(m_hMainWnd,WM_USERLOGIN_RSP,(WPARAM)nameMsg,NULL);
二、PostThreadMessage用法
学会了SendMessage的用法,PostThreadMessage其实是一样的,不过SendMessage函数的第一个参数是句柄,
是struct HWND__ *类型,但是PostThreadMessage的第一个参数是DWORD类型,用来表示线程ID,
所以其使用一般是结合多线程来使用,所以我们有必要谈一下CreateThread()这个函数。
CreateThread()属于Windows Api,其实并不建议大家使用,更经常使用的是_beginThread函数,
这个函数属于CRT(c running time)函数,是编译器带的,但是底层同样调用了CreateThread,
这个我们先不讨论,有关_beginThread使用方法大家可以参考我的另一篇文章——使用_beginThread创建自己的Thread基类。
(不发链接了(*^__^*) 每次发链接都被审核,童鞋们有兴趣就自己翻一翻)。
比如现在我们要创建一个日志线程,专门用来存储日志,TradeProc()作为消息接收入口函数,
接收其他各个线程发送来的数据,并不影响其他线程继续工作。
1.
//首先要声明变量:
HANDLE m_hTradeThread; //用来表示线程
DWORD m_dwTradeId; //用来记录线程ID
2.
//使用CreateThread将线程和ID绑定到函数TradeProc上,函数名就是入口地址(不多解释)
m_hTradeThread = CreateThread( NULL,0,TradeProc,(LPVOID)this,0,&m_dwTradeId); //日志线程
if (m_hTradeThread == NULL)
{
AfxMessageBox("创建日志记录线程失败!");
}
3.入口函数的定义
//当然函数要提前声明或者位置要在绑定的前方
DWORD WINAPI TradeProc(LPVOID lpParameter) //日志线程函数
{
MSG msg;
while(GetMessage(&msg,NULL,0,0))
{
//做你想做的事情
//such as : Public.CreateRecord(LogRecord);
}
return 1;
}
其中的GetMessage()专门用来接收PostThreadMessage()发出的消息,当没有消息发出时,该线程一直处于阻塞状态,
一旦接收到消息,就可以根据消息类型或内容做你想做的事儿。我一般的做法是:创建一个主接收消息线程,
给不同的消息(数据)标识不同的类型,接收到消息后根据消息类型立即抛出到相对应的子线程中,
不影响下一次的消息接收,并可以效率比较高,但是可能会耗费内存喔。当然这些设计思想要根据实际的需求,最后还得取决于你。
4.
最后,你又可以随意使用PostThreadMessage()了:
PostThreadMessage(m_dwTradeId,0,(WPARAM)m_tuse,1); //发送消息
想详细讨论的童鞋可以加Q 1466231850
- PostThreadMessage和SendMessage用法+结合CreateThread多线程讲解
- SendMessage和PostMessage PostThreadMessage
- SendMessage和PostMessage的区别PostThreadMessage
- PostMessage、SendMessage、PostThreadMessage
- PostMessage SendMessage SendNotifyMesage PostThreadMessage
- PostThreadMessage用法
- SendMessage和Findwindow用法
- 多线程CreateThread函数的用法及注意事项
- 多线程CreateThread函数的用法及注意事项
- 多线程CreateThread函数的用法及注意事项
- 多线程CreateThread函数的用法及注意事项
- 多线程CreateThread函数的用法及注意事项
- 多线程CreateThread函数的用法及注意事项
- 多线程CreateThread函数的用法及注意事项
- 多线程CreateThread函数的用法及注意事项
- 多线程 CreateThread 函数的用法及注意事项
- 多线程CreateThread函数的用法及注意事项
- SendMessage和WM_COPYDATA的用法
- SSM(Spring+SpringMVC+MyBatis)开发框架的搭建个人总结
- BZOJ_P1503&Codevs_P1286 [NOI2004]郁闷的出纳员(SplayTree)
- 【JDBC开发】JDBC一些值得注意的细节问题
- Java基础:一个关于java数组的深度思考
- junit设计模式--组合模式
- PostThreadMessage和SendMessage用法+结合CreateThread多线程讲解
- 二进制 快速count 1
- Linux快捷键
- Codeforces Round #322 (Div. 2) D. Three Logos(暴力)
- 开启Hadoop2.6.0出现ssh无法解析主机名等错误提示的解决办法!
- wordcount加强版和各种wordCount
- 模板_KMP和AC自动机
- [LeetCode]152. Maximum Product Subarray
- Android adb基本命令-cd,ls,目录相关命令