You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何正确获取系统边框的实际颜色?

问题

WinAPI中的GetSysColor(COLOR_ACTIVEBORDER)函数本应返回系统活动窗口的边框颜色,但在部分自定义了Windows颜色的系统中,实际显示的边框颜色与标准色不同,可GetSysColor()始终返回标准灰色。请问如何获取系统实际使用的边框颜色?

已尝试的方法

我试过以下几种方式,但部分结果不符合预期:

var color = SystemColors.Desktop; // 正确获取桌面颜色
var color1 = SystemColors.ControlText; // 错误:无论启用何种Windows主题,始终返回黑色

var color = GetThemeSysColor(HTHEME.NULL, SystemColorIndex.COLOR_DESKTOP); // 正确获取桌面颜色
var color1 = GetThemeSysColor(HTHEME.NULL, SystemColorIndex.COLOR_BTNTEXT); // 错误

var theme = OpenThemeData(HWND.NULL, "BUTTON");
var color = GetThemeSysColor(theme, COLOR_BTNTEXT); // 错误

var theme = OpenThemeData(_button.Handle, "BUTTON");
var color = GetThemeSysColor(theme, COLOR_BTNTEXT); // 错误
解决方案

要获取系统实际使用的活动窗口边框颜色,需区分系统是否启用主题和DWM(桌面窗口管理器),使用对应的API处理:

1. 针对启用主题的系统

当系统启用主题时,GetSysColor无法获取自定义主题颜色,需通过主题API获取窗口边框的实际颜色:

  • 调用OpenThemeData打开"Window"主题类(对应窗口相关主题样式)
  • 使用GetThemeColor获取活动窗口边框对应的颜色属性,元素ID为WP_ACTIVEBORDER,状态ID为CBS_NORMAL

示例代码:

[DllImport("uxtheme.dll", CharSet = CharSet.Unicode)]
private static extern IntPtr OpenThemeData(IntPtr hwnd, string pszClassList);

[DllImport("uxtheme.dll")]
private static extern int GetThemeColor(IntPtr hTheme, int iPartId, int iStateId, int iPropId, out COLORREF pColor);

[DllImport("uxtheme.dll")]
private static extern int CloseThemeData(IntPtr hTheme);

public enum WindowParts
{
    WP_ACTIVEBORDER = 2
}

public enum CommonStates
{
    CBS_NORMAL = 1
}

public enum ThemeColorProps
{
    TMT_FILLCOLOR = 310
}

public struct COLORREF
{
    public uint ColorDWORD;

    public COLORREF(uint dwColor)
    {
        ColorDWORD = dwColor;
    }

    public Color ToColor()
    {
        return Color.FromArgb(
            (byte)((ColorDWORD >> 16) & 0xFF),
            (byte)((ColorDWORD >> 8) & 0xFF),
            (byte)(ColorDWORD & 0xFF)
        );
    }
}

public Color GetActiveBorderColor()
{
    IntPtr themeHandle = OpenThemeData(IntPtr.Zero, "Window");
    if (themeHandle != IntPtr.Zero)
    {
        COLORREF colorRef;
        if (GetThemeColor(themeHandle, (int)WindowParts.WP_ACTIVEBORDER, (int)CommonStates.CBS_NORMAL, (int)ThemeColorProps.TMT_FILLCOLOR, out colorRef) == 0)
        {
            CloseThemeData(themeHandle);
            return colorRef.ToColor();
        }
        CloseThemeData(themeHandle);
    }
    //  降级使用GetSysColor
    return ColorTranslator.FromWin32(GetSysColor((int)SystemColorIndex.COLOR_ACTIVEBORDER));
}

2. 针对启用DWM的系统(Windows Vista及以上)

如果系统启用了DWM颜色着色功能,窗口边框颜色可能与DWM全局着色颜色一致,可使用DwmGetColorizationColor获取:

[DllImport("dwmapi.dll")]
private static extern int DwmGetColorizationColor(out uint pcrColorization, out bool pfOpaqueBlend);

public Color GetDwmBorderColor()
{
    uint color;
    bool opaque;
    if (DwmGetColorizationColor(out color, out opaque) == 0)
    {
        //  DWM颜色包含alpha通道,提取RGB部分
        return Color.FromArgb(
            (byte)((color >> 16) & 0xFF),
            (byte)((color >> 8) & 0xFF),
            (byte)(color & 0xFF)
        );
    }
    //  降级使用主题API或GetSysColor
    return GetActiveBorderColor();
}

注意事项

  • 调用主题API前,需用IsAppThemed判断系统是否支持主题
  • 不同Windows版本的主题元素、属性可能存在差异,需做好兼容性处理
  • 自定义主题可能覆盖默认边框颜色逻辑,优先使用主题API获取

内容的提问来源于stack exchange,提问作者user626528

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 02:36:00