1.SendMessage()和PostMessage()相同点:
a)能够向指定的窗口内发送窗口消息,既可以是本进程内窗口也可以是其他进程的;(要用FindWindow查找其他进程的句柄)
b)既可以发送系统消息(例如WM_LBUTTONDOWM,WM_MOUSEMOVE),范围是1-(WM_USER-1),也可以发送非系统消息(开发者定义的消息),范围是WM_USER-0x7FFF。
开发者自己定义的非系统消息范围必须是 WM_USER-0x7FFF 之间的,非系统消息主要是用来传递数据的,下面我们就来看一个发送非系统消息的使用例子,如下:
// 非系统消息主要是用来传递数据
enum{WM_TEST = WM_USER+10}; // 消息种类只要在WM_USER-0x7FFF就可以,不能再系统消息之内
void CMyDlg::OnNosysmessage() // 按键点击后发送非系统消息
{
// 参数1:消息类型 WM_TEST
// 参数2:
// 参数3:
SendMessage(WM_TEST, 0x1234, 0x5678);
}
建立完非系统消息发送的代码之后(点击按键时发送),现在要需要截获用户定义的消息,操作步骤如下:
a)首先建立一个成员函数,用于接收非系统消息
// 自己先建立一个这样的成员函数,用于接收非系统消息
LRESULT CMyDlg::OnTestMsg(WPARAM w, LPARAM l)
{
return w+l;
}
b)人工加入消息映射
BEGIN_MESSAGE_MAP(CMyDlg, CDialog)
<span style="color:#ff0000;">ON_MESSAGE(WM_TEST, OnTestMsg)</span>
//{{AFX_MSG_MAP(CMyDlg)
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_WM_LBUTTONDOWN()
ON_BN_CLICKED(IDC_SIMULATEMESSAGE, OnSimulatemessage)
ON_BN_CLICKED(IDC_NOSYSMESSAGE, OnNosysmessage)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
这里之所以把我们映射关系和系统的映射关系分开,是因为破换了系统的映射表,我们放在系统映射关系表的外面就行。
这样就建立好了非系统的消息映射函数。我们可以运行程序进行测试了。
2.SendMessage()和PostMessage()的不同点:
LRESULT SendMessage(UINT message, WPARAM w, LPARAM l);
BOOL PostMessage(UINT message, WPARAM w, LPARAM l);
a)SendMessage()是阻塞型的函数,把消息发送给消息队列后,在消息没有响应完之前这个函数是不会返回的,返回值和消息处理函数时是有直接关系的,消息处理函数返回什么,SendMessage就返回什么参数。而PostMessage()是非阻塞型函数,把消息抛出去之后就返回,不管消息是否响应,返回的是发送的成功和失败,一般是很少失败,除非窗口不存在。
b)跨现成或者跨进程发送消息时推荐使用PostMessage(),因为它不阻塞。