.net 油漆应用标题栏?

.net 油漆应用标题栏?,.net,vb.net,winforms,drawing,gdi+,.net,Vb.net,Winforms,Drawing,Gdi+,如何在标题栏上绘制渐变(仅绘制为与visual XP主题颜色不同的颜色)以保持windows XP风格 我试图找到一些例子,但我没有找到任何东西,甚至只是为了替换纯色的标题栏渐变,我找到了一个简单的代码来绘制纯色,但它在Dim g As Graphics中抛出了一个异常,表示该值不能为空: <Runtime.InteropServices.DllImport("user32.dll")> Private Shared Function GetDCEx( ByVal h

如何在标题栏上绘制渐变(仅绘制为与visual XP主题颜色不同的颜色)以保持windows XP风格

我试图找到一些例子,但我没有找到任何东西,甚至只是为了替换纯色的标题栏渐变,我找到了一个简单的代码来绘制纯色,但它在
Dim g As Graphics
中抛出了一个异常,表示该值不能为空:

<Runtime.InteropServices.DllImport("user32.dll")>
Private Shared Function GetDCEx(
        ByVal hWnd As IntPtr,
        ByVal hrgnClip As IntPtr,
        ByVal DeviceContextValues As DeviceContextValues
) As IntPtr
End Function

Protected Overrides Sub WndProc(ByRef m As Message)

    MyBase.WndProc(m)

    If (m.Msg = 133) Then
        Dim DCX_CACHE As Integer = 2
        Dim DCX_WINDOW As Integer = 1
        Dim g As Graphics = Graphics.FromHdc(GetDCEx(Me.Handle, m.WParam, (DCX_WINDOW Or DCX_CACHE)))
        g.DrawLine(Pens.Red, New Point(0, 0), New Point(30, 30)) 'Draw Here
    End If

End Sub

私有共享函数GetDCEx(
ByVal hWnd作为IntPtr,
ByVal hrgnClip作为IntPtr,
ByVal DeviceContextValues作为DeviceContextValues
)As IntPtr
端函数
受保护的覆盖子WndProc(ByRef m作为消息)
MyBase.WndProc(m)
如果(m.Msg=133),则
Dim DCX_缓存为整数=2
Dim DCX_窗口为整数=1
Dim g As Graphics=Graphics.FromHdc(GetDCEx(Me.Handle,m.WParam,(DCX_窗口或DCX_缓存)))
g、 画线(钢笔。红色,新点(0,0),新点(30,30))'在这里画
如果结束
端接头

考虑到我从未做过你想做的事,我实在无法理解上面的代码。只要您不介意不能更改渐变,就可以创建一个VisualStudio主题,并将其作为代码中每个表单的主题。我也从来没有这样做过,所以我也不确定这会有多困难。

为了避免在dot-net应用程序中使用API调用,您可以在这里做很多事情

  • 删除了windows边框,并在窗体中创建了一个虚拟标题栏。这是一个最简单的解决方案,它允许您执行各种UI外观,而无需处理Windows API
  • 查看名称空间
  • 查看您的解决方案如何在windows 8中迁移到WPF和metro UI。应用程序菜单的整个方法都会发生变化,因此您的工作可能会被丢弃
  • 询问您的客户,标题栏颜色变化的商业案例是什么。也就是说,在过去,我曾让平面艺术家为我指定标题栏的颜色。我使用了上面的选项1
  • 一旦您完成了任何解决方案,您必须在各种操作系统中测试它,以确认API仍然相关(因此我建议您不要使用它们,因为M$不再是您的API调用朋友,因此建议使用.net方法)

  • 之后的某个时候,但这里是:

    a) 必须删除窗体的主题

    SetWindowTheme(Me.Handle, String.Empty, String.Empty)
    
    b) 对于m.WParam=1,GetDCEx失败。因此,GetWindowDC是您所需要的。你的超控是这样的

        Protected Overrides Sub WndProc(ByRef m As Message)
    
        MyBase.WndProc(m)
    
        If (m.Msg = 133) Then
            If m.WParam = 1 Then
                Dim g As Graphics = Graphics.FromHdc(GetWindowDC(Me.Handle))
                Using g
                    g.DrawLine(Pens.Red, New PointF(0, 0), New PointF(30, 30)) 'Draw Here
                End Using
                Me.Refresh()
    
            Else
    
                Dim DCX_CACHE As Integer = 2
                Dim DCX_WINDOW As Integer = 1
                Dim g As Graphics = Graphics.FromHdc(GetDCEx(Me.Handle, m.WParam, (DCX_WINDOW Or DCX_CACHE)))
                Using g
                    g.DrawLine(Pens.Red, New PointF(0, 0), New PointF(30, 30)) 'Draw Here
                End Using
                Me.Invalidate()
                Me.Refresh()
            End If
        End If
    
    End Sub
    
    另外两个声明如下所示

        <Runtime.InteropServices.DllImport("user32.dll")>
    Private Shared Function GetWindowDC(ByVal hWnd As IntPtr) As IntPtr
    End Function
    <Runtime.InteropServices.DllImport("uxtheme.dll")>
    Private Shared Function SetWindowTheme(ByVal hWnd As IntPtr, ByVal appName As String, ByVal partList As String) As Integer
    End Function
    

    而不是您拥有的IF块,并将GetDCEx的第二个参数作为Intptr.Zero传递。您永远不会得到空的返回值。这也会画一个边框(有点像某些Office或MS软件)和水平居中的表单文本(或标题)标题栏。绘画中有一个不包括客户区的添加项。这样,这个区域(客户端1)就不会出问题。希望能有所帮助。

    我想提醒大家,在标题栏中添加渐变会改变用户体验。如果你看一下所有的“现代”UI设计,渐变并没有被使用,因为它们增加了CPU/GPU的工作量。这也使得色盲的人更难使用你的软件。我怀疑这不是一个关于VS主题颜色的问题,而是一个应用程序主题化的问题。
    Using g As Graphics = Graphics.FromHdc(GetDCEx(Me.Handle, IntPtr.Zero, (DeviceContextValues.Window Or DeviceContextValues.Cache)))
        g.ExcludeClip(New Rectangle((Me.Width - Me.ClientSize.Width) / 2, (Me.Height - Me.ClientSize.Height) - ((Me.Width - Me.ClientSize.Width) / 2), Me.ClientRectangle.Width, Me.ClientRectangle.Height))
        g.FillRectangle(Brushes.DarkRed, New Rectangle(0, 0, Me.Width, Me.Height))
        g.DrawRectangle(Pens.Blue, New Rectangle(0, 0, Me.Width - 1, Me.Height - 1))
        g.DrawString(Me.Text, New Font("Tahoma", 10), Brushes.LightCyan, New PointF(Me.Width / 2 - Len(Me.Text) / 2, 4))
        End Using