ProblemYou want to alter the appearance of a control by drawing on it in reaction to mouse or other events. SolutionSample code folder: Chapter 09\SpecialEffects Add code to the control's Paint event handler, and if required, call the control's Refresh() method to trigger the Paint event. DiscussionAny visible control has a Paint event that lets you patch in code to modify the control's appearance in any way you want. The following code demonstrates this technique by completely changing the appearance and behavior of a standard Button control. For the sample, we created a new Windows Forms application, then added a Panel control named Panel1 and two Button controls, Button1 and Button2. Button1 is left untouched for comparison, but Button2 changes as the mouse is used with it. The button's background color is altered as the mouse moves over its face, and again when the mouse is clicked. The ButtonBackColor variable holds the indicated color as set within the various mouse-event procedures, and it is used in the button's Paint event to render its background color: Public Class Form1 Private ButtonBackColor As Color = Color.LightGreen These four events change the background color in response to the mouse cursor entering or leaving the face of the button and to the mouse button being depressed and released when the cursor is over the button: Private Sub Button2_MouseEnter(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles Button2.MouseEnter ' ----- Change the button to show the effect of the mouse. ButtonBackColor = Color.FromArgb(32, 192, 32) End Sub Private Sub Button2_MouseLeave(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles Button2.MouseLeave ' ----- Return the button to normal mode. ButtonBackColor = Color.LightGreen End Sub Private Sub Button2_MouseDown(ByVal sender As Object, _ ByVal e As System.Windows.Forms.MouseEventArgs) _ Handles Button2.MouseDown ' ----- The mouse is clicking the button. Show an effect. ButtonBackColor = Color.LightPink End Sub Private Sub Button2_MouseUp(ByVal sender As Object, _ ByVal e As System.Windows.Forms.MouseEventArgs) _ Handles Button2.MouseUp ' ----- The mouse was released. Go back to normal. ButtonBackColor = Color.LightGreen Button2.Refresh() End Sub The Refresh() method in the MouseUp event handler tells the control to redraw itself, triggering a Paint event. You would expect the other three event handlers to each need a Refresh() call as well, but the Button control issues those calls on our behalf during these events. The following method repaints Button2's surface whenever Windows fires the Paint event: Private Sub Button2_Paint(ByVal sender As Object, _ ByVal e As System.Windows.Forms.PaintEventArgs) _ Handles Button2.Paint ' ----- Draw a fancy button surface. Dim counter As Integer Const numberOfLobes As Integer = 5 ' ----- Get the graphics object for the button. Dim canvas As Graphics = e.Graphics ' ----- Set a new background color. canvas. Clear(ButtonBackColor) The button's Graphics object provides the surface for all graphics commands. The Clear() method optionally renders the background in a given color. In this case, the variable ButtonBackColor tells the button what colors to set the background to in response to the various mouse events: ' ----- Draw the atomic orbits in blue, two pixels wide. Dim atomPen As Pen = New Pen(Color.Blue, 2) ' ----- Specify the location and size of the electron orbits. Dim sizeFactor As Integer = Button2.ClientSize.Width \ 2 Dim lobeLength As Integer = sizeFactor * 8 \ 10 Dim lobeWidth As Integer = lobeLength \ 4 ' ----- Shift center of orbits to center of button. canvas.TranslateTransform(sizeFactor, sizeFactor) The following lines of code repeatedly draw an ellipse in blue, rotated around its center to create an "atom" effect: ' ----- Draw orbits rotated around center. For counter = 1 To numberOfLobes canvas.RotateTransform(360 / numberOfLobes) canvas.DrawEllipse(atomPen, -lobeLength, -lobeWidth, _ lobeLength * 2, lobeWidth * 2) Next counter End Sub We chose this graphic partly because it was just plain fun to create, but also to show how easy it is to draw some things in Visual Basic 2005 that are cumbersome to draw in VB 6. The following Paint event handler paints the panel with a background color and some text, as shown in Figure 9-2. This same effect can be accomplished with a standard Label, but this provides another example of how the face of just about any control can be graphically rendered as desired: Figure 9-2. Buttons and other controls can be graphically redefined for unique or special effectsPrivate Sub Panel1_Paint(ByVal sender As Object, _ ByVal e As System.Windows.Forms.PaintEventArgs) _ Handles Panel1.Paint ' ----- Draw a nice title. Dim canvas As Graphics = e.Graphics canvas.Clear(Color.Azure) canvas.DrawString( _ " Drawing on Controls for Special Effects", _ New Font("Arial", 14), Brushes.DarkBlue, 5, 5) End Sub The next two methods, one for Button1 and the other for Button2, are nearly identical. They demonstrate that even though Button2 now appears much different from the more standard Button1 (see Figure 9-2), both buttons behave the same and can be used in a program in the same way: Private Sub Button1_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles Button1.Click MsgBox("Button1 clicked!", MsgBoxStyle.Exclamation, _ "Painting on Controls") End Sub Private Sub Button2_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles Button2.Click MsgBox("Button2 clicked!", MsgBoxStyle.Exclamation, _ "Painting on Controls") End Sub End Class |