一个老外关于 WM_CTLCOLOR,WM_ERASEBKGND给出的结论:
结论是同是在wm_erasebkgnd,wm_ctlcolor里修改对话框的背景颜色引起的问题Default implementation of WM_ERASEBKGND message handler erases invalidated areas and fills it with color of the brush window was register with.
 After that, native drawing is done in WM_PAINT handler. If you return TRUE from WM_ERASEBKGND you tell system to not to erase background and that is why you do not have background impact on your dialog.
 摘录:
http://blog.csdn.net/coolboylai2/article/details/7238712这个博客里有详细的说明。 大家可以帮忙看看
我验证了一下,发现不对,不知道是自己验证的方式不对,还是他说错了
实验:
在一个对话框上添加一个编辑框。对对话框相应
ON_WM_CTLCOLOR()
ON_WM_ERASEBKGND()代码:brushDlg.CreateSolidBrush(RGB(255,0,0)); //red
HBRUSH Ctest7Dlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{ return (HBRUSH)brushDlg;}BOOL Ctest7Dlg::OnEraseBkgnd(CDC* pDC)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值 RECT rect;
GetClientRect(&rect); pDC->FillSolidRect(&rect,RGB(0,255,0)); //green
return FALSE; //return CDialog::OnEraseBkgnd(pDC);
}
运行后,效果为: 界面为绿色。      不是红色。修改Ctest7Dlg::OnEraseBkgnd的返回值为true,   后, 效果依然为:绿色。除了编辑框依然是红色。难道老外说错了吗?

解决方案 »

  1.   

    什么老外,这种标题一看就估计是什么the old new thing,那个人看名字就是华人
      

  2.   

    在SDK程序中系统对 对话框注册的 窗口函数 对WM_ERASEBKGND的处理是如此,如果你提供的对话框过程函数处理了消息却返回FALSE,还是会进行默认处理,WM_ERASEBKGND的默认处理就是SendMessage(WM_CTLCOLOR_DLG)但是在MFC中不一样,所有通过MFC子类化生成的窗口函数的代码逻辑就是在消息映射表中找消息处理映射,如果你定义了映射,无论TRUE FALSE返回,均不调用 原窗口处理函数所以你这里对WM_ERASEBKGND的处理不会调用对话框原窗口处理函数,也不会触发SendMessage(WM_CTLCOLOR_DLG)
      

  3.   


    牛逼,你用mfc, sdk多少年了,这些背后的原理,msdn,和一般的书籍应该没有介绍吧。自悟的?
      

  4.   


    在这里补充一下自己的经验, 不对的,请跟正:子类化控件的wm_erasebkgnd或者wm_paint后,  父对话框中的
    wm_ctlcoloredit ,wm_ctlcolorbtn之类则失效.
      

  5.   

    有关这个问题我最近也遇到了,不过仔细阅读类MSDN貌似有些概念了,希望大神勿喷WM_ERASEBKGND,没有啥悬念,重绘背景而已。
    WM_CTLCOLOR即,对应MFC中ON_WM_CTLCOLOR(),这个用来填充子控件的背景色,也就是说要改变子窗口(控件)的背景色,要依赖父窗口的OnCtrColor中设置。MFC后来又提供了一个消息反射机制(参考MSDN中TN062: Message Reflection for Windows Controls):
    即,在子窗口(控件)中用ON_WM_CTLCOLOR_REFLECT()消息映射宏,并在自己的消息响应函数afx_msg HBRUSH CtlColor ( CDC*pDC , UINTnCtlColor )中就可以修改自己的背景色了。同时,如果子窗口(控件)中使用了ON_WM_CTLCOLOR_REFLECT()或者ON_WM_ERASEBKGND(),那么父窗口中的ON_WM_CTLCOLOR()对子窗口(控件)再无影响,且子窗口(控件)中,ON_WM_ERASEBKGND()会优先于ON_WM_CTLCOLOR_REFLECT(),也就是说ON_WM_CTLCOLOR_REFLECT()用来设置控件颜色,而ON_WM_ERASEBKGND()用来重绘背景,所以自然ON_WM_ERASEBKGND()才是最终结果。
      

  6.   

    对于子控件,是先wm_paint ,然后wm_erasebkgnd,  然后wm_paint, 然后进入父窗口的wm_ctlcolor里,所以决定 子类化一个控件,比如edit。 wm_ctlcolor恐怕影响的仅仅是背景颜,前景色。文字颜色。时间久了,有的我记不清了,你可以实验验证。
      

  7.   

    HBRUSH CMyTestPrj2View::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
    {
    ////HBRUSH hbr = CView::OnCtlColor(pDC, pWnd, nCtlColor); // TODO:  在此更改 DC 的任何属性
    // TODO:  如果默认的不是所需画笔,则返回另一个画笔
    pDC->SetBkMode(TRANSPARENT);
    pDC->SetTextColor(RGB(255,200,200));
    HBRUSH hbr=CreateSolidBrush(155);
    return hbr;
    }BOOL CMyTestPrj2View::OnEraseBkgnd(CDC* pDC)
    {
    // TODO: 在此添加消息处理程序代码和/或调用默认值
    //return CView::OnEraseBkgnd(pDC); CBrush br;
    br.CreateSolidBrush(RGB(100,200,120));
    //pDC->SelectObject(hbr);
    RECT r;
    GetClientRect(&r);
    pDC->FillRect(&r,&br); return TRUE;
    }工作的很正常
      

  8.   

    OnEraseBkgnd要返回true否则系统又帮你重绘背景