C++Builder11中TCheckListBox自绘时如何避免VCL样式覆盖自定义颜色
VCL样式覆盖自绘颜色问题解决方案
核心原因
启用VCL样式后,控件自绘事件执行前后,样式引擎会默认重写Canvas的画笔、画刷、字体颜色属性,导致自定义设置被覆盖,你遇到的文本发白就是样式默认给深色模式配置的白色字体没有被主动覆盖导致的。
具体解决方法
方法1:自绘时临时禁用当前控件的样式注入(最符合你的需求)
在自绘函数开头禁用样式对当前控件的重写,自绘完成后恢复即可,所有自定义颜色都会正常生效,不会被样式替换。
方法2:显式覆盖所有Canvas属性
如果不需要完全禁用样式,可以手动指定所有用到的Canvas属性(包括字体颜色,你原代码中没有显式设置字体颜色,所以会继承样式的默认值)。
检测样式是否启用的方法
全局判断VCL样式是否启用可以读取 StyleServices->Enabled 属性,返回 true 即为当前启用了VCL样式。
修正后的代码
//TCheckListBox *clbxCategory; void __fastcall TFormATB::clbxCategoryDrawItem(TWinControl* Control, int Index, TRect &Rect, TOwnerDrawState State) { bool styleEnabled = StyleServices->Enabled; if (styleEnabled) { // 临时禁用样式对当前控件的属性重写 StyleServices->DisableStyle(Control->Handle); } // 显式指定字体颜色,避免继承样式默认值 clbxCategory->Canvas->Font->Color = clBlack; if(State.Contains(odSelected)) { clbxCategory->Canvas->Pen->Color = clBlack; clbxCategory->Canvas->Brush->Color = clActiveCaption; clbxCategory->Canvas->RoundRect(Rect.Left, Rect.Top , Rect.Right, Rect.Bottom, 0, 50); } else { clbxCategory->Canvas->Pen->Color = Colours[Index]; clbxCategory->Canvas->Brush->Color = Colours[Index]; } clbxCategory->Canvas->Rectangle(Rect.Left, Rect.Top - 1, Rect.Right, Rect.Bottom + 1); clbxCategory->Canvas->TextOut(Rect.Left, Rect.Top,clbxCategory->Items->Strings[Index]); if (styleEnabled) { // 恢复样式,避免影响后续控件渲染 StyleServices->EnableStyle(Control->Handle); } }
补充说明
如果需要获取当前样式的指定系统颜色,可以调用 StyleServices->GetStyleColor() 方法,传入对应的颜色枚举值即可获取,比如 StyleServices->GetStyleColor(scWindowText) 可以拿到当前样式下的窗口文本颜色。
内容的提问来源于stack exchange,提问作者iplayfast
相关产品推荐
相关产品推荐

