mfc关于CButtonST按钮设置不可用时 EnableWindow(FALSE) 按键图标的问题

时间:2022-09-05 23:14:23

不可否认,CButtonST是一个十分强大的类,在应用时,十分方便,但是我最近遇到了一个很大的问题,就是设置按钮不可用时,按钮就变为一个灰框,怎么办呢,有人的解决办法是:

参考网址:http://dev.csdn.net/htmls/66/66766.html

1、在资源编辑的时候选中按钮的Owner  draw即可,不需要选择Bitmap属性!  
2、在程序中定义一个CBitmapButton成员变量。不能使用ClassWizard为按钮映射一个CButton变量,然后改为CBitmapButton,这么做并不能将按钮直接映射为CBitmapButton类的对象,反而会出现初始化错误。  
3-1、使用CBitmapButton::LoadBitmaps装载各种状态的图片,使用SubclassDlgItem关联到想要的按钮,使用CBitmapButton::SizeToContent函数使按钮适合图片大小。。注意Loadbitmaps一定要在关联到按钮之前进行!  

按照上面的注意事项做如下操作即可
CBitmapButton m_syncbtn;

m_syncbtn.LoadBitmaps(IDB_DOWNLOAD_ALL_GRAY, 0, 0, 0);
m_syncbtn.SubclassDlgItem(IDC_BUTTON_DOWNALL, this);
m_syncbtn.SizeToContent();
m_syncbtn.EnableWindow(FALSE);

m_syncbtn.LoadBitmaps(IDB_DOWNLOAD_ALL_COLOR, 0, 0, 0);
m_syncbtn.EnableWindow(TRUE);

 

这样的确很容易做到,但是这就违背了我们最初想使用CButtonST的初衷,参考http://bbs.csdn.net/topics/320232857,我做了如下尝试,对BtnST.cpp中的代码DrawTheBitmap函数,做简单的修改,如下:

void CButtonST::DrawTheBitmap(CDC* pDC, BOOL bHasTitle, RECT* rpItem, CRect* rpCaption, BOOL bIsPressed, BOOL bIsDisabled)
{
 HDC   hdcBmpMem = NULL;
 HBITMAP  hbmOldBmp = NULL;
 HDC   hdcMem  = NULL;
 HBITMAP  hbmT  = NULL;

 BYTE  byIndex  = 0;

 // Select the bitmap to use
 if ((m_bIsCheckBox && bIsPressed) || (!m_bIsCheckBox && (bIsPressed || m_bMouseOnButton)))
  byIndex = 0;
 else
  byIndex = (m_csBitmaps[1].hBitmap == NULL ? 0 : 1);

 CRect rImage;
 PrepareImageRect(bHasTitle, rpItem, rpCaption, bIsPressed, m_csBitmaps[byIndex].dwWidth, m_csBitmaps[byIndex].dwHeight, &rImage);

 hdcBmpMem = ::CreateCompatibleDC(pDC->m_hDC);

 hbmOldBmp = (HBITMAP)::SelectObject(hdcBmpMem, m_csBitmaps[byIndex].hBitmap);

 hdcMem = ::CreateCompatibleDC(NULL);

 hbmT = (HBITMAP)::SelectObject(hdcMem, m_csBitmaps[byIndex].hMask);

 //if (bIsDisabled && m_bShowDisabledBitmap)
 //{
 // HDC  hDC = NULL;
 // HBITMAP hBitmap = NULL;

 // hDC = ::CreateCompatibleDC(pDC->m_hDC);
 // hBitmap = ::CreateCompatibleBitmap(pDC->m_hDC, m_csBitmaps[byIndex].dwWidth, m_csBitmaps[byIndex].dwHeight);
 // HBITMAP hOldBmp2 = (HBITMAP)::SelectObject(hDC, hBitmap);

 // RECT rRect;
 // rRect.left = 0;
 // rRect.top = 0;
 // rRect.right = rImage.right + 1;
 // rRect.bottom = rImage.bottom + 1;
 // ::FillRect(hDC, &rRect, (HBRUSH)RGB(255, 255, 255));

 // COLORREF crOldColor = ::SetBkColor(hDC, RGB(255,255,255));

 // ::BitBlt(hDC, 0, 0, m_csBitmaps[byIndex].dwWidth, m_csBitmaps[byIndex].dwHeight, hdcMem, 0, 0, SRCAND);
 // ::BitBlt(hDC, 0, 0, m_csBitmaps[byIndex].dwWidth, m_csBitmaps[byIndex].dwHeight, hdcBmpMem, 0, 0, SRCPAINT);

 // ::SetBkColor(hDC, crOldColor);
 // ::SelectObject(hDC, hOldBmp2);
 // ::DeleteDC(hDC);

 // pDC->DrawState( CPoint(rImage.left/*+1*/, rImage.top),
 //     CSize(m_csBitmaps[byIndex].dwWidth, m_csBitmaps[byIndex].dwHeight),
 //     hBitmap, DST_BITMAP | DSS_DISABLED);

 // ::DeleteObject(hBitmap);
 //} // if
 //else
 //{

 ::BitBlt(pDC->m_hDC, rImage.left, rImage.top, m_csBitmaps[byIndex].dwWidth, m_csBitmaps[byIndex].dwHeight, hdcMem, 0, 0, SRCAND);

 ::BitBlt(pDC->m_hDC, rImage.left, rImage.top, m_csBitmaps[byIndex].dwWidth, m_csBitmaps[byIndex].dwHeight, hdcBmpMem, 0, 0, SRCPAINT);
 //} // else

 ::SelectObject(hdcMem, hbmT);
 ::DeleteDC(hdcMem);

 ::SelectObject(hdcBmpMem, hbmOldBmp);
 ::DeleteDC(hdcBmpMem);
} // End of DrawTheBitmap

 

我对红色加粗部分的代码,进行了注释,这样在按钮不可用时,它就不会更改现有的图标,如果你希望在不可用时,换一种图标,你只要在置为不可用之前,先设置一下即可

CButtonST m_btnObjStatistics;

m_btnObjStatistics.SetBitmaps(IDB_BMP_OBJSTATISTICS1,RGB(255,255,255));    //设置按钮不可用时的图片
 m_btnObjStatistics.EnableWindow(FALSE);

当然,这样你在置为可用时,也要重新设置可用时图标

m_btnObjStatistics.SetBitmaps(IDB_BMP_OBJSTATISTICS,RGB(255,255,255));    //设置按钮不可用时的图片
 m_btnObjStatistics.EnableWindow(TRUE);