-- 作者:admin
-- 发布时间:11/9/2004 2:25:00 AM
-- 用VB.NET做个时钟
发信人: mydea (请多关照), 信区: DotNET 标 题: 用VB.NET做个时钟 发信站: BBS 水木清华站 (Sat Dec 15 01:10:58 2001) 是使用GDI+画图的例子 本章最后的综合实例是一个模拟时钟。程序运行时,窗体中模拟一个真实的时钟那样显示当前的时间。 本程序使用了面向对象的编程方法,由于时针(HourHand)、分针(MinuteHand)和秒针(SecondHand)包含相似的属性和方法,我们生成一个针(Hand)类作为它们共同的基类,提供共有的类成员。下面是定义Hand类的代码: Public MustInherit Class Hand Protected gp As GraphicsPath = New GraphicsPath() Protected gpBase As GraphicsPath = Nothing Protected midX As Integer = 150 ‘默认的窗体 Protected midY As Integer = 150 ‘中心位置 ‘构造器,得到窗体中心位置 Public Sub New(ByVal theForm As Form1) midX = (theForm.ClientRectangle.Left + theForm.ClientRectangle.Right) / 2 midY = (theForm.ClientRectangle.Top + theForm.ClientRectangle.Bottom) / 2 End Sub MustOverride Sub Transform(ByVal d As DateTime) ‘绘制指针路径 Overridable Sub Draw(ByVal g As Graphics) Dim aPen As Pen = New Pen(Brushes.Black, 4F) g.DrawPath(aPen, gp) g.FillPath(Brushes.Black, gp) aPen.Dispose() End Sub ‘使用矩阵实现路径(gp)的旋转 Public Sub Rotate(ByVal angle As Double) gp = CType(gpBase.Clone(), GraphicsPath) Dim mTransform As Matrix = New Matrix() mTransform.RotateAt(CType(angle,Single),NewPointF(midX,midY)) gp.Transform(mTransform) End Sub End Class 为了节省篇幅,上面的代码省略了引入命名空间的语句。 下面是分针(MinuteHand)类的定义: Public Class MinuteHand Inherits Hand ‘构造器,生成绘制分针的路径(gp) Public Sub New(ByVal myForm As Form1) MyBase.New(myForm) gp.AddLine(midX, midY, midX, 45) gp.AddLine(midX, 45, midX - 3, 50) gp.AddLine(midX - 3, 50, midX + 3, 50) gp.AddLine(midX + 3, 50, midX, 45) gpBase = CType(gp.Clone(), GraphicsPath) End Sub ‘Transform方法取得系统当前时间,并旋转时钟指针。 Public Overrides Sub Transform(ByVal d As DateTime) Dim minuteTime As Double = (CDbl(d.Minute) + CDbl(d.Second / 60)) Dim angle As Double = (CDbl(minuteTime) / 60) * 360 Rotate(angle) End Sub End Class 对所有的指针旋转的方法都是相同的,因此在基类中实现。由于时针和秒针的实现与分针相似,所不同者,只在于构造器中绘制的指针路径不同和Transform方法中转动的角度不同,在这里就不在赘述了。 另外还需要提一下的是画时钟表面的代码,时钟表面用ClockFace类来实现。这个类首先画一个圆代表时钟,然后画上米老鼠的图案,最后在相应的位置画上数字1~12代表12个小时。 Public Sub Draw(ByVal g As Graphics) DrawClockFace(g) DrawImage(g) DrawNumbers(g) DrawPin(g) End Sub 下面是ClockFace类的属性: Private ClockRectangle As Rectangle Private ClockFont As Font = New Font("Arial", 12) Private midPoint As Point Private ClockImage As Bitmap Private Const IMAGEX As Integer = 50 Private Const IMAGEY As Integer = 50 DrawClockFace方法用来画时钟表面: Private Sub DrawClockFace(ByVal g As Graphics) g.FillEllipse(Brushes.White, ClockRectangle.Left + 10, ClockRectangle.Top + 10, ClockRectangle.Width - 20, ClockRectangle.Height - 20) g.DrawEllipse(Pens.Black, ClockRectangle.Left + 10, ClockRectangle.Top + 10, ClockRectangle.Width - 20, ClockRectangle.Height - 20) End Sub 然后用Graphics对象的DrawImage方法画出米老鼠的图片: Private Sub DrawImage(ByVal g As Graphics) Dim nWidth As Integer = ClockImage.Width Dim nHeight As Integer = ClockImage.Height Dim destRect As Rectangle = New Rectangle(midPoint.X - IMAGEX / 2, midPoint.Y - IMAGEY / 2, IMAGEX, IMAGEY) g.DrawImage(ClockImage, destRect) End Sub 数字在时钟上的位置是用sin和cos函数计算的: Private Sub DrawNumbers(ByVal g As Graphics) Dim count As Integer = 1 Dim a As Double For a = 0 To 2 * Math.PI Step 2 * Math.PI / 12 Dim x As Double = (ClockRectangle.Width - 70) / 2 * Math.Cos(a - Math.PI / 3) + (ClockRectangle.Width - 70) / 2 + 25 Dim y As Double = (ClockRectangle.Width - 70) / 2 * Math.Sin(a - Math.PI / 3) + (ClockRectangle.Width - 70) / 2 + 20 g.DrawString(Convert.ToString(count), ClockFont, Brushes.Black, CType(x, Single), CType(y, Single), New StringFormat()) count += 1 Next End Sub 最后是窗体文件(Form1.vb): Public Class Form1 Inherits System.Windows.Forms.Form Private MyMinuteHand As MinuteHand Private MyHourHand As HourHand Private MySecondHand As SecondHand Private TheClockFace As ClockFace Private FirstTick As Boolean = False ‘在窗体的OnPaint事件中取得Graphics对象 Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs) If (FirstTick = False) Then Exit Sub Dim g As Graphics = e.Graphics TheClockFace.Draw(g) MyHourHand.Draw(g) MyMinuteHand.Draw(g) MySecondHand.Draw(g) TheClockFace.DrawPin(g) End Sub ‘计时器事件 Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick MySecondHand.Transform(DateTime.Now) MyHourHand.Transform(DateTime.Now) MyMinuteHand.Transform(DateTime.Now) FirstTick = True Invalidate() ‘此方法继承自Control类,使控件失效而导致窗体重绘(即再次调用OnPaint事件) End Sub End Class 注意要在Form1类的构造器中键入下列代码: MyMinuteHand = New MinuteHand(Me) MyHourHand = New HourHand(Me) MySecondHand = New SecondHand(Me) TheClockFace = New ClockFace(ClientRectangle) 在Dispose方法中键入 timer1.Start() 图13-9为程序执行时显示的效果: -- ※ 来源:·BBS 水木清华站 smth.org·[FROM: 162.105.106.97] 上一篇 返回上一页 回到目录 回到页首
|