Wince5.0下实现XP风格的开始菜单源码(VB.net编码实现)

如果想学自定义控件及自己写事件和绑定事件处理过程,请仔细阅读源码,此源码属100%原创,遵循GPL协议但不限于GPL,本人给予复制创新者以用于商业软件的权力,但复制创新者对于本源码实现功能的提升修改必须遵循GPL开源精神。

 

下面是源码(分两部分)

第一部分:图文混编按钮自定义控件源码

Imports System.Reflection
Imports System.Drawing.Imaging
Public Class PictureButtonMenu
    Inherits System.Windows.Forms.UserControl
    Private ChangeColor As Boolean
    Private _BorderColor As Color = Color.Gold
    '标识文本的位置
    Public Enum Layout
        Left = 0
        right = 1
        up = 2
        down = 3
        middle = 4
    End Enum
    '字段
    '起始按钮颜色
    Private BackgroundImgColor As Color = Me.BackColor
    '按下后按钮颜色
    Private PressedImgColor As Color = Color.SteelBlue
    '是否按下
    Public Pressed As Boolean = False
    '是否移动到上面
    Public Moved As Boolean = False
    '当前图文布局
    Private TxtImgLayout As Layout = 1
    '当前按钮是否可用标志
    Private BtnEnabled As Boolean = True
    '属性
    Private Ctext As String = "按钮文本按钮文本"
    Public imageHeight As Integer = 16
    Public imageWidth As Integer = 16
    '当作为工具栏最终重新设置其大小时的变量
    Public BtnWidth As Integer = 0
    Public BtnHeight As Integer = 0
    ''' <summary>
    ''' 设置Icon图标的高度
    ''' </summary>
    ''' <remarks>设置Icon图标的高度</remarks>
    ''' <value>32</value>
    Public Property setImageHeight() As Integer
        Get
            Return Me.ImageHeight
        End Get
        Set(ByVal Value As Integer)
            Me.ImageHeight = Value
        End Set
    End Property

    Public Property SetTag() As Integer
        Get
            Return MyBase.Tag
        End Get
        Set(ByVal value As Integer)
            MyBase.Tag = value
        End Set
    End Property
    '单击按钮后启动的外接程序(平台可以任意添加EXE了)
    Public BtnAppName As String = ""
    Public Property SetAppName() As String
        Get
            Return Me.BtnAppName
        End Get
        Set(ByVal value As String)
            Me.BtnAppName = value
        End Set
    End Property

    Public Property setImageWidth() As Integer
        Get
            Return Me.ImageWidth
        End Get
        Set(ByVal Value As Integer)
            Me.ImageWidth = Value
        End Set
    End Property


    '平时的背景色
    Public Property BackgroundImgColorValue() As Color
        Get
            Return Me.BackgroundImgColor
        End Get
        Set(ByVal Value As Color)
            Me.BackgroundImgColor = Value
        End Set
    End Property


    '鼠标按下后的背景色
    Public Property PressedImageColorValue() As Color
        Get
            Return Me.pressedImgColor
        End Get
        Set(ByVal Value As Color)
            Me.pressedImgColor = Value
        End Set
    End Property
    '显示的文本
    Public Property Caption() As String
        Get
            Return Me.Ctext
        End Get
        Set(ByVal Value As String)
            Me.Ctext = Value
        End Set
    End Property
    '文字的布局
    Public Property TextImageLayout() As Layout
        Get
            Return Me.TxtImgLayout
        End Get
        Set(ByVal Value As Layout)
            Me.TxtImgLayout = Value
        End Set
    End Property
    '控件大小是否自动调整
    Private ControlSizeSet As Boolean = False
    Public Property ControlSizeSetF() As Boolean
        Get
            Return ControlSizeSet
        End Get
        Set(ByVal value As Boolean)
            Me.ControlSizeSet = value
        End Set
    End Property
    Private bmpIconCount As Integer = 0
    Private bmp As Image
    Public Sub AddBmp(ByVal bmpSl As Image)
        bmp = bmpSl
        bmpIconCount = 1
    End Sub
    '是否是父菜单(默认不是)
    Private YNParentMenu As Boolean = False
    Public Property SetParentMenu() As Boolean
        Get
            Return YNParentMenu
        End Get
        Set(ByVal value As Boolean)
            YNParentMenu = value
        End Set
    End Property

    '绘制表面
    Protected Overrides Sub OnPaint(ByVal e As PaintEventArgs)

        Dim gp As Graphics = e.Graphics
        '控件大小不自动调整
        If ControlSizeSet = False Then

            Select Case bmpIconCount
                Case 0 '画背景
                    Dim backgroundImg As Image = MakeBitmap(BackgroundImgColor, Me.Width, Me.Height)
                    Dim pressedImg As Image = MakeBitmap(PressedImgColor, Me.Width, Me.Height)
                    If Me.Pressed AndAlso (pressedImg IsNot Nothing) Then
                        gp.DrawImage(pressedImg, 0, 0)

                        e.Graphics.DrawRectangle(DirectCast(New Pen(_BorderColor), Pen), 0, 0, Me.Width - 1, Me.Height - 1)

                    ElseIf Me.Moved AndAlso (pressedImg IsNot Nothing) Then
                        gp.DrawImage(pressedImg, 0, 0)
                    ElseIf Me.BtnEnabled = False Then
                        '按钮不可用时
                        Dim UnenableImg As Image = MakeBitmap(Color.FromArgb(247, 247, 239), Me.Width, Me.Width)
                        gp.DrawImage(UnenableImg, 0, 0)
                        e.Graphics.DrawRectangle(DirectCast(New Pen(Color.FromArgb(206, 199, 189), 3), Pen), 0, 0, Me.Width - 1, Me.Height - 1)
                        UnenableImg.Dispose()
                    Else
                        gp.DrawImage(backgroundImg, 0, 0)
                        '三维效果
                        ' e.Graphics.DrawRectangle(DirectCast(New Pen(Color.Transparent), Pen), 0, 0, Me.Width, Me.Height)

                    End If
                    backgroundImg.Dispose()
                    pressedImg.Dispose()
                    If Me.Ctext.Length > 0 Then
                        Dim size As SizeF = e.Graphics.MeasureString(Me.Ctext, Me.Font)
                        If Me.BtnEnabled = False Then
                            e.Graphics.DrawString(Me.Ctext, Me.Font, New SolidBrush(Color.FromArgb(173, 170, 156)), (Me.ClientSize.Width - size.Width) / 2, (Me.ClientSize.Height - size.Height) / 2)
                        Else
                            e.Graphics.DrawString(Me.Ctext, Me.Font, New SolidBrush(Me.ForeColor), (Me.ClientSize.Width - size.Width) / 2, (Me.ClientSize.Height - size.Height) / 2)
                        End If
                    End If
                Case 1 '画图像

                    Dim vsizef As SizeF

                    If Me.Pressed AndAlso (bmp IsNot Nothing) Then
                        '文本颜色取按下的颜色
                        Dim cbrush As New System.Drawing.SolidBrush(Me.PressedImgColor)
                        Select Case Me.TxtImgLayout
                            Case Layout.Left
                                vsizef = gp.MeasureString(Ctext, Me.Font)

                                '虽然预留了8个像素 但是只平均8个像素
                                gp.DrawString(Ctext, Me.Font, cbrush, 4, (Me.ClientSize.Height - vsizef.Height) / 2)
                                '图像的X坐标是vsizef.Width + 8
                                Dim imgRect As Rectangle = New Rectangle(vsizef.Width + 8, (Me.ClientSize.Height - imageHeight) / 2, ImageWidth, ImageHeight)
                                Dim imageAttr As New ImageAttributes
                                imageAttr.SetColorKey(BackgroundImageColor(bmp), BackgroundImageColor(bmp))
                                gp.DrawImage(bmp, imgRect, 0, 0, imageWidth, imageHeight, GraphicsUnit.Pixel, imageAttr)
                                imgRect = Nothing
                                imageAttr = Nothing
                            Case Layout.right
                                vsizef = gp.MeasureString(Ctext, Me.Font)

                                '图像的Y坐标是(cHeight - ImageHeight) / 2
                                Dim imgRect As Rectangle = New Rectangle(0, (Me.ClientSize.Height - imageHeight) / 2, imageWidth, imageHeight)
                                Dim imageAttr As New ImageAttributes
                                imageAttr.SetColorKey(BackgroundImageColor(bmp), BackgroundImageColor(bmp))
                                gp.DrawImage(bmp, imgRect, 0, 0, imageWidth, imageHeight, GraphicsUnit.Pixel, imageAttr)
                                imgRect = Nothing
                                imageAttr = Nothing
                                '虽然预留了8个像素 但是只平均6个像素
                                gp.DrawString(Ctext, Me.Font, cbrush, Me.ImageWidth + 3, (Me.ClientSize.Height - vsizef.Height) / 2)
                            Case Layout.up
                                vsizef = gp.MeasureString(Ctext, Me.Font)

                                '文本起始坐标(3,2)
                                gp.DrawString(Ctext, Me.Font, cbrush, (Me.ClientSize.Width - vsizef.Width) / 2, 2)

                                '图像的Y坐标是vsizef.Height + 4
                                Dim imgRect As Rectangle = New Rectangle((Me.ClientSize.Width - imageWidth) / 2 - 1, vsizef.Height + 4, imageWidth, imageHeight)
                                Dim imageAttr As New ImageAttributes
                                imageAttr.SetColorKey(BackgroundImageColor(bmp), BackgroundImageColor(bmp))
                                gp.DrawImage(bmp, imgRect, 0, 0, imageWidth, imageHeight, GraphicsUnit.Pixel, imageAttr)
                                imgRect = Nothing
                                imageAttr = Nothing
                            Case Layout.down

                                vsizef = gp.MeasureString(Ctext, Me.Font)

                                '图像的X坐标是(Me.Width - ImageWidth) / 2 - 1
                                Dim imgRect As Rectangle = New Rectangle((Me.ClientSize.Width - imageWidth) / 2 - 1, 0, imageWidth, imageHeight)
                                Dim imageAttr As New ImageAttributes
                                imageAttr.SetColorKey(BackgroundImageColor(bmp), BackgroundImageColor(bmp))
                                gp.DrawImage(bmp, imgRect, 0, 0, imageWidth, imageHeight, GraphicsUnit.Pixel, imageAttr)
                                imgRect = Nothing
                                imageAttr = Nothing
                                '文本起始坐标(3,2)
                                gp.DrawString(Ctext, Me.Font, cbrush, (Me.ClientSize.Width - vsizef.Width) / 2 - 1, ImageHeight + 2)

                            Case Layout.middle
                                vsizef = gp.MeasureString(Ctext, Me.Font)

                                '图像的X坐标是(Me.Width - ImageWidth) / 2 - 1
                                Dim imgRect As Rectangle = New Rectangle((Me.ClientSize.Width - imageWidth) / 2, (Me.ClientSize.Height - imageHeight) / 2, imageWidth, imageHeight)
                                Dim imageAttr As New ImageAttributes
                                imageAttr.SetColorKey(BackgroundImageColor(bmp), BackgroundImageColor(bmp))
                                gp.DrawImage(bmp, imgRect, 0, 0, imageWidth, imageHeight, GraphicsUnit.Pixel, imageAttr)
                                imgRect = Nothing
                                imageAttr = Nothing
                                '文本起始坐标(3,2)
                                gp.DrawString(Ctext, Me.Font, cbrush, (Me.ClientSize.Width - vsizef.Width) / 2, (Me.ClientSize.Height - vsizef.Height) / 2)
                        End Select

                        cbrush.Dispose()
                        cbrush = Nothing
                        '四周画颜色矩形
                        e.Graphics.DrawRectangle(DirectCast(New Pen(_BorderColor), Pen), 0, 0, Me.ClientSize.Width - 1, Me.ClientSize.Height - 1)
                        gp.Dispose()
                        gp = Nothing

                    ElseIf Me.Moved AndAlso (bmp IsNot Nothing) Then
                        '文本颜色取前景色
                        Dim cbrush As New System.Drawing.SolidBrush(Me.PressedImgColor)
                        Select Case Me.TxtImgLayout
                            Case Layout.Left
                                vsizef = gp.MeasureString(Ctext, Me.Font)

                                '虽然预留了8个像素 但是只平均8个像素
                                gp.DrawString(Ctext, Me.Font, cbrush, 4, (Me.ClientSize.Height - vsizef.Height) / 2)
                                '图像的X坐标是vsizef.Width + 8
                                Dim imgRect As Rectangle = New Rectangle(vsizef.Width + 8, (Me.ClientSize.Height - imageHeight) / 2, imageWidth, imageHeight)
                                Dim imageAttr As New ImageAttributes
                                imageAttr.SetColorKey(BackgroundImageColor(bmp), BackgroundImageColor(bmp))
                                gp.DrawImage(bmp, imgRect, 0, 0, imageWidth, imageHeight, GraphicsUnit.Pixel, imageAttr)
                                imgRect = Nothing
                                imageAttr = Nothing
                            Case Layout.right
                                vsizef = gp.MeasureString(Ctext, Me.Font)

                                '图像的Y坐标是(cHeight - ImageHeight) / 2
                                Dim imgRect As Rectangle = New Rectangle(0, (Me.ClientSize.Height - imageHeight) / 2, imageWidth, imageHeight)
                                Dim imageAttr As New ImageAttributes
                                imageAttr.SetColorKey(BackgroundImageColor(bmp), BackgroundImageColor(bmp))
                                gp.DrawImage(bmp, imgRect, 0, 0, imageWidth, imageHeight, GraphicsUnit.Pixel, imageAttr)
                                imgRect = Nothing
                                imageAttr = Nothing
                                '虽然预留了8个像素 但是只平均6个像素
                                gp.DrawString(Ctext, Me.Font, cbrush, Me.imageWidth + 3, (Me.ClientSize.Height - vsizef.Height) / 2)
                            Case Layout.up
                                vsizef = gp.MeasureString(Ctext, Me.Font)

                                '文本起始坐标(3,2)
                                gp.DrawString(Ctext, Me.Font, cbrush, (Me.ClientSize.Width - vsizef.Width) / 2, 2)

                                '图像的Y坐标是vsizef.Height + 4
                                Dim imgRect As Rectangle = New Rectangle((Me.ClientSize.Width - imageWidth) / 2 - 1, vsizef.Height + 4, imageWidth, imageHeight)
                                Dim imageAttr As New ImageAttributes
                                imageAttr.SetColorKey(BackgroundImageColor(bmp), BackgroundImageColor(bmp))
                                gp.DrawImage(bmp, imgRect, 0, 0, imageWidth, imageHeight, GraphicsUnit.Pixel, imageAttr)
                                imgRect = Nothing
                                imageAttr = Nothing
                            Case Layout.down

                                vsizef = gp.MeasureString(Ctext, Me.Font)

                                '图像的X坐标是(Me.Width - ImageWidth) / 2 - 1
                                Dim imgRect As Rectangle = New Rectangle((Me.ClientSize.Width - imageWidth) / 2 - 1, 0, imageWidth, imageHeight)
                                Dim imageAttr As New ImageAttributes
                                imageAttr.SetColorKey(BackgroundImageColor(bmp), BackgroundImageColor(bmp))
                                gp.DrawImage(bmp, imgRect, 0, 0, imageWidth, imageHeight, GraphicsUnit.Pixel, imageAttr)
                                imgRect = Nothing
                                imageAttr = Nothing
                                '文本起始坐标(3,2)
                                gp.DrawString(Ctext, Me.Font, cbrush, (Me.ClientSize.Width - vsizef.Width) / 2 - 1, imageHeight + 2)

                            Case Layout.middle
                                vsizef = gp.MeasureString(Ctext, Me.Font)

                                '图像的X坐标是(Me.Width - ImageWidth) / 2 - 1
                                Dim imgRect As Rectangle = New Rectangle((Me.ClientSize.Width - imageWidth) / 2, (Me.ClientSize.Height - imageHeight) / 2, imageWidth, imageHeight)
                                Dim imageAttr As New ImageAttributes
                                imageAttr.SetColorKey(BackgroundImageColor(bmp), BackgroundImageColor(bmp))
                                gp.DrawImage(bmp, imgRect, 0, 0, imageWidth, imageHeight, GraphicsUnit.Pixel, imageAttr)
                                imgRect = Nothing
                                imageAttr = Nothing
                                '文本起始坐标(3,2)
                                gp.DrawString(Ctext, Me.Font, cbrush, (Me.ClientSize.Width - vsizef.Width) / 2, (Me.ClientSize.Height - vsizef.Height) / 2)
                        End Select
                        cbrush.Dispose()
                        cbrush = Nothing
                        gp.Dispose()
                        gp = Nothing
                    ElseIf Me.BtnEnabled = False Then
                        '文本颜色取前景色
                        Dim cbrush As New System.Drawing.SolidBrush(Color.FromArgb(173, 170, 156))
                        Select Case Me.TxtImgLayout
                            Case Layout.Left
                                vsizef = gp.MeasureString(Ctext, Me.Font)

                                '虽然预留了8个像素 但是只平均8个像素
                                gp.DrawString(Ctext, Me.Font, cbrush, 4, (Me.ClientSize.Height - vsizef.Height) / 2)
                                '图像的X坐标是vsizef.Width + 8
                                Dim imgRect As Rectangle = New Rectangle(vsizef.Width + 8, (Me.ClientSize.Height - imageHeight) / 2, imageWidth, imageHeight)
                                Dim imageAttr As New ImageAttributes
                                imageAttr.SetColorKey(BackgroundImageColor(bmp), BackgroundImageColor(bmp))
                                gp.DrawImage(bmp, imgRect, 0, 0, imageWidth, imageHeight, GraphicsUnit.Pixel, imageAttr)
                                imgRect = Nothing
                                imageAttr = Nothing
                            Case Layout.right
                                vsizef = gp.MeasureString(Ctext, Me.Font)

                                '图像的Y坐标是(cHeight - ImageHeight) / 2
                                Dim imgRect As Rectangle = New Rectangle(0, (Me.ClientSize.Height - imageHeight) / 2, imageWidth, imageHeight)
                                Dim imageAttr As New ImageAttributes
                                imageAttr.SetColorKey(BackgroundImageColor(bmp), BackgroundImageColor(bmp))
                                gp.DrawImage(bmp, imgRect, 0, 0, imageWidth, imageHeight, GraphicsUnit.Pixel, imageAttr)
                                imgRect = Nothing
                                imageAttr = Nothing
                                '虽然预留了8个像素 但是只平均6个像素
                                gp.DrawString(Ctext, Me.Font, cbrush, Me.imageWidth + 3, (Me.ClientSize.Height - vsizef.Height) / 2)
                            Case Layout.up
                                vsizef = gp.MeasureString(Ctext, Me.Font)

                                '文本起始坐标(3,2)
                                gp.DrawString(Ctext, Me.Font, cbrush, (Me.ClientSize.Width - vsizef.Width) / 2, 2)

                                '图像的Y坐标是vsizef.Height + 4
                                Dim imgRect As Rectangle = New Rectangle((Me.ClientSize.Width - imageWidth) / 2 - 1, vsizef.Height + 4, imageWidth, imageHeight)
                                Dim imageAttr As New ImageAttributes
                                imageAttr.SetColorKey(BackgroundImageColor(bmp), BackgroundImageColor(bmp))
                                gp.DrawImage(bmp, imgRect, 0, 0, imageWidth, imageHeight, GraphicsUnit.Pixel, imageAttr)
                                imgRect = Nothing
                                imageAttr = Nothing
                            Case Layout.down

                                vsizef = gp.MeasureString(Ctext, Me.Font)

                                '图像的X坐标是(Me.Width - ImageWidth) / 2 - 1
                                Dim imgRect As Rectangle = New Rectangle((Me.ClientSize.Width - imageWidth) / 2 - 1, 0, imageWidth, imageHeight)
                                Dim imageAttr As New ImageAttributes
                                imageAttr.SetColorKey(BackgroundImageColor(bmp), BackgroundImageColor(bmp))
                                gp.DrawImage(bmp, imgRect, 0, 0, imageWidth, imageHeight, GraphicsUnit.Pixel, imageAttr)
                                imgRect = Nothing
                                imageAttr = Nothing
                                '文本起始坐标(3,2)
                                gp.DrawString(Ctext, Me.Font, cbrush, (Me.ClientSize.Width - vsizef.Width) / 2 - 1, imageHeight + 2)

                            Case Layout.middle
                                vsizef = gp.MeasureString(Ctext, Me.Font)

                                '图像的X坐标是(Me.Width - ImageWidth) / 2 - 1
                                Dim imgRect As Rectangle = New Rectangle((Me.ClientSize.Width - imageWidth) / 2, (Me.ClientSize.Height - imageHeight) / 2, imageWidth, imageHeight)
                                Dim imageAttr As New ImageAttributes
                                imageAttr.SetColorKey(BackgroundImageColor(bmp), BackgroundImageColor(bmp))
                                gp.DrawImage(bmp, imgRect, 0, 0, imageWidth, imageHeight, GraphicsUnit.Pixel, imageAttr)
                                imgRect = Nothing
                                imageAttr = Nothing
                                '文本起始坐标(3,2)
                                gp.DrawString(Ctext, Me.Font, cbrush, (Me.ClientSize.Width - vsizef.Width) / 2, (Me.ClientSize.Height - vsizef.Height) / 2)
                        End Select
                        cbrush.Dispose()
                        cbrush = Nothing
                        e.Graphics.DrawRectangle(DirectCast(New Pen(Color.FromArgb(206, 199, 189), 3), Pen), 0, 0, Me.Width - 1, Me.Height - 1)
                        gp.Dispose()
                        gp = Nothing
                    Else
                        '文本颜色取前景色
                        Dim cbrush As New System.Drawing.SolidBrush(Me.ForeColor)
                        Select Case Me.TxtImgLayout
                            Case Layout.Left
                                vsizef = gp.MeasureString(Ctext, Me.Font)

                                '虽然预留了8个像素 但是只平均8个像素
                                gp.DrawString(Ctext, Me.Font, cbrush, 4, (Me.ClientSize.Height - vsizef.Height) / 2)
                                '图像的X坐标是vsizef.Width + 8
                                Dim imgRect As Rectangle = New Rectangle(vsizef.Width + 8, (Me.ClientSize.Height - imageHeight) / 2, imageWidth, imageHeight)
                                Dim imageAttr As New ImageAttributes
                                imageAttr.SetColorKey(BackgroundImageColor(bmp), BackgroundImageColor(bmp))
                                gp.DrawImage(bmp, imgRect, 0, 0, imageWidth, imageHeight, GraphicsUnit.Pixel, imageAttr)
                                imgRect = Nothing
                                imageAttr = Nothing
                            Case Layout.right
                                vsizef = gp.MeasureString(Ctext, Me.Font)

                                '图像的Y坐标是(cHeight - ImageHeight) / 2
                                Dim imgRect As Rectangle = New Rectangle(0, (Me.ClientSize.Height - imageHeight) / 2, imageWidth, imageHeight)
                                Dim imageAttr As New ImageAttributes
                                imageAttr.SetColorKey(BackgroundImageColor(bmp), BackgroundImageColor(bmp))
                                gp.DrawImage(bmp, imgRect, 0, 0, imageWidth, imageHeight, GraphicsUnit.Pixel, imageAttr)
                                imgRect = Nothing
                                imageAttr = Nothing
                                '虽然预留了8个像素 但是只平均6个像素
                                gp.DrawString(Ctext, Me.Font, cbrush, Me.imageWidth + 3, (Me.ClientSize.Height - vsizef.Height) / 2)
                            Case Layout.up
                                vsizef = gp.MeasureString(Ctext, Me.Font)

                                '文本起始坐标(3,2)
                                gp.DrawString(Ctext, Me.Font, cbrush, (Me.ClientSize.Width - vsizef.Width) / 2, 2)

                                '图像的Y坐标是vsizef.Height + 4
                                Dim imgRect As Rectangle = New Rectangle((Me.ClientSize.Width - imageWidth) / 2 - 1, vsizef.Height + 4, imageWidth, imageHeight)
                                Dim imageAttr As New ImageAttributes
                                imageAttr.SetColorKey(BackgroundImageColor(bmp), BackgroundImageColor(bmp))
                                gp.DrawImage(bmp, imgRect, 0, 0, imageWidth, imageHeight, GraphicsUnit.Pixel, imageAttr)
                                imgRect = Nothing
                                imageAttr = Nothing
                            Case Layout.down

                                vsizef = gp.MeasureString(Ctext, Me.Font)

                                '图像的X坐标是(Me.Width - ImageWidth) / 2 - 1
                                Dim imgRect As Rectangle = New Rectangle((Me.ClientSize.Width - imageWidth) / 2 - 1, 0, imageWidth, imageHeight)
                                Dim imageAttr As New ImageAttributes
                                imageAttr.SetColorKey(BackgroundImageColor(bmp), BackgroundImageColor(bmp))
                                gp.DrawImage(bmp, imgRect, 0, 0, imageWidth, imageHeight, GraphicsUnit.Pixel, imageAttr)
                                imgRect = Nothing
                                imageAttr = Nothing
                                '文本起始坐标(3,2)
                                gp.DrawString(Ctext, Me.Font, cbrush, (Me.ClientSize.Width - vsizef.Width) / 2 - 1, imageHeight + 2)

                            Case Layout.middle
                                vsizef = gp.MeasureString(Ctext, Me.Font)

                                '图像的X坐标是(Me.Width - ImageWidth) / 2 - 1
                                Dim imgRect As Rectangle = New Rectangle((Me.ClientSize.Width - imageWidth) / 2, (Me.ClientSize.Height - imageHeight) / 2, imageWidth, imageHeight)
                                Dim imageAttr As New ImageAttributes
                                imageAttr.SetColorKey(BackgroundImageColor(bmp), BackgroundImageColor(bmp))
                                gp.DrawImage(bmp, imgRect, 0, 0, imageWidth, imageHeight, GraphicsUnit.Pixel, imageAttr)
                                imgRect = Nothing
                                imageAttr = Nothing
                                '文本起始坐标(3,2)
                                gp.DrawString(Ctext, Me.Font, cbrush, (Me.ClientSize.Width - vsizef.Width) / 2, (Me.ClientSize.Height - vsizef.Height) / 2)
                        End Select
                        cbrush.Dispose()
                        cbrush = Nothing
                        '加上这句将显示按钮的三维
                        'e.Graphics.DrawRectangle(DirectCast(New Pen(Color.Transparent), Pen), 0, 0, Me.Width, Me.Height)
                        gp.Dispose()
                        gp = Nothing
                    End If
            End Select
        End If
        '画一条边框
        'e.Graphics.DrawRectangle(New Pen(System.Drawing.SystemColors.ControlDark), 0, 0, Me.ClientSize.Width + 1, Me.ClientSize.Height + 1)
        '============================================================================================================================================
        '大小自动设置时
        If ControlSizeSet = True Then
            Select Case bmpIconCount
                Case 0 '画背景
                    Dim backgroundImg As Image = MakeBitmap(BackgroundImgColor, Me.Width, Me.Height)
                    Dim pressedImg As Image = MakeBitmap(PressedImgColor, Me.Width, Me.Height)
                    If Me.Pressed AndAlso (pressedImg IsNot Nothing) Then
                        gp.DrawImage(pressedImg, 0, 0)

                        e.Graphics.DrawRectangle(DirectCast(New Pen(_BorderColor), Pen), 0, 0, Me.Width, Me.Height)

                    ElseIf Me.Moved AndAlso (pressedImg IsNot Nothing) Then
                        gp.DrawImage(pressedImg, 0, 0)
                    ElseIf Me.BtnEnabled = False Then
                        '按钮不可用时
                        Dim UnenableImg As Image = MakeBitmap(Color.FromArgb(247, 247, 239), Me.Width, Me.Width)
                        gp.DrawImage(UnenableImg, 0, 0)
                        e.Graphics.DrawRectangle(DirectCast(New Pen(Color.FromArgb(206, 199, 189), 3), Pen), 0, 0, Me.Width - 1, Me.Height - 1)
                        UnenableImg.Dispose()
                    Else
                        gp.DrawImage(backgroundImg, 0, 0)

                        e.Graphics.DrawRectangle(DirectCast(New Pen(Color.Transparent), Pen), 0, 0, Me.Width, Me.Height)

                    End If
                    backgroundImg.Dispose()
                    pressedImg.Dispose()
                    If Me.Ctext.Length > 0 Then
                        Dim size As SizeF = e.Graphics.MeasureString(Me.Ctext, Me.Font)
                        If Me.BtnEnabled = False Then
                            e.Graphics.DrawString(Me.Ctext, Me.Font, New SolidBrush(Color.FromArgb(173, 170, 156)), (Me.ClientSize.Width - size.Width) / 2, (Me.ClientSize.Height - size.Height) / 2)
                        Else
                            e.Graphics.DrawString(Me.Ctext, Me.Font, New SolidBrush(Me.ForeColor), (Me.ClientSize.Width - size.Width) / 2, (Me.ClientSize.Height - size.Height) / 2)
                        End If
                    End If
                Case 1 '画图像
                    Dim cHeight As Integer = 0
                    Dim cWidth As Integer = 0
                    Dim vsizef As SizeF

                    If Me.Pressed AndAlso (bmp IsNot Nothing) Then
                        '文本颜色取按下的颜色
                        Dim cbrush As New System.Drawing.SolidBrush(Me.PressedImgColor)
                        Select Case Me.TxtImgLayout
                            Case Layout.Left
                                vsizef = gp.MeasureString(Ctext, Me.Font)
                                If Me.imageHeight > vsizef.Height Then
                                    cHeight = Me.imageHeight
                                Else
                                    cHeight = vsizef.Height
                                End If

                                '高度取大的
                                Me.Height = cHeight
                                ' 预留8个像素
                                Me.Width = imageWidth + vsizef.Width + 8
                                '虽然预留了8个像素 但是只平均8个像素
                                gp.DrawString(Ctext, Me.Font, cbrush, 4, (cHeight - vsizef.Height) / 2)
                                '图像的X坐标是vsizef.Width + 8

                                Dim imgRect As Rectangle = New Rectangle(vsizef.Width + 8, (cHeight - imageHeight) / 2, imageWidth, imageHeight)
                                Dim imageAttr As New ImageAttributes
                                imageAttr.SetColorKey(BackgroundImageColor(bmp), BackgroundImageColor(bmp))
                                gp.DrawImage(bmp, imgRect, 0, 0, imageWidth, imageHeight, GraphicsUnit.Pixel, imageAttr)
                                imgRect = Nothing
                                imageAttr = Nothing

                            Case Layout.right

                                vsizef = gp.MeasureString(Ctext, Me.Font)
                                If Me.imageHeight > vsizef.Height Then
                                    cHeight = Me.imageHeight
                                Else
                                    cHeight = vsizef.Height
                                End If
                                '高度取大的
                                Me.Height = cHeight + 2
                                ' 预留8个像素
                                Me.Width = imageWidth + vsizef.Width + 12
                                Dim imgRect As Rectangle = New Rectangle(0, (cHeight - imageHeight) / 2, imageWidth, imageHeight)
                                Dim imageAttr As New ImageAttributes
                                imageAttr.SetColorKey(BackgroundImageColor(bmp), BackgroundImageColor(bmp))
                                gp.DrawImage(bmp, imgRect, 0, 0, imageWidth, imageHeight, GraphicsUnit.Pixel, imageAttr)
                                imgRect = Nothing
                                imageAttr = Nothing
                                '虽然预留了8个像素 但是只平均6个像素
                                gp.DrawString(Ctext, Me.Font, cbrush, Me.imageWidth + 3, (cHeight - vsizef.Height) / 2)
                            Case Layout.up
                                vsizef = gp.MeasureString(Ctext, Me.Font)
                                If Me.imageWidth > vsizef.Width Then
                                    cWidth = Me.imageWidth
                                Else
                                    cWidth = vsizef.Width
                                End If
                                '高度预留4个像素
                                Me.Height = imageHeight + vsizef.Height + 4
                                ' 宽度取大的 预留8个像素
                                Me.Width = cWidth + 8
                                '文本起始坐标(3,2)
                                gp.DrawString(Ctext, Me.Font, cbrush, (Me.ClientSize.Width - vsizef.Width) / 2, 2)
                                Dim imgRect As Rectangle = New Rectangle((Me.Width - imageWidth) / 2 - 1, vsizef.Height + 4, imageWidth, imageHeight)
                                Dim imageAttr As New ImageAttributes
                                imageAttr.SetColorKey(BackgroundImageColor(bmp), BackgroundImageColor(bmp))
                                gp.DrawImage(bmp, imgRect, 0, 0, imageWidth, imageHeight, GraphicsUnit.Pixel, imageAttr)
                                imgRect = Nothing
                                imageAttr = Nothing

                            Case Layout.down

                                vsizef = gp.MeasureString(Ctext, Me.Font)
                                If Me.imageWidth > vsizef.Width Then
                                    cWidth = Me.imageWidth
                                Else
                                    cWidth = vsizef.Width
                                End If
                                '高度预留4个像素
                                Me.Height = imageHeight + vsizef.Height + 4
                                ' 宽度取大的 预留8个像素
                                Me.Width = cWidth + 8
                                '图像的X坐标是(Me.Width - ImageWidth) / 2 - 1
                                Dim imgRect As Rectangle = New Rectangle((Me.Width - imageWidth) / 2 - 1, 0, imageWidth, imageHeight)
                                Dim imageAttr As New ImageAttributes
                                imageAttr.SetColorKey(BackgroundImageColor(bmp), BackgroundImageColor(bmp))
                                gp.DrawImage(bmp, imgRect, 0, 0, imageWidth, imageHeight, GraphicsUnit.Pixel, imageAttr)
                                imgRect = Nothing
                                imageAttr = Nothing
                                '文本起始坐标(3,2)
                                gp.DrawString(Ctext, Me.Font, cbrush, (Me.Width - vsizef.Width) / 2 - 1, imageHeight + 2)
                            Case Layout.middle
                                vsizef = gp.MeasureString(Ctext, Me.Font)
                                If Me.imageWidth > vsizef.Width Then
                                    cWidth = Me.imageWidth
                                Else
                                    cWidth = vsizef.Width
                                End If
                                If Me.imageHeight > vsizef.Height Then
                                    cHeight = Me.imageHeight
                                Else
                                    cHeight = vsizef.Height
                                End If
                                '高度预留4个像素
                                Me.Height = cHeight
                                ' 宽度取大的 预留8个像素
                                Me.Width = cWidth
                                '图像的X坐标是(Me.Width - ImageWidth) / 2 - 1
                                Dim imgRect As Rectangle = New Rectangle((Me.Width - imageWidth) / 2, (Me.Height - imageHeight) / 2, imageWidth, imageHeight)
                                Dim imageAttr As New ImageAttributes
                                imageAttr.SetColorKey(BackgroundImageColor(bmp), BackgroundImageColor(bmp))
                                gp.DrawImage(bmp, imgRect, 0, 0, imageWidth, imageHeight, GraphicsUnit.Pixel, imageAttr)
                                imgRect = Nothing
                                imageAttr = Nothing
                                '文本起始坐标(3,2)
                                gp.DrawString(Ctext, Me.Font, cbrush, (Me.Width - vsizef.Width) / 2, (Me.Height - vsizef.Height) / 2)
                        End Select

                        cbrush.Dispose()
                        cbrush = Nothing
                        '四周画颜色矩形
                        e.Graphics.DrawRectangle(DirectCast(New Pen(_BorderColor), Pen), 0, 0, Me.ClientSize.Width - 1, Me.ClientSize.Height - 1)
                        gp.Dispose()
                        gp = Nothing

                    ElseIf Me.Moved AndAlso (bmp IsNot Nothing) Then
                        '文本颜色取前景色
                        Dim cbrush As New System.Drawing.SolidBrush(Me.PressedImgColor)
                        Select Case Me.TxtImgLayout
                            Case Layout.Left
                                vsizef = gp.MeasureString(Ctext, Me.Font)
                                If Me.imageHeight > vsizef.Height Then
                                    cHeight = Me.imageHeight
                                Else
                                    cHeight = vsizef.Height
                                End If

                                '高度取大的
                                Me.Height = cHeight
                                ' 预留8个像素
                                Me.Width = imageWidth + vsizef.Width + 8
                                '虽然预留了8个像素 但是只平均8个像素
                                gp.DrawString(Ctext, Me.Font, cbrush, 4, (cHeight - vsizef.Height) / 2)
                                '图像的X坐标是vsizef.Width + 8

                                Dim imgRect As Rectangle = New Rectangle(vsizef.Width + 8, (cHeight - imageHeight) / 2, imageWidth, imageHeight)
                                Dim imageAttr As New ImageAttributes
                                imageAttr.SetColorKey(BackgroundImageColor(bmp), BackgroundImageColor(bmp))
                                gp.DrawImage(bmp, imgRect, 0, 0, imageWidth, imageHeight, GraphicsUnit.Pixel, imageAttr)
                                imgRect = Nothing
                                imageAttr = Nothing

                            Case Layout.right

                                vsizef = gp.MeasureString(Ctext, Me.Font)
                                If Me.imageHeight > vsizef.Height Then
                                    cHeight = Me.imageHeight
                                Else
                                    cHeight = vsizef.Height
                                End If
                                '高度取大的
                                Me.Height = cHeight + 2
                                ' 预留8个像素
                                Me.Width = imageWidth + vsizef.Width + 12
                                Dim imgRect As Rectangle = New Rectangle(0, (cHeight - imageHeight) / 2, imageWidth, imageHeight)
                                Dim imageAttr As New ImageAttributes
                                imageAttr.SetColorKey(BackgroundImageColor(bmp), BackgroundImageColor(bmp))
                                gp.DrawImage(bmp, imgRect, 0, 0, imageWidth, imageHeight, GraphicsUnit.Pixel, imageAttr)
                                imgRect = Nothing
                                imageAttr = Nothing
                                '虽然预留了8个像素 但是只平均6个像素
                                gp.DrawString(Ctext, Me.Font, cbrush, Me.imageWidth + 3, (cHeight - vsizef.Height) / 2)
                            Case Layout.up
                                vsizef = gp.MeasureString(Ctext, Me.Font)
                                If Me.imageWidth > vsizef.Width Then
                                    cWidth = Me.imageWidth
                                Else
                                    cWidth = vsizef.Width
                                End If
                                '高度预留4个像素
                                Me.Height = imageHeight + vsizef.Height + 4
                                ' 宽度取大的 预留8个像素
                                Me.Width = cWidth + 8
                                '文本起始坐标(3,2)
                                gp.DrawString(Ctext, Me.Font, cbrush, (Me.ClientSize.Width - vsizef.Width) / 2, 2)
                                Dim imgRect As Rectangle = New Rectangle((Me.Width - imageWidth) / 2 - 1, vsizef.Height + 4, imageWidth, imageHeight)
                                Dim imageAttr As New ImageAttributes
                                imageAttr.SetColorKey(BackgroundImageColor(bmp), BackgroundImageColor(bmp))
                                gp.DrawImage(bmp, imgRect, 0, 0, imageWidth, imageHeight, GraphicsUnit.Pixel, imageAttr)
                                imgRect = Nothing
                                imageAttr = Nothing

                            Case Layout.down

                                vsizef = gp.MeasureString(Ctext, Me.Font)
                                If Me.imageWidth > vsizef.Width Then
                                    cWidth = Me.imageWidth
                                Else
                                    cWidth = vsizef.Width
                                End If
                                '高度预留4个像素
                                Me.Height = imageHeight + vsizef.Height + 4
                                ' 宽度取大的 预留8个像素
                                Me.Width = cWidth + 8
                                '图像的X坐标是(Me.Width - ImageWidth) / 2 - 1
                                Dim imgRect As Rectangle = New Rectangle((Me.Width - imageWidth) / 2 - 1, 0, imageWidth, imageHeight)
                                Dim imageAttr As New ImageAttributes
                                imageAttr.SetColorKey(BackgroundImageColor(bmp), BackgroundImageColor(bmp))
                                gp.DrawImage(bmp, imgRect, 0, 0, imageWidth, imageHeight, GraphicsUnit.Pixel, imageAttr)
                                imgRect = Nothing
                                imageAttr = Nothing
                                '文本起始坐标(3,2)
                                gp.DrawString(Ctext, Me.Font, cbrush, (Me.Width - vsizef.Width) / 2 - 1, imageHeight + 2)
                            Case Layout.middle
                                vsizef = gp.MeasureString(Ctext, Me.Font)
                                If Me.imageWidth > vsizef.Width Then
                                    cWidth = Me.imageWidth
                                Else
                                    cWidth = vsizef.Width
                                End If
                                If Me.imageHeight > vsizef.Height Then
                                    cHeight = Me.imageHeight
                                Else
                                    cHeight = vsizef.Height
                                End If
                                '高度预留4个像素
                                Me.Height = cHeight
                                ' 宽度取大的 预留8个像素
                                Me.Width = cWidth
                                '图像的X坐标是(Me.Width - ImageWidth) / 2 - 1
                                Dim imgRect As Rectangle = New Rectangle((Me.Width - imageWidth) / 2, (Me.Height - imageHeight) / 2, imageWidth, imageHeight)
                                Dim imageAttr As New ImageAttributes
                                imageAttr.SetColorKey(BackgroundImageColor(bmp), BackgroundImageColor(bmp))
                                gp.DrawImage(bmp, imgRect, 0, 0, imageWidth, imageHeight, GraphicsUnit.Pixel, imageAttr)
                                imgRect = Nothing
                                imageAttr = Nothing
                                '文本起始坐标(3,2)
                                gp.DrawString(Ctext, Me.Font, cbrush, (Me.Width - vsizef.Width) / 2, (Me.Height - vsizef.Height) / 2)
                        End Select

                        cbrush.Dispose()
                        cbrush = Nothing
                        gp.Dispose()
                        gp = Nothing
                    ElseIf Me.BtnEnabled = False Then
                        '文本颜色取按下的颜色
                        Dim cbrush As New System.Drawing.SolidBrush(Color.FromArgb(173, 170, 156))
                        Select Case Me.TxtImgLayout
                            Case Layout.Left
                                vsizef = gp.MeasureString(Ctext, Me.Font)
                                If Me.imageHeight > vsizef.Height Then
                                    cHeight = Me.imageHeight
                                Else
                                    cHeight = vsizef.Height
                                End If

                                '高度取大的
                                Me.Height = cHeight
                                ' 预留8个像素
                                Me.Width = imageWidth + vsizef.Width + 8
                                '虽然预留了8个像素 但是只平均8个像素
                                gp.DrawString(Ctext, Me.Font, cbrush, 4, (cHeight - vsizef.Height) / 2)
                                '图像的X坐标是vsizef.Width + 8

                                Dim imgRect As Rectangle = New Rectangle(vsizef.Width + 8, (cHeight - imageHeight) / 2, imageWidth, imageHeight)
                                Dim imageAttr As New ImageAttributes
                                imageAttr.SetColorKey(BackgroundImageColor(bmp), BackgroundImageColor(bmp))
                                gp.DrawImage(bmp, imgRect, 0, 0, imageWidth, imageHeight, GraphicsUnit.Pixel, imageAttr)
                                imgRect = Nothing
                                imageAttr = Nothing

                            Case Layout.right

                                vsizef = gp.MeasureString(Ctext, Me.Font)
                                If Me.imageHeight > vsizef.Height Then
                                    cHeight = Me.imageHeight
                                Else
                                    cHeight = vsizef.Height
                                End If
                                '高度取大的
                                Me.Height = cHeight + 2
                                ' 预留8个像素
                                Me.Width = imageWidth + vsizef.Width + 12
                                Dim imgRect As Rectangle = New Rectangle(0, (cHeight - imageHeight) / 2, imageWidth, imageHeight)
                                Dim imageAttr As New ImageAttributes
                                imageAttr.SetColorKey(BackgroundImageColor(bmp), BackgroundImageColor(bmp))
                                gp.DrawImage(bmp, imgRect, 0, 0, imageWidth, imageHeight, GraphicsUnit.Pixel, imageAttr)
                                imgRect = Nothing
                                imageAttr = Nothing
                                '虽然预留了8个像素 但是只平均6个像素
                                gp.DrawString(Ctext, Me.Font, cbrush, Me.imageWidth + 3, (cHeight - vsizef.Height) / 2)
                            Case Layout.up
                                vsizef = gp.MeasureString(Ctext, Me.Font)
                                If Me.imageWidth > vsizef.Width Then
                                    cWidth = Me.imageWidth
                                Else
                                    cWidth = vsizef.Width
                                End If
                                '高度预留4个像素
                                Me.Height = imageHeight + vsizef.Height + 4
                                ' 宽度取大的 预留8个像素
                                Me.Width = cWidth + 8
                                '文本起始坐标(3,2)
                                gp.DrawString(Ctext, Me.Font, cbrush, (Me.ClientSize.Width - vsizef.Width) / 2, 2)
                                Dim imgRect As Rectangle = New Rectangle((Me.Width - imageWidth) / 2 - 1, vsizef.Height + 4, imageWidth, imageHeight)
                                Dim imageAttr As New ImageAttributes
                                imageAttr.SetColorKey(BackgroundImageColor(bmp), BackgroundImageColor(bmp))
                                gp.DrawImage(bmp, imgRect, 0, 0, imageWidth, imageHeight, GraphicsUnit.Pixel, imageAttr)
                                imgRect = Nothing
                                imageAttr = Nothing

                            Case Layout.down

                                vsizef = gp.MeasureString(Ctext, Me.Font)
                                If Me.imageWidth > vsizef.Width Then
                                    cWidth = Me.imageWidth
                                Else
                                    cWidth = vsizef.Width
                                End If
                                '高度预留4个像素
                                Me.Height = imageHeight + vsizef.Height + 4
                                ' 宽度取大的 预留8个像素
                                Me.Width = cWidth + 8
                                '图像的X坐标是(Me.Width - ImageWidth) / 2 - 1
                                Dim imgRect As Rectangle = New Rectangle((Me.Width - imageWidth) / 2 - 1, 0, imageWidth, imageHeight)
                                Dim imageAttr As New ImageAttributes
                                imageAttr.SetColorKey(BackgroundImageColor(bmp), BackgroundImageColor(bmp))
                                gp.DrawImage(bmp, imgRect, 0, 0, imageWidth, imageHeight, GraphicsUnit.Pixel, imageAttr)
                                imgRect = Nothing
                                imageAttr = Nothing
                                '文本起始坐标(3,2)
                                gp.DrawString(Ctext, Me.Font, cbrush, (Me.Width - vsizef.Width) / 2 - 1, imageHeight + 2)
                            Case Layout.middle
                                vsizef = gp.MeasureString(Ctext, Me.Font)
                                If Me.imageWidth > vsizef.Width Then
                                    cWidth = Me.imageWidth
                                Else
                                    cWidth = vsizef.Width
                                End If
                                If Me.imageHeight > vsizef.Height Then
                                    cHeight = Me.imageHeight
                                Else
                                    cHeight = vsizef.Height
                                End If
                                '高度预留4个像素
                                Me.Height = cHeight
                                ' 宽度取大的 预留8个像素
                                Me.Width = cWidth
                                '图像的X坐标是(Me.Width - ImageWidth) / 2 - 1
                                Dim imgRect As Rectangle = New Rectangle((Me.Width - imageWidth) / 2, (Me.Height - imageHeight) / 2, imageWidth, imageHeight)
                                Dim imageAttr As New ImageAttributes
                                imageAttr.SetColorKey(BackgroundImageColor(bmp), BackgroundImageColor(bmp))
                                gp.DrawImage(bmp, imgRect, 0, 0, imageWidth, imageHeight, GraphicsUnit.Pixel, imageAttr)
                                imgRect = Nothing
                                imageAttr = Nothing
                                '文本起始坐标(3,2)
                                gp.DrawString(Ctext, Me.Font, cbrush, (Me.Width - vsizef.Width) / 2, (Me.Height - vsizef.Height) / 2)
                        End Select


                        cbrush.Dispose()
                        cbrush = Nothing
                        e.Graphics.DrawRectangle(DirectCast(New Pen(Color.FromArgb(206, 199, 189), 3), Pen), 0, 0, Me.Width - 1, Me.Height - 1)
                        gp.Dispose()
                        gp = Nothing
                    Else
                        '文本颜色取按下的颜色
                        Dim cbrush As New System.Drawing.SolidBrush(Me.ForeColor)
                        Select Case Me.TxtImgLayout
                            Case Layout.Left
                                vsizef = gp.MeasureString(Ctext, Me.Font)
                                If Me.imageHeight > vsizef.Height Then
                                    cHeight = Me.imageHeight
                                Else
                                    cHeight = vsizef.Height
                                End If

                                '高度取大的
                                Me.Height = cHeight
                                ' 预留8个像素
                                Me.Width = imageWidth + vsizef.Width + 8
                                '虽然预留了8个像素 但是只平均8个像素
                                gp.DrawString(Ctext, Me.Font, cbrush, 4, (cHeight - vsizef.Height) / 2)
                                '图像的X坐标是vsizef.Width + 8

                                Dim imgRect As Rectangle = New Rectangle(vsizef.Width + 8, (cHeight - imageHeight) / 2, imageWidth, imageHeight)
                                Dim imageAttr As New ImageAttributes
                                imageAttr.SetColorKey(BackgroundImageColor(bmp), BackgroundImageColor(bmp))
                                gp.DrawImage(bmp, imgRect, 0, 0, imageWidth, imageHeight, GraphicsUnit.Pixel, imageAttr)
                                imgRect = Nothing
                                imageAttr = Nothing

                            Case Layout.right

                                vsizef = gp.MeasureString(Ctext, Me.Font)
                                If Me.imageHeight > vsizef.Height Then
                                    cHeight = Me.imageHeight
                                Else
                                    cHeight = vsizef.Height
                                End If
                                '高度取大的
                                Me.Height = cHeight + 2
                                ' 预留8个像素
                                Me.Width = imageWidth + vsizef.Width + 12
                                Dim imgRect As Rectangle = New Rectangle(0, (cHeight - imageHeight) / 2, imageWidth, imageHeight)
                                Dim imageAttr As New ImageAttributes
                                imageAttr.SetColorKey(BackgroundImageColor(bmp), BackgroundImageColor(bmp))
                                gp.DrawImage(bmp, imgRect, 0, 0, imageWidth, imageHeight, GraphicsUnit.Pixel, imageAttr)
                                imgRect = Nothing
                                imageAttr = Nothing
                                '虽然预留了8个像素 但是只平均6个像素
                                gp.DrawString(Ctext, Me.Font, cbrush, Me.imageWidth + 3, (cHeight - vsizef.Height) / 2)
                            Case Layout.up
                                vsizef = gp.MeasureString(Ctext, Me.Font)
                                If Me.imageWidth > vsizef.Width Then
                                    cWidth = Me.imageWidth
                                Else
                                    cWidth = vsizef.Width
                                End If
                                '高度预留4个像素
                                Me.Height = imageHeight + vsizef.Height + 4
                                ' 宽度取大的 预留8个像素
                                Me.Width = cWidth + 8
                                '文本起始坐标(3,2)
                                gp.DrawString(Ctext, Me.Font, cbrush, (Me.ClientSize.Width - vsizef.Width) / 2, 2)
                                Dim imgRect As Rectangle = New Rectangle((Me.Width - imageWidth) / 2 - 1, vsizef.Height + 4, imageWidth, imageHeight)
                                Dim imageAttr As New ImageAttributes
                                imageAttr.SetColorKey(BackgroundImageColor(bmp), BackgroundImageColor(bmp))
                                gp.DrawImage(bmp, imgRect, 0, 0, imageWidth, imageHeight, GraphicsUnit.Pixel, imageAttr)
                                imgRect = Nothing
                                imageAttr = Nothing

                            Case Layout.down

                                vsizef = gp.MeasureString(Ctext, Me.Font)
                                If Me.imageWidth > vsizef.Width Then
                                    cWidth = Me.imageWidth
                                Else
                                    cWidth = vsizef.Width
                                End If
                                '高度预留4个像素
                                Me.Height = imageHeight + vsizef.Height + 4
                                ' 宽度取大的 预留8个像素
                                Me.Width = cWidth + 8
                                '图像的X坐标是(Me.Width - ImageWidth) / 2 - 1
                                Dim imgRect As Rectangle = New Rectangle((Me.Width - imageWidth) / 2 - 1, 0, imageWidth, imageHeight)
                                Dim imageAttr As New ImageAttributes
                                imageAttr.SetColorKey(BackgroundImageColor(bmp), BackgroundImageColor(bmp))
                                gp.DrawImage(bmp, imgRect, 0, 0, imageWidth, imageHeight, GraphicsUnit.Pixel, imageAttr)
                                imgRect = Nothing
                                imageAttr = Nothing
                                '文本起始坐标(3,2)
                                gp.DrawString(Ctext, Me.Font, cbrush, (Me.Width - vsizef.Width) / 2 - 1, imageHeight + 2)
                            Case Layout.middle
                                vsizef = gp.MeasureString(Ctext, Me.Font)
                                If Me.imageWidth > vsizef.Width Then
                                    cWidth = Me.imageWidth
                                Else
                                    cWidth = vsizef.Width
                                End If
                                If Me.imageHeight > vsizef.Height Then
                                    cHeight = Me.imageHeight
                                Else
                                    cHeight = vsizef.Height
                                End If
                                '高度预留4个像素
                                Me.Height = cHeight
                                ' 宽度取大的 预留8个像素
                                Me.Width = cWidth
                                '图像的X坐标是(Me.Width - ImageWidth) / 2 - 1
                                Dim imgRect As Rectangle = New Rectangle((Me.Width - imageWidth) / 2, (Me.Height - imageHeight) / 2, imageWidth, imageHeight)
                                Dim imageAttr As New ImageAttributes
                                imageAttr.SetColorKey(BackgroundImageColor(bmp), BackgroundImageColor(bmp))
                                gp.DrawImage(bmp, imgRect, 0, 0, imageWidth, imageHeight, GraphicsUnit.Pixel, imageAttr)
                                imgRect = Nothing
                                imageAttr = Nothing
                                '文本起始坐标(3,2)
                                gp.DrawString(Ctext, Me.Font, cbrush, (Me.Width - vsizef.Width) / 2, (Me.Height - vsizef.Height) / 2)
                        End Select

                        cbrush.Dispose()
                        cbrush = Nothing
                        '加上这句将显示按钮的三维
                        'e.Graphics.DrawRectangle(DirectCast(New Pen(Color.Transparent), Pen), 0, 0, Me.Width, Me.Height)
                        gp.Dispose()
                        gp = Nothing
                    End If
            End Select
        End If
        MyBase.OnPaint(e)
    End Sub
    '确定按钮的宽度高度(工具栏专用)
    Public Sub RefreshPicBtn()
        Dim gp As Graphics = Me.CreateGraphics
        Dim cHeight As Integer = 0
        Dim cWidth As Integer = 0
        Dim vsizef As SizeF

        Ctext = Caption

        Select Case Me.TxtImgLayout
            Case Layout.Left
                vsizef = gp.MeasureString(Ctext, Me.Font)
                If Me.ImageHeight > vsizef.Height Then
                    cHeight = Me.ImageHeight
                Else
                    cHeight = vsizef.Height
                End If

                '高度取大的
                Me.Height = cHeight
                ' 预留8个像素
                Me.Width = ImageWidth + vsizef.Width + 8
            Case Layout.right

                vsizef = gp.MeasureString(Ctext, Me.Font)
                If Me.ImageHeight > vsizef.Height Then
                    cHeight = Me.ImageHeight
                Else
                    cHeight = vsizef.Height
                End If

                '高度取大的
                Me.Height = cHeight
                ' 预留8个像素
                Me.Width = ImageWidth + vsizef.Width + 8
            Case Layout.up
                vsizef = gp.MeasureString(Ctext, Me.Font)
                If Me.ImageWidth > vsizef.Width Then
                    cWidth = Me.ImageWidth
                Else
                    cWidth = vsizef.Width
                End If
                '高度预留4个像素
                Me.Height = ImageHeight + vsizef.Height + 6
                ' 宽度取大的 预留8个像素
                Me.Width = cWidth + 8
            Case Layout.down

                vsizef = gp.MeasureString(Ctext, Me.Font)
                If Me.ImageWidth > vsizef.Width Then
                    cWidth = Me.ImageWidth
                Else
                    cWidth = vsizef.Width
                End If
                '高度预留4个像素
                Me.Height = ImageHeight + vsizef.Height + 6
                ' 宽度取大的 预留8个像素
                Me.Width = cWidth + 8
            Case Layout.middle
                vsizef = gp.MeasureString(Ctext, Me.Font)
                If Me.imageWidth > vsizef.Width Then
                    cWidth = Me.imageWidth
                Else
                    cWidth = vsizef.Width
                End If
                If Me.imageHeight > vsizef.Height Then
                    cHeight = Me.imageHeight
                Else
                    cHeight = vsizef.Height
                End If
                '高度预留4个像素
                Me.Height = cHeight
                ' 宽度取大的 预留8个像素
                Me.Width = cWidth
        End Select
    End Sub
    '鼠标按下
    Protected Overrides Sub OnMouseDown(ByVal e As MouseEventArgs)
        '父菜单不响应按下事件
        If e.Button = Windows.Forms.MouseButtons.Left AndAlso YNParentMenu = False Then
            Me.Pressed = True
            Me.Invalidate()
            MyBase.OnMouseDown(e)
            ChangeColor = True
        End If
    End Sub
    '鼠标抬起
    Protected Overrides Sub OnMouseUp(ByVal e As MouseEventArgs)
        If e.Button = Windows.Forms.MouseButtons.Left Then
            Me.pressed = False
            Me.Invalidate()
            MyBase.OnMouseUp(e)
            ChangeColor = False
        End If
    End Sub

    '颜色变为图片画背景用
    Function MakeBitmap(ByVal ButtonColor As Color, ByVal width As Integer, ByVal height As Integer) As Bitmap
        Dim bmpThis As New Bitmap(width, height)
        Dim g As Graphics = Graphics.FromImage(bmpThis)
        g.FillRectangle(New SolidBrush(ButtonColor), 0, 0, bmpThis.Width, bmpThis.Height)
        g.Dispose()
        Return bmpThis
    End Function
    '销毁时清空
    Public Sub DisposePictureButton()
        bmp.Dispose()
    End Sub

 

    Public Sub New()

        ' 此调用是 Windows 窗体设计器所必需的。
        InitializeComponent()

        ' 在 InitializeComponent() 调用之后添加任何初始化。
        Me.BorderStyle = Windows.Forms.BorderStyle.None
    End Sub
    '获取图片的背景色
    Private Function BackgroundImageColor(ByVal image As Image) As System.Drawing.Color
        Dim bmp As Bitmap = New Bitmap(image)
        Return bmp.GetPixel(0, 0)
    End Function
    '控件enabled属性发生变化时的表面重绘代码
    Private Sub PictureButtonMenu_EnabledChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.EnabledChanged
        If Me.Enabled = False Then
            BtnEnabled = False
            Me.Invalidate()
        Else
            BtnEnabled = True
            Me.Invalidate()
        End If
    End Sub

    '用定时器实现mouseleave事件

    Private Sub PictureButton_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles MyBase.MouseMove
        Me.Timer1.Enabled = True
    End Sub

    '父菜单上的鼠标离开事件
    Public Event ParentMenuMouseLeave(ByVal sender As Object, ByVal ParentMenuName As String)
   
    '父菜单的鼠标在其内部事件
    Public Event ParentMenuMouseMoveInto(ByVal sender As Object, ByVal ParentMenuName As String)
    Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
        Dim rect As Rectangle = Me.RectangleToScreen(Me.ClientRectangle)
        If Moved = False AndAlso rect.Contains(Control.MousePosition.X, Control.MousePosition.Y) = True Then
            Moved = True
            Me.Invalidate()
            If YNParentMenu = True Then
                RaiseEvent ParentMenuMouseMoveInto(Me, Me.Caption)
            End If
        End If

        If rect.Contains(Control.MousePosition.X, Control.MousePosition.Y) = False Then
            Timer1.Enabled = False
            Moved = False
            Me.Invalidate()
            If YNParentMenu = True Then
                RaiseEvent ParentMenuMouseLeave(Me, Me.Caption)
            End If
        End If
    End Sub
End Class

第二部分:基于图文混编按钮的XP开始菜单自定义控件源码(本源码精简集可以实现完全自定义工具栏,有心者可自己实现)


Imports PictureButtonMenu.PictureButtonMenu
Public Class FullyCustomizableMenu
    Inherits System.Windows.Forms.UserControl
    ''' <summary>
    ''' 按钮的单击事件(供平台监听)
    ''' </summary>
    Public Event btnclick(ByVal id As Integer, ByVal AppName As String)
    '父菜单上的鼠标离开事件
    Public Event ParentMenuMouseLeave(ByVal sender As Object, ByVal ParentMenuName As String)
    '父菜单的鼠标在其内部事件
    Public Event ParentMenuMouseMoveInto(ByVal sender As Object, ByVal ParentMenuName As String)
    '菜单的横竖标志(false为横;true为竖)
    Public HorVerFlag As Boolean = False

    Public Property SetHorVerFlag() As Boolean
        Get
            Return HorVerFlag
        End Get
        Set(ByVal Value As Boolean)
            HorVerFlag = Value
        End Set
    End Property
    '菜单中按钮的大小
    Public MaxBtnWidth As Integer = 0
    Public MaxBtnHeight As Integer = 0
  
    '当前控件中各个子控件的图像和文件的排列格式
    Public CurBtnLayout As Integer = 1
    ''' <summary>
    ''' 根据传入的用户菜单的参数动态创建开始菜单所有父菜单的项目
    ''' </summary>
    ''' 生成菜单
    ''' ListInfo中元素的组成是:菜单名,菜单快捷访问符,父菜单(true时表示为父菜单,false表示为子菜单;只提供两级菜单),父菜单名
    ''' 是否添加到工具栏显示(true为在工具栏中显示),Imagelist对象,Imagelist中的index
    Public Sub CreateParentMenu(ByRef ListInfo As List(Of List(Of Object)), ByRef imagelist1 As System.Windows.Forms.ImageList, ByVal PicTextLayout As Integer)
        Dim t As Integer = 0
        Dim i As Integer = 0

        MaxBtnWidth = 0
        MaxBtnHeight = 0
        If IsNothing(ListInfo) = False Then
            If ListInfo.Count > 0 Then
                For i = 0 To ListInfo.Count - 1
                    '是否父菜单
                    If CBool(ListInfo.Item(i).Item(3)) = True Then
                        '是否这个菜单是主菜单;是则生成主菜单列表
                        '创建图片按钮
                        Me.Controls.Add(New PictureButtonMenu.PictureButtonMenu)
                        '是否父菜单
                        CType(Me.Controls.Item(t), PictureButtonMenu.PictureButtonMenu).SetParentMenu = True
                        '背景色
                        CType(Me.Controls.Item(t), PictureButtonMenu.PictureButtonMenu).BackColor = System.Drawing.SystemColors.ControlLight
                        '边框样式
                        CType(Me.Controls.Item(t), PictureButtonMenu.PictureButtonMenu).BorderStyle = Windows.Forms.BorderStyle.None
                        '是否自动适应大小
                        CType(Me.Controls.Item(t), PictureButtonMenu.PictureButtonMenu).ControlSizeSetF = True
                        '图片按钮的图片文字排版格式
                        CType(Me.Controls.Item(t), PictureButtonMenu.PictureButtonMenu).TextImageLayout = CType(PicTextLayout, PictureButtonMenu.PictureButtonMenu.Layout)
                        '添加图片按钮的图片
                        CType(Me.Controls.Item(t), PictureButtonMenu.PictureButtonMenu).AddBmp(imagelist1.Images(CType(ListInfo.Item(i).Item(6), Integer)))
                        '记下当前按钮的外接应用程序名
                        CType(Me.Controls.Item(t), PictureButtonMenu.PictureButtonMenu).SetAppName = ListInfo.Item(i).Item(7).ToString
                        '记下当前图片按钮的菜单号
                        CType(Me.Controls.Item(t), PictureButtonMenu.PictureButtonMenu).SetTag = CType(ListInfo.Item(i).Item(1), Integer)
                        '按钮文本
                        CType(Me.Controls.Item(t), PictureButtonMenu.PictureButtonMenu).Caption = CType(ListInfo.Item(i).Item(0), String)
                        '控件索引
                        CType(Me.Controls.Item(t), PictureButtonMenu.PictureButtonMenu).Text = t.ToString
                     
                        '是否自动适应大小
                        CType(Me.Controls.Item(t), PictureButtonMenu.PictureButtonMenu).ControlSizeSetF = False
                        '重绘确定大小
                        CType(Me.Controls.Item(t), PictureButtonMenu.PictureButtonMenu).RefreshPicBtn()

                        '获取最大值,以便于统一所有工具栏上按钮的大小
                        If CType(Me.Controls.Item(t), PictureButtonMenu.PictureButtonMenu).Width > MaxBtnWidth Then
                            MaxBtnWidth = CType(Me.Controls.Item(t), PictureButtonMenu.PictureButtonMenu).Width
                        End If
                        If CType(Me.Controls.Item(t), PictureButtonMenu.PictureButtonMenu).Height > MaxBtnHeight Then
                            MaxBtnHeight = CType(Me.Controls.Item(t), PictureButtonMenu.PictureButtonMenu).Height
                        End If
                        '绑定单击事件
                        AddHandler CType(Me.Controls.Item(t), PictureButtonMenu.PictureButtonMenu).ParentMenuMouseLeave, AddressOf ActiveMouseLeaveEvent
                        AddHandler CType(Me.Controls.Item(t), PictureButtonMenu.PictureButtonMenu).ParentMenuMouseMoveInto, AddressOf ActiveMouseMoveIntoEvent
                        t = t + 1
                    End If
                Next
                '工具栏背景色
                ' Me.BackColor = Me.BackColor
                '工具栏整个的大小
                If HorVerFlag = False Then
                    Me.Width = Me.Controls.Count * MaxBtnWidth
                    Me.Height = MaxBtnHeight
                Else
                    Me.Width = MaxBtnWidth
                    Me.Height = Me.Controls.Count * MaxBtnHeight
                End If


                For j As Integer = 0 To Me.Controls.Count - 1
                    '大小重新设置
                    CType(Me.Controls.Item(j), PictureButtonMenu.PictureButtonMenu).Size = New System.Drawing.Size(MaxBtnWidth, MaxBtnHeight)
                Next

                '工具栏中控件重新排版
                Dim xzb As Integer = 0
                Dim yzb As Integer = 0
                For k As Integer = 0 To Me.Controls.Count - 1
                    If HorVerFlag = False Then
                        CType(Me.Controls.Item(k), PictureButtonMenu.PictureButtonMenu).Location = New Point(xzb, 0)
                        xzb = (CType(Me.Controls.Item(k), PictureButtonMenu.PictureButtonMenu).Width) + xzb
                    Else
                        CType(Me.Controls.Item(k), PictureButtonMenu.PictureButtonMenu).Location = New Point(0, yzb)
                        yzb = (CType(Me.Controls.Item(k), PictureButtonMenu.PictureButtonMenu).Height) + yzb
                    End If
                Next
            End If
        End If
        Me.Refresh()
    End Sub

    '存放当前子菜单的主窗体上的panel的字典
    Private ParentBhPanelDic As New Dictionary(Of String, System.Windows.Forms.Panel)
    ''' <summary>
    ''' 根据传入的用户菜单的参数动态创建开始菜单各个父菜单下面子菜单的项目
    ''' </summary>
    ''' 生成菜单
    ''' ListInfo中元素的组成是:菜单名,菜单快捷访问符,父菜单(true时表示为父菜单,false表示为子菜单;只提供两级菜单),父菜单名
    ''' 是否添加到工具栏显示(true为在工具栏中显示),Imagelist对象,Imagelist中的index
    Public Sub CreateChildMenu(ByRef ListInfo As List(Of List(Of Object)), ByRef imagelist1 As System.Windows.Forms.ImageList, ByVal PicTextLayout As Integer)
        HorVerFlag = True
        Dim t As Integer = 0
        Dim i As Integer = 0
        Dim m As Integer = 0

        If IsNothing(ListInfo) = False Then
            If ListInfo.Count > 0 Then
                '各个主菜单下面的子菜单逐个依次生成
                Dim panelMenu As System.Windows.Forms.Panel
                Dim panelMenuFb As System.Windows.Forms.Panel
                For m = 0 To Me.Controls.Count - 1
                    t = 0
                    MaxBtnWidth = 0
                    MaxBtnHeight = 0
                    For i = 0 To ListInfo.Count - 1
                        '是否父菜单
                        If CBool(ListInfo.Item(i).Item(3)) = False AndAlso CType(ListInfo.Item(i).Item(4), String) = CType(Me.Controls.Item(m), PictureButtonMenu.PictureButtonMenu).Caption Then
                            '是否这个菜单是主菜单;是则生成菜单列表

                            If ParentBhPanelDic.TryGetValue(CType(ListInfo.Item(i).Item(4), String), panelMenuFb) = False Then
                                panelMenu = New System.Windows.Forms.Panel
                                Me.Parent.Controls.Add(panelMenu)
                                ParentBhPanelDic.Add(CType(ListInfo.Item(i).Item(4), String), panelMenu)
                                panelMenu = Nothing
                            End If
                            If ParentBhPanelDic.TryGetValue(CType(ListInfo.Item(i).Item(4), String), panelMenuFb) = True Then
                                '创建图片按钮

                                panelmenufb.Controls.Add(New PictureButtonMenu.PictureButtonMenu)
                                '是否父菜单
                                CType(panelmenufb.Controls.Item(t), PictureButtonMenu.PictureButtonMenu).SetParentMenu = False
                                '背景色
                                CType(panelmenufb.Controls.Item(t), PictureButtonMenu.PictureButtonMenu).BackColor = System.Drawing.SystemColors.ControlLight
                                '边框样式
                                CType(panelmenufb.Controls.Item(t), PictureButtonMenu.PictureButtonMenu).BorderStyle = Windows.Forms.BorderStyle.None
                                '是否自动适应大小
                                CType(panelmenufb.Controls.Item(t), PictureButtonMenu.PictureButtonMenu).ControlSizeSetF = True
                                '图片按钮的图片文字排版格式
                                CType(panelmenufb.Controls.Item(t), PictureButtonMenu.PictureButtonMenu).TextImageLayout = CType(PicTextLayout, PictureButtonMenu.PictureButtonMenu.Layout)
                                '添加图片按钮的图片
                                CType(panelmenufb.Controls.Item(t), PictureButtonMenu.PictureButtonMenu).AddBmp(imagelist1.Images(CType(ListInfo.Item(i).Item(6), Integer)))
                                '记下当前按钮的外接应用程序名
                                CType(panelmenufb.Controls.Item(t), PictureButtonMenu.PictureButtonMenu).SetAppName = ListInfo.Item(i).Item(7).ToString
                                '记下当前图片按钮的菜单号
                                CType(panelmenufb.Controls.Item(t), PictureButtonMenu.PictureButtonMenu).SetTag = CType(ListInfo.Item(i).Item(1), Integer)
                                '按钮文本
                                CType(panelmenufb.Controls.Item(t), PictureButtonMenu.PictureButtonMenu).Caption = CType(ListInfo.Item(i).Item(0), String)
                                '控件索引
                                CType(panelmenufb.Controls.Item(t), PictureButtonMenu.PictureButtonMenu).Text = t.ToString
                              
                                '是否自动适应大小
                                CType(panelMenuFb.Controls.Item(t), PictureButtonMenu.PictureButtonMenu).ControlSizeSetF = False
                                '重绘确定大小
                                CType(panelMenuFb.Controls.Item(t), PictureButtonMenu.PictureButtonMenu).RefreshPicBtn()
                                '获取最大值,以便于统一所有工具栏上按钮的大小
                                If CType(panelmenufb.Controls.Item(t), PictureButtonMenu.PictureButtonMenu).Width > MaxBtnWidth Then
                                    MaxBtnWidth = CType(panelMenuFb.Controls.Item(t), PictureButtonMenu.PictureButtonMenu).Width
                                End If
                                If CType(panelmenufb.Controls.Item(t), PictureButtonMenu.PictureButtonMenu).Height > MaxBtnHeight Then
                                    MaxBtnHeight = CType(panelMenuFb.Controls.Item(t), PictureButtonMenu.PictureButtonMenu).Height
                                End If
                                '绑定单击事件
                                AddHandler CType(panelMenuFb.Controls.Item(t), PictureButtonMenu.PictureButtonMenu).Click, AddressOf ActiveEvent

                                t = t + 1
                            End If
                        End If
                    Next

                    '一个主菜单下所有子菜单的panel整个的大小
                    If HorVerFlag = False Then
                        panelmenufb.Width = panelmenufb.Controls.Count * MaxBtnWidth
                        panelmenufb.Height = MaxBtnHeight
                    Else
                        panelmenufb.Width = MaxBtnWidth
                        panelmenufb.Height = panelmenufb.Controls.Count * MaxBtnHeight
                    End If
                  

                    For j As Integer = 0 To panelmenufb.Controls.Count - 1
                        '大小重新设置
                        CType(panelmenufb.Controls.Item(j), PictureButtonMenu.PictureButtonMenu).Size = New System.Drawing.Size(MaxBtnWidth, MaxBtnHeight)
                    Next

                    '工具栏中控件重新排版
                    Dim xzb As Integer = 0
                    Dim yzb As Integer = 0
                    For k As Integer = 0 To panelmenufb.Controls.Count - 1
                        If HorVerFlag = False Then
                            CType(panelmenufb.Controls.Item(k), PictureButtonMenu.PictureButtonMenu).Location = New Point(xzb, 0)
                            xzb = (CType(panelmenufb.Controls.Item(k), PictureButtonMenu.PictureButtonMenu).Width) + xzb
                        Else
                            CType(panelmenufb.Controls.Item(k), PictureButtonMenu.PictureButtonMenu).Location = New Point(0, yzb)
                            yzb = (CType(panelmenufb.Controls.Item(k), PictureButtonMenu.PictureButtonMenu).Height) + yzb
                        End If
                    Next

                    panelmenufb.Refresh()
                    panelmenufb.Visible = False
                Next
            End If
        End If
    End Sub
    ''' <summary>
    ''' 销毁控件,以便于释放控件占用的资源
    ''' </summary>
    ''' 销毁按钮
    ''' 销毁工具栏
    Public Sub DisposeToolbar()
        Dim list As New List(Of System.Windows.Forms.Panel)
        If ParentBhPanelDic.Count > 0 Then '
            Dim keyvalue As KeyValuePair(Of String, System.Windows.Forms.Panel)
            For Each keyvalue In ParentBhPanelDic
                list.Add(keyvalue.Value)
            Next
            keyvalue = Nothing

            ParentBhPanelDic.Clear()
            ParentBhPanelDic = Nothing
            For j As Integer = list.Count - 1 To 0
                For index As Integer = list(j).Controls.Count - 1 To 0
                    RemoveHandler CType(list(j).Controls.Item(index), PictureButtonMenu.PictureButtonMenu).Click, AddressOf ActiveEvent
                    CType(list(j).Controls.Item(index), PictureButtonMenu.PictureButtonMenu).DisposePictureButton()
                    CType(list(j).Controls.Item(index), PictureButtonMenu.PictureButtonMenu).Dispose()
                Next
                list(j).Controls.Clear()
                list(j).Refresh()
                list(j).Dispose()
            Next
            list.Clear()
            list = Nothing

        End If
        For i As Integer = Me.Controls.Count - 1 To 0 Step -1
            '销毁
            RemoveHandler CType(Me.Controls.Item(i), PictureButtonMenu.PictureButtonMenu).ParentMenuMouseLeave, AddressOf ActiveMouseMoveIntoEvent
            RemoveHandler CType(Me.Controls.Item(i), PictureButtonMenu.PictureButtonMenu).ParentMenuMouseMoveInto, AddressOf ActiveMouseLeaveEvent
            CType(Me.Controls.Item(i), PictureButtonMenu.PictureButtonMenu).DisposePictureButton()
            CType(Me.Controls.Item(i), PictureButtonMenu.PictureButtonMenu).Dispose()
        Next
        Me.Controls.Clear()
        Me.Refresh()
        Me.Dispose()
    End Sub
    ''' <summary>
    ''' 对此工具栏控件的按下状态进行重置;同时激发按钮的按下自定义事件
    ''' </summary>
    ''' 激发事件处理函数
    Private Sub ActiveEvent(ByVal sender As Object, ByVal e As System.EventArgs)
        Dim PicBtn As PictureButtonMenu.PictureButtonMenu
        PicBtn = CType(sender, PictureButtonMenu.PictureButtonMenu)
        If PicBtn.Pressed = True Then
            '单击后都隐藏
            PicBtn.Parent.Visible = False
            RaiseEvent btnclick(CInt(PicBtn.Tag), CStr(PicBtn.BtnAppName))
        End If
    End Sub
    ''' <summary>
    ''' 父菜单的鼠标滑过事件处理
    ''' </summary>
    ''' <param name="parentName"></param>
    ''' <remarks></remarks>
    Private Sub ActiveMouseMoveIntoEvent(ByVal sender As Object, ByVal parentName As String)
        Dim PanelMenuFb As System.Windows.Forms.Panel
        If ParentBhPanelDic.TryGetValue(CType(sender, PictureButtonMenu.PictureButtonMenu).Caption, PanelMenuFb) Then
            If CType(sender, PictureButtonMenu.PictureButtonMenu).Moved = True Then
                '显示一个新的之前先都隐藏
                Dim keyvalue As KeyValuePair(Of String, System.Windows.Forms.Panel)
                For Each keyvalue In ParentBhPanelDic
                    keyvalue.Value.Visible = False
                Next

                PanelMenuFb.Location = New Point(CType(sender, PictureButtonMenu.PictureButtonMenu).RectangleToScreen(CType(sender, PictureButtonMenu.PictureButtonMenu).ClientRectangle).Left, Me.RectangleToScreen(Me.ClientRectangle).Bottom)
                PanelMenuFb.Visible = True
                PanelMenuFb.BringToFront()
            End If
        End If
    End Sub
    ''' <summary>
    ''' 父菜单的鼠标离开事件处理
    ''' </summary>
    ''' <param name="parentName"></param>
    ''' <remarks></remarks>
    Private Sub ActiveMouseLeaveEvent(ByVal sender As Object, ByVal parentName As String)
        Dim PanelMenuFb As System.Windows.Forms.Panel
        If ParentBhPanelDic.TryGetValue(CType(sender, PictureButtonMenu.PictureButtonMenu).Caption, PanelMenuFb) Then
            If CType(sender, PictureButtonMenu.PictureButtonMenu).Moved = False Then
                Dim rect As Rectangle = Me.RectangleToScreen(Me.ClientRectangle)
                If rect.Contains(Control.MousePosition.X, Control.MousePosition.Y) = True Then
                    PanelMenuFb.Visible = False
                End If
            End If
        End If
    End Sub

  


End Class

 最后,菜单的形成代码(自己建立一个应用程序项目,拷贝下面的代码):

 Public curDir As String = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase().ToString())
    Public SystemLanguage As String = "zh-CN"

    Private Sub Form1_Closed(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Closed
        Me.FullyCustomizableMenu1.DisposeToolbar()
        Me.Close()
        Me.Dispose()
    End Sub
    Dim ChildMenuPanelsDic As Dictionary(Of Integer, Panel)
    Dim panelMenu As Panel
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        '---------------------------------------------------------------------
        Dim xmlPro As New XMLProcess(curDir, SystemLanguage)
        Dim Result As New List(Of List(Of Object))
        xmlPro.SelectShowMenu(Result, "Menus", "Menus")
        If Result.Count > 0 Then
            '完全自定义工具栏控件
            Me.FullyCustomizableMenu1.CreateParentMenu(Result, Me.ImageList1, 1)
          
            Me.FullyCustomizableMenu1.CreateChildMenu(Result, Me.ImageList1, 1)
            MsgBox(Me.FullyCustomizableMenu1.Width)
            Result.Clear()
            Result = Nothing
        End If
        xmlPro = Nothing
        Me.FullyCustomizableMenu1.Location = New Point(0, 300)
    End Sub

 

说明:XMLProcess是我自定义的一个处理xml配置文件的类,关于菜单Menus.xml的文件结构如下:

<?xml version="1.0"?>
<Menus>
  <Menu MenuName="菜单名" MenuId="菜单编号">
    <MenuShortKeys>快捷键</MenuShortKeys>
    <YNPMenu>是否父菜单</YNPMenu>
    <PMenuName>父菜单名</PMenuName>
    <YNToolbar>本项目菜单是否在工具栏显示</YNToolbar>
    <ImageIndex>菜单图片索引号</ImageIndex>
    <appName>菜单调用EXE名称</appName>
  </Menu>

————--  这里自己添加   ----------------------------------------------
    </Menus>

以上就是关于图文混编按钮、XP风格开始菜单及右键菜单、工具栏自定义控件的源码,转载请注明出处,

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值