分析与理解MFC消息反射机制

来源:互联网 发布:五级三晋制奖金算法 编辑:程序博客网 时间:2024/05/22 06:37

前言:

我曾写过一篇文章对通知消息WM_NOTIFY进行分析,消息反射是MFC中对通知消息的处理方式,两者之间关系十分紧密,因此,我写了这篇文章,希望能够描绘出通知消息的完整印象。

消息反射的基础知识

1、消息反射解释:
父窗口将控制子窗口发给它的通知消息,首先反射回子窗口进行处理(即给控制子窗口一个机会,让控制子窗口处理此消息),这样通知消息就有机会能被子窗口自身进行处理。

2、MFC中引入消息反射的原因:
在Windows的消息处理中,控制子窗口的发给其父窗口的通知消息只能由其父窗口进行处理,这使得控制子窗口的自身能动性大大降低(你想,它连改变 自己的背景色,处理一个自身滚动问题都要其父窗口来完成),为了解决这个问题,在MFC中引入了反射消息“Reflect Message”的概念,进行消息反射,可以使得控制子窗口能够自行处理与自身相关的一些消息,增强了封装性,从而提高了控制子窗口的可重用性。

消息反射的处理流程(不考虑OLE控制)

一、消息反射处理流程图:
1、父窗口收到控制子窗口发来的通知消息后,调用它的虚函数CWnd::OnNotify.
CWnd::OnNotify()主体部分:
{
if (ReflectLastMsg(hWndCtrl, pResult)) //此时,hWndCtrl,为发送窗口,即子窗口的窗口句柄
return TRUE; // 子窗口已处理了此消息
AFX_NOTIFY notify;
notify.pResult = pResult;
notify.pNMHDR = pNMHDR;
return OnCmdMsg(nID, MAKELONG(nCode, WM_NOTIFY), ¬ify, NULL);
}

分析:首先,调用ReflectLastMsg(hCtrlChildWnd,...)给子窗口一个自身处理的机会,将消息反射给子窗口处理,函数返 回TRUE,表明子窗口处理了此消息。反之,表示子窗口未处理此消息,此时,调用OnCmdMsg(...)由父窗口进行通常的处理。

2、ReflectLastMsg中:
主要是调用发送窗口的SendChildNotifyLastMsg(...)。

3、SendChildNotifyLastMsg 中:
调用发送窗口的虚函数OnChildNotify函数,进行处理。 如果没有处理,则调用ReflectChildNotify(...)函数进行标准的反射消息的消息映射处理。


二、消息处理

方式1:
由上述处理流程可以看出来,子窗口要想自身处理此消息,重载子控件窗口的OnChildNotify虚拟函数应该是很容易想到的方式。

注意:MFC中对各个子控件窗口一般都已经重载了OnChildNotify函数,它对应调用类的虚函数进行处理,所以,你重载对应的虚函数即可,如下例:
BOOL CStatusBarCtrl::OnChildNotify(UINT message, WPARAM wParam, LPARAM lParam,LRESULT* pResult)
{
if (message != WM_DRAWITEM) //对应不同的控制,会有不同的有特殊处理要求的消息。
return CWnd::OnChildNotify(message, wParam, lParam, pResult);
...
...
DrawItem((LPDRAWITEMSTRUCT)lParam);
return TRUE;
}
virtual void DrawItem( LPDRAWITEMSTRUCT lpDrawItemStruct );
void CStatusBarCtrl::DrawItem(LPDRAWITEMSTRUCT)
{
ASSERT(FALSE); // must override for self draw status bars
}

你重载CSTatusBarCtrl类的DrawItem虚拟函数,即可实现对反射消息WM_DRAWITEM的处理。

方式2:
从方式1可以看出,如果你不在被重载的OnChildNotify中对消息进行处理,函数会调用CWnd::OnChildNotify,它调用ReflectChildNotify函数进行标准的处理。
1、增加反射消息的映射入口。
2、增加对应的消息处理函数。
注意:可以使用MFC的ClassWizard作上述动作,在ClassWizard中,可处理的反射消息以一个"="号以示区别。返回值为TRUE,表示控件窗口已处理此反射消息,为FALSE,表示控件子窗口未处理此反射消息。

结语:

消息反射不是很难的概念。它仅出现在MFC中;它的用意是方便控制子窗口的重用;对某些通知消息你可以重载对应的虚函数 (WM_DRAWITEM...)进行处理;对其它你可以使用标准的消息反射映射进行处理。限于篇幅,一些细节问题,请阅读MFC中对应的源代码。

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 老板请朋友吃饭司机应该怎么办 被化妆学校坑了怎么办 快车约得太远怎么办 工资好低2000多怎么办 苹果手机不能下载软件怎么办 苹果手机下不了软件怎么办 苹果6s下不了软件怎么办 苹果6下不了软件怎么办 ipad更新系统卡住了怎么办 ipad卡住了关不了机怎么办 ipad卡住了没反应怎么办 苹果7下不了软件怎么办 苹果手机开机密码忘了怎么办 苹果开机密码忘了怎么办 我的ipad很卡怎么办 6s升级后卡顿严重怎么办 软件升级后手机卡顿怎么办 ps通道抠图模糊怎么办 电脑锁屏死机了怎么办 ipad电源键坏了怎么办 华为平板死机黑屏了怎么办 苹果4s锁屏键坏了怎么办 平板电脑密码锁忘记密码怎么办 苹果平板电脑密码锁忘记密码怎么办 平板电脑密码锁密码锁死怎么办 小米平板黑屏按键亮怎么办 小米平板黑屏没反应怎么办 小米平板一刷黑屏了怎么办 小米4卡死了怎么办啊 苹果平板电脑开不了机怎么办 ipad开不了机怎么办都是黑屏 手机突然黑屏了死机状态怎么办 苹果平板死机不能重启怎么办 韩众平板死机了怎么办 苹果平板输入密码多次停用怎么办 ld密码被停用了怎么办 档案被自己丢了怎么办 手机在厂里丢了怎么办 在厂里借工具丢了怎么办 导出的考勤没有姓名怎么办 退休时档案丢了怎么办