vb.net获取Windows主题颜色、深色模式窗体,实时响应

小明 2025-05-01 06:07:37 10

先上效果图

可���接跳到完整代码

目录

先上效果图

开始教学

响应用户的更改

API讲解

 读取深浅模式、主题颜色、十六进制颜色转换

完整代码


如果大家留意资源管理器的“文件”菜单的话就会发现它的底色就是你设置的主题色,在更改Windows颜色模式时,很多的应用例如“文件资源管理器explorer”、“edge浏览器msedge”等等,那么如何做到这种效果呢?

开始教学

响应用户的更改

这可以放在自己的应用程序中,来适应和实时更改用户的设置,例如用户更改成深色模式,窗体自动变为深色,使用.net的事件响应用户更改:

对于vb.net用户,需要在窗体加载时加入语句:

Sub ChangeTheme(sender As Object, e As UserPreferenceChangedEventArgs)
    If e.Category = UserPreferenceCategory.General Then
        GetThemeColor()
        DwmSetWindowAttribute(Me.Handle, DwmWindowAttribute.UseImmersiveDarkMode, ThemeColor, Marshal.SizeOf(Of Integer))
        color = GetSystemColor()
        Label1.BackColor = color
    End If
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    GetThemeColor()
    color = GetSystemColor()
    Label1.BackColor = color
    AddHandler SystemEvents.UserPreferenceChanged, AddressOf ChangeTheme
    DwmSetWindowAttribute(Me.Handle, DwmWindowAttribute.UseImmersiveDarkMode, ThemeColor, Marshal.SizeOf(Of Integer))
End Sub

API讲解

本次使用的API为 DwmSetWindowAttribute 函数,使用常量DwmWindowAttribute.UseImmersiveDarkMode

    
    Public Shared Function DwmSetWindowAttribute(ByVal hwnd As IntPtr, ByVal attr As DwmWindowAttribute, ByRef attrValue As Integer, ByVal attrSize As Integer) As Integer
    End Function
    Public Enum DwmWindowAttribute
        NCRenderingEnabled = 1
        NCRenderingPolicy
        TransitionsForceDisabled
        AllowNCPaint
        CaptionButtonBounds
        NonClientRtlLayout
        ForceIconicRepresentation
        Flip3DPolicy
        ExtendedFrameBounds
        HasIconicBitmap
        DisallowPeek
        ExcludedFromPeek
        Cloak
        Cloaked
        FreezeRepresentation
        PassiveUpdateMode
        UseHostBackdropBrush
        UseImmersiveDarkMode = 20
        WindowCornerPreference = 33
        BorderColor
        CaptionColor
        TextColor
        VisibleFrameBorderThickness
        SystemBackdropType
        Last
    End Enum

 摘自:DWMWINDOWATTRIBUTE (dwmapi.h) - Win32 apps | Microsoft Learn

DWMWA_NCRENDERING_ENABLED

与 DwmGetWindowAttribute 一起使用。 发现是否启用了非客户端呈现。 检索到的值的类型为 BOOL。 如果启用非客户端呈现,则为 TRUE;否则为 FALSE。

DWMWA_NCRENDERING_POLICY

与 DwmSetWindowAttribute 一起使用。 设置非客户端呈现策略。 pvAttribute 参数指向 DWMNCRENDERINGPOLICY 枚举中的值。

DWMWA_TRANSITIONS_FORCEDISABLED

与 DwmSetWindowAttribute 一起使用。 启用或强制禁用 DWM 转换。 pvAttribute 参数指向 BOOL 类型的值。 如果为 TRUE ,则禁用转换; 如果为 FALSE ,则启用转换。

DWMWA_ALLOW_NCPAINT

与 DwmSetWindowAttribute 一起使用。 使非工作区中呈现的内容在 DWM 绘制的框架上可见。 pvAttribute 参数指向 BOOL 类型的值。 如果为 TRUE ,则使非工作区中呈现的内容在框架上可见;否则为 FALSE。

DWMWA_CAPTION_BUTTON_BOUNDS

与 DwmGetWindowAttribute 一起使用。 检索窗口相对空间中描述文字按钮区域的边界。 检索到的值的类型为 RECT。 如果窗口最小化或对用户不可见,则检索到的 RECT 的值是未定义的。 应检查检索到的 RECT 是否包含可以使用的边界,如果它不包含,则可以断定窗口已最小化或不可见。

