MFC--自定义消息

2014-11-24 03:09:25 · 作者: · 浏览: 1

在windows程序中,消息是一个重要的概念,最常见的消息一般都是以WM_开头,WM就是window message,窗口消息的缩写,通过处理标准的windows消息,我们可以改变窗口的外观,如使用WM_ERASEBKGND消息可以改变窗口默认的窗口背景,窗口每次需要绘制窗口的背景的时候,就会发送一次这个消息,如果我们处理这个消息,我们就可以绘制我们自己的特性化的背景,如果不处理,默认窗口过程就会处理,绘制背景。通过处理标准的windows消息,我们可以对用户的输入做出响应,如WM_LBUTTONDOWN,当鼠标按下的时候,就可以对用户的操作作出响应,通过命令消息WM_COMMAND消息,可以获取来自菜单,按钮的命令。另外,控件还有自己的notification消息,当控件的状态发生改变的时候,如点击按钮,点击编辑框,选择一个列表框项目时,就会发送相应的消息,通过处理消息,就可以对获取控件的一些消息,做出一些处理。在sdk中还有一种消息,也是用于控件的,也是通过发送消息来控制控件的属性和操作,而这个在MFC中变成了成员函数,但是底层的原理还是一样的。消息的作用还有很多,我们不能单一的去理解消息这个概念,一方面,我们可以通过阅读msdn可以深入的学习消息,另一方面,我们可以通过在使用的过程中,加深对消息的理解。除了使用上面说的这些windows提供的预定义消息(系统消息)之外,我们也可以使用我们自定义的消息。

每个消息有一个ID,对于自定义消息,我们在定义的时候,也要定义一个ID,而这个ID的范围是有要求的,可以是WM_USER (0x0400) 到 0x7FFF,也可以是 WM_APP (0x8000) 到0xBFFF,别的ID范围呢,系统保留。在使用的时候,通常都是以WM_USER+X,WM_APP+X或是在定义消息ID的时候,有两种方法:

第一种方法是通过常量声明幅值的方法,也就是常量的使用方法,因为一个消息的ID就是一个常量,确定之后,就不能改变,因此,可以使用定义常量的方法来为一个消息附上ID,如下:

const UINT WM_MYMESSAGE1=WM_APP+1;

第二种方法是通过#define,如下:

#define WM_MYMESSAGE2 WM_APP+2

通过这两种方法,我们就可以在为一个消息指定ID。下面是要说说,上面这两句定义消息ID的表达式所放的位置的不同所产生的使用方法的不同。下面以实例来说明:

第一种情况,当我把定义消息ID的表达式放在了头文件MyView.h中

\

当我在SINView.cpp文件中接收和处理这两个消息时,必须事先包含声明两个消息ID的头文件,这里是MyView.h。否则,在cpp中处理的时候,就是出现语法错误,提示未声明的标示符。< http://www.2cto.com/kf/ware/vc/" target="_blank" class="keylink">vcD4KPHA+tdq2/tbWx+m/9qOsyOe5+87Sw8fTydPa0rvQqdSt0vKjrLK7xNyw/LqsyfnD98/7z6JJRLXEzbfOxLz+o6zA/cjno6zI57n7ztLDx7D8uqzBy6Osvs274bP2z9a7pc/gsPy6rLXEx+m/9qOsvs274dTss8m07c7zo6y78srHo6y9q9Tat6LLzdXiuPbP+8+itcRjcHDOxLz+us2908rctKbA7dXiuPbP+8+itcRjcHDOxLz+1tC2qNLl1eLBvbj2z/vPorXESUSjrMTHw7TV4rj2yrG68qOsztLDx7HY0OvU2sG9uPa12Le9yfnD97rNt/kmIzIwNTQwO8/7z6JJRKOs0ru49rXYt73Kx7eiy821xMDgtcTUtM7EvP678s23zsS8/tbQo6zB7dK7uPa12Le9yse908rVus20psDt1eK49tfUtqjS5c/7z6K1xNS0zsS8/tbQoaPA/cjno6xXTV9NWU1FU1NBR0Uzo6zO0tTaTXlWaWV3Lmi78srHTXlWaWV3LmNwcNbQvfjQ0Mn5w/ejrNLyzqrO0tKqtNNNeVZpZXcuY3Bw1tC3osvN1eK49s/7z6KjrMjnzbyjujwvcD4KPHA+PGltZyBzcmM9"https://www.cppentry.com/upload_files/article/49/1_auxmo__.jpg" width="350" height="200" alt="\">

在接收消息的地方,我再次定义一次,可以直接复制上次定义的,我要在SINView.cpp中接收和处理,于是在这个文件的开头,如下图:

\

现在已经定义好了消息的ID,接下来是发送消息,发送消息,一般是是用SendMessage和PostMessage,SendMessage必须要等到这个消息被处理并返回之后才会结束执行,否则会一直等待,如果消息一直得不到处理,函数一直等待,就会造成发送消息的线程阻塞。PostMessage是将消息发送之后,就立即返回,不管消息是否到达目的地,处理。如果在单线程程序中,我们最好是用PostMessage,用SendMessage容易造成线程锁死。另外,在MFC中使用这两个函数,如果直接使用,第一个参数就是要发送的消息,这样只能向本窗口发送消息,如果在MFC中使用::PostMessage,这样就是使用的是win32函数的api,第一个参数是目标窗口句柄,就可以向任意窗口发送消息。

下面说说如何处理发送的消息,首先介绍一种最为简单的处理方法,这种方法和在win32 sdk中的窗口过程一样,通过switch/case语句来处理.在MFC窗口类都有一个WindowProc虚函数,当这个窗口的消息进入这个窗口的消息映射之前,会首先通过这个虚函数,因此,我们在这里就可以拦截处理我们的自定义消息,甚至是别的任何消息,当然,标准窗口消息仍然是推荐使用MFC的消息映射的方法来处理。如下图:

\

使用这种方法,有一点很重要,那就是最后那一句return语句:return CView::WindowProc(message, wParam, lParam);这样保证别的消息可以正确处理。这种处理方式和win32 sdk中的窗口过程处理消息的方式是一样的。

接着介绍一种MFC标准的自定义消息处理的方式,也就是是用ON_MESSAGE宏。使用这种方式,就和我的博文"MFC-消息机制"中描述的消息处理方式一样,要使用这种处理方式,首先要声明一个消息响应函数原型,接着添加消息映射,最后实现消息响应函数。我们一步一步来看,首先看ON_MESSAGE宏的原型:

ON_MESSAGE(message, memberFxn)

第一个参数是消息ID,第二个参数消息响应函数。现在,针对WM_MYMESSAGE3消息,我们使用这种处理方式。首先在CSINView类中声明一个消息响应函数:

afx_msg LRESULT OnMyMessage3(WPARAM wParam, LPARAM lParam);

消息响应函数的名称由自己确定,这里我使用的是OnMyMessage3。在声明这个消息响应函数的时候,一般就是按照这个样式,而且一般声明为protected。

接着是消息添加消息映射,使用ON_MESSAGE,如下:

\

最后是实现消息响应函数,在SINView.cpp中,如下:

\

通过ON_MESSAGE宏,当窗口接收到消息的时候,就会自动调用我们的消息响应函数了。

以上就阐述了一下,在MFC自定义消息的使用方法,下面是效果图:

n块 нk b % 
i	h    {%j z    辟   +zf ┹ u魑踣  i i h hi vy薹 胆  并殁 并殁 加  Z  http://www.2cto.com/os/windows/windows7 vs2010环境下