HBITMAP CButtonST::CreateBitmapMask(HBITMAP hSourceBitmap, DWORD dwWidth, DWORD dwHeight, COLORREF crTransColor)
{
    HBITMAP        hMask        
= NULL;
    HDC            hdcSrc        
= NULL;
    HDC            hdcDest        
= NULL;
    HBITMAP        hbmSrcT        
= NULL;
    HBITMAP        hbmDestT    
= NULL;
    COLORREF    crSaveBk;
    COLORREF    crSaveDestText;

    hMask 
= ::CreateBitmap(dwWidth, dwHeight, 11, NULL);
    
if (hMask == NULL)    return NULL;

    hdcSrc    
= ::CreateCompatibleDC(NULL);
    hdcDest    
= ::CreateCompatibleDC(NULL);

    hbmSrcT 
= (HBITMAP)::SelectObject(hdcSrc, hSourceBitmap);
    hbmDestT 
= (HBITMAP)::SelectObject(hdcDest, hMask);

    crSaveBk 
= ::SetBkColor(hdcSrc, crTransColor);

    ::BitBlt(hdcDest, 
00, dwWidth, dwHeight, hdcSrc, 00, SRCCOPY);

    crSaveDestText 
= ::SetTextColor(hdcSrc, RGB(255255255));
    ::SetBkColor(hdcSrc,RGB(
000));

    ::BitBlt(hdcSrc, 
00, dwWidth, dwHeight, hdcDest, 00, SRCAND);

    SetTextColor(hdcDest, crSaveDestText);

    ::SetBkColor(hdcSrc, crSaveBk);
    ::SelectObject(hdcSrc, hbmSrcT);
    ::SelectObject(hdcDest, hbmDestT);

    ::DeleteDC(hdcSrc);
    ::DeleteDC(hdcDest);

    
return hMask;
}
 // End of CreateBitmapMask

//
// Parameters:
//        [IN]    bHasTitle
//                TRUE if the button has a text
//        [IN]    rpItem
//                A pointer to a RECT structure indicating the allowed paint area
//        [IN/OUT]rpTitle
//                A pointer to a CRect object indicating the paint area reserved for the
//                text. This structure will be modified if necessary.
//        [IN]    bIsPressed
//                TRUE if the button is currently pressed
//        [IN]    dwWidth
//                Width of the image (icon or bitmap)
//        [IN]    dwHeight
//                Height of the image (icon or bitmap)
//        [OUT]    rpImage
//                A pointer to a CRect object that will receive the area available to the image
//
void CButtonST::PrepareImageRect(BOOL bHasTitle, RECT* rpItem, CRect* rpTitle, BOOL bIsPressed, DWORD dwWidth, DWORD dwHeight, CRect* rpImage)
{
    CRect rBtn;

    rpImage
->CopyRect(rpItem);

    
switch (m_byAlign)
    
{
        
case ST_ALIGN_HORIZ:
            
if (bHasTitle == FALSE)
            
{
                
// Center image horizontally
                rpImage->left += ((rpImage->Width() - (long)dwWidth)/2);
            }

            
else
            
{
                
// Image must be placed just inside the focus rect
                rpImage->left += m_ptImageOrg.x;  
                rpTitle
->left += dwWidth + m_ptImageOrg.x;
            }

            
// Center image vertically
            rpImage->top += ((rpImage->Height() - (long)dwHeight)/2);
            
break;

        
case ST_ALIGN_HORIZ_RIGHT:
            GetClientRect(
&rBtn);
            
if (bHasTitle == FALSE)
            
{
                
// Center image horizontally
                rpImage->left += ((rpImage->Width() - (long)dwWidth)/2);
            }

            
else
            
{
                
// Image must be placed just inside the focus rect
                rpTitle->right = rpTitle->Width() - dwWidth - m_ptImageOrg.x;
                rpTitle
->left = m_ptImageOrg.x;
                rpImage
->left = rBtn.right - dwWidth - m_ptImageOrg.x;
                
// Center image vertically
                rpImage->top += ((rpImage->Height() - (long)dwHeight)/2);
            }

            
break;
        
        
case ST_ALIGN_VERT:
            
// Center image horizontally
            rpImage->left += ((rpImage->Width() - (long)dwWidth)/2);
            
if (bHasTitle == FALSE)
            
{
                
// Center image vertically
                rpImage->top += ((rpImage->Height() - (long)dwHeight)/2);           
            }

            
else
            
{
                rpImage
->top = m_ptImageOrg.y;
                rpTitle
->top += dwHeight;
            }

            
break;

        
case ST_ALIGN_OVERLAP:
            
break;
    }
 // switch
    
    
// If button is pressed then press image also
    if (bIsPressed && m_bIsCheckBox == FALSE)
        rpImage
->OffsetRect(m_ptPressedOffset.x, m_ptPressedOffset.y);
}
 // End of PrepareImageRect

void CButtonST::DrawTheIcon(CDC* pDC, BOOL bHasTitle, RECT* rpItem, CRect* rpCaption, BOOL bIsPressed, BOOL bIsDisabled)
{
    BYTE        byIndex        
= 0;

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

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

    
// Ole'!
    pDC->DrawState(    rImage.TopLeft(),
                    rImage.Size(), 
                    m_csIcons[byIndex].hIcon,
                    (bIsDisabled 
? DSS_DISABLED : DSS_NORMAL), 
                    (CBrush
*)NULL);
}
 // End of DrawTheIcon

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(255255255));

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

        ::BitBlt(hDC, 
00, m_csBitmaps[byIndex].dwWidth, m_csBitmaps[byIndex].dwHeight, hdcMem, 00, SRCAND);
        ::BitBlt(hDC, 
00, m_csBitmaps[byIndex].dwWidth, m_csBitmaps[byIndex].dwHeight, hdcBmpMem, 00, 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, 00, SRCAND);

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

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

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

void CButtonST::DrawTheText(CDC* pDC, LPCTSTR lpszText, RECT* rpItem, CRect* rpCaption, BOOL bIsPressed, BOOL bIsDisabled)
{
    
// Draw the button's title
    
// If button is pressed then "press" title also
    if (m_bIsPressed && m_bIsCheckBox == FALSE)
        rpCaption
->OffsetRect(m_ptPressedOffset.x, m_ptPressedOffset.y);

    
// ONLY FOR DEBUG 
    
//CBrush brBtnShadow(RGB(255, 0, 0));
    
//pDC->FrameRect(rCaption, &brBtnShadow);

    
// Center text
    CRect centerRect = rpCaption;
    pDC
->DrawText(lpszText, -1, rpCaption, DT_WORDBREAK | DT_CENTER | DT_CALCRECT);
    rpCaption
->OffsetRect((centerRect.Width() - rpCaption->Width())/2, (centerRect.Height() - rpCaption->Height())/2);
    
/* RFU
    rpCaption->OffsetRect(0, (centerRect.Height() - rpCaption->Height())/2);
    rpCaption->OffsetRect((centerRect.Width() - rpCaption->Width())-4, (centerRect.Height() - rpCaption->Height())/2);
    
*/


    pDC
->SetBkMode(TRANSPARENT);
    
/*
    pDC->DrawState(rCaption->TopLeft(), rCaption->Size(), (LPCTSTR)sTitle, (bIsDisabled ? DSS_DISABLED : DSS_NORMAL), 
                    TRUE, 0, (CBrush*)NULL);
    
*/

    
if (m_bIsDisabled)
    
{
        rpCaption
->OffsetRect(11);
        pDC
->SetTextColor(::GetSysColor(COLOR_3DHILIGHT));
        pDC
->DrawText(lpszText, -1, rpCaption, DT_WORDBREAK | DT_CENTER);
        rpCaption
->OffsetRect(-1-1);
        pDC
->SetTextColor(::GetSysColor(COLOR_3DSHADOW));
        pDC
->DrawText(lpszText, -1, rpCaption, DT_WORDBREAK | DT_CENTER);
    }
 // if
    else
    
{
        
if (m_bMouseOnButton || m_bIsPressed) 
        
{
            pDC
->SetTextColor(m_crColors[BTNST_COLOR_FG_IN]);
            pDC
->SetBkColor(m_crColors[BTNST_COLOR_BK_IN]);
        }
 // if
        else 
        
{
            
if (m_bIsFocused)
            

                pDC
->SetTextColor(m_crColors[BTNST_COLOR_FG_FOCUS]); 
                pDC
->SetBkColor(m_crColors[BTNST_COLOR_BK_FOCUS]); 
            }
 // if
            else 
            
{
                pDC
->SetTextColor(m_crColors[BTNST_COLOR_FG_OUT]); 
                pDC
->SetBkColor(m_crColors[BTNST_COLOR_BK_OUT]); 
            }
 // else
        }
 // else
        pDC->DrawText(lpszText, -1, rpCaption, DT_WORDBREAK | DT_CENTER);
    }
 // if
}
 // End of DrawTheText

// This function creates a grayscale bitmap starting from a given bitmap.
// The resulting bitmap will have the same size of the original one.
//
// Parameters:
//        [IN]    hBitmap
//                Handle to the original bitmap.
//        [IN]    dwWidth
//                Specifies the bitmap width, in pixels.
//        [IN]    dwHeight
//                Specifies the bitmap height, in pixels.
//        [IN]    crTrans
//                Color to be used as transparent color. This color will be left unchanged.
//
// Return value:
//        If the function succeeds, the return value is the handle to the newly created
//        grayscale bitmap.
//        If the function fails, the return value is NULL.
//
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

// This function creates a bitmap that is 25% darker than the original.
// The resulting bitmap will have the same size of the original one.
//
// Parameters:
//        [IN]    hBitmap
//                Handle to the original bitmap.
//        [IN]    dwWidth
//                Specifies the bitmap width, in pixels.
//        [IN]    dwHeight
//                Specifies the bitmap height, in pixels.
//        [IN]    crTrans
//                Color to be used as transparent color. This color will be left unchanged.
//
// Return value:
//        If the function succeeds, the return value is the handle to the newly created
//        darker bitmap.
//        If the function fails, the return value is NULL.
//
HBITMAP CButtonST::CreateDarkerBitmap(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;

        
for (dwLoopY = 0; dwLoopY < dwHeight; dwLoopY++)
        
{
            
for (dwLoopX = 0; dwLoopX < dwWidth; dwLoopX++)
            
{
                crPixel 
= ::GetPixel(hMemDC2, dwLoopX, dwLoopY);

                
if (crPixel != crTrans)
                    ::SetPixel(hMemDC1, dwLoopX, dwLoopY, DarkenColor(crPixel, 
0.25));
                
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 CreateDarkerBitmap
Posted on 2007-04-12 11:47 艾凡赫 阅读(571) 评论(0)  编辑 收藏 引用 所属分类: MFC技术

只有注册用户登录后才能发表评论。
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理