65.9K
CodeProject 正在变化。 阅读更多。
Home

DWM - 使用 DWMGetColorizationColor 进行着色颜色处理

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.18/5 (6投票s)

2008年3月24日

CPOL

2分钟阅读

viewsIcon

68390

downloadIcon

637

使用 WM_COLORIZATIONCOLORCHANGED 和 DWMGetColorizationColor。

cc_white.jpg

引言

我试图让一个文本框在玻璃效果下工作,但却惨遭失败。 然后,我产生了反转背景色和前景色、制作一个漂亮的玻璃文本框的想法,但它有一个问题。 如果你将主题设置为白色或非常明亮的颜色,并且窗体位于非常明亮或白色的颜色之上,那么文本将无法读取。 我想到的解决方案? 检测玻璃颜色,如果他们使用非常明亮的颜色方案,则使用不同的前景色。 好吧,经过很长时间,我最终得到了这段代码,实际上它并没有解决我的文本框问题。 事实证明,将前景色设置为除了**白色**之外的**任何东西**都会使其再次清晰地绘制。 好的一面是? 我做了一些其他 VB.NET 或 C# 代码示例中没有找到的事情。 本文将向您展示如何使用该代码。

您将需要什么

  • Windows Vista Home Premium、Business、Enterprise 或 Ultimate
  • Visual Studio 2005/2008 (2003 可能有效)
  • DWM 已开启
  • 对 Windows 的工作方式有基本的了解(事件驱动)
  • 对消息的基本理解
  • 一台电脑 :P

使用代码

使用代码首先需要声明常量来保存事件的“友好名称”,以确定颜色何时更改。

Private Const WM_DWMCOLORIZATIONCOLORCHANGED As Integer = 800

接下来,我们需要处理 WndProc。处理 WndProc 基本上意味着我们将“监听” Windows 将消息传递到消息流中。

Protected Overloads Overrides Sub WndProc(ByRef msg As Message) 
'Code
  MyBase.WndProc(msg)
End Sub 

现在,我们需要“监听”颜色变化

If msg.Msg = WM_DWMCOLORIZATIONCOLORCHANGED Then 
'Color was Changed!
End If

现在我们知道用户更改了色彩颜色,我们应该获取该颜色并使其成为可用的颜色,对吧?

Dim aarrggbb = _
  My.Computer.Registry.GetValue("HKEY_CURRENT_USER\Software\Microsoft\Windows\DWM", _
  "ColorizationColor", "00000000")
Dim argb = Convert.ToInt32(CLng(aarrggbb.ToString), 10)
Dim argbcol = System.Drawing.Color.FromArgb(argb)

好的,那是一些有趣的代码,对吧? 基本上,它所做的是

  • 获取当前的色彩颜色
  • 将其从二进制转换为十进制(即使它是十六进制)
  • 从色彩颜色的十进制副本中创建颜色

现在,我们可以使用颜色。 在示例项目中,我使用该颜色来执行以下操作

PictureBox2.BackColor = System.Drawing.Color.FromArgb(argb)
Label1.Text = System.Drawing.Color.FromArgb(argb).ToString
Label1.ForeColor = System.Drawing.Color.FromArgb(argb)
Button1.Text = argbcol.ToString
Button1.ForeColor = argbcol

如果您不想向上滚动,这里再次运行项目

ccblue.jpg

您也可以在您自己的应用程序中使用 argbcol,它将代表 DWM 颜色。

一条额外的信息:出于文本框在玻璃效果下无法工作的相同原因,当同时使用多种颜色时,WinForms 无法正确处理 argbcol 的 alpha 值。 它将使用窗体的背景色作为其要透明的颜色,这就是为什么最清晰的玻璃设置在窗体上没有显示白色的原因

cc_white.jpg

它改为这样。 完整的代码清单是

Private Const WM_DWMCOLORIZATIONCOLORCHANGED As Integer = 800
Protected Overloads Overrides Sub WndProc(ByRef msg As Message)
    If msg.Msg = WM_DWMCOLORIZATIONCOLORCHANGED Then 
        'Color was Changed! 
        Dim aarrggbb = _
          My.Computer.Registry.GetValue("HKEY_CURRENT_USER\" & _ 
          "Software\Microsoft\Windows\DWM", _
          "ColorizationColor", "00000000")
        Dim argb = Convert.ToInt32(CLng(aarrggbb.ToString), 10)
        Dim argbcol = System.Drawing.Color.FromArgb(argb)
        PictureBox2.BackColor = System.Drawing.Color.FromArgb(argb)
        Label1.Text = System.Drawing.Color.FromArgb(argb).ToString
        Label1.ForeColor = System.Drawing.Color.FromArgb(argb)
        Button1.Text = argbcol.ToString
        Button1.ForeColor = argbcol
    End If 

    MyBase.WndProc(msg)
End Sub
© . All rights reserved.