假设你已有了名为My的对话框工程.你有了两个STATIC的控件

IDC_STATIC1和IDC_STATIC2、两个按钮控件

IDC_BUTTON1和IDC_BUTTON2。此函数简单实用见实例1:

HBRUSH

CMyDlg

::

OnCtlColor

(

CDC

*

pDC

,

CWnd

*

pWnd

,

UINT nCtlColor

)

{

HBRUSH hbr

=

CDialog

::

OnCtlColor

(

pDC

,

pWnd

,

nCtlColor

);

// TODO: Change any attributes of the DC here

if (nCtlColor==CTLCOLOR_STATIC)//如果当前控件属于静态文本

{

pDC-> SetTextColor(RGB(255,0,0)); //字体颜色

//pDC->SetBkMode(TRANSPARENT); //设置字体背景为透明

pDC-> SetBkColor(RGB(0, 0, 255)); //字体背景色

}

else if (nCtlColor==CTLCOLOR_BTN) //如果当前控件属于按钮

{

pDC-> SetTextColor(RGB(255,0,0)); //字体颜色

//pDC->SetBkMode(TRANSPARENT);

//设置字体背景为透明

pDC-> SetBkColor(RGB(0, 0, 255)); //字体背景色

}

// TODO: Return a different brush if the default is not desired

return hbr;

}

这样

IDC_STATIC1、IDC_STATIC2

IDC_BUTTON1和IDC_BUTTON2都被设置了红色字体、字体背景为l蓝色,显示效果如下所示:

这是IDC_STATIC1的显示效果。

注意:必须搞清楚

字体背景和

空间背景区别。如图中蓝色部分是字体的背景,而蓝色+白色才是次STATIC控件的背景区域。而

SetBkColor和SetBkMode是针对字体背景做修改的,

所以SetBkColor和SetBkMode是不能同时使用的,原因很简单:既然已经设置为字体背景透明,又怎么能再设置字体背景颜色呢?

一下是SetBkMode函数的使用案例,实例2:

HBRUSH CMyDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)

{

HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);

// TODO: Change any attributes of the DC here

if (nCtlColor==CTLCOLOR_STATIC)//如果当前控件属于静态文本

{

pDC-> SetTextColor(RGB(255,0,0)); //字体颜色

pDC->SetBkMode(TRANSPARENT); //设置字体背景为透明

//pDC-> SetBkColor(RGB(0, 0, 255)); //字体背景色

}

else if (nCtlColor==CTLCOLOR_BTN) //如果当前控件属于按钮

{

pDC-> SetTextColor(RGB(255,0,0)); //字体颜色

pDC->SetBkMode(TRANSPARENT); //设置字体背景为透明

//pDC-> SetBkColor(RGB(0, 0, 255)); //字体背景色

}

// TODO: Return a different brush if the default is not desired

return hbr;

}

其效果为:

可见只是将字体的背景变成了透明。要想实现相对对话框的背景透明就需要再OnCtlColor返回时返回一个透明画刷(也即空画刷)

,见

实例3:

HBRUSH CMyDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)

{

HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);

// TODO: Change any attributes of the DC here

if (nCtlColor==CTLCOLOR_STATIC)//如果当前控件属于静态文本

{

return (HBRUSH)GetStockObject(NULL_BRUSH);

}

else if (nCtlColor==CTLCOLOR_BTN) //如果当前控件属于按钮

{

return (HBRUSH)GetStockObject(NULL_BRUSH);

}

// TODO: Return a different brush if the default is not desired

return hbr;

}

效果为:

这个应该就是我们想要的效果了!

以上只是针对静态文本框的,看起来貌似很容易实现预期效果,但是对于按钮,其字体和字体背景的修改和静态文本框如出一辙,但在按照以上方式修改按钮背景时却碰到了麻烦。例如,我们打算使用以下方式修改所有按钮(IDC_BUTTON1和IDC_BUTTON2)的背景颜色(注意不是字体的背景),实例4:

HBRUSH CMyDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)

{

HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);

// TODO: Change any attributes of the DC here

else if (nCtlColor==CTLCOLOR_BTN) //如果当前控件属于按钮

{

CBrush m_bkBrush; //准备一把主窗口背景刷子

m_bkBrush.CreateSolidBrush(RGB(0xff,0x00,0x00)); //创建一把黄色的背景刷子

return m_bkBrush; //返回刚才创建的背景刷子

}

// TODO: Return a different brush if the default is not desired

return hbr;

}

这样不能实现修改按钮背景的效果。因为,我们定义的是局部的

m_bkBrush,这样在函数OnCtlColor返回时

m_bkBrush就会被销毁释放掉,所以我们需要定义全局的

m_bkBrush或将

m_bkBrush定义成

CMyDlg的成员变量。此外必须设置按钮的

OwnerDraw属性为TRUE!不然按钮的背景不会被修改。

此处我们将

m_bkBrush定义成

CMyDlg的成员变量,并把按钮的

OwnerDraw属性为TRUE,

然后运行之后效果(IDC_BUTTON1):

这效果貌似让我们大失所望,原本按钮上的

字都没了,

而且还不能按下去了,不然会报错

!!后来查了资料发现,这样修改按钮的背景时是会清空掉按钮上的文本。其实很多时候使用MFC是都会碰到类似的问题,明明思路都是对的,却就是不能实现,现在越来越发现MFC不好用了,不光很多小功能(就像我们这里简单的实现按钮背景修改)实现起来很复杂,而且实现的效果也和你一般,根本谈不上美观!有机会还是去玩Qt或Delphi。

为了解决这个问题找了很多资料都难以实现,在网上找的方法基本上都不管用,还说得跟真的一样,各种OnCtrlColor()和OnEraseBkground(),看了各种技术帝的方法看起来都很厉害,但是都不管用(真的很怀疑自己有没有做过,不过在中国本来就是技术帖子一大抄,只能忍了,参考而已嘛)。

到最后发现,

真正有用的办法是

自定义button类才能实现按钮颜色(自己实现了),即

重载按钮类比较方便,重载后子类中SetBkColor就可以了

。但是这个办法不免有些复杂,我不是勤快的人,这种方式适合只修改少量按钮背景的情况下使用,多以大量修改按钮背景的情况下就不推荐大家使用了,在这里也就不想往上写了(想了解此方法可参:考

http://blog.csdn.net/liangzhonglin/article/details/3260349

)。所以只能另辟蹊径了,介绍给大家一个很简单的方法 - 使用

CMFCButton类便可以轻松实现这种功能

。详细

CMFCButton类

使用方法请参考

《BUTTON - CMFCButton》

------------------------------------------------------------------------------------------

以上那个都是针对某一类控件的整体设置,加入我只想设置IDC_STATIC1而不想改变IDC_STATIC2该怎么办呢?其实只要改变switch中的参数即可:

HBRUSH CDSCAMDEMODlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)

{

HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);

// TODO: Change any attributes of the DC here

//对特定的控件做修改

switch (pWnd->GetDlgCtrlID())

{

case IDC_STATIC1:

pDC->SetTextColor(RGB(0,0,0)); //设置字体颜色

pDC->SetBkColor(RGB(0,0,0)); //设置字体背景颜色

break;

case IDC_STATIC2://此段可忽略

break;

default:

break;

}

}