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

20 篇文章 1 订阅
4 篇文章 0 订阅

先上效果图

可直接跳到完整代码

目录

先上效果图

开始教学

响应用户的更改

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

    <DllImport("dwmapi.dll", PreserveSig:=True)>
    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
    <DllImport("dwmapi.dll", PreserveSig:=True)>
    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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值