CMFCEditBrowseCtrl调用EnableWindow(false)时图标未灰显的修复方法
CMFCEditBrowseCtrl禁用时自定义图标不灰显的解决方法
CMFCEditBrowseCtrl默认不会自动对自定义设置的图标做灰显处理,禁用控件后图标保持原始状态,导致视觉不一致。以下是几种可行的解决方式:
方法一:提前准备禁用状态图标,手动切换
- 提前制作好与原始图标尺寸、风格匹配的灰显图标(比如资源ID设为
IDB_PNG_IMAGE_DISABLED) - 在控制控件启用/禁用时,同步切换图标:
void SetEditBrowseCtrlState(CMFCEditBrowseCtrl& ctrl, BOOL bEnable) { ctrl.EnableWindow(bEnable); ctrl.SetBrowseButtonImage(bEnable ? IDB_PNG_IMAGE : IDB_PNG_IMAGE_DISABLED); }
- 使用时直接调用该函数替代
EnableWindow:SetEditBrowseCtrlState(m_control, FALSE);
方法二:动态生成灰显图标,无需额外资源
通过MFC的图像处理函数,将原始图标实时转换为灰显版本,无需提前制作禁用图标:
HICON CreateDisabledIcon(UINT nIconResID) { HICON hOriginal = AfxGetApp()->LoadIcon(nIconResID); if (!hOriginal) return nullptr; ICONINFO iconInfo = { 0 }; GetIconInfo(hOriginal, &iconInfo); CDC dcScreen; dcScreen.CreateDC(_T("DISPLAY")); CDC dcMem; dcMem.CreateCompatibleDC(&dcScreen); BITMAP bm; GetObject(iconInfo.hbmColor, sizeof(BITMAP), &bm); CSize iconSize(bm.bmWidth, bm.bmHeight); CBitmap bmDisabled; bmDisabled.CreateCompatibleBitmap(&dcScreen, iconSize.cx, iconSize.cy); CBitmap* pOldBmp = dcMem.SelectObject(&bmDisabled); dcMem.FillSolidRect(0, 0, iconSize.cx, iconSize.cy, GetSysColor(COLOR_3DFACE)); dcMem.DrawIcon(0, 0, hOriginal); dcMem.GrayImage(iconSize, 0, 0, iconSize.cx, iconSize.cy, 0, 0); ICONINFO disabledIconInfo = { 0 }; disabledIconInfo.fIcon = TRUE; disabledIconInfo.hbmColor = (HBITMAP)bmDisabled.Detach(); disabledIconInfo.hbmMask = iconInfo.hbmMask; HICON hDisabled = CreateIconIndirect(&disabledIconInfo); dcMem.SelectObject(pOldBmp); DeleteObject(iconInfo.hbmColor); DeleteObject(iconInfo.hbmMask); DestroyIcon(hOriginal); return hDisabled; }
- 禁用控件时调用该函数生成并设置灰显图标:
m_control.EnableWindow(FALSE); HICON hDisabledIcon = CreateDisabledIcon(IDB_PNG_IMAGE); if (hDisabledIcon) { m_control.SetBrowseButtonImage(hDisabledIcon); DestroyIcon(hDisabledIcon); }
方法三:派生控件类,自动处理图标切换
如果需要多处使用该功能,可派生CMFCEditBrowseCtrl重写EnableWindow,实现自动切换:
class CMyEditBrowseCtrl : public CMFCEditBrowseCtrl { public: virtual BOOL EnableWindow(BOOL bEnable) override { BOOL bResult = __super::EnableWindow(bEnable); if (bEnable) { SetBrowseButtonImage(IDB_PNG_IMAGE); } else { HICON hDisabled = CreateDisabledIcon(IDB_PNG_IMAGE); if (hDisabled) { SetBrowseButtonImage(hDisabled); DestroyIcon(hDisabled); } } return bResult; } };
- 将控件变量类型改为
CMyEditBrowseCtrl,直接调用EnableWindow即可自动完成图标灰显处理
内容的提问来源于stack exchange,提问作者Andrew Truckle
相关产品推荐
相关产品推荐

