MFC消息机制

一、消息的分类

1、 队列消息、非队列消息

l         队列消息:

windows为每个应用程序都建立一个消息队列,那么通过消息队列,进行传送的消息都属于队列消息;一般来说,由鼠标、键盘产生的消息都属于队列消息。(为什么呢?想想,鼠标、键盘事件都是由系统捕获的,系统捕获后要传递给应用程序,就一定的通过消息队列);

l         非队列消息:

除了队列消息,剩下的自然而然就是非队列消息了;

 

u       队列消息是通过PostMessage()的方式投递消息的,这样的消息发送也叫“寄送”,该函数寄送消息即可返回,不需要等待程序处理结果;

u       非队列消息是通过SendMessage()的方式进行的,这样的消息发送叫“发送”;消息不需要进入窗口的消息队列,

 

然而不管是队列消息,还是非队列消息,消息处理的起点都是AfxWndProc不同的是队列消息,是操作系统把消息投放到消息队列,应用程序空闲是,通过一个消息循环,搜索消息队列,不停的从消息队列抓取消息,并处理。大致流程是:CwinThread->PumpMessage->CWnd->PreTranslateMessage->…………..->USER32内核->AfxWndProcBase->AfxWndProc->…….(继续处理)

而非队列消息呢(即通过SendMessage方式发送的消息)?它是直接进入了USER32内核,然后处理的流程和队列消息一样了。

注意,不管是队列消息,还是非队列消息,都是从USER32内核开始,转到了AfxWndProcBase(有时候不经过这里),再到AfxWndProc,所以可以认为AfxWndProc是消息传递与处理的起点!

 

补充一点儿:按理说,从USER32出来后,不管是队列消息,还是非队列消息,应该由Windosw系统发往各个窗口的消息处理函数(这个处理函数是DefWindowProc,这是很直觉的想法,而且传统的SDK程序确实是这样的,但是MFC程序比传统的SDK多了document/view,如果如果某个消息是做文档处理,那么就让这个消息直接流到document中去不是更好吗?所以才有了MFC命令传递机制、MFC消息映射的出现),但是为什么都统一到了AfxWndProc这里呢?这里用到了钩子技术。(关于这一段儿描述的,不管是“深入浅出MFC”、“MFC逆向分析”、“精通MFC”都由介绍,但是都不是很清楚,需要再仔细揣摩。而且由于MFC版本的不同,实际的函数流程也可能和资料描述的不同)[微软用户1] 

 

2、  命令消息、通知消息、一般消息

下面以表格来分析这几类消息:

 

 

形式

来源

谁能处理?

 

命令消息

WM_Command

菜单、工具栏

凡派生自CcmdTarget的类,都可以

 

通知消息

WM_Notify,也是以WM_Command形式出现

子控件传给父控件的

 

 

一般消息(又叫标准消息、窗口消息)

WM_(任意),比如WM_CreateWM_Move等等

 

派生自CWnd的类

 

然而,看一下MFC一些基类的继承关系,如下图:

Cobject

   |

CCmdTarget

   |

   |----CwinThread---CWinApp---CMyWinApp

   |

   |----CWnd----

   |           |----CView

   |           |----CFrameWnd

   |

   |----Cdocument----CmyDoc

 

看上图的继承关系,可以这么说,

a)         凡是派生自CWnd的类,可以拦截并处理任何Windows消息,不管是WM_Command,还是WM_Notify,还是其它什么WM_CreateWM_Move等消息;

b)        而与窗口无关的CwinApp类、Cdocument类,因为继承自CcmdTarget,只能处理WM_Command消息;因为没有继承自CWnd,不能处理一般消息。

 

3、 消息的处理流程

好了,有了前面12小节的基础,我们接下来来看消息的处理流程:

 


 [微软用户1]这一块儿似懂非懂,需要继续研究

posted @ 2011-01-11 23:14  pjh123  阅读(527)  评论(0编辑  收藏  举报