1
CMFCRibbonBar
については、アプリケーション状態にあるボタンのアイコンを変更したいと思います。MFCリボン:ボタンのアイコンを(動的に)変更してください
(私はしばらくの間、コードとドキュメントを通じて掘ってきましたが、役に立つものを見つけていません。)
CMFCRibbonBar
については、アプリケーション状態にあるボタンのアイコンを変更したいと思います。MFCリボン:ボタンのアイコンを(動的に)変更してください
(私はしばらくの間、コードとドキュメントを通じて掘ってきましたが、役に立つものを見つけていません。)
私はアイコンが描かれている方法を制御するために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(およびアプリケーション状態をアイコンに適用する特別な方法)を問題なく実行できます。
ありがとうございました!私は夕方にそれを試してきました - それはまだ変わっていますが、少なくとも行く方法のように見えます。 – peterchen