Bitmap Button 不可用的情况

时间:2022-08-26 12:42:23
根据CButtonST类写了一个可以加载Bitmap 、Icon的按钮

但是缺陷是设置Bitmap按钮为不可用的时候 

按钮就变成一个灰色框框 

想实现设置Bitmap按钮为不可用的时候 只是让Bitmap变为灰色 

这个怎么实现啊 

望高手赐教

PS:下面是CButtonST类中重画Bitmap的代码

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) //按钮为不可用的时候的处理代码 m_bShowDisabledBitmap为TRUE
{
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

6 个解决方案

#1


Bitmap Button 不可用的情况

#2


调整一下bmp灰度再贴上去按钮上吧

#3


引用 2 楼 nintendo_dskay 的回复:
调整一下bmp灰度再贴上去按钮上吧

赞成,在按钮废止时(其实未废止,仅仅是你不让其相应,方法是onclick加上返回),然后显示灰色的位图,然后就形成了那种变灰废止的效果

#4


设置为不可用后按钮应该还要重绘,不能用默认的重绘

#5


哇咔咔 自己解决啦 
说一下实现的思想 :就是2楼和3楼的,实现将彩色Bitmap转换成灰色Bitmap 
最后重绘灰度Bitmap

我很不HD的使用了CButtonST中的彩色Bitmap向灰度Bitmap转换的函数实现
下面是实现以后的代码 大家自己看看吧 

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;
  STRUCT_BITMAPS grayBitmap;
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);
  hdcMem = ::CreateCompatibleDC(NULL); 

  if (bIsDisabled && (NULL == m_csBitmaps[1].hBitmap))//创建灰色图像
  {
    grayBitmap.hBitmap = CreateGrayscaleBitmap(m_csBitmaps[0].hBitmap,       //Bitmap ID
                                               m_csBitmaps[0].dwWidth,
                                               m_csBitmaps[0].dwHeight,
                                               m_csBitmaps[0].crTransparent);
    grayBitmap.dwWidth = m_csBitmaps[0].dwWidth;
    grayBitmap.dwHeight = m_csBitmaps[0].dwHeight;
    grayBitmap.crTransparent = m_csBitmaps[0].crTransparent;
    grayBitmap.hMask = CreateBitmapMask( grayBitmap.hBitmap,
                                         grayBitmap.dwWidth,
                                         grayBitmap.dwHeight,
                                         grayBitmap.crTransparent);
    hbmOldBmp = (HBITMAP)::SelectObject(hdcBmpMem, grayBitmap.hBitmap);
    hbmT = (HBITMAP)::SelectObject(hdcMem, grayBitmap.hMask);
  }else
  {
  hbmOldBmp = (HBITMAP)::SelectObject(hdcBmpMem, m_csBitmaps[byIndex].hBitmap);
    hbmT = (HBITMAP)::SelectObject(hdcMem, m_csBitmaps[byIndex].hMask);
  }

if (bIsDisabled && m_bShowDisabledBitmap)     //button disabled
{
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);

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_NORMAL);

::DeleteObject(hBitmap);
} // if
else        //button abled
{
::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


特此结贴~~~~~ ^^

#6


厄 这个是CButtonSt中的将彩色Bitmap转换成灰度图的代码:

HBITMAP CButtonST::CreateGrayscaleBitmap(HBITMAP hBitmap, 
                                         DWORD dwWidth, 
                                         DWORD dwHeight, 
                                         COLORREF crTrans)
{
HBITMAP hGrayBitmap = NULL;
HDC hMainDC = NULL, hMemDC1 = NULL, hMemDC2 = NULL;
HBITMAP hOldBmp1 = NULL, hOldBmp2 = NULL;

hMainDC = ::GetDC(NULL);
if (hMainDC == NULL) return NULL;
hMemDC1 = ::CreateCompatibleDC(hMainDC);
if (hMemDC1 == NULL)
{
::ReleaseDC(NULL, hMainDC);
return NULL;
} // if
hMemDC2 = ::CreateCompatibleDC(hMainDC);
if (hMemDC2 == NULL)
{
::DeleteDC(hMemDC1);
::ReleaseDC(NULL, hMainDC);
return NULL;
} // if

hGrayBitmap = ::CreateCompatibleBitmap(hMainDC, dwWidth, dwHeight);
if (hGrayBitmap)
{
hOldBmp1 = (HBITMAP)::SelectObject(hMemDC1, hGrayBitmap);
hOldBmp2 = (HBITMAP)::SelectObject(hMemDC2, hBitmap);

//::BitBlt(hMemDC1, 0, 0, dwWidth, dwHeight, hMemDC2, 0, 0, SRCCOPY);

DWORD dwLoopY = 0, dwLoopX = 0;
COLORREF crPixel = 0;
BYTE byNewPixel = 0;

for (dwLoopY = 0; dwLoopY < dwHeight; dwLoopY++)
{
for (dwLoopX = 0; dwLoopX < dwWidth; dwLoopX++)
{
crPixel = ::GetPixel(hMemDC2, dwLoopX, dwLoopY);
byNewPixel = (BYTE)((GetRValue(crPixel) * 0.299) + (GetGValue(crPixel) * 0.587) + (GetBValue(crPixel) * 0.114));

if (crPixel != crTrans)
::SetPixel(hMemDC1, dwLoopX, dwLoopY, RGB(byNewPixel, byNewPixel, byNewPixel));
else
::SetPixel(hMemDC1, dwLoopX, dwLoopY, crPixel);
} // for
} // for

::SelectObject(hMemDC1, hOldBmp1);
::SelectObject(hMemDC2, hOldBmp2);
} // if

::DeleteDC(hMemDC1);
::DeleteDC(hMemDC2);
::ReleaseDC(NULL, hMainDC);

return hGrayBitmap;
} // End of CreateGrayscaleBitmap

#1


Bitmap Button 不可用的情况

#2


调整一下bmp灰度再贴上去按钮上吧

#3


引用 2 楼 nintendo_dskay 的回复:
调整一下bmp灰度再贴上去按钮上吧

赞成,在按钮废止时(其实未废止,仅仅是你不让其相应,方法是onclick加上返回),然后显示灰色的位图,然后就形成了那种变灰废止的效果

#4


设置为不可用后按钮应该还要重绘,不能用默认的重绘

#5


哇咔咔 自己解决啦 
说一下实现的思想 :就是2楼和3楼的,实现将彩色Bitmap转换成灰色Bitmap 
最后重绘灰度Bitmap

我很不HD的使用了CButtonST中的彩色Bitmap向灰度Bitmap转换的函数实现
下面是实现以后的代码 大家自己看看吧 

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;
  STRUCT_BITMAPS grayBitmap;
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);
  hdcMem = ::CreateCompatibleDC(NULL); 

  if (bIsDisabled && (NULL == m_csBitmaps[1].hBitmap))//创建灰色图像
  {
    grayBitmap.hBitmap = CreateGrayscaleBitmap(m_csBitmaps[0].hBitmap,       //Bitmap ID
                                               m_csBitmaps[0].dwWidth,
                                               m_csBitmaps[0].dwHeight,
                                               m_csBitmaps[0].crTransparent);
    grayBitmap.dwWidth = m_csBitmaps[0].dwWidth;
    grayBitmap.dwHeight = m_csBitmaps[0].dwHeight;
    grayBitmap.crTransparent = m_csBitmaps[0].crTransparent;
    grayBitmap.hMask = CreateBitmapMask( grayBitmap.hBitmap,
                                         grayBitmap.dwWidth,
                                         grayBitmap.dwHeight,
                                         grayBitmap.crTransparent);
    hbmOldBmp = (HBITMAP)::SelectObject(hdcBmpMem, grayBitmap.hBitmap);
    hbmT = (HBITMAP)::SelectObject(hdcMem, grayBitmap.hMask);
  }else
  {
  hbmOldBmp = (HBITMAP)::SelectObject(hdcBmpMem, m_csBitmaps[byIndex].hBitmap);
    hbmT = (HBITMAP)::SelectObject(hdcMem, m_csBitmaps[byIndex].hMask);
  }

if (bIsDisabled && m_bShowDisabledBitmap)     //button disabled
{
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);

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_NORMAL);

::DeleteObject(hBitmap);
} // if
else        //button abled
{
::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


特此结贴~~~~~ ^^

#6


厄 这个是CButtonSt中的将彩色Bitmap转换成灰度图的代码:

HBITMAP CButtonST::CreateGrayscaleBitmap(HBITMAP hBitmap, 
                                         DWORD dwWidth, 
                                         DWORD dwHeight, 
                                         COLORREF crTrans)
{
HBITMAP hGrayBitmap = NULL;
HDC hMainDC = NULL, hMemDC1 = NULL, hMemDC2 = NULL;
HBITMAP hOldBmp1 = NULL, hOldBmp2 = NULL;

hMainDC = ::GetDC(NULL);
if (hMainDC == NULL) return NULL;
hMemDC1 = ::CreateCompatibleDC(hMainDC);
if (hMemDC1 == NULL)
{
::ReleaseDC(NULL, hMainDC);
return NULL;
} // if
hMemDC2 = ::CreateCompatibleDC(hMainDC);
if (hMemDC2 == NULL)
{
::DeleteDC(hMemDC1);
::ReleaseDC(NULL, hMainDC);
return NULL;
} // if

hGrayBitmap = ::CreateCompatibleBitmap(hMainDC, dwWidth, dwHeight);
if (hGrayBitmap)
{
hOldBmp1 = (HBITMAP)::SelectObject(hMemDC1, hGrayBitmap);
hOldBmp2 = (HBITMAP)::SelectObject(hMemDC2, hBitmap);

//::BitBlt(hMemDC1, 0, 0, dwWidth, dwHeight, hMemDC2, 0, 0, SRCCOPY);

DWORD dwLoopY = 0, dwLoopX = 0;
COLORREF crPixel = 0;
BYTE byNewPixel = 0;

for (dwLoopY = 0; dwLoopY < dwHeight; dwLoopY++)
{
for (dwLoopX = 0; dwLoopX < dwWidth; dwLoopX++)
{
crPixel = ::GetPixel(hMemDC2, dwLoopX, dwLoopY);
byNewPixel = (BYTE)((GetRValue(crPixel) * 0.299) + (GetGValue(crPixel) * 0.587) + (GetBValue(crPixel) * 0.114));

if (crPixel != crTrans)
::SetPixel(hMemDC1, dwLoopX, dwLoopY, RGB(byNewPixel, byNewPixel, byNewPixel));
else
::SetPixel(hMemDC1, dwLoopX, dwLoopY, crPixel);
} // for
} // for

::SelectObject(hMemDC1, hOldBmp1);
::SelectObject(hMemDC2, hOldBmp2);
} // if

::DeleteDC(hMemDC1);
::DeleteDC(hMemDC2);
::ReleaseDC(NULL, hMainDC);

return hGrayBitmap;
} // End of CreateGrayscaleBitmap