如何在C#中获取当前标题栏颜色?实现与下方面板配色统一
如何通过C#获取当前窗口标题栏颜色并同步面板颜色
可以通过调用Windows系统API获取标题栏颜色,适配不同Windows版本(Win7/Win10/Win11),以下是具体实现方案:
核心思路
现代Windows系统的标题栏颜色由系统主题着色值控制(Win10/11),或通过系统非客户端指标获取(Win7),调用对应API后将颜色值应用到面板即可实现视觉统一。
Win10/Win11 适配方案(推荐)
使用DwmGetColorizationColor API获取系统主题的着色颜色,这是Win10及以上系统标题栏颜色的直接来源:
代码实现
using System; using System.Drawing; using System.Runtime.InteropServices; using System.Windows.Forms; public partial class YourForm : Form { // 导入DWM API [DllImport("dwmapi.dll", PreserveSig = false)] private static extern void DwmGetColorizationColor(out uint colorizationColor, out bool opaqueBlend); private Color GetTitleBarColor() { DwmGetColorizationColor(out uint colorValue, out bool isOpaque); // 转换ARGB格式,处理透明度 return Color.FromArgb( isOpaque ? 255 : (int)(colorValue >> 24), (int)(colorValue >> 16) & 0xFF, (int)(colorValue >> 8) & 0xFF, (int)colorValue & 0xFF ); } private void YourForm_Load(object sender, EventArgs e) { // 将面板颜色设置为标题栏颜色 yourPanel.BackColor = GetTitleBarColor(); // 监听主题变化,实时更新颜色 SystemEvents.UserPreferenceChanged += SystemEvents_UserPreferenceChanged; } private void SystemEvents_UserPreferenceChanged(object sender, UserPreferenceChangedEventArgs e) { if (e.Category == UserPreferenceCategory.General || e.Category == UserPreferenceCategory.VisualStyle) { yourPanel.BackColor = GetTitleBarColor(); } } protected override void Dispose(bool disposing) { if (disposing) { SystemEvents.UserPreferenceChanged -= SystemEvents_UserPreferenceChanged; } base.Dispose(disposing); } }
Win7 兼容方案
如果需要支持Win7,可通过SystemParametersInfo API获取系统非客户端指标中的标题栏颜色:
代码实现
using System; using System.Drawing; using System.Runtime.InteropServices; using System.Windows.Forms; public partial class YourForm : Form { [DllImport("user32.dll", SetLastError = true)] private static extern bool SystemParametersInfo(uint uiAction, uint uiParam, ref uint pvParam, uint fWinIni); private const uint SPI_GETNONCLIENTMETRICS = 0x0029; [StructLayout(LayoutKind.Sequential)] private struct NONCLIENTMETRICS { public uint cbSize; public int iBorderWidth; public int iScrollWidth; public int iScrollHeight; public int iCaptionWidth; public int iCaptionHeight; public LOGFONT lfCaptionFont; public int iSmCaptionWidth; public int iSmCaptionHeight; public LOGFONT lfSmCaptionFont; public int iMenuWidth; public int iMenuHeight; public LOGFONT lfMenuFont; public LOGFONT lfStatusFont; public LOGFONT lfMessageFont; public int iPaddedBorderWidth; public uint dwTitleColor; public uint dwInactiveTitleColor; } [StructLayout(LayoutKind.Sequential)] private struct LOGFONT { public int lfHeight; public int lfWidth; public int lfEscapement; public int lfOrientation; public int lfWeight; public byte lfItalic; public byte lfUnderline; public byte lfStrikeOut; public byte lfCharSet; public byte lfOutPrecision; public byte lfClipPrecision; public byte lfQuality; public byte lfPitchAndFamily; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)] public string lfFaceName; } private Color GetWin7TitleBarColor(bool isActiveWindow = true) { NONCLIENTMETRICS metrics = new NONCLIENTMETRICS(); metrics.cbSize = (uint)Marshal.SizeOf(metrics); if (SystemParametersInfo(SPI_GETNONCLIENTMETRICS, metrics.cbSize, ref metrics.cbSize, 0)) { uint colorValue = isActiveWindow ? metrics.dwTitleColor : metrics.dwInactiveTitleColor; return Color.FromArgb(255, (int)(colorValue >> 16) & 0xFF, (int)(colorValue >> 8) & 0xFF, (int)colorValue & 0xFF); } // 获取失败时返回默认灰色 return Color.FromArgb(217, 217, 217); } private void YourForm_Load(object sender, EventArgs e) { yourPanel.BackColor = GetWin7TitleBarColor(); SystemEvents.UserPreferenceChanged += SystemEvents_UserPreferenceChanged; } private void SystemEvents_UserPreferenceChanged(object sender, UserPreferenceChangedEventArgs e) { if (e.Category == UserPreferenceCategory.General || e.Category == UserPreferenceCategory.VisualStyle) { yourPanel.BackColor = GetWin7TitleBarColor(); } } protected override void Dispose(bool disposing) { if (disposing) { SystemEvents.UserPreferenceChanged -= SystemEvents_UserPreferenceChanged; } base.Dispose(disposing); } }
WPF 适配调整
如果是WPF项目,只需将获取到的Color转换为SolidColorBrush即可:
private SolidColorBrush GetTitleBarBrush() { DwmGetColorizationColor(out uint colorValue, out bool isOpaque); byte alpha = isOpaque ? (byte)255 : (byte)(colorValue >> 24); byte red = (byte)((colorValue >> 16) & 0xFF); byte green = (byte)((colorValue >> 8) & 0xFF); byte blue = (byte)(colorValue & 0xFF); return new SolidColorBrush(System.Windows.Media.Color.FromArgb(alpha, red, green, blue)); } // 使用示例: yourPanel.Background = GetTitleBarBrush();
内容的提问来源于stack exchange,提问作者damichab
相关产品推荐
相关产品推荐

