locked
Set Form's Backcolor to Same Color as Current Aero Style Color RRS feed

  • Question

  • Windows 7 Home Premium and VB Express 2010.

    I found the following Code on the Net for changing a Picturebox Backcolor to the current Aero color (ie. Windows Forms, non-client area, and Taskbar, etc):

    Private Const WM_DWMCOMPOSITIONCHANGED As Integer = 798
    Private Const WM_DWMNCRENDERINGCHANGED As Integer = 799
    Private Const WM_DWMCOLORIZATIONCOLORCHANGED As Integer = 800
    Private Const WM_DWMWINDOWMAXIMIZEDCHANGE As Integer = 801

    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)
       Me.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

    I added the Me.BackColor because that's all i wanted to accomplish.  To make my form have the same Backcolor as the current Aero color.

    First of all, I don't really like reading the Registry.

    Secondly, the above code produces a Run-time error for Me.BackColor.  Without that, it works well enough.

    Can someone knowledgeable in these things help me to change the code so it works for the Forms Backcolor?

    I've searched the net and only found examples of changing the Forms Backcolor to a System Color (ie, Control, ActiveCaption, etc.).

    But, those colors have NOTHING to do with the current Aero color.


    If the directions say go straight, but I turn left, then right: Will I still get there?
    Wednesday, May 18, 2011 3:30 PM

Answers

  • As Silvisoft suggested - the alpha channel is < 255 on the color returned, so it doesn't like it. You can set it to 255 by Or-ing with &HFF000000.

    You can get the current colour with an api call.

    You should check the OS version as the api calls will fail on OSes that were released before Aero. You don't have to check if composition is enabled - but it might make sense - why set things to Aero colors if the user doesn't have Aero switched on. If you decide to check if composition is enabled then you should also check to see if the enabled state changes by catching its windows message.

    Option Strict On
    Option Explicit On
    
    Imports System.ComponentModel
    Imports System.Runtime.InteropServices
    Imports System.Security
    
    Public Class Form1
    
      Public Event ColourizationChanged As EventHandler(Of ColorizationChangedEventArgs)
    
      Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
        Const WM_DWMCOLORIZATIONCOLORCHANGED As Integer = 800
        If m.Msg = WM_DWMCOLORIZATIONCOLORCHANGED Then
          Dim l As Boolean = (m.LParam.ToInt32 = 0)
          Dim w As Integer = m.WParam.ToInt32
          Dim c As New Colorization(w, l)
          Dim args As New ColorizationChangedEventArgs(c)
          RaiseEvent ColourizationChanged(Me, args)
        End If
        MyBase.WndProc(m)
      End Sub
    
      Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        If Colorization.OsSupportsAero Then SetBackColor(Colorization.GetDwmColorization)
      End Sub
    
      Private Sub Form1_ColourizationChanged(ByVal sender As Object, ByVal e As ColorizationChangedEventArgs) Handles Me.ColourizationChanged
        SetBackColor(e.Colorization)
      End Sub
    
      Private Sub SetBackColor(ByVal colorization As Colorization)
        Me.Text = colorization.Color.ToString & " " & colorization.OpaqueBlend.ToString
        Me.BackColor = colorization.SolidColor ' alpha is set to 255.
      End Sub
    
    End Class
    
    Public Class Colorization
    
      Public Property Color As Color
      Public Property SolidColor As Color    
      Public Property OpaqueBlend As Boolean
    
      <SuppressUnmanagedCodeSecurity()> _
      Private Class NativeMethods
        <DllImport("dwmapi.dll")> _
        Public Shared Function DwmGetColorizationColor(<Out()> ByRef pColor As Integer, <Out()> ByRef opaqueBlend As Boolean) As Integer
        End Function
      End Class
    
      Public Sub New(ByVal argb As Integer, ByVal opaqueBlend As Boolean)
        Me.Color = Color.FromArgb(argb)
        Me.SolidColor = Color.FromArgb(argb Or &HFF000000)
        Me.OpaqueBlend = opaqueBlend
      End Sub
    
      Public Shared Function GetDwmColorization() As Colorization
        Dim argb As Integer
        Dim opaqueBlend As Boolean
        Dim result As Integer = NativeMethods.DwmGetColorizationColor(argb, opaqueBlend)
        If result <> 0 Then Throw New Win32Exception
        Return New Colorization(argb, opaqueBlend)
      End Function
    
      Public Shared Function OsSupportsAero() As Boolean
        Return (Environment.OSVersion.Version.Major > 5)
      End Function
    
    End Class
    
    
    Public Class ColorizationChangedEventArgs
      Inherits EventArgs
    
      Public Property Colorization As Colorization
    
      Public Sub New(ByVal colorization As Colorization)
        Me.Colorization = colorization
      End Sub
    
    End Class
    

     

    Sunday, May 22, 2011 10:24 AM

All replies

  • I should just forget this plea for assistance as further research has shown me that this has been an issue for well over one year.

    The issue being DwmGetColorizationColor function, its returns -- and opaque blending onto glass.  Wow!!

    Quite a handful for Visual Basic beginners (speaking of myself) !!!

    Being able to retrieve a base color would be so nice.  Oh, well...


    If the directions say go straight, but I turn left, then right: Will I still get there?
    Wednesday, May 18, 2011 9:22 PM
  • Windows 7 Home Premium and VB Express 2010.

    I found the following Code on the Net for changing a Picturebox Backcolor to the current Aero color (ie. Windows Forms, non-client area, and Taskbar, etc):

    Private Const WM_DWMCOMPOSITIONCHANGED As Integer = 798
    Private Const WM_DWMNCRENDERINGCHANGED As Integer = 799
    Private Const WM_DWMCOLORIZATIONCOLORCHANGED As Integer = 800
    Private Const WM_DWMWINDOWMAXIMIZEDCHANGE As Integer = 801

    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)
       Me.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

    I added the Me.BackColor because that's all i wanted to accomplish.  To make my form have the same Backcolor as the current Aero color.

    First of all, I don't really like reading the Registry.

    Secondly, the above code produces a Run-time error for Me.BackColor.  Without that, it works well enough.

    Can someone knowledgeable in these things help me to change the code so it works for the Forms Backcolor?

    I've searched the net and only found examples of changing the Forms Backcolor to a System Color (ie, Control, ActiveCaption, etc.).

    But, those colors have NOTHING to do with the current Aero color.


    If the directions say go straight, but I turn left, then right: Will I still get there?

    A much simpler method would be:

    Remember to: Import System.Runtime.InteropServices

    #Region "Aero"

       <StructLayout(LayoutKind.Sequential)> _

        Public Structure MARGINS

            Public cxLeftWidth As Integer

            Public cxRightWidth As Integer

            Public cyTopHeight As Integer

            Public cyButtomheight As Integer

        End Structure

     

    <DllImport("dwmapi.dll")> _

        Public Shared Function DwmExtendFrameIntoClientArea(ByVal hWnd As IntPtr, ByRef pMarinset As MARGINS) As Integer

        End Function

     

        Sub AeroConfig()

            If Environment.OSVersion.Version.Major > 5 Then

                For Each clsProcess As Process In Process.GetProcesses()

                    If clsProcess.ProcessName.Contains("dwm") Then

                        Dim margins As New MARGINS()

                        margins.cxLeftWidth = 0

                        margins.cxRightWidth = 0

                        margins.cyTopHeight = 35

                        margins.cyButtomheight = 30

                        Bar1.BackColor = Color.Transparent

                        QTabControl1.BackColor = Color.Black

                        Dim hwnd As IntPtr = Me.Handle

                        Dim result As Integer = DwmExtendFrameIntoClientArea(hwnd, margins)

                        Exit For

                    End If

                Next

            End If

     

        End Sub

    #End Region

     

    Run the sub aeroconfig in the forms load event :)

    Set the size of the aero area with:

       margins.cxLeftWidth = 0

        margins.cxRightWidth = 0

        margins.cyTopHeight = 35

         margins.cyButtomheight = 30

     

    I hope this helped :D

     

    OB6160

    Thursday, May 19, 2011 4:00 PM
  • Without looking deeply into the code and without running it, I would guess that the runtime error you got is because you can't set a form's background color to a transparent color and that Aero uses transparency. That's my closest guess.
    Just call me Silvi or LS... My site: here
    Sunday, May 22, 2011 8:47 AM
  • As Silvisoft suggested - the alpha channel is < 255 on the color returned, so it doesn't like it. You can set it to 255 by Or-ing with &HFF000000.

    You can get the current colour with an api call.

    You should check the OS version as the api calls will fail on OSes that were released before Aero. You don't have to check if composition is enabled - but it might make sense - why set things to Aero colors if the user doesn't have Aero switched on. If you decide to check if composition is enabled then you should also check to see if the enabled state changes by catching its windows message.

    Option Strict On
    Option Explicit On
    
    Imports System.ComponentModel
    Imports System.Runtime.InteropServices
    Imports System.Security
    
    Public Class Form1
    
      Public Event ColourizationChanged As EventHandler(Of ColorizationChangedEventArgs)
    
      Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
        Const WM_DWMCOLORIZATIONCOLORCHANGED As Integer = 800
        If m.Msg = WM_DWMCOLORIZATIONCOLORCHANGED Then
          Dim l As Boolean = (m.LParam.ToInt32 = 0)
          Dim w As Integer = m.WParam.ToInt32
          Dim c As New Colorization(w, l)
          Dim args As New ColorizationChangedEventArgs(c)
          RaiseEvent ColourizationChanged(Me, args)
        End If
        MyBase.WndProc(m)
      End Sub
    
      Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        If Colorization.OsSupportsAero Then SetBackColor(Colorization.GetDwmColorization)
      End Sub
    
      Private Sub Form1_ColourizationChanged(ByVal sender As Object, ByVal e As ColorizationChangedEventArgs) Handles Me.ColourizationChanged
        SetBackColor(e.Colorization)
      End Sub
    
      Private Sub SetBackColor(ByVal colorization As Colorization)
        Me.Text = colorization.Color.ToString & " " & colorization.OpaqueBlend.ToString
        Me.BackColor = colorization.SolidColor ' alpha is set to 255.
      End Sub
    
    End Class
    
    Public Class Colorization
    
      Public Property Color As Color
      Public Property SolidColor As Color    
      Public Property OpaqueBlend As Boolean
    
      <SuppressUnmanagedCodeSecurity()> _
      Private Class NativeMethods
        <DllImport("dwmapi.dll")> _
        Public Shared Function DwmGetColorizationColor(<Out()> ByRef pColor As Integer, <Out()> ByRef opaqueBlend As Boolean) As Integer
        End Function
      End Class
    
      Public Sub New(ByVal argb As Integer, ByVal opaqueBlend As Boolean)
        Me.Color = Color.FromArgb(argb)
        Me.SolidColor = Color.FromArgb(argb Or &HFF000000)
        Me.OpaqueBlend = opaqueBlend
      End Sub
    
      Public Shared Function GetDwmColorization() As Colorization
        Dim argb As Integer
        Dim opaqueBlend As Boolean
        Dim result As Integer = NativeMethods.DwmGetColorizationColor(argb, opaqueBlend)
        If result <> 0 Then Throw New Win32Exception
        Return New Colorization(argb, opaqueBlend)
      End Function
    
      Public Shared Function OsSupportsAero() As Boolean
        Return (Environment.OSVersion.Version.Major > 5)
      End Function
    
    End Class
    
    
    Public Class ColorizationChangedEventArgs
      Inherits EventArgs
    
      Public Property Colorization As Colorization
    
      Public Sub New(ByVal colorization As Colorization)
        Me.Colorization = colorization
      End Sub
    
    End Class
    

     

    Sunday, May 22, 2011 10:24 AM