孟学桢
一般情况下,VC中的对话框及控件的颜色大都是灰色的,但一个良好的应用程序,它的界面都是丰富多彩的,那么在VC中怎样实现窗体及控件的着色呢? 改变窗体的颜色 要改变一个对话框的背景色,可以调用CWin::SetDialogBkColor,它可以改变所有的对话框的颜色。第一参数指定了背景颜色,第二参数指定了文本颜色。 用法如下: BOOL CSampleApp::InitInstance() { ... //set yellow dialog and green text SetDialogBkColor(RGB(255,255,0),RGB(0,255,0)); ... } 需要重画对话框(或对话框的子控件)时,Windows向对话框发送消息WM—CTLCOLOR。通常用户可以让Windows选择绘画背景的刷子,也可以重置该消息指定刷子。下面的说明创建了一个红色背景对话框的步骤。 首先,给对话框基类增加一个成员变量。 class CMyFormView::public CFormView { ... private: CBrush m—brush ; //background brush ... }; 其次,在类的构造函数中将刷子初始化为所需的背景颜色。 CMyFormView::CMyFormView() { // Initialize background brush m—brush.CreateSolidBrush(RGB(255,0,0)); } 最后,使用ClassWizard处理WM—CTLCOLOR消息并返回一个用来绘画对话框背景的刷子句柄。由于重画对话框控件时也要调用该函数,所以要检测nCtlColor参量。 HBRUSH CMyFormView::OnCtlColor() { //determine if drawing a dialog box, //otherwise let windows handle it if(nCtlColor==CTLCOLOR—DLG) return (HBRUSH) m—brush.GetSafeHandle(); return CFormView::OnCtlColor(pDC,pWnd,nCtlColor); } 改变控件的颜色 需要改变控件的颜色,可以通过两种方法,其一,可以在父类中指定控件的颜色。其二,利用消息反射在控件类中指定颜色。 当控件需要重新着色时,工作框调用父窗口(通常是对话框)的CWnd::OnCtlColor,可以在父窗口类中重置该函数并指定新的绘画属性。 如下所示,将对话框中的编辑控件的文本颜色改为蓝色。 HBRUSH CMyDialog::OnCtlColor(CDC* pDC,CWnd* pWnd,UINT nCtlColor) { HBRUSH hbr=CDialog::OnCtlColor(pDC,pWnd,nCtlColor); //Draw blue text for edit controls if(nCtlColor==CLTCOLOR—EDIT) pDC->SetTextColor(RGB(0,0,255)); return hbr; } 由于每个窗口必须处理通知消息并指定每个控件的绘画属性,所以,这种方法不是完全的面向对象的方法,控件处理该消息并指定绘画属性更合理一些。 消息反射允许用户这样做,通知消息发给父窗口,若父窗口没有处理则发给控件,创建一个定制彩色列表框控件,其步骤如下。 首先用ClassWizard创建一个CListBox的派生类,并添加如下的成员变量。 class CMyListBox::public CListBox { ... private : COLORREF m—clrFore; //foreground color COLORREF m—clrBack; //background color CBrush m—brush ; //background brush ... }; 其二,在类的构造函数中初始化数据成员。 CMyListBox::CMyListBox() { //Initialize data members m—clrfore=RGB(255,0,0); //red text m—clrBack=RGB(0,255,0); //green background m—brush.CreateSolidBrush(m—clrBack); } 第三,使用ClassWizard处理反射消息(=WM—CTLCOLOR)并指定新的绘画属性。 HBRUSH CMyListBox::CtlColor(CDC* pDC,UINT nCtlColor) { pDC->SetTextColor(m—clrFore); pDC->SetBkColor(m—clrBack); return (HBRUSH)m—brush.GetSafeHandle(); } 现在控件可以重画自身,与父窗口无关。 最后,在父窗口头文件中包含派生的CMyListBox类,然后用ClassWizard 定义列表框控件的成员变量即可。其成员变量的类性为CMyListBox。 这样我