MFC的消息过程

MFC 窗口消息流程:

     MFC把Windows的窗口句柄HWND封装成一个CWnd类,每个MFC窗口类(对话框除外)的Create最终都是会调用基类的CWnd::CreateEx过程。在CWnd::CreateEx过程中:

1)  调用PreCreateWindow虚函数允许用户在窗口创建之前修改窗口的相关属性。

2)  调用AfxHookWindowCreate安装窗口创建钩子WH_CBT: _AfxCbtFilterHook (目的在于将窗口过程替换成AfxWndProc)。

3)  调用::AfxCtxCreateWindowEx系统创建创建窗口。窗口创建过程中的消息被转移_AfxCbtFilterHook过程。

4)  窗口创建完毕后。调用AfxUnhookWindowCreate将窗口创建钩子WH_CBT从钩子链中移除。之后的窗口消息就会被分派到MFC的窗口过程函数AfxWndProc中。

 

_AfxCbtFilterHook过程:

1)  将创建的C++类对象与窗口句柄关联。

2)  调到虚函数PreSubclassWindow允许用户在窗口关联后做一些额外的事情。例如:修改样式ModifyStyle。 这是窗口创建后修改数据的最佳之处。无论是Create,还是通过对话框DoDataExchange关联的窗口类。都会调用到这个函数。

创建方式

PreCreateWindow

PreSubclassWindow

OnCreate

Create

SubclassWindow

对话框模板创建的控件跟随对话框一起创建。这期间并没有关联C++对象。控件句柄与C++对象的关联是在DoDataExchange中完成的。而此时窗口已经创建完成。固然子类化不可能再收到WM_CREATE这种创建消息。

 

AfxWndProc过程:

     所有的MFC窗口消息都会被分派到这个函数。

1.首先是通过窗口句柄在窗口哈希表afxMapHWND中找到关联的C++类。

2.若查找不是,则调用::DefWindowProc直接让系统默认处理此消息。

3.若查找成功,则调用AfxCallWndProc的调用过程。

1)设置一些线程数据。

2)调用虚函数WindowProc进入到具体的窗口类窗口过程。内部调用OnWndMsg处理Windows的消息。若消息在OnWndMsg中得不到处理。则DefWindowProc交给系统处理。

              (1)若是命令消息WM_COMMAND调用虚函数OnCommand 处理。

若是子控件发过来的命令消息。则通过ReflectLastMsg先将消息反射回子控件。若子控件没有处理。再到消息映射表中找对应的处理函数。若找到对应的函数,则执行。否则返回失败。

               (2)若是通知消息WM_NOTIFY调用虚函数OnNotify

               处理过程跟OnCommand基本上是一致的的。

(3) 其他的WM_标准消息:则直接查找消息映射表。若查找成功,则执行映射实体中指定的函数。否则返回失败。

 

消息棒:

     应用程序初始化InitInstance完成后,就会进入消息循环Run。

1)  PeekMessage探测消息队列里是否有消息。若无则进入空闲处理OnIdle。默认处理是会向可见的框架窗口的子控件(工具栏,状态栏)以及浮动的窗口发送WM_IDLEUPDATECMDUI更新界面状态。子控件收到WM_IDLEUPDATECMDUI后,继而会促发CN_UPDATE_COMMAND_UI的命令消息来更新界面的Check, radio, disable等状态。

2)  若有消息,则将消息取出来。在消息派发给窗口过程之前先调用AfxPreTranslateMessage让应用程序有权先处理消息,决定要不要将消息派发到窗口过程。若消息没有被AfxPreTranslateMessage截断。则对消息进行转化派发

::TranslateMessage

::DispatchMessage

派发过程中会调用MFC的窗口过程AfxWndProc。

线程消息队列的消息主要有三个来源:

1)  用户的输入:鼠标,键盘等消息。

2)  系统内核促发的消息。例如:WM_PAINT等消息。

3)  程序PostMessage发送过来的消息。

程序调用SendMessage的消息会直接被派发到MFC窗口过程AfxWndProc中,并不经过线程消息队列。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值