MFC消息反射

来源:互联网 发布:重生之歪歪网络土豪 编辑:程序博客网 时间:2024/05/01 14:58

在基于对话框的程序中,有一个任务是改变编辑框控件的背景,怎么办?

实现思路如下,子控件要绘制时会向父类(这里是主窗口)发送WM_CTLCOLOR

消息,在父类中(这里是主窗口)响应WM_CTLCOLOR,根据消息传递过来的

参数进行相应的操作,具体代码如下:

CBrush m_brush;

m_brush.CreateSolidBrush(RGB(0, 0, 255));

HBRUSH CMy112Dlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) {HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);if (pWnd->GetDlgCtrlID() == IDC_EDIT1){pDC->SetBkMode(TRANSPARENT);return m_brush;}return hbr;}

代码解释如下:在主对话框类CMy112Dlg中定义一个成员变量m_brush,并在主对话

框类中的构造函数中进行初始化。然后为父类编写WM_CTLCOLOR,在消息响应中判断

控件是否为要设置的编辑框控件(要设置的编辑框控件ID为IDC_EDIT1)将背景模式设

置为透明,并设置控件背景为蓝色。

这和消息反射有什么关系呢?上述代码有问题吗?上述方法也不失为一种好方法,但从

软件工程角度看还有一些缺憾,子类控件的消息都要父类去处理,这样就会导致父类

中的代码臃肿,而子类无事可做。另一方面,如果其它的工程要用到类似功能,怎么办?

只好把上述函数代码拷贝到另外工程中,并进行稍微修改。

MFC4.0开始有了解决此问题的一种新方法:消息反射,以上面为例,子控件要绘制时,

会向父类发送要绘制的消息,父类收到消息后,首先反射(再发给)给子控件,看子控件

是否对此消息做了处理,如果做了处理,父类将不再处理。如果子控件没有处理,则

父类对子控件发送的消息做处理。

再看一下上面例子的另一种方法:消息反射法

为工程添加一处新类CYellowEdit,此类从MFC的CEdit类派生,为类添加三个成员变量

COLORREF m_clrText;COLORREF m_clrBkgnd;CBrush   m_brBkgnd;
分别是文本颜色,背景色,画刷,在CYellowEdit类构造函数中进行初始化

CYellowEdit::CYellowEdit(){m_clrText = RGB(0, 0, 0);m_clrBkgnd = RGB(255, 255, 0);m_brBkgnd.CreateSolidBrush(m_clrBkgnd);}
为CYellowEdit类添加反射函数(消息前面带有=的是反射消息,本例中为=WM_CTRLCOLR,

HBRUSH CYellowEdit::CtlColor(CDC* pDC, UINT nCtlColor) {pDC->SetTextColor(m_clrText);    // 文本颜色pDC->SetBkColor(m_clrBkgnd);     // 背景色return m_brBkgnd;                // 控件背景}
在主对话框上再添加一个编辑框,并为之关联变量,关联变量类型为CYelloEdit,运行程序可

以看到编辑框的背景已变成黄色了。

这就是消息反射的一个用处,使用消息反射和不使用消息反射这两个例子有什么区别呢?个

人认为最大的区别就是代码的可重用性,使用消息反射后,如果碰到类似应用,直接将

CYellowEdit拷贝到其它工程直接应用,不需要修改代码。


上述例子在MSDN中有详细介绍,在MSDN中主题为:ON_NOTIFY_REFLECT,

里面有一篇

TN062: Message Reflection for Windows Controls

的文章专门讲述了消息反射。网上也有不少这方面的文章,但基本上都是参考MSDN翻译的,

下面给出几个消息反射资料的博文地址

1    http://blog.csdn.net/gao_zilai/article/details/7417690

2    http://blog.csdn.net/cay22/article/details/6171616

3    http://bbs.ednchina.com/BLOG_ARTICLE_1926378.HTM




原创粉丝点击