这完全取决于用户当前的主题。在 Windows Classic 主题、所有 3 个标准 Windows XP Luna 主题、Aero 主题以及 Windows 8 中可能完全出现的其他内容中,组框标题使用了不同的颜色。更不用说它是用户可自定义的,这意味着他们甚至可能没有使用标准的主题颜色。
因此,根据计算机上显示的内容对 RGB 值进行硬编码不是一个好计划。这是确保您的应用程序会像拇指酸痛一样突出的好方法。因此,在这个问题的其他答案中建议的截取屏幕截图和采样像素颜色的策略是正确的。错误的次数多于正确的次数。
相反,您需要向系统询问此值以确保它与用户的当前配置相匹配。这可以分为两种一般可能性:
用户打开了视觉样式(主题)服务,这意味着他们正在使用 Luna 或 Aero 之类的东西。
在这种情况下,您需要查询 Visual Styles 服务以获取适当的颜色。使用命名空间中提供的托管包装器很简单System.Windows.Forms.VisualStyles
。例如,您可以编写以下代码(在 C# 中任意编写):
using System.Windows.Drawing;
using System.Windows.Forms.VisualStyles;
// ...
var vsr = new VisualStyleRenderer(VisualStyleElement.Button.GroupBox.Normal);
var groupBoxCaptionColor = vsr.GetColor(ColorProperty.TextColor);
用户关闭了视觉样式服务或它不可用(XP 之前的 Windows 版本),这意味着他们正在使用“Windows 经典”主题。
在这种情况下,组框使用标准 3D(控制)颜色作为其标题,因此您可以简单地从System.Drawing.SystemColors
类中获取它。您要查找的属性称为ControlText
:
using System.Windows.Drawing;
// ...
var groupBoxCaptionColor = SystemColors.ControlText;
在实际应用程序中,您必须将这两种情况放在一起才能处理所有可能的客户端配置。如果 Visual Styles 服务被关闭,第一个路由会爆炸,所以你需要先检查它(你可以通过查询Application.RenderWithVisualStyles
属性来做到这一点,如果它被关闭,则回退到第二种方法。类似于:
using System.Windows.Drawing;
using System.Windows.Forms.VisualStyles;
// ...
public Color GroupBoxCaptionColor
{
get
{
// Test to see if Visual Styles are enabled.
if (Application.RenderWithVisualStyles())
{
// If Visual Styles are enabled, use that color.
var vsr = new VisualStyleRenderer(VisualStyleElement.Button.GroupBox.Normal);
return vsr.GetColor(ColorProperty.TextColor);
}
else
{
// Otherwise, fall back to the Classic theme.
return SystemColors.ControlText;
}
}
}
该GroupBoxCaptionColor
属性将返回一个与当前用于组合框控件标题的颜色Color
相对应的对象。从技术上讲,这个对象将具有 RGB 值,但您必须通过所有这些歌曲和舞蹈来确保您的应用程序使用的颜色始终与当前主题颜色同步。Color
一旦你了解了工作中的各种力量,它真的不会太复杂。除了乐趣还没有完全结束。您必须考虑是否要处理用户在应用程序运行时更改其系统主题的可能性。在这种情况下,实际组合框控件的标题颜色会发生变化,但您以编程方式确定的标题颜色将过时,匹配旧主题而不是新主题。
修复是监视SystemEvents.UserPreferenceChanged
事件,当用户在控制面板中更改主题时会引发该事件。在该事件的处理程序方法中,您需要再次获取组框标题颜色,并更新可能正在使用它的任何 UI 元素。
值得特别注意的是,正如上面链接的文档所述,这是一个静态事件,这意味着您必须在应用程序关闭时分离事件处理程序,否则您可能会泄漏内存。