|
|||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||
|
Announcements
Chapters
Services
Feature Zones
|
IntroductionWe are going to be taking a look at the construction of an analog clock using textured backgrounds. I know this "looks" hard and intimidating, but believe me, it's anything but hard :-) Step 1Modifying your form's startupFirst thing is, we need to change the way your form starts so we can control the loading procedure. This is fairly simple to accomplish. What you need to do is create a Shared Sub Main()
Application.Run(New frmClock())
Application.Exit()
End Sub
This will start up the form named Public Sub New()
MyBase.New()
InitializeComponent()
initclock()
End Sub
All that's left to do now is change the project's startup properties to make it use our Step 2Create the cHands class to hold the hands information01: Public Class cHands
02: Private Angle As Integer = 0
03: Public Path As New Drawing2D.GraphicsPath()
04: Public filled As Boolean = False
05:
06:
07: ' We have to set a new angle so subtract it from the old one and thats
08: ' how far we have to move
09: '
10: Public Sub setAngle(ByVal newAngle As Integer, ByVal imgCenter As PointF)
11: Dim Rotate As Integer = newAngle - Angle
12: Dim trans As New Drawing2D.Matrix()
13: trans.RotateAt(Rotate, imgCenter)
14: Path.Transform(trans)
15: Me.Angle = newAngle
16: End Sub
17:
18:
19: ' Did somone say draw?
20: '
21: Public Sub draw(ByVal imgDraw As Graphics)
22: If filled Then
23: imgDraw.FillPath(Brushes.DimGray, Path)
24: imgDraw.DrawPath(Pens.Black, Path)
25: Else
26: imgDraw.DrawPath(New Pen(Color.DimGray, 2), Path)
27: End If
28: End Sub
29: End Class
In this step, we have created a class that will be used to store information about the individual hands of the clock. Step 3ControlsGo to your form, add a Step 4Tick tock goes the clockFirst thing we need to do is create the variables for the clock hands using our Private handHour As New cHands()
Private handMinute As New cHands()
Private handSecond As New cHands()
Private center = New PointF(150, 150)
Next is the part where it all starts, the Private Sub initclock()
Me.ClientSize = New Size(300, 300)
First things first, make sure the client area for the form is 300 x 300. Now, we initialize the hands, remember the Dim drawHour As Point() = _
{New Point(Int(clock.Width / 2), Int(clock.Height / 2)), _
New Point(Int(clock.Width / 2 - 5), 80), _
New Point(Int(clock.Width / 2), 50), _
New Point(Int(clock.Width / 2 + 5), 80), _
New Point(Int(clock.Width / 2), Int(clock.Height / 2))}
Dim drawMinute As Point() = _
{New Point(Int(clock.Width / 2), Int(clock.Height / 2)), _
New Point(Int(clock.Width / 2 - 5), 60), _
New Point(Int(clock.Width / 2), 30), _
New Point(Int(clock.Width / 2 + 5), 60), _
New Point(Int(clock.Width / 2), Int(clock.Height / 2))}
Why didn't we use handHour.Path.AddLines(drawHour)
handHour.filled = True
handMinute.Path.AddLines(drawMinute)
handMinute.filled = True
But wait, what about the second hand? Well, the second hand is just a line. It's not a shape that needs to be filled. So, it's really easy to draw. handSecond.Path.AddLine(center, New PointF(Int(clock.Width / 2), 25))
End Sub
That's it for this Private Sub Timer1_Tick(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles Timer1.Tick
clock.Invalidate()
End Sub
Basically, what this says is every time the timer ticks, repaint the clock. Now we need to create the painting event for clock. Private Sub clock_Paint(ByVal sender As Object, _
ByVal e As System.Windows.Forms.PaintEventArgs) Handles clock.Paint
handHour.setAngle((360 / 60) * Val(Format(Now, "hh")), center)
handMinute.setAngle((360 / 60) * Val(Format(Now, "mm")), center)
handSecond.setAngle((360 / 60) * Val(Format(Now, "ss")), center)
handHour.draw(e.graphics)
handMinute.draw(e.graphics)
handSecond.draw(e.graphics)
End Sub
What this Why not run your program now and watch the hands move across the screen? Step 5Dressing it upHere, you create a Private Sub drawFace(ByVal g As Graphics)
Dim path As String = Mid(Application.ExecutablePath, 1, _
InStrRev(Application.ExecutablePath, "\"))
Dim grdFace As New TextureBrush(New Bitmap(path & "\face.jpg"))
Dim grdWatch As New TextureBrush(New Bitmap(path & "\watch.jpg"))
g.FillEllipse(grdWatch, New Rectangle(5, 5, 290, 290))
g.FillEllipse(Brushes.Black, New Rectangle(15, 15, 270, 270))
g.FillEllipse(grdFace, New Rectangle(20, 20, 260, 260))
Dim f As New Font("Arial", 10, FontStyle.Bold)
Dim Sze = g.MeasureString("Powered by Visual Basic.NET", f)
g.DrawString("Powered by Visual Basic.NET", f, _
Brushes.Black, (300 - Sze.width) / 2, 200)
grdFace.Dispose()
grdWatch.Dispose()
' Don't dispose g !
End Sub
The last thing you need to do is add the Private Sub clock_Paint(ByVal sender As Object, _
ByVal e As System.Windows.Forms.PaintEventArgs) Handles clock.Paint
drawFace(e.Graphics)
...
...
...
End Sub
Well, that's it, you should now have a working clock with a cool looking face.
|
||||||||||||||||||||||||||||||||||||||||||||||||||