油漆应用标题栏?

时间:2013-12-29 20:10:51

标签: .net vb.net winforms drawing gdi+

如何在titlbebar上绘制渐变(只是绘制与视觉XP主题颜色不同的颜色),保留windows XP风格?

我试图找到示例但是我甚至没有找到任何内容,只是为了替换纯色的标题栏渐变,我发现了一个简单的代码来绘制纯色,但它在{{{{{{ 1}}说该值不能为null:

Dim g As Graphics

3 个答案:

答案 0 :(得分:1)

您可以在此处执行许多操作以避免在dot net应用程序中使用API​​调用。

  1. 删除了窗口边框,并在表单中创建了一个虚拟标题栏。这是最简单的解决方案,允许您执行各种UI外观,而无需处理Windows API。
  2. 查看System.Drawing.Drawing2D.LinearGradientBrush命名空间。
  3. 回顾一下您的解决方案如何在Windows 8中迁移到WPF和Metro UI。应用程序菜单的整个方法发生了变化,因此您的工作可能会被丢弃。
  4. 询问您的客户,标题栏颜色的变化是什么商业案例。话虽如此,我曾经有过图形艺术家在过去对我说标题栏的颜色。我使用了上面的选项1.
  5. 一旦你完成任何解决方案,你将不得不在各种操作系统中测试它以确认API仍然相关(因此我建议你不要使用它们,因为M $不再是你的API调用的朋友了,因此建议使用.net方法)。

答案 1 :(得分:1)

之后的某个时间,但在这里:

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

SetThemeWindow我在form_load事件中调用它,它工作正常。 Using语句用于GC处理图形(清理)和Me.Refresh(),因为客户区域在调整表单大小(或最大化)时没有得到干草。

来自Mike(来自How to set the client area (ClientRectangle) in a borderless form?)的积分用于他在C#中的代码,这是相当完整的,并且具有不同的方向。他的编码指向NC区域大小,但也绘制它们。这里更像是画作。

希望它有所帮助!

[编辑]

我进行了第一次编辑,但进一步调查显示它可能在特定情况下有效,而不是真正的“最终解决方案”!

最近的调查结果如此。 GetDCEx函数实际上失败了,因为m.WParam没有提供所需的信息,并且让GetDCEx函数工作,你不需要“m.WParam = 1”IF测试。只需使用以下内容:

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

代替您拥有的IF块,并将GetDCEx的第二个参数作为Intptr.Zero传递。你永远不会得到一个空的返回值。这也绘制了边框(有点像Office或MS软件)和表单文本(或标题)标题栏水平居中。除了客户区之外,还有一个添加到绘画中。这样,这个区域(客户端1)没有任何问题。希望它有所帮助。

答案 2 :(得分:0)

我真的无法理解上面的代码,因为我从来没有做过你想要做的事情。只要您不介意无法更改渐变,您就可以创建一个Visual Studio主题并将其选为代码中每个表单的主题。我也从未这样做过,所以我不确定它会有多难。