DWMWA_NONCLIENT_RTL_LAYOUT

与 DwmSetWindowAttribute 一起使用。 指定非客户端内容是否为从右到左 (RTL) 镜像。 pvAttribute 参数指向 BOOL 类型的值。 如果非客户端内容从右到左 (RTL) 镜像,则为 TRUE;否则为 FALSE。

DWMWA_FORCE_ICONIC_REPRESENTATION

与 DwmSetWindowAttribute 一起使用。 强制窗口 (静态位图) 显示图标缩略图或速览表示形式,即使窗口的实时或快照表示形式可用也是如此。 此值通常在创建窗口期间设置,在窗口的整个生存期内不会更改。 但是,某些方案可能需要值随时间推移而更改。 pvAttribute 参数指向 BOOL 类型的值。 如果为 TRUE ,则需要图标缩略图或速览表示形式;否则为 FALSE。

DWMWA_FLIP3D_POLICY

与 DwmSetWindowAttribute 一起使用。 设置 Flip3D 处理窗口的方式。 pvAttribute 参数指向DWMFLIP3DWINDOWPOLICY枚举中的值。

DWMWA_EXTENDED_FRAME_BOUNDS

与 DwmGetWindowAttribute 一起使用。 检索屏幕空间中的扩展框架边界矩形。 检索到的值的类型为 RECT。

DWMWA_HAS_ICONIC_BITMAP

与 DwmSetWindowAttribute 一起使用。 窗口将提供一个位图供 DWM 用作图标缩略图或速览表示形式, (窗口的静态位图) 。 可以使用 DWMWA_FORCE_ICONIC_REPRESENTATION 指定DWMWA_HAS_ICONIC_BITMAP。 DWMWA_HAS_ICONIC_BITMAP 通常在创建窗口期间设置,在窗口的整个生存期内不会更改。 但是,某些方案可能需要值随时间推移而更改。 pvAttribute 参数指向 BOOL 类型的值。 如果为 TRUE ,则告知 DWM 窗口将提供图标缩略图或速览表示形式;否则为 FALSE。Windows Vista 及更早版本: 不支持此值。

DWMWA_DISALLOW_PEEK

与 DwmSetWindowAttribute 一起使用。 不显示窗口的速览预览。 当鼠标悬停在任务栏中的窗口缩略图上时,速览视图将显示窗口的全尺寸预览。 如果设置了此属性,将鼠标指针悬停在窗口缩略图上会消除速览 (以防组中的另一个窗口具有显示) 的速览预览。 pvAttribute 参数指向 BOOL 类型的值。 如果为 TRUE ,则阻止速览功能,如果为 FALSE ,则允许它。Windows Vista 及更早版本: 不支持此值。

DWMWA_EXCLUDED_FROM_PEEK

与 DwmSetWindowAttribute 一起使用。 防止窗口在调用 peek 时褪色到玻璃板。 pvAttribute 参数指向 BOOL 类型的值。 如果为 TRUE ,则防止窗口在另一个窗口的速览期间褪色,对于正常行为, 则为 FALSE 。Windows Vista 及更早版本: 不支持此值。

DWMWA_CLOAK

与 DwmSetWindowAttribute 一起使用。 遮罩窗口,使其对用户不可见。 窗口仍由 DWM 组成。将 与 DirectComposition 配合使用: 通过与分层子窗口关联的 DirectComposition 视觉对象对窗口内容的表示形式进行动画处理时,使用 DWMWA_CLOAK 标志遮蔽分层子窗口。 有关此用例的更多详细信息,请参阅 如何对分层子窗口的位图进行动画处理。Windows 7 及更早版本: 不支持此值。

DWMWA_CLOAKED

与 DwmGetWindowAttribute 一起使用。 如果窗口是隐藏的, 请提供以下值之一来解释原因。DWM_CLOAKED_APP (值0x00000001) 。 窗口已被其所有者应用程序遮蔽。DWM_CLOAKED_SHELL (值0x00000002) 。 窗户被壳牌遮蔽了。DWM_CLOAKED_INHERITED (值0x00000004) 。 隐藏值继承自其所有者窗口。Windows 7 及更早版本: 不支持此值。

DWMWA_FREEZE_REPRESENTATION

与 DwmSetWindowAttribute 一起使用。 使用当前视觉对象冻结窗口的缩略图。 不要对缩略图进行进一步的实时更新,以匹配窗口的内容。Windows 7 及更早版本: 不支持此值。

DWMWA_USE_HOSTBACKDROPBRUSH

与 DwmSetWindowAttribute 一起使用。 允许非 UWP 窗口使用主机背景画笔。 如果设置了此标志,则调用 Windows::UI::Composition API 的 Win32 应用可以使用主机背景画笔生成透明度效果 (请参阅 Compositor.CreateHostBackdropBrush) 。 pvAttribute 参数指向 BOOL 类型的值。 如果为 TRUE ,则为窗口启用主机背景画笔,如果为 FALSE ,则禁用它。

从 Windows 11 版本 22000 开始支持此值。

DWMWA_USE_IMMERSIVE_DARK_MODE

与 DwmSetWindowAttribute 一起使用。 启用深色模式系统设置时,允许以深色模式颜色绘制此窗口的窗口框架。 出于兼容性原因,无论系统设置如何,所有窗口都默认为浅色模式。 pvAttribute 参数指向 BOOL 类型的值。 TRUE 表示窗口采用深色模式, FALSE 表示始终使用浅色模式。

从 Windows 11 版本 22000 开始支持此值。

DWMWA_WINDOW_CORNER_PREFERENCE

与 DwmSetWindowAttribute 一起使用。 指定窗口的圆角首选项。 pvAttribute 参数指向 DWM_WINDOW_CORNER_PREFERENCE 类型的值。

从 Windows 11 版本 22000 开始支持此值。

DWMWA_BORDER_COLOR

与 DwmSetWindowAttribute 一起使用。 指定窗口边框的颜色。 pvAttribute 参数指向 COLORREF 类型的值。 应用负责根据状态更改(例如窗口激活中的更改)更改边框颜色。

为颜色 指定DWMWA_COLOR_NONE (值0xFFFFFFFE) 将禁止绘制窗口边框。 这样,就可以有一个没有边框的圆角窗口。

为颜色指定 DWMWA_COLOR_DEFAULT (值0xFFFFFFFF) 会将窗口重置回使用系统对边框颜色的默认行为。

从 Windows 11 内部版本 22000 开始支持此值。

DWMWA_CAPTION_COLOR

与 DwmSetWindowAttribute 一起使用。 指定描述文字的颜色。 pvAttribute 参数指向 COLORREF 类型的值。

为颜色指定DWMWA_COLOR_DEFAULT (值0xFFFFFFFF) 会将窗口重置回使用系统对描述文字颜色的默认行为。

从 Windows 11 内部版本 22000 开始支持此值。

DWMWA_TEXT_COLOR

与 DwmSetWindowAttribute 一起使用。 指定描述文字文本的颜色。 pvAttribute 参数指向 COLORREF 类型的值。

指定颜色DWMWA_COLOR_DEFAULT (值0xFFFFFFFF) 会将窗口重置回使用系统描述文字文本颜色的默认行为。

从 Windows 11 内部版本 22000 开始支持此值。

DWMWA_VISIBLE_FRAME_BORDER_THICKNESS

与 DwmGetWindowAttribute 一起使用。 检索 DWM 将围绕此窗口绘制的外部边框的宽度。 该值可能因窗口的 DPI 而异。 pvAttribute 参数指向 UINT 类型的值。

从 Windows 11 内部版本 22000 开始支持此值。

DWMWA_SYSTEMBACKDROP_TYPE

与 DwmGetWindowAttribute 或 DwmSetWindowAttribute 一起使用。 检索或指定窗口的系统绘制背景材料,包括在非工作区后面。 pvAttribute 参数指向 DWM_SYSTEMBACKDROP_TYPE 类型的值。

从 Windows 11 内部版本 22621 开始支持此值。

DWMWA_LAST

最大识别的 DWMWINDOWATTRIBUTE 值,用于验证目的。

 读取深浅模式、主题颜色、十六进制颜色转换

注意,ThemeColor是Bool值

Public ThemeColor As Boolean
Public color As Color
Private Sub GetThemeColor()
    Dim key As RegistryKey = Registry.CurrentUser.OpenSubKey("SOFTWARE\Microsoft\Windows\CurrentVersion\Themes\Personalize")
    If key IsNot Nothing Then
        Dim appsUseLightTheme As Integer = CInt(key.GetValue("AppsUseLightTheme", -1))
        If appsUseLightTheme = 0 Then
            ThemeColor = 1
        ElseIf appsUseLightTheme = 1 Then
            ThemeColor = 0
        Else
        End If
        key.Close()
    End If
End Sub
Function GetSystemColor() As Color
    Dim key As RegistryKey = Registry.CurrentUser.OpenSubKey("SOFTWARE\Microsoft\Windows\DWM")
    If key IsNot Nothing Then
        Dim value As Integer = CInt(key.GetValue("ColorizationColor"))
        Dim HexColor = Convert.ToString(value, 16)
        key.Close()
        Return ConvertSystemColor(HexColor)
    End If
End Function
Function ConvertSystemColor(HexColor As String) As Color
    Return Color.FromArgb(Convert.ToInt32(HexColor.Substring(0, 2), 16), Convert.ToInt32(HexColor.Substring(2, 2), 16), Convert.ToInt32(HexColor.Substring(4, 2), 16), Convert.ToInt32(HexColor.Substring(6, 2), 16))
End Function

完整代码

Imports Microsoft.Win32
Imports System.Runtime.InteropServices
Public Class Form1
    Public ThemeColor As Boolean
    Public color As Color
    Private Sub GetThemeColor()
        Dim key As RegistryKey = Registry.CurrentUser.OpenSubKey("SOFTWARE\Microsoft\Windows\CurrentVersion\Themes\Personalize")
        If key IsNot Nothing Then
            Dim appsUseLightTheme As Integer = CInt(key.GetValue("AppsUseLightTheme", -1))
            If appsUseLightTheme = 0 Then
                ThemeColor = 1
            ElseIf appsUseLightTheme = 1 Then
                ThemeColor = 0
            Else
            End If
            key.Close()
        End If
    End Sub
    Function GetSystemColor() As Color
        Dim key As RegistryKey = Registry.CurrentUser.OpenSubKey("SOFTWARE\Microsoft\Windows\DWM")
        If key IsNot Nothing Then
            Dim value As Integer = CInt(key.GetValue("ColorizationColor"))
            Dim HexColor = Convert.ToString(value, 16)
            key.Close()
            Return ConvertSystemColor(HexColor)
        End If
    End Function
    Function ConvertSystemColor(HexColor As String) As Color
        Return Color.FromArgb(Convert.ToInt32(HexColor.Substring(0, 2), 16), Convert.ToInt32(HexColor.Substring(2, 2), 16), Convert.ToInt32(HexColor.Substring(4, 2), 16), Convert.ToInt32(HexColor.Substring(6, 2), 16))
    End Function
    Sub ChangeTheme(sender As Object, e As UserPreferenceChangedEventArgs)
        If e.Category = UserPreferenceCategory.General Then
            GetThemeColor()
            DwmSetWindowAttribute(Me.Handle, DwmWindowAttribute.UseImmersiveDarkMode, ThemeColor, Marshal.SizeOf(Of Integer))
            color = GetSystemColor()
            Label1.BackColor = color
        End If
    End Sub
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        GetThemeColor()
        color = GetSystemColor()
        Label1.BackColor = color
        AddHandler SystemEvents.UserPreferenceChanged, AddressOf ChangeTheme
        DwmSetWindowAttribute(Me.Handle, DwmWindowAttribute.UseImmersiveDarkMode, ThemeColor, Marshal.SizeOf(Of Integer))
    End Sub
    
    Public Shared Function DwmSetWindowAttribute(ByVal hwnd As IntPtr, ByVal attr As DwmWindowAttribute, ByRef attrValue As Integer, ByVal attrSize As Integer) As Integer
    End Function
    Public Enum DwmWindowAttribute
        NCRenderingEnabled = 1
        NCRenderingPolicy
        TransitionsForceDisabled
        AllowNCPaint
        CaptionButtonBounds
        NonClientRtlLayout
        ForceIconicRepresentation
        Flip3DPolicy
        ExtendedFrameBounds
        HasIconicBitmap
        DisallowPeek
        ExcludedFromPeek
        Cloak
        Cloaked
        FreezeRepresentation
        PassiveUpdateMode
        UseHostBackdropBrush
        UseImmersiveDarkMode = 20
        WindowCornerPreference = 33
        BorderColor
        CaptionColor
        TextColor
        VisibleFrameBorderThickness
        SystemBackdropType
        Last
    End Enum
End Class
The End
微信