MFC教程(4)-- 消息映射的实现(2)
2010-03-25 20:33:48 来源:WEB开发网消息的多次处理
如果消息处理函数不返回值,则DispatchCmdMsg返回TRUE;否则,DispatchCmdMsg返回消息处理函数的返回值。这个返回值沿着消息发送相反的路径逐级向上传递,使得各个环节的OnCmdMsg和OnCommand得到返回的处理结果:TRUE或者FALSE,即成功或者失败。
这样就产生了一个问题,如果消息处理函数有意返回一个FALSE,那么不就传递了一个错误的信息?例如,OnCmdMsg函数得到FALSE返回值,就认为消息没有被处理,它将继续发送消息到下一环节。的确是这样的,但是这不是MFC的漏洞,而是有意这么设计的,用来处理一些特别的消息映射宏,实现同一个消息的多次处理。
通常的命令或者通知消息是没有返回值的(见4.4.2节的消息映射宏),仅仅一些特殊的消息处理函数具有返回值,这类消息的消息处理函数是使用扩展消息映射宏映射的,例如:
ON_COMMAND对应的ON_COMMAND_EX
扩展映射宏和对应的普通映射宏的参数个数相同,含义一样。但是扩展映射宏的消息处理函数的原型和对应的普通映射宏相比,有两个不同之处:一是多了一个UINT类型的参数,另外就是有返回值(返回BOOL类型)。回顾4.4.2章节,范围映射宏ON_COMMAND_RANGE的消息处理函数也有一个这样的参数,该参数在两处的含义是一样的,例如:命令消息扩展映射宏ON_COMMAND_EX定义的消息处理函数解释该参数是当前要处理的命令消息ID。有返回值的意义在于:如果扩展映射宏的消息处理函数返回FALSE,则导致当前消息被发送给消息路径上的下一个消息目标处理。
综合来看,ON_COMMAND_EX宏有两个功能:
一是可以把多个命令消息指定给一个消息处理函数处理。这类似于ON_COMMAND_RANGE宏的作用。不过,这里的多条消息的命令ID或者控制子窗口ID可以不连续,每条消息都需要一个ON_COMMAND_EX宏。
二是可以让几个消息目标处理同一个命令或者通知或者反射消息。如果消息发送路径上较前的命令目标不处理消息或者处理消息后返回FALSE,则下一个命令目标将继续处理该消息。
对于通知消息、反射消息,它们也有扩展映射宏,而且上述论断也适合于它们。例如:
ON_NOTIFY对应的ON_NOTIFY_EX
ON_CONTROL对应的ON_CONTROL_EX
ON_CONTROL_REFLECT对应的ON_CONTROL_REFLECT_EX
等等。
范围消息映射宏也有对应的扩展映射宏,例如:
ON_NOTIFY_RANGE对应的ON_NOTIFY_EX_RANGE
ON_COMMAND_RANGE对应的ON_COMMAND_EX_RANGE
使用这些宏的目的在于利用扩展宏的第二个功能:实现消息的多次处理。
关于扩展消息映射宏的例子,参见13.2..4.4节和13.2.4.6节。
更多精彩
赞助商链接