1.给对话框加背景色
当Windows系统需要重画某个窗口客户区的背景的时候,就会向该窗口发送WM_ERASEBKGND 消息,窗口的处理过程响应这个消息重新画窗口的背景。改变对话框的背景颜色的原理很简单,就是响应这个消息,用自定义的颜色填充对话框的客户区背景,代替对话框窗口默认的背景填充动作。
因此给对话框加背景色只需要响应WM_ERASEBKGND就可以了.如下:
{
CRect clientRect;
GetClientRect(&clientRect);
pDC->FillRect(&clientRect, &m_backgroundBrush);
return TRUE;
//return CDialog::OnEraseBkgnd(pDC);
}
m_backgroundBrush是个CBrush对象,在InitDialog中就初始化好了的.
但是仅给对话框加了背景还不行.控件的背景还是灰色.像有些桌面图标下面的字没开阴影的那种效果.很丑很丑..
因此还要给控件加上背景才行
2.给控件加背景色
这里要该响应WM_CTLCOLOR消息了.同时涉及到一个"消息反射"的概念.
WM_CTLCOLOR是Windows的控件向其父窗口发送最频繁的通知消息之一,例如,许多控件发送WM_CTLCOLOR消息给父窗口,让父窗口提供画刷来画自己的背景.MFC的窗口类对这个通知消息特殊对待.如果父窗口没有处理这个通知消息,MFC的窗口类就根据WM_CTLCOLOR通知消息的来源将这个WM_CTLCOLOR消息发送回控件,让控件自己处理,这就是所谓的"消息反射".不仅是WM_CTLCOLOR,MFC对很多通知消息都做了反射.
因此我们只要在收到控件的WM_CTLCOLOR消息时准备好相应的画刷返回了就可以了.
{
HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
pDC->SetTextColor(RGB(0,0,0)); //设置字体前景色为黑色
pDC->SetBkMode(TRANSPARENT); //设置字体背景色为透明
return (HBRUSH)m_backgroundBrush; //因为CBrush类实现了HBRUSH类型转换操作符
//return hbr;
}
hbr是默认的画刷.灰色或者白色背景的那种,所以我们要返回自己定义好背景色的画刷.
如果要对不同类型的控件设置不同的颜色可以根据nCtlColor的值来确定.nCtlColor的取值有:
CTLCOLOR_BTN Button control
CTLCOLOR_DLG Dialog box
CTLCOLOR_EDIT Edit control
CTLCOLOR_LISTBOX List-box control
CTLCOLOR_MSGBOX Message box
CTLCOLOR_SCROLLBAR Scroll-bar control
CTLCOLOR_STATIC Static control
也可以用pWnd->GetDlgCtrlID()取得控件ID号来对单个控件进行设置.
对于多行的edit.如果用了pDC->SetBkColor.而设的颜色又与返回的画刷颜色不一致的话就会出现下面的情况..
有字的地方是一种背景色.没字的那几行又是一种颜色.
因此可以再多准备一个CBrush对象.专门用来保存edit的背景色.用来在OnCtlColor中返回给edit
但是这样又会出现新问题,很多时候edit没有刷新,字符重叠在一起(比如显示超过一屏的内容),按下退格键时删掉的字符也没有消失.很麻烦啊..
解决方法还是只有由CEit派生出一个类.重载里面的OnEraseBkgnd,OnGetDlgCode,OnMouseMove等消息函数.详细的去下面两个帖子看吧:
关于CEdit控件的透明 如何在EDITBOX控件中使用背景位图
如果要派生CEdit的话也好可以好好利用下WM_CTLCOLOR的消息反射.
在子类中响应WM_CTLCOLOR消息.这样就可以不用在父窗口里面设置控件的颜色了.更利于封装吧
但是控件中的滚动条始终顽固地保持着它一贯的灰色.要解决的方法...不知道.
3.背景图片
大概就是好好改造那些个CBrush对象吧.我没试,就不写了
看到段话,先堆这吧..
使用位图作为对话框的背景也很简单,就是在OnEraseBkgnd中用位图填充客户区,只是在OnCtlColor中需要注意返回空画刷代替原来的画刷,返回空画刷是为了阻止控件绘制自己的背景,从而破坏位图背景的完整性,但是有时候返回空画刷会对其他控件产生不良影响.