如何重置Rich Edit控件颜色以恢复CFE_DISABLED文本的灰色显示?
恢复Rich Edit控件中CFE_DISABLED文本的默认灰色显示
我正在为Finale音乐程序开发一款插件,使用Rich Edit控件显示和编辑格式化文本。其中“隐藏”样式通过CFM_DISABLED/CFE_DISABLED实现:标记为禁用的文本会自动灰色显示,且不影响编辑能力,核心实现代码如下:
static CHARFORMAT2W charFormatFromFontInfo(const FCFontInfo *pFont) { FCString fontName; pFont->GetNameString(&fontName); CHARFORMAT2W cf{}; cf.cbSize = sizeof(cf); cf.dwMask = CFM_BOLD | CFM_FACE | CFM_ITALIC | CFM_SIZE | CFM_STRIKEOUT | CFM_UNDERLINE | CFM_DISABLED; lstrcpynW(cf.szFaceName, (LPCWSTR)fontName._GetUnicodeBuffer(), DIM(cf.szFaceName)); cf.szFaceName[DIM(cf.szFaceName) - 1] = 0; cf.yHeight = 20.0 * pFont->GetSizeFloat(); // points to twps if (pFont->GetBold()) cf.dwEffects |= CFE_BOLD; if (pFont->GetItalic()) cf.dwEffects |= CFE_ITALIC; if (pFont->GetUnderline()) cf.dwEffects |= CFE_UNDERLINE; if (pFont->GetStrikeOut()) cf.dwEffects |= CFE_STRIKEOUT; if (pFont->GetHidden()) cf.dwEffects |= CFE_DISABLED; return cf; }
问题描述
给控件设置颜色范围后,与颜色范围重叠的禁用文本会失去灰色显示效果。尝试通过设置RGB(0,0,0)恢复黑色文本,但禁用文本也会被强制设为黑色;设置crTextColor = -1同样无效。需要找到方法撤销所有颜色更改,让CFE_DISABLED文本恢复自动灰色显示的默认行为。
解决方案
Rich Edit中控件的显式颜色设置会覆盖CFE_DISABLED的自动着色逻辑,要恢复默认行为,需清除文本的显式颜色格式,而非强制设置黑色。
方法1:使用CLR_DEFAULT清除显式颜色
// 选中全部文本 SendDlgItemMessageW(GetWindowHandle(), GetControlID(), EM_SETSEL, 0, -1); CHARFORMAT2W cf{}; cf.cbSize = sizeof(cf); cf.dwMask = CFM_COLOR; // 用CLR_DEFAULT清除用户设置的显式颜色 cf.crTextColor = CLR_DEFAULT; // 将格式应用到选中的全部文本 SendDlgItemMessageW(GetWindowHandle(), GetControlID(), EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
CLR_DEFAULT会告诉Rich Edit控件放弃使用显式设置的颜色,回归默认格式逻辑,此时CFE_DISABLED标记的文本会自动恢复灰色显示。注意不要添加SCF_DEFAULT参数,该参数用于设置控件默认格式,而非修改现有文本格式。
方法2:重新应用CFE_DISABLED格式(备选)
如果方法1无效,可针对有隐藏标记的文本范围重新应用禁用格式,确保格式标记的优先级:
// 遍历所有隐藏文本的范围(需自行实现范围获取逻辑) for (auto& range : hiddenTextRanges) { // 选中当前隐藏文本范围 SendDlgItemMessageW(GetWindowHandle(), GetControlID(), EM_SETSEL, range.start, range.end); CHARFORMAT2W cfDisable{}; cfDisable.cbSize = sizeof(cfDisable); cfDisable.dwMask = CFM_DISABLED; cfDisable.dwEffects |= CFE_DISABLED; // 重新应用禁用格式 SendDlgItemMessageW(GetWindowHandle(), GetControlID(), EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cfDisable); }
内容的提问来源于stack exchange,提问作者rpatters1
相关产品推荐
相关产品推荐

