如何在VC中改变控件的背景色

时间:2023-01-30 14:49:27

转载自《电脑报》   (文/欧阳沐)  
   
  提要:  
   
    在VC编程中要改变控件(诸如CView,   CFrameWnd,   or   CWnd等)的背景色可通过处理特定的消息来实现。但如果想改变按钮的颜色,就只能使用自绘制的按钮(也可以用位图按钮,此处未做说明)而不能通过OnCtlColor()改变。  
   
   
  正文:  
   
    一、在一个MFC应用程序中,要改变控件的背景色可通过重载OnCtlColor()函数来实现。方法是在该函数中设置所需颜色后再返回一个画刷句柄便可重绘控件背景色。OnCtlColor()函数对于控件背景色的处理是通过捕捉相应的控件消息来实现的。常用的此类消息有:  
   
  CTLCOLOR_DLG   对话框    
   
  CTLCOLOR_EDIT   编辑框  
   
  CTLCOLOR_LISTBOX   列表框    
   
  CTLCOLOR_MSGBOX   消息框  
   
  CTLCOLOR_SCROLLBAR   滑动条  
   
  CTLCOLOR_STATIC   静态文本框、矩形等。  
   
   
  以下示例代码说明如何更改以上控件的背景色:  
   
  //CmyDialog.h定义    
   
  class   CMyDialog   :   public   Cdialog   //派生自己的对话框类  
   
  {  
   
  ……..  
   
  //   Implementation    
   
  protected:    
   
  //   Generated   message   map   functions  
   
  //{{AFX_MSG(CMyDialog)  
   
  afx_msg   HBRUSH   OnCtlColor(CDC*   pDC,   CWnd*   pWnd,   UINT   nCtlColor);  
   
  …….    
   
  //}}AFX_MSG  
   
  DECLARE_MESSAGE_MAP()    
   
  };  
   
   
  //CmyDialog.cpp   定义  
   
  ……  
   
  HBRUSH   CMyDialog::OnCtlColor(CDC*   pDC,   CWnd*   pWnd,   UINT   nCtlColor)    
   
  {  
   
  switch   (nCtlColor)   {    
   
  case   CTLCOLOR_EDIT:  
   
  case   CTLCOLOR_MSGBOX:  
   
  case   CTLCOLOR_DLG   :    
   
  case   CTLCOLOR_EDIT   :   //在此加入你想要改变背景色的控件消息  
   
  pDC->SetBkMode(TRANSPARENT);  
   
  HBRUSH   B   =   CreateSolidBrush(COLOR);   //COLOR是你想设置的颜色    
   
  return   (HBRUSH)   B;  
   
  default:   //其他控件设置自己默认的颜色和背景刷.  
   
  return   CDialog::OnCtlColor(pDC,   pWnd,   nCtlColor);    
   
  }}  
   
  说明:1、可分别处理以上消息以实现不同控件不同背景色。  
   
  2、此方法不适用于按纽控件。  
   
   
  二、通过定制来实现不同颜色按纽。  
   
  以下通过定制方形彩色按纽来说明:    
   
  第一步:派生出自己的按纽类。  
   
  //CcolorButton.h    
   
  class   CColorButton   :   public   CButton  
   
  {  
   
  DECLARE_DYNAMIC(CColorButton)  
   
  public:  
   
  CColorButton();    
   
  virtual   ~CColorButton();    
   
   
  BOOL   Attach(const   UINT   nID,   CWnd*   pParent,    
   
  const   COLORREF   BGColor   =   RGB(192,   123,   192),   //   按纽的背景色  
   
  const   COLORREF   FGColor   =   RGB(1,   1,   1),   //   文本颜色  
   
  );  
   
  protected:  
   
  virtual   void   DrawItem(LPDRAWITEMSTRUCT   lpDIS);   //重定义虚拟函数DrawItem  
   
  void   DrawFrame(CDC   *DC,   CRect   R);   //绘制按纽框  
   
  void   DrawFilledRect(CDC   *DC,   CRect   R,   COLORREF   color);   //填充按纽框  
   
  void   DrawLine(CDC   *DC,   CRect   EndPoints,   COLORREF   color);    
   
  void   DrawLine(CDC   *DC,   long   left,   long   top,   long   right,   long   bottom,   COLORREF   color);  
   
  void   DrawButtonText(CDC   *DC,   CRect   R,   const   char   *Buf,   COLORREF   TextColor);  
   
  //绘制按纽上的文本  
   
   
  COLORREF   GetFGColor()   {   return   m_fg;   }    
   
  COLORREF   GetBGColor()   {   return   m_bg;   }  
   
  private:  
   
  COLORREF   m_fg,   m_bg;  
   
  };  
   
  #endif  
   
   
  第二步:定义各函数  
   
  //CcolorButton.cpp  
   
  ……  
   
  //   CColorButton  
   
  IMPLEMENT_DYNAMIC(CColorButton,   CButton)  
   
  CColorButton::CColorButton()    
   
  {   }    
   
  CColorButton::~CColorButton()  
   
  {  
   
  }    
   
   
  //定义Attach()函数  
   
  BOOL   CColorButton::Attach(const   UINT   nID,   CWnd*   pParent,   const   COLORREF   BGColor,   const   COLORREF   FGColor)  
   
  {  
   
  if   (!SubclassDlgItem(nID,   pParent))  
   
  return   FALSE;  
   
  m_fg   =   FGColor;  
   
  m_bg   =   BGColor;    
   
  return   TRUE;  
   
  }  
   
   
  //重载DrawItem()  
   
  void   CColorButton::DrawItem(LPDRAWITEMSTRUCT   lpDIS)  
   
  {  
   
  CDC*   pDC   =   CDC::FromHandle(lpDIS->hDC);  
   
  UINT   state   =   lpDIS->itemState;    
   
  CRect   focusRect,   btnRect;  
   
  focusRect.CopyRect(&lpDIS->rcItem);   //按纽的选中虚线框  
   
  btnRect.CopyRect(&lpDIS->rcItem);    
   
   
  //   设置表示按纽被选中的虚线框  
   
  focusRect.left   +=   4;  
   
  focusRect.right   -=   4;  
   
  focusRect.top   +=   4;  
   
  focusRect.bottom   -=   4;  
   
   
  //   按纽标题  
   
  const   int   bufSize   =   512;  
   
  TCHAR   buffer[bufSize];  
   
  GetWindowText(buffer,   bufSize);  
   
   
  //   绘制并标志按纽    
   
  DrawFilledRect(pDC,   btnRect,   GetBGColor());    
   
  DrawFrame(pDC,   btnRect);  
   
  DrawButtonText(pDC,   btnRect,   buffer,   GetFGColor());  
   
   
  //   如果按纽处于选中状态则在其上绘制选中虚线框  
   
  if   (state   &   ODS_FOCUS)   {  
   
  DrawFocusRect(lpDIS->hDC,   (LPRECT)&focusRect);  
   
  }  
   
  }  
   
  void   CColorButton::DrawFrame(CDC   *DC,   CRect   R)  
   
  {   //绘制按纽,用户通过定制该函数可实现不同形状的按纽。  
   
  DrawLine(DC,   R.left,   R.top,   R.right,   R.top,   RGB(255,   255,   255));    
   
  DrawLine(DC,   R.left,   R.top,   R.left,   R.bottom,   RGB(255,   255,   255));    
   
  //以下绘制按纽的外围框线以使按纽有立体感  
   
  DrawLine(DC,   R.left   +   1,   R.bottom   -   1,   R.right,   R.bottom   -   1,   RGB(1,   1,   1));  
   
  //绘制按纽左框线和上框线  
   
  DrawLine(DC,   R.right   -   1,   R.top   +   1,   R.right   -   1,   R.bottom,   RGB(1,   1,   1));  
   
  //绘制按纽右框线和下框线    
   
  }  
   
  //用色彩填充按纽框  
   
  void   CColorButton::DrawFilledRect(CDC   *DC,   CRect   R,   COLORREF   color)  
   
  {    
   
  CBrush   B;  
   
  B.CreateSolidBrush(color);  
   
  DC->FillRect(R,   &B);  
   
  }  
   
  //   DrawLine用于绘制按纽,其为多态函数  
   
  void   CColorButton::DrawLine(CDC   *DC,   CRect   EndPoints,   COLORREF   color)  
   
  {    
   
  ……  
   
  }  
   
  void   CColorButton::DrawLine(CDC   *DC,   long   left,   long   top,   long   right,   long   bottom,   COLORREF   color)  
   
  {    
   
  ……  
   
  }  
   
  //绘制按纽文本  
   
  void   CColorButton::DrawButtonText(CDC   *DC,   CRect   R,   const   char   *Buf,   COLORREF   TextColor)  
   
  {  
   
  COLORREF   prevColor   =   DC->SetTextColor(TextColor);  
   
  DC->SetBkMode(TRANSPARENT);  
   
  DC->DrawText(Buf,   strlen(Buf),   R,   DT_CENTER|DT_VCENTER|DT_SINGLELINE);  
   
  DC->SetTextColor(prevColor);  
   
  }  
   
   
  第三步:引用定制类  
   
  定制任意对话框CColorDlg,在其上画一按键控件。ID为IDOK。  
   
  //CColorDlg.h  
   
  class   CColorDlg   :   public   CDialog  
   
  {  
   
  …..  
   
  //   Implementation  
   
  protected:  
   
  CColorButton   m_btnOK;  
   
  }  
   
   
  //CColorDlg.cpp  
   
  …….  
   
  BOOL   CColorBtnSampleDlg::OnInitDialog()  
   
  {  
   
  CDialog::OnInitDialog();  
   
  …….  
   
  VERIFY(m_btnOK.Attach(IDOK,   this,   RED,   BLUE,   YELLOW));  
   
  …….  
   
  }  
   
  ……