如何让CMFCToolBar菜单禁用项图片呈现Visual Studio风格?
实现VS风格禁用菜单图标(半灰而非全灰)的方法
要实现类似Visual Studio中禁用菜单图标保留部分色彩的效果,你需要调整MFC菜单按钮的绘制逻辑,具体可通过以下两种方式实现:
1. 自定义菜单按钮类(精准控制效果)
继承CMFCToolBarMenuButton,重写OnDraw函数替换默认的禁用图标绘制逻辑,模拟VS的半灰蒙版效果:
class CMyToolBarMenuButton : public CMFCToolBarMenuButton { public: CMyToolBarMenuButton(UINT nID, HMENU hMenu, int iImage = -1) : CMFCToolBarMenuButton(nID, hMenu, iImage) {} virtual void OnDraw(CDC* pDC, const CRect& rect, CMFCToolBarImages* pImages, BOOL bHorz = TRUE, BOOL bCustomizeMode = FALSE, BOOL bHighlight = FALSE, BOOL bDrawBorder = TRUE, BOOL bGrayDisabledButtons = TRUE) override { if (!IsEnabled() && m_iImage != -1 && pImages != nullptr) { CImageList* pOrgImageList = pImages->GetImageList(CMFCToolBarImages::ImageNormal); if (pOrgImageList != nullptr) { // 创建临时图像列表存放半灰处理后的图标 CImageList grayImageList; grayImageList.Create(pImages->GetImageSize().cx, pImages->GetImageSize().cy, ILC_COLOR32 | ILC_MASK, 1, 1); CDC dcMem; dcMem.CreateCompatibleDC(pDC); CBitmap bmp; bmp.CreateCompatibleBitmap(pDC, pImages->GetImageSize().cx, pImages->GetImageSize().cy); CBitmap* pOldBmp = dcMem.SelectObject(&bmp); // 先绘制原始图标,再叠加半透明灰色层 pOrgImageList->Draw(&dcMem, m_iImage, CPoint(0,0), ILD_NORMAL); CRect imgRect(0,0,pImages->GetImageSize().cx,pImages->GetImageSize().cy); dcMem.FillSolidRect(imgRect, RGB(210,210,210)); dcMem.SetBkMode(TRANSPARENT); grayImageList.Add(&bmp, nullptr); // 用处理后的图像绘制按钮 CMFCToolBarImages grayImages; grayImages.Attach(grayImageList); CMFCToolBarMenuButton::OnDraw(pDC, rect, &grayImages, bHorz, bCustomizeMode, bHighlight, bDrawBorder, FALSE); // 清理资源 dcMem.SelectObject(pOldBmp); grayImages.Detach(); grayImageList.DeleteImageList(); return; } } // 正常状态调用基类绘制逻辑 CMFCToolBarMenuButton::OnDraw(pDC, rect, pImages, bHorz, bCustomizeMode, bHighlight, bDrawBorder, bGrayDisabledButtons); } };
之后在创建菜单按钮时,用自定义类替代默认按钮:
void AddCustomMenuButton(CMenu* pMenu, UINT nID, int iImage, HMENU hSubMenu) { CMyToolBarMenuButton* pButton = new CMyToolBarMenuButton(nID, hSubMenu, iImage); pMenu->InsertMenu(0, MF_BYPOSITION | MF_OWNERDRAW, nID, (LPCTSTR)pButton); }
2. 全局设置(快速生效)
如果不需要精准自定义,可在程序初始化阶段修改MFC全局设置,让所有禁用按钮使用半灰效果:
// 在InitInstance中添加 CMFCToolBar::SetDisableGrayImage(TRUE); // 可自定义灰化颜色,接近VS风格的浅灰 CMFCToolBar::SetGrayDisabledButtonsColor(RGB(220,220,220));
注意:该设置会影响所有工具栏和菜单按钮的禁用效果,需根据实际场景测试。
核心原理
VS的禁用图标并非完全灰度化,而是在原始图标上叠加了一层低透明度的灰色蒙版,保留了图标的基础色彩信息。自定义绘制时通过先绘制原始图标、再叠加半透明灰色层的方式,即可模拟该效果。
内容的提问来源于stack exchange,提问作者latosvarun
相关产品推荐
相关产品推荐

