|
Custom Controls - II
The C# Column - Yashawant Kanetkar
In
the last article we had added the Tick event handler for the mytimer control.
Let us see what we have done in this handler. Consider the following code of
the mytimer_Tick( ) handler:
g.TranslateTransform ( 60, 60 ) ;
for ( int i = 0 ; i<=12; i++ )
{
g.FillRectangle ( b, -2, -45, 4, 5 ) ;
g.RotateTransform ( 30 ) ;
}
g.ResetTransform( ) ;
Here we have drawn the rectangles that represent the
hours. We have used the TranslateTransform( ) method of the Graphics class to
shift the origin to (60, 60). Using the FillRectangle( ) method we drew 12 rectangles
and rotated the graphics world every time by 30 degrees. After drawing the rectangles
we used the ResetTransform( ) method to reset the transform world
to default settings.
Next we have drawn the seconds, minutes and hour hands.
To display the current time we need to calculate the angles of the hands first.
For every second, the second hand should be rotated by 6 degrees (360 / 60).
For every minute, the minute hand should be rotated by 6 degrees (360 / 60)
again; and for every hour the hour hand should be rotated by 30 degrees (360
/ 12).
Moreover, the hour hand should also be rotated by 0.5
degrees for every minute. This is because in every 60 minutes the hour hand
rotates by 30 degrees, hence in every minute it would rotate by 0.5 degrees.
So while displaying the current time we need to multiply the seconds, minutes
and hours values by the angles and rotate the hands by the multiplication results.
These calculations need to be done before starting the timer and hence we have
written this logic in a method called start( ). We will see this method later.
To draw the hands we have used appropriate Color, Width
and EndCap style of the Pen object. Next we have translated the graphics world
by 60, 60 and rotated it by s degrees. Then we have drawn the hand using the
DrawLine( ) method at appropriate co-ordinates. We have again used the ResetTransform(
) method to reset the transform.
For drawing the minute hand we have used the same logic
but rotated the hand by m degrees and made the hand shorter, thicker and of
blue color. We have also changed the EndCap style to LineCap.Triangle. After
resetting the transform we have drawn the hour hand rotated at an angle of h
degrees and made it shorter and thicker than the minute hand. We have used the
same EndCap style as that of the minute hand for the hour hand.
With every second we have incremented s by 6 degrees.
As soon as the angle becomes 360 degrees, we have reset it to 0 degrees. With
every second we have also incremented the value of sec by 1. As soon as sec
becomes 60 (i.e. after 1 minute) we have done three thingsreset sec to
0, incremented angle m by 6 degrees and incremented the value of min by 1. As
soon as the angle m becomes 360 degrees, we have reset it to 0 degrees.
With every minute we have incremented the value of
angle h by 0.5 degrees. Similarly, after completion of 360 degrees, we have
reset the angle to 0 degrees. After min becomes 60 (i.e. after 1 hour) we have
reset the value of min to 0 and incremented the value of hr.
All these would get drawn on the bitmap because the
graphics context is of the bitmap. Now we need to display the bitmap on the
control. To do so we created another bitmap object bm using the Clone( ) method.
We created bm with the same size as that of the control and having the same
PixelFormat as of mybmp. PixelFormat represents the number of bits associated
with one pixel of data. Next we have displayed the bitmap on the control by
setting the BackGroundImage property of the control to bm. Lastly, we have cleared
mybmp with the BackColor of the control making it ready for painting.
Let us now see the start( ) method that was mentioned
above.
public void start( )
{
now = DateTime.Now ;
sec = now.Second ;
min = now.Minute ;
hr = now.Hour ;
s = sec * 6 ;
m = min * 6 ;
h = ( ( hr % 12f ) * 30f ) + ( min * 0.5f ) ;
mytimer.Start( ) ;
}
The start( ) method is called by the client when he
wants to start the clock. We must start the clock and place the second, minute
and hour hands according to the present time. To do this we have first collected
the current system time in now of type DateTime. We have added now as a data
member of the class. To collect the seconds, minutes and hours values we have
also added 3 integers named sec, min and hr as data members of the Clock class.
According to the current time we have displayed the hands at different angles.
We have used two integer variables s and m to specify the angles for the second
and minute hands respectively and we have used a single variable h to specify
the angle for the hour hand. We have also added s, m and h as data members of
the Clock class.
The % (modulus operator) is used to avoid the AM/PM
conflict. As soon as we start the timer using the Start( ) method, the Tick
event is fired every second. And every second we have painted the control with
the new bitmap and changed the angles.
To stop the timer we have added a method called Halt(
) to the control shown below:
public void Halt( )
{
mytimer.Stop( ) ;
}
Using the custom control
To use the control we have created Windows Form
client called ClockClient. To be able to add the control to our form, we need
to add it first to the Toolbox. For this we need to right-click on the Toolbox
and select Customize Toolbox. On doing so the Customize Toolbox window gets
opened. Here we need to select the .NET Framework Components Tab.
Our
control will not get displayed in the list of existing controls; we need to
browse for its DLL. After selecting the DLL we need to click the OK button.
This will add our control to the Toolbox as shown in the following figure.
To add the control to our form we need to drag it on
the form. After adding it to the form, we have changed its name to myclock
and set its Locked property to True to lock its size.
To start the ticking, we have called the start( ) method of the control in the
constructor of the form as shown below:
public Form1( )
{
InitializeComponent( ) ;
myclock.start( ) ;
}
This starts the timer and the control starts displaying the
time.
 |
Yashavant Kanetkar, one of the earliest Express Computer
columnists, is an established software expert, speaker and author with several
best-sellers to his credit, including titles like “Let Us C” and the “Fundas”
series. Contact him at kanet@nagpur.dot.net.in |
|