|
Continued from last week...
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°. 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° (360 / 60). For every minute, the minute hand should be rotated by 6° (360 / 60) again and for every hour the hour hand should be rotated by 30° (360 / 12). Moreover, the hour hand should also be rotated by 0.5° for every minute. This is because in every 60 minutes the hour hand rotates by 30°, hence in every minute it would rotate by 0.5°. 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 would 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°. 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° 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° and made it more short and thick than the minute hand. We have used the same
EndCap style as of the minute hand for the hour hand.
With every second we have incremented s by 6°. As soon as the angle becomes 360°, we have reset it to 0°. 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 things-reset
sec to 0, incremented angle m by 6° and incremented the value of
min by 1. As soon as the angle m becomes 360°, we have reset it to 0°.
With every minute we have incremented the value of angle h by 0.5°. Similarly, after completion of 360°, we have reset the angle to 0°. 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 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 would be 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.
% (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 would get opened. Here we need to select the .NET Framework Components Tab.
Our control would 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 would 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.
|