BUTTONG这个按钮比较特殊。想在按下按钮时改变其背景颜色,同时按钮的文字还要显示。试了很多方法,ctlcolor肯定是不行的,因此这种方法就不要提了;单纯的加载图片背景也不行(因为文字没有了)。查了一下,比较常用的方法是CButton的派生类。以下是实例代码,从CSDN上转载来的(感谢原作者),但是调试有错误,麻烦大家给看看,问题出在哪儿。需要的结果是按下按钮时改变按钮背景颜色,仅要这个功能就行了,所以代码要尽可能简单。
在Windows中Edit,StaticBox的背景色都可以通过处理WM_CTLCOLOR消息来改变,但Push Button却不行。唯一的方法是使用OwnerDraw风格的按钮。本文讲述的方法是使用CButton的派生类。
class CCButton : public CButton
{
DECLARE_DYNAMIC(CCButton)
public:
    CCButton(); 
    virtual ~CCButton(); 
    BOOL CCButton::Attach(const UINT nID, CWnd* pParent)protected:
    virtual void DrawItem(LPDRAWITEMSTRUCT lpDIS);//必需重载的函数public:
    COLORREF m_fg, m_bg, m_disabled_fg, m_disabled_bg;//四种颜色分别为文字,背景,失效时文字,失效时背景
};
实现DrawItemvoid CCButton::DrawItem(LPDRAWITEMSTRUCT lpDIS)
{
    CDC* pDC = CDC::FromHandle(lpDIS->hDC);//???????DC    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;    //
    // 得当Button上文字
    //
   const int bufSize = 512;
   TCHAR buffer[bufSize];
   GetWindowText(buffer, bufSize);
    
   // 使用m_fg, m_bg颜色利用 Draw3dRect(...)绘制按钮边框   // FillRect(...)填充按钮内部   // DrawText(...)绘制文字    //根据当前状态调整显示
    //
    if (state & ODS_FOCUS) {
        .........//得到输入焦点,通过focusRect画虚线
        if (state & ODS_SELECTED){ 
        .....// 被按下,绘制下陷边框
        }
    }
    else if (state & ODS_DISABLED) {
    //失效,通过m_disabled_fg, m_disabled_bg 重绘按钮内部
    }

CCButton是CButton派生类,具有CButton的全部成员函数,但在创建时需要使用BS_OWNERDRAW风格。如果按钮不是动态生成,使用Attach函数使CCButton代替原来按钮的窗口过程。BOOL CCButton::Attach(const UINT nID, CWnd* pParent)
{
    GetDlgItem(nID)->ModifyStyle(0,BS_OWNERDRAW,0);    if (!SubclassDlgItem(nID, pParent))
        return FALSE;    return TRUE;
} 如在一对话框的InitDialog(...)中加入下面几行{// 假定 m_cbBtn为成员变量 IDC_BUTTON1为一按钮ID值   m_cbBtn.Attach(IDC_BUTTON1,this);} 

解决方案 »

  1.   

    把button定义成一个CButton变量,然后在头文件里把CButton改为CCButton界面上的效果,基本就是派生类的效果了
      

  2.   

    "把button定义成一个CButton变量,然后在头文件里把CButton改为CCButton界面上的效果,基本就是派生类的效果了"
    1楼能说详细一点吗?
      

  3.   

    WM_LBUTTONDOWN里重绘不可以吗?贴两张图片,一张贴背景,
    一张为透明的BMP,写文字,
      

  4.   

    m_cbBtn.Attach(IDC_BUTTON1,this); 
    这一句报错,参数不对,“don't take 2 参数”
      

  5.   

        1.在头文件里添加, CCButton m_cbBtn,
        2.在BOOL CXXDlg::OnInitDialog()添加m_cbBtn.SubclassDlgItem(IDC_BUTTON1,this);
        3.重新运行就可以看到效果了
      
      

  6.   

    透明的BMP为内存位图,文字你自己画,就算变化也可以实现啊
      

  7.   

    又报这个错误,是什么原因?
    rror LNK2001: unresolved external symbol "public: virtual struct CRuntimeClass * __thiscall CCButton::GetRuntimeClass(void)const " (?GetRuntimeClass@CCButton@@UBEPAUCRuntimeClass@@XZ)
    Debug/1.exe : fatal error LNK1120: 1 unresolved externals
    Error executing link.exe.
      

  8.   

    BOOL CCButton::Attach(const UINT nID, CWnd* pParent)
    {
        GetDlgItem(nID)->ModifyStyle(0,BS_OWNERDRAW,0);

        if (!SubclassDlgItem(nID, pParent))
            return FALSE;

        return TRUE;

    这一段加在那个文件中?
      

  9.   

    DECLARE_MESSAGE_MAP和IMPLEMENT_DYNCREATE不匹配
      

  10.   

    那你自己直接SubclassDlgItem试试,不用那个Attach
      

  11.   

    干嘛要用那个CButton类,麻烦,还不如自己从CWnd派生一个类,然后自己画,想干嘛都成
    我自己有一个,要的话,留下邮箱,我发给你
      

  12.   

    有个WM_CTLCOLOR(可能是WM_CTLCOLORDLG)的消息,你看看。
      

  13.   

    CTLCOLOR唯独不能改变BUTTON的值!
    有一个XPBUTTONST,在VCKBASE上有,很简单很好用,肯定满足你需求!
    VCKBASE这个论坛也不错。