不可否认,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);