2017-06-11 99 views

答えて

3

私はアイコンが描かれている方法を制御するためにCMFCRibbonButtonからクラスCMFCRibbonButtonExを導出しました。

ヘッダー:この特別なケースでは、私は、元のアイコンの上に緑色のチェックマークをアルファブレンドしたかった

class CMFCRibbonButtonEx : public CMFCRibbonButton 
{ 
// Construction 
public: 
    CMFCRibbonButtonEx(); 
    CMFCRibbonButtonEx(UINT nID, LPCTSTR lpszText, int nSmallImageIndex = -1, int nLargeImageIndex = -1, BOOL bAlwaysShowDescription = FALSE); 
    CMFCRibbonButtonEx(UINT nID, LPCTSTR lpszText, HICON hIcon, BOOL bAlwaysShowDescription = FALSE, HICON hIconSmall = NULL, BOOL bAutoDestroyIcon = FALSE, BOOL bAlphaBlendIcon = FALSE); 

// Overridden 
    void SetCheck(BOOL bCheck = TRUE); 
    void DrawImage(CDC* pDC, RibbonImageType type, CRect rectImage); 

// Attributes 
private: 
    BOOL m_bChecked; 

// Helper 
private: 
    void DrawCheckmark(CDC* pDC, int CheckmarkResourceBitmapID, RECT *r); 
    void PremultiplyBitmapAlpha(HDC hDC, HBITMAP hBmp); 
}; 

実装:

CMFCRibbonButtonEx::CMFCRibbonButtonEx() : CMFCRibbonButton() { } 
CMFCRibbonButtonEx::CMFCRibbonButtonEx(UINT nID, LPCTSTR lpszText, int nSmallImageIndex, int nLargeImageIndex, BOOL bAlwaysShowDescription) 
    : CMFCRibbonButton(nID, lpszText, nSmallImageIndex, nLargeImageIndex, bAlwaysShowDescription) { } 
CMFCRibbonButtonEx::CMFCRibbonButtonEx(UINT nID, LPCTSTR lpszText, HICON hIcon, BOOL bAlwaysShowDescription, HICON hIconSmall, BOOL bAutoDestroyIcon, BOOL bAlphaBlendIcon) 
    : CMFCRibbonButton(nID, lpszText, hIcon, bAlwaysShowDescription , hIconSmall, bAutoDestroyIcon, bAlphaBlendIcon) { } 
void CMFCRibbonButtonEx::SetCheck(BOOL bCheck) 
{ 
    m_bChecked = bCheck; 
} 
void CMFCRibbonButtonEx::DrawImage(CDC* pDC, RibbonImageType type, CRect rectImage) 
{ 
    CMFCRibbonButton::DrawImage(pDC, type, rectImage); 
    if (type == RibbonImageLarge && m_bChecked) 
     DrawCheckmark(pDC, IDB_BIG_ICON_CHECKMARK, &rectImage); 
} 
void CMFCRibbonButtonEx::DrawCheckmark(CDC* pDC, int CheckmarkResourceBitmapID, RECT *r) 
{ 
    HDC hdc; 
    CDC *dc; 
    CDC dcMem; 
    CBitmap cbm; 

    VERIFY(hdc = pDC->m_hDC); 
    VERIFY(dc = pDC); 

    dcMem.CreateCompatibleDC(dc); 

    cbm.LoadBitmap(CheckmarkResourceBitmapID); 
    PremultiplyBitmapAlpha(dcMem.m_hDC, cbm); 
    SelectObject(dcMem.m_hDC, cbm.m_hObject); 

    BLENDFUNCTION bf; 
    bf.BlendOp = AC_SRC_OVER; 
    bf.BlendFlags = 0; 
    bf.SourceConstantAlpha = 255; 
    bf.AlphaFormat = AC_SRC_ALPHA; 
    ::AlphaBlend(hdc, r->left, r->top, r->right-r->left, r->bottom-r->top, dcMem, 0, 0, 32, 32, bf); 

    VERIFY(dcMem.DeleteDC()); 
} 
void CMFCRibbonButtonEx::PremultiplyBitmapAlpha(HDC hDC, HBITMAP hBmp) 
{ 
    BITMAP bm = { 0 }; 
    GetObject(hBmp, sizeof(bm), &bm); 
    BITMAPINFO* bmi = (BITMAPINFO*) _alloca(sizeof(BITMAPINFOHEADER) + (256 * sizeof(RGBQUAD))); 
    ::ZeroMemory(bmi, sizeof(BITMAPINFOHEADER) + (256 * sizeof(RGBQUAD))); 
    bmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); 
    BOOL bRes = ::GetDIBits(hDC, hBmp, 0, bm.bmHeight, NULL, bmi, DIB_RGB_COLORS); 
    if(!bRes || bmi->bmiHeader.biBitCount != 32) return; 
    LPBYTE pBitData = (LPBYTE) ::LocalAlloc(LPTR, bm.bmWidth * bm.bmHeight * sizeof(DWORD)); 
    if(pBitData == NULL) return; 
    LPBYTE pData = pBitData; 
    ::GetDIBits(hDC, hBmp, 0, bm.bmHeight, pData, bmi, DIB_RGB_COLORS); 
    for(int y = 0; y < bm.bmHeight; y++) { 
     for(int x = 0; x < bm.bmWidth; x++) { 
     pData[0] = (BYTE)((DWORD)pData[0] * pData[3]/255); 
     pData[1] = (BYTE)((DWORD)pData[1] * pData[3]/255); 
     pData[2] = (BYTE)((DWORD)pData[2] * pData[3]/255); 
     pData += 4; 
     } 
    } 
    ::SetDIBits(hDC, hBmp, 0, bm.bmHeight, pBitData, bmi, DIB_RGB_COLORS); 
    ::LocalFree(pBitData); 
} 

これは私が私の「フィルター」サブメニューを構築する方法ですCMFCRibbonButtonExのアイテム:

m_pBtnFilter->RemoveAllSubItems(); 

int i; 
for (i = 0; i < m_csaNames.GetSize(); i++) 
{ 
    std::auto_ptr<CMFCRibbonButtonEx> apBtn(new CMFCRibbonButtonEx(ID_FILTER_BASE + i, (LPCTSTR)m_csaNames[i], m_tbiIcons.ExtractIcon(m_nIcons[i], true, NULL, true, true)); 
    apBtn->SetToolTipText(m_csaTooltips[i]); 
    m_pBtnFilter->AddSubItem(apBtn.release()); 
} 

これはメインメニューにも当てはまりますns(およびアプリケーション状態をアイコンに適用する特別な方法)を問題なく実行できます。

+0

ありがとうございました!私は夕方にそれを試してきました - それはまだ変わっていますが、少なくとも行く方法のように見えます。 – peterchen

関連する問題