在标题栏VB.NET中添加自定义按钮

时间:2011-05-30 05:08:31

标签: vb.net winforms titlebar

我只是想知道是否有可能使用VB.NET将自定义按钮添加到标题栏中。我在Stack Overflow上看过很多这样的问题,但未能得到确定的答案和工作答案。

任何人都可以帮我解决这个问题吗?我也检查过Google和其他网站,但无法渲染。我希望代码可以在Windows XP,Windows Vista和Windows 7上运行。

如果您能够提供正常工作的代码并且该按钮甚至必须能够接受点击事件并将其发布到其所处的表单以进行某些操作,我将感激

提前致谢

3 个答案:

答案 0 :(得分:4)

如果你的意思是winforms,我可以想到两种方法:

  • 隐藏标题栏并将其替换为您自己的标题栏,我不建议这样做。
  • 将按钮构建为一个非常小的形式,每次窗口移动时,您都会将其停靠在正确的位置。

答案 1 :(得分:1)

Matthew Scharley在his answer here写道:

  

以下将在XP中运行,我没有Vista机器方便测试   它,但我认为你的问题源于一个不正确的hWnd   不知何故。无论如何,使用评论不佳的代码。

我认为这不会在Vista和7中以图形方式显示.Maxw代码的翻译版本如下:

' The state of our little button
Private _buttState As ButtonState = ButtonState.Normal
Private _buttPosition As New Rectangle()

<DllImport("user32.dll")> _
Private Shared Function GetWindowDC(hWnd As IntPtr) As IntPtr
End Function
<DllImport("user32.dll")> _
Private Shared Function GetWindowRect(hWnd As IntPtr, ByRef lpRect As Rectangle) As Integer
End Function
<DllImport("user32.dll")> _
Private Shared Function ReleaseDC(hWnd As IntPtr, hDC As IntPtr) As Integer
End Function
Protected Overrides Sub WndProc(ByRef m As Message)
    Dim x As Integer, y As Integer
    Dim windowRect As New Rectangle()
    GetWindowRect(m.HWnd, windowRect)

    Select Case m.Msg
        ' WM_NCPAINT
        ' WM_PAINT
        Case &H85, &Ha
            MyBase.WndProc(m)

            DrawButton(m.HWnd)

            m.Result = IntPtr.Zero

            Exit Select

        ' WM_ACTIVATE
        Case &H86
            MyBase.WndProc(m)
            DrawButton(m.HWnd)

            Exit Select

        ' WM_NCMOUSEMOVE
        Case &Ha0
            ' Extract the least significant 16 bits
            x = (CInt(m.LParam) << 16) >> 16
            ' Extract the most significant 16 bits
            y = CInt(m.LParam) >> 16

            x -= windowRect.Left
            y -= windowRect.Top

            MyBase.WndProc(m)

            If Not _buttPosition.Contains(New Point(x, y)) AndAlso _buttState = ButtonState.Pushed Then
                _buttState = ButtonState.Normal
                DrawButton(m.HWnd)
            End If

            Exit Select

        ' WM_NCLBUTTONDOWN
        Case &Ha1
            ' Extract the least significant 16 bits
            x = (CInt(m.LParam) << 16) >> 16
            ' Extract the most significant 16 bits
            y = CInt(m.LParam) >> 16

            x -= windowRect.Left
            y -= windowRect.Top

            If _buttPosition.Contains(New Point(x, y)) Then
                _buttState = ButtonState.Pushed
                DrawButton(m.HWnd)
            Else
                MyBase.WndProc(m)
            End If

            Exit Select

        ' WM_NCLBUTTONUP
        Case &Ha2
            ' Extract the least significant 16 bits
            x = (CInt(m.LParam) << 16) >> 16
            ' Extract the most significant 16 bits
            y = CInt(m.LParam) >> 16

            x -= windowRect.Left
            y -= windowRect.Top

            If _buttPosition.Contains(New Point(x, y)) AndAlso _buttState = ButtonState.Pushed Then
                _buttState = ButtonState.Normal
                ' [[TODO]]: Fire a click event for your button 
                '           however you want to do it.
                DrawButton(m.HWnd)
            Else
                MyBase.WndProc(m)
            End If

            Exit Select

        ' WM_NCHITTEST
        Case &H84
            ' Extract the least significant 16 bits
            x = (CInt(m.LParam) << 16) >> 16
            ' Extract the most significant 16 bits
            y = CInt(m.LParam) >> 16

            x -= windowRect.Left
            y -= windowRect.Top

            If _buttPosition.Contains(New Point(x, y)) Then
                m.Result = DirectCast(18, IntPtr)
            Else
                ' HTBORDER
                MyBase.WndProc(m)
            End If

            Exit Select
        Case Else

            MyBase.WndProc(m)
            Exit Select
    End Select
End Sub

Private Sub DrawButton(hwnd As IntPtr)
    Dim hDC As IntPtr = GetWindowDC(hwnd)
    Dim x As Integer, y As Integer

    Using g As Graphics = Graphics.FromHdc(hDC)
        ' Work out size and positioning
        Dim CaptionHeight As Integer = Bounds.Height - ClientRectangle.Height
        Dim ButtonSize As Size = SystemInformation.CaptionButtonSize
        x = Bounds.Width - 4 * ButtonSize.Width
        y = (CaptionHeight - ButtonSize.Height) \ 2
        _buttPosition.Location = New Point(x, y)

        ' Work out color
        Dim color As Brush
        If _buttState = ButtonState.Pushed Then
            color = Brushes.LightGreen
        Else
            color = Brushes.Red
        End If

        ' Draw our "button"
        g.FillRectangle(color, x, y, ButtonSize.Width, ButtonSize.Height)
    End Using

    ReleaseDC(hwnd, hDC)
End Sub

Private Sub Form1_Load(sender As Object, e As EventArgs)
    _buttPosition.Size = SystemInformation.CaptionButtonSize
End Sub

答案 2 :(得分:0)

这是一个包含一些工作代码的示例:

http://www.dreamincode.net/forums/topic/69215-2008-custom-title-bar/

基本上,你需要创建一个没有边框的表单,然后滚动你自己的“标题栏”,它基本上是你可以自定义的顶部区域。这是一个难以完全正确实现的解决方案,但它可能是最好地实现这一目标的方法。