我的假按钮 第一部分





4.00/5 (2投票s)
如何使用 GDI+ 制作一个假按钮。
引言
大家好,
在开始之前,首先我想深表歉意。这是因为我的英语很差,所以我使用谷歌翻译写了这篇文章。再次深表歉意。
这是我第一次写文章。所以,如果出现问题,请指正错误之处。
我一直在学习和使用 Visual Basic,从版本 5 开始。借此机会,我想分享一下关于 GDI + 的知识。对我来说,当我了解 GDI + 时。我真的很惊讶。众所周知,发生这种情况是因为 Visual Basic 5 和 Visual Basic 6 不了解它。更值得注意的是,您可以测试鼠标光标在单击区域时的准确性。如果您有 MSDN,您可以通过打开页面 How to: Use Hit Testing with a Region 来学习它。阅读完这篇文章后,我突然想到,我的心里说,等等,这基本上是在制作一个控件。
开始吧
运行 Visual Basic 后。创建一个 Windows 应用程序类型的项目。之后将其命名为 GDIPP01。 GDIPP01 是 GDI + Project 1 的扩展。只是一个首字母缩写词。一旦项目制作完成,您将找到文件 Form1.vb。此时您不需要更改其名称。之后创建一个新的代码文件类型的文件,您也不需要更改其名称。因此,默认情况下,该文件将被命名为 CodeFile1.vb。
在开始之前,我将概述稍后将要完成的事情,从
- MyPath。
MyPath 是一个模块。此模块用于操作路径和区域。
- MyColor。
MyColor 是组件类类型的模块。此组件将用于操作颜色。结果可以是 Color 或 Brush。
- MyButton。
MyButton 是组件类型的类模块。此组件将在 Form1.vb 上创建一个假按钮
注意:MyPath、MyColor 和 MyButton 将仅在一个类中创建,即 CodeFile1.vb。
现在,进入 CodeFile1.vb 文件拥有的代码视图窗口。之后键入以下代码
Imports System.ComponentModel
Public Module MyPath
Dim vPath As New Drawing2D.GraphicsPath
Function GetRoundedRectangle(ByVal Size As SizeF, _
ByVal Rounded As Single) As Drawing2D.GraphicsPath
vPath.Dispose()
vPath = New Drawing2D.GraphicsPath
Dim r1 As New Rectangle(0, 0, Rounded * 2, Rounded * 2)
Dim r2 As New Rectangle(Size.Width - r1.Width, 0, r1.Width, r1.Height)
Dim r3 As New Rectangle(r2.X, Size.Height - r1.Height, r1.Width, r1.Height)
Dim r4 As New Rectangle(r1.X, r3.Y, r1.Width, r1.Height)
Dim l1() As PointF = {New PointF(Rounded, 0), New PointF(Size.Width - Rounded, 0)}
Dim l2() As PointF = {New PointF(Size.Width, Rounded), New PointF(Size.Width, Size.Height - Rounded)}
Dim l3() As PointF = {New PointF(Size.Width - Rounded, Size.Height), New PointF(Rounded, Size.Height)}
Dim l4() As PointF = {New PointF(0, Size.Height - Rounded), New PointF(0, Rounded)}
vPath.AddArc(r1, -180, 90)
vPath.AddLines(l1)
vPath.AddArc(r2, -90, 90)
vPath.AddLines(l2)
vPath.AddArc(r3, 0, 90)
vPath.AddLines(l3)
vPath.AddArc(r4, 90, 90)
vPath.AddLines(l4)
Return vPath
End Function
End Module
到这里,您已经完成了 MyPath 模块的制作。现在我们将制作 MyColor 类。以下是您应该键入的内容
Public Class MyColor
Inherits Component
Dim vColor As Color = Drawing.Color.White
Dim vTransBool As Boolean = False
Dim vTransInt As Integer = 255
Event ColorChanged(ByVal o As Object)
Property Color() As Color
Get
Return vColor
End Get
Set(ByVal value As Color)
vColor = value
RaiseEvent ColorChanged(Me)
End Set
End Property
Property CanTransparent() As Boolean
Get
Return vTransBool
End Get
Set(ByVal value As Boolean)
vTransBool = value
RaiseEvent ColorChanged(Me)
End Set
End Property
Property TransparentValue() As Integer
Get
Return vTransInt
End Get
Set(ByVal value As Integer)
vTransInt = value
RaiseEvent ColorChanged(Me)
End Set
End Property
Function GetColor() As Color
With Me
If .vTransBool = True Then
Return Drawing.Color.FromArgb(.vTransInt, .vColor)
Else
Return .vColor
End If
End With
End Function
Function GetBrush() As Brush
Return New SolidBrush(Me.GetColor)
End Function
Sub New()
MyBase.New()
End Sub
Sub New(ByVal Color As Color, Optional ByVal CanTransparent As _
Boolean = False, Optional ByVal TransparentValue As Integer = 255)
MyBase.New()
With Me
.Color = Color
.CanTransparent = CanTransparent
.TransparentValue = TransparentValue
End With
End Sub
End Class
到这里,您已经完成了 MyColor 类的制作。接下来我们将制作 MyButton 类。以下是您应该键入的内容
Public Class MyButton
Inherits Component
#Region "- Building Layout -"
Dim vRect As New RectangleF(0, 0, 100, 30)
Private Const CLayout As String = "Layout"
<Category(CLayout)> _
Property LayoutLeft() As Single
Get
Return vRect.X
End Get
Set(ByVal value As Single)
vRect.X = value
End Set
End Property
<Category(CLayout)> _
Property LayoutTop() As Single
Get
Return vRect.Y
End Get
Set(ByVal value As Single)
vRect.Y = value
End Set
End Property
<Category(CLayout)> _
Property LayoutWidth() As Single
Get
Return vRect.Width
End Get
Set(ByVal value As Single)
vRect.Width = value
End Set
End Property
<Category(CLayout)> _
Property LayoutHeight() As Single
Get
Return vRect.Height
End Get
Set(ByVal value As Single)
vRect.Height = value
End Set
End Property
Function GetRectangle() As Rectangle
Return New Rectangle(vRect.X, vRect.Y, vRect.Width, vRect.Height)
End Function
Function GetRectangleF() As RectangleF
Return vRect
End Function
#End Region
#Region "- Matrix -"
Dim vScale As New PointF(1, 1)
Dim vShear As New PointF
Dim vRotate As Single
Private Const CMatrix As String = "Matrix"
<Category(CMatrix)> _
Property MatrixRotate() As Single
Get
Return vRotate
End Get
Set(ByVal value As Single)
vRotate = value
End Set
End Property
<Category(CMatrix)> _
Property MatrixScaleX() As Single
Get
Return vScale.X
End Get
Set(ByVal value As Single)
vScale.X = value
End Set
End Property
<Category(CMatrix)> _
Property MatrixScaleY() As Single
Get
Return vScale.Y
End Get
Set(ByVal value As Single)
vScale.Y = value
End Set
End Property
<Category(CMatrix)> _
Property MatrixShearX() As Single
Get
Return vShear.X
End Get
Set(ByVal value As Single)
vShear.X = value
End Set
End Property
<Category(CMatrix)> _
Property MatrixShearY() As Single
Get
Return vShear.Y
End Get
Set(ByVal value As Single)
vShear.Y = value
End Set
End Property
#End Region
#Region "- Font & String Format -"
Dim vFont As New Font("tahoma", 8)
Dim vFormat As New StringFormat
Dim vStr As String = "My Button"
Dim WithEvents vStrColor As New MyColor(Color.Yellow)
Private Const CFont As String = "Writing Styles"
<Category(CFont)> _
Property StringFont() As Font
Get
Return vFont
End Get
Set(ByVal value As Font)
vFont = value
End Set
End Property
<Category(CFont)> _
Property StringVerticalAlingment() As StringAlignment
Get
Return vFormat.Alignment
End Get
Set(ByVal value As StringAlignment)
vFormat.Alignment = value
End Set
End Property
<Category(CFont)> _
Property StringHorizontalAlingment() As StringAlignment
Get
Return vFormat.LineAlignment
End Get
Set(ByVal value As StringAlignment)
vFormat.LineAlignment = value
End Set
End Property
<Category(CFont)> _
Property StringTrimming() As StringTrimming
Get
Return vFormat.Trimming
End Get
Set(ByVal value As StringTrimming)
vFormat.Trimming = value
End Set
End Property
<Category(CFont)> _
Property StringFormatFlags() As StringFormatFlags
Get
Return vFormat.FormatFlags
End Get
Set(ByVal value As StringFormatFlags)
vFormat.FormatFlags = value
End Set
End Property
<Category(CFont)> _
Property StringText() As String
Get
Return vStr
End Get
Set(ByVal value As String)
vStr = value
End Set
End Property
<Category(CFont)> _
ReadOnly Property StringColor() As MyColor
Get
Return vStrColor
End Get
End Property
#End Region
#Region "- Gradient -"
Dim WithEvents vColor1 As New MyColor(Color.Red), vColor2 As New MyColor(Color.Blue)
Dim vColorRotate As Single
Dim vGamma As Boolean = False
Private Const CBackcolor As String = "Background Color"
<Category(CBackcolor)> _
ReadOnly Property GradientColor1() As MyColor
Get
Return vColor1
End Get
End Property
<Category(CBackcolor)> _
ReadOnly Property GradientColor2() As MyColor
Get
Return vColor2
End Get
End Property
<Category(CBackcolor)> _
Property GradientRotate() As Single
Get
Return vColorRotate
End Get
Set(ByVal value As Single)
vColorRotate = value
End Set
End Property
<Category(CBackcolor)> _
Property GradientGamma() As Boolean
Get
Return vGamma
End Get
Set(ByVal value As Boolean)
vGamma = value
End Set
End Property
#End Region
#Region "- Else -"
Dim vRounded As Single = 10
Private Const CElse As String = "Else"
<Category(CElse)> _
Property Rounded() As Single
Get
Return vRounded
End Get
Set(ByVal value As Single)
vRounded = value
End Set
End Property
#End Region
Dim vMousePress, vMouseFocus As Boolean
Dim vMousePoint As New Point
Private Function OnAreaTarget(ByVal p As Point) As Boolean
With Me
Try
Using m1 As New Drawing2D.Matrix
m1.RotateAt(.vRotate, New PointF(.vRect.Width / 2, .vRect.Height / 2))
m1.Scale(.vScale.X, .vScale.Y)
m1.Shear(.vShear.X, .vShear.Y)
Using m2 As New Drawing2D.Matrix
m2.Translate(.vRect.X, .vRect.Y)
m2.Multiply(m1)
Using gp As New Drawing2D.GraphicsPath
gp.AddPath(MyPath.GetRoundedRectangle(.vRect.Size, .vRounded), False)
gp.Transform(m2)
Using Region As New Region(gp)
Return Region.IsVisible(p)
End Using
End Using
End Using
End Using
Catch ex As Exception
End Try
End With
End Function
Dim WithEvents vControl As New Control
Event Click(ByVal o As Object)
Event DoubleClick(ByVal o As Object)
Sub BindingControl(ByVal c As Control)
vControl = c
End Sub
Private Sub eColorChanged(ByVal o As Object) Handles _
vColor1.ColorChanged, vColor2.ColorChanged, vStrColor.ColorChanged
Me.vControl.Invalidate()
End Sub
Private Sub ePaint(ByVal o As Object, ByVal e As PaintEventArgs) Handles vControl.Paint
With Me
Try
Dim g As Graphics = e.Graphics
Dim gc As Drawing2D.GraphicsContainer = g.BeginContainer
g.CompositingQuality = Drawing2D.CompositingQuality.AssumeLinear
g.PixelOffsetMode = Drawing2D.PixelOffsetMode.Half
g.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias
g.TextRenderingHint = Drawing.Text.TextRenderingHint.AntiAlias
Dim Path As New Drawing2D.GraphicsPath
Path.AddPath(MyPath.GetRoundedRectangle(.vRect.Size, .vRounded), False)
Using m1 As New Drawing2D.Matrix
m1.RotateAt(.vRotate, New PointF(.vRect.Width / 2, .vRect.Height / 2))
m1.Scale(.vScale.X, .vScale.Y)
m1.Shear(.vShear.X, .vShear.Y)
Using m2 As New Drawing2D.Matrix
m2.Translate(.vRect.X, .vRect.Y)
m2.Multiply(m1)
g.MultiplyTransform(m2)
End Using
End Using
Using lgb As New Drawing2D.LinearGradientBrush(New Rectangle(0, 0, _
.vRect.Width, .vRect.Height), .vColor1.GetColor, .vColor2.GetColor, .vColorRotate, True)
lgb.GammaCorrection = .vGamma
g.FillPath(lgb, Path)
End Using
If .vMouseFocus = True Then
Using Trans As New MyColor(Color.White, True, 50)
g.FillRectangle(Trans.GetBrush, New Rectangle(0, 0, _
.vRect.Width, IIf(.vMousePress, .vRect.Height / 2, .vRect.Height / 2.4)))
End Using
End If
g.DrawString(.vStr, .vFont, .vStrColor.GetBrush, _
New Rectangle(4, 4, .vRect.Width - 8, .vRect.Height - 8), .vFormat)
If .vMouseFocus = True Then
g.DrawPath(New Pen(Color.Orange, IIf(.vMousePress, 4, 2)), Path)
End If
Path.Dispose()
g.EndContainer(gc)
Catch ex As Exception
End Try
End With
End Sub
Private Sub eMouseClick(ByVal o As Object, ByVal e As MouseEventArgs) Handles vControl.MouseClick
If Me.OnAreaTarget(e.Location) = True Then
RaiseEvent Click(Me)
End If
End Sub
Private Sub eMouseDoubleClick(ByVal o As Object, _
ByVal e As MouseEventArgs) Handles vControl.MouseDoubleClick
If Me.OnAreaTarget(e.Location) = True Then
RaiseEvent DoubleClick(Me)
End If
End Sub
Private Sub eMouseDown(ByVal o As Object, ByVal e As MouseEventArgs) Handles vControl.MouseDown
With Me
Try
If .OnAreaTarget(e.Location) = True Then
If .vMousePress = False Then
.vMousePress = True
.vControl.Invalidate()
Else
.vMousePress = True
End If
End If
Catch ex As Exception
End Try
End With
End Sub
Private Sub eMouseUp(ByVal o As Object, ByVal e As MouseEventArgs) Handles vControl.MouseUp
With Me
Try
If .vMousePress = True Then
.vMousePress = False
.vControl.Invalidate()
Else
.vMousePress = False
End If
Catch ex As Exception
End Try
End With
End Sub
Private Sub eMouseMove(ByVal o As Object, ByVal e As MouseEventArgs) Handles vControl.MouseMove
With Me
Try
If .OnAreaTarget(e.Location) = True Then
If .vMouseFocus = False Then
.vMouseFocus = True
.vControl.Invalidate()
Else
.vMouseFocus = True
End If
Else
If .vMouseFocus = True Then
.vMouseFocus = False
.vControl.Invalidate()
Else
.vMouseFocus = False
End If
End If
Catch ex As Exception
End Try
End With
End Sub
Sub New()
MyBase.New()
With Me
Try
With .vFormat
.Alignment = StringAlignment.Center
.LineAlignment = StringAlignment.Center
.FormatFlags = Drawing.StringFormatFlags.DisplayFormatControl
.Trimming = Drawing.StringTrimming.EllipsisCharacter
End With
Catch ex As Exception
End Try
End With
End Sub
End Class
到这里,您已经完成了 MyButton 类的制作。立即构建您的项目。稍后,如果成功,您将在工具箱窗口中找到两个新组件,大致如下所示
之后,将一个 MyButton 组件拖到 Form1.vb 拥有的设计视图中。之后,会发生以下情况
此时,已创建 MyButton 组件。现在查看属性窗口。这是 MyButton 拥有的所有属性
现在,让我们删除 Form1.vb 中现有的 MyButton1
组件。这样做是因为我更喜欢通过代码窗口而不是设计视图窗口来设计代码。之后,让我们进入 Form1.vb 拥有的代码窗口,并键入以下代码
Public Class Form1
Dim WithEvents vComboBox As New ComboBox
Dim WithEvents vButtonMin, vButtonMax, vButtonNormal, vButtonOut As New MyButton
Dim WithEvents vPropGrid As New PropertyGrid
Private Sub eLoad(ByVal o As System.Object, ByVal e As EventArgs) Handles MyBase.Load
With Me
Try
.DoubleBuffered = True
.ControlBox = False
Dim ArrayString() As String = {"Minimum", "Maximum", "Normal", "Close"}
.vComboBox.Items.AddRange(ArrayString)
.vComboBox.DropDownStyle = ComboBoxStyle.DropDownList
.vComboBox.Width = 200
.vComboBox.SelectedIndex = 0
Dim ArrayButton() As MyButton = {.vButtonMin, .vButtonMax, .vButtonNormal, .vButtonOut}
For a As Integer = 0 To ArrayButton.Length - 1
ArrayButton(a).LayoutLeft = 10
If a = 0 Then
ArrayButton(a).LayoutTop = 10
Else
ArrayButton(a).LayoutTop = ArrayButton(a - 1).LayoutTop + ArrayButton(a - 1).LayoutHeight + 10
End If
ArrayButton(a).StringText = ArrayString(a)
ArrayButton(a).BindingControl(Me)
Next
.Controls.Add(.vComboBox)
.Controls.Add(.vPropGrid)
.Size = New Size(640, 480)
Catch ex As Exception
End Try
End With
End Sub
Private Sub eResize(ByVal o As Object, ByVal e As EventArgs) Handles Me.Resize
With Me
Try
.vComboBox.Location = New Point(.ClientSize.Width - .vComboBox.Width - 10, 10)
.vPropGrid.Location = New Point(.vComboBox.Left, .vComboBox.Bottom + 10)
.vPropGrid.Size = New Size(.vComboBox.Width, .ClientSize.Height - .vPropGrid.Top - 10)
.Invalidate()
Catch ex As Exception
End Try
End With
End Sub
Private Sub eComboBoxSelIndexChanged(ByVal o As Object, _
ByVal e As EventArgs) Handles vComboBox.SelectedIndexChanged
With Me
Try
Dim ArrayButton() As MyButton = {.vButtonMin, .vButtonMax, .vButtonNormal, .vButtonOut}
.vPropGrid.SelectedObject = ArrayButton(.vComboBox.SelectedIndex)
Catch ex As Exception
End Try
End With
End Sub
Private Sub ePropValChanged(ByVal s As Object, ByVal e As _
PropertyValueChangedEventArgs) Handles vPropGrid.PropertyValueChanged
Me.Invalidate()
End Sub
Private Sub eMyButtonClick(ByVal o As Object) Handles vButtonMin.Click, _
vButtonMax.Click, vButtonNormal.Click, vButtonOut.Click
With Me
Try
If o Is .vButtonMin Then
.WindowState = FormWindowState.Minimized
End If
If o Is .vButtonMax Then
.WindowState = FormWindowState.Maximized
End If
If o Is .vButtonNormal Then
.WindowState = FormWindowState.Normal
End If
If o Is .vButtonOut Then
.Close()
End If
Catch ex As Exception
End Try
End With
End Sub
End Class
完成键入上面列出的代码后,我们只需运行该程序。稍后,看起来大致如下
现在,您可以测试所有按钮。您也可以更改每个按钮拥有的属性值。为此,您只需单击可用的组合框,大致如图所示
之后单击可用的项目。例如,我将 vButtonNormal 拥有的某些属性值更改如下
属性 |
值 |
圆角 |
30 |
布局高度 |
100 |
布局左侧 |
120 |
矩阵旋转 |
10 |
矩阵倾斜 Y |
0.5 |
StringFont -> 大小 |
12 |
结果大致如下
关注点
是不是很有趣。当控件通常无法执行此类操作时。精确控制哪个是假的,在这种情况下,MyButton 可能会这样做。到此为止是我第一次写这篇文章。如果有人想问,您可以发送电子邮件至 wahyu.pratama@hotmail.com。