Beginning Visual Basic 2005 (2006)
.pdf
Chapter 14
Next, you set the new button’s ButtonAssignment property to Left. You also invalidate the button (so that you can draw the L on this one instead) and update the LeftButton property to point at the new button:
‘Mark the button objColorPaletteButton.ButtonAssignment = _
ColorPaletteButton.ButtonAssignments.LeftButton
Me.Invalidate(objColorPaletteButton.Rectangle)
LeftButton = objColorPaletteButton
Finally, you fire the LeftClick event as you did before:
‘Raise the event
RaiseEvent LeftClick(Me, New EventArgs())
The remainder of ColorPalette_MouseUp is the same as this but is obviously reversed to deal with the right-hand button.
When it’s time to draw the button, you can check to see whether a button assignment is set. If it is, you draw some text. (You’ve only fleetingly covered drawing text here, but you’ll deal with it in more detail later in this chapter.) To draw the text, you need to create a new System.Drawing.Font object. Here you’re creating a new object for 8-point Verdana in bold:
Public Sub Draw(ByVal graphics As Graphics) ‘Draw the color block
Dim objSolidBrush As New SolidBrush(Color) graphics.FillRectangle(objSolidBrush, Rectangle)
‘Draw an edge around the control
Dim objPen As New Pen(System.Drawing.Color.Black) graphics.DrawRectangle(objPen, Rectangle)
‘Are you selected?
If ButtonAssignment <> ButtonAssignments.None Then
‘Create a font
Dim objFont As New Font(“verdana”, 8, FontStyle.Bold)
Next, you choose the text to draw:
‘Set the default button assignment Dim strButtonText As String = “L”
‘Update the button assignment if necessary
If ButtonAssignment = ButtonAssignments.RightButton Then strButtonText = “R”
End If
456
Programming Custom Graphics
Choosing the brush you want is quite tricky. You can’t just choose a color, because there’s a chance it won’t show up on the color that you’re drawing. Instead, you have to examine the color to see whether it is a light color or a dark color. If it’s dark, you choose to draw the letter in white; otherwise, you draw it in black:
‘What brush do you want?
If Color.R < 100 Or Color.B < 100 Or Color.G < 100 Then objSolidBrush = New SolidBrush(System.Drawing.Color.White)
Else
objSolidBrush = New SolidBrush(System.Drawing.Color.Black) End If
Finally, you actually draw the text:
‘Draw the text ‘L’ or ‘R’ graphics.DrawString(strButtonText, objFont, objSolidBrush, _
Rectangle.Left, Rectangle.Top)
End If End Sub
Using Advanced Colors
So far, the only colors you’ve used are the ones defined by the .NET Framework, such as Color.Black and Color.Blue. The list of colors available to you on the Color structure is considerable, but you can define your own colors if you want to.
To find a list of predefined colors use the MSDN documentation to display “all members” of the “Color structure.” Alternatively, you can use IntelliSense from within the code editor to display a list of possibilities.
Windows defines a color as a 24-bit number, with the three bytes of the 24 bits representing a red value, a green value, and a blue value — this is commonly known as RGB. In effect, each component represents one of a possible 256 shades of red, green, or blue. By combining these shades you can get any color from a possible set of 16.7 million. For example, setting red to 255 and setting blue and green to 0 would result in bright red. Setting all components to 255 would give white. Setting all to 0 would give black, and so on.
If you’re used to mixing paints, these color combinations may seem strange. This is because you are working with colored lights instead of colored paints — they combine in different ways.
To illustrate this, in the next Try It Out section you see how you can choose a color and then manually add that color as a button to the control palette.
Try It Out |
Creating Custom Colors |
1.Open the Form Designer for the ColorPalette control. In the Properties window find the
BackColor property.
2.Drop down the list and change to the Custom tab. Right-click in one of the 16 bottom blank squares.
457
Chapter 14
3.This will bring up the Color dialog box. Use the two controls at the top to find a color you like. In the bottom-right corner, you’ll see three text boxes marked Red, Green, and Blue, as shown in Figure 14-5. Note down the values in these boxes.
Figure 14-5
4.Close the Define Color dialog box.
5.Open up the Code Editor for ColorPalette to access the constructor. In the constructor, define a new button as in the following highlighted code, but replace the three values I’ve used here with three values you noted. (Do this in order — the first value is the red component, the second is green, and the third is blue.)
Public Sub New()
‘This call is required by the Windows Form Designer. InitializeComponent()
‘Add any initialization after the InitializeComponent() call. ‘Add the colors
AddColor(Color.Black)
AddColor(Color.White)
AddColor(Color.Red)
AddColor(Color.Blue)
AddColor(Color.Green)
AddColor(Color.Gray)
AddColor(Color.DarkRed)
AddColor(Color.DarkBlue)
AddColor(Color.DarkGreen)
AddColor(Color.DarkGray)
AddColor(Color.FromArgb(208, 112, 222))
End Sub
458
Programming Custom Graphics
6.Now run the project; the color you selected should appear in the palette.
The FromArgb method is a shared method on the Color class. You can use this to define any color that you like, so long as you follow the “red, green, blue” convention Windows itself uses.
Using the Color Dialog Box
In this Try It Out, you use the Color dialog box that’s built into Windows to let the user add colors to the palette.
Try It Out |
Using the Color Dialog Box |
1.Open the Form Designer for ColorPalette. From the toolbar, select a ColorDialog control and drag it onto the form; the control will be positioned at the bottom of the IDE. Change the name of the control to dlgColor.
2.Now, open the Code Editor for ColorPalette. Find the ColorPalette_MouseUp method. Whenever the user clicks the background of the control (in other words, doesn’t click a button), you want to display the dialog box. Go to the bottom of the method and add an Else clause along with this code. (I’ve omitted most of the existing code for brevity.)
Private Sub ColorPalette_MouseUp(ByVal sender As Object, _
ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseUp
‘Find the button that we clicked
Dim objColorPaletteButton As ColorPaletteButton = GetButtonAt(e.X, e.Y)
If Not objColorPaletteButton Is Nothing Then
. . .
RaiseEvent RightClick(Me, New EventArgs())
End If
End If
Else
‘Display the color dialog
If dlgColor.ShowDialog = DialogResult.OK Then
‘Add the new color AddColor(dlgColor.Color)
‘Resize the palette to show the dialog OnResize(New EventArgs())
End If
End If
End Sub
3.Run the project. Now if you click the background to the palette, you should have the opportunity to add your own colors (see Figure 14-6).
459
Chapter 14
Figure 14-6
Using System Colors
Now you know that you can choose colors from a list of possibilities as well as define your own. The final thing you need to learn about colors is the idea of system colors.
When using Windows, the user has the ability to define all of the colors that are used for things like buttons, menus, captions, and so on. If you’re building the UI for your own controls, it’s reasonable to assume that from time to time you’ll need to know what these colors are so that your controls have the same look and feel as the existing controls in the system.
System colors are exposed through the System.Drawing.SystemColors class. If you want to find a list of all the system colors, look in the MSDN documentation under System.Drawing.SystemColors class. Alternatively, use IntelliSense when in the Code Editor or the Object Browser.
In this Try It Out, you’ll add a button to the control palette that is the same as the menu bar.
Try It Out |
Adding System Colors |
1.Open the Code Editor for ColorPalette.Designer.vb. Find the constructor and add the following highlighted code:
Public Sub New()
‘This call is required by the Windows Form Designer. InitializeComponent()
‘Add any initialization after the InitializeComponent() call. ‘Add the colors
AddColor(Color.Black)
AddColor(Color.White)
AddColor(Color.Red)
AddColor(Color.Blue)
AddColor(Color.Green)
460
Programming Custom Graphics
AddColor(Color.Gray)
AddColor(Color.DarkRed)
AddColor(Color.DarkBlue)
AddColor(Color.DarkGreen)
AddColor(Color.DarkGray)
AddColor(Color.FromArgb(208, 112, 222))
AddColor(Drawing.SystemColors.MenuBar)
End Sub
2.Run the project. You should see a new color that matches the menu bar color.
Using Different Tools
Now that you have successfully cracked the nut of drawing filled circles on the page, turn your attention to building the other tools that you can use to put your applications together. In the next Try It Out, you add a menu that lets you select the tool you want.
If you need a refresher on how to use the Visual Basic 2005 Menu Designer, refer to Chapter 8.
Try It Out |
Adding a Tools Menu |
1.Open the Forms Designer for Form1 and change the Anchor property for Canvas to Bottom, Right, Left.
2.Now click the title bar of the form and then resize the form so that there is enough room for a MenuStrip control at the top.
3.Drag a MenuStrip control onto the top of the form; then, at the bottom of the IDE, right-click MenuStrip1 and choose Insert Standard Items from the context menu to have the standard menus inserted.
4.Resize the form if necessary so that the Canvas control is just under the menu. Then click the Canvas control and change the Anchor property to Top, Bottom, Right, Left.
5.Now click the Tools menu on the MenuStrip and then click in the white Type Here box that appears at the bottom of the Tools menu and enter &Circle. Using the Properties window set the Checked property to True and the CheckOnClick property to True.
6.In the new Type Here box at the bottom, enter &Hollow Circle, and in the Properties window, set the CheckOnClick property to True. You will see the results of these steps in Figure 14-7.
Implementing Hollow Circle
Up until now, you have used a solid circle as the graphics pen to perform the drawing on your form. In this Try It Out, you’ll be implementing the functionality to use the hollow circle graphics pen. You’ll also be adding the necessary code that will allow you to select which pen you want to use from the Tools menu.
461
Chapter 14
Figure 14-7
Try It Out |
Implementing Hollow Circle |
1.The first thing you need to do is change the GraphicTools enumeration defined in the PaintCanvas class to include the hollow circle tool. Open the Code Editor for PaintCanvas and add the following highlighted code to the enumeration:
Public Class PaintCanvas
‘Public enumerations
Public Enum GraphicTools As Integer
CirclePen = 0
HollowCirclePen = 1
End Enum
2.Now switch to the Code Editor for Form1. In the Class Name combo box, select CircleToolStripMenuItem, and then select the Click event in the Method Name combo box. Add the following highlighted code to the Click event handler:
Private Sub CircleToolStripMenuItem_Click(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles CircleToolStripMenuItem.Click
‘Set the tool
Canvas.GraphicTool = PaintCanvas.GraphicTools.CirclePen
‘Uncheck the Hollow Circle menu item HollowCircleToolStripMenuItem.Checked = False
End Sub
3.Now select HollowCircleToolStripMenuItem in the Class Name combo box and the Click event in the Method Name combo box. Add the following highlighted code:
Private Sub HollowCircleToolStripMenuItem_Click(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles HollowCircleToolStripMenuItem.Click
462
Programming Custom Graphics
‘Set the tool
Canvas.GraphicTool = PaintCanvas.GraphicTools.HollowCirclePen
‘Uncheck the Circle menu item CircleToolStripMenuItem.Checked = False
End Sub
4.It only makes sense that, since you’ve implemented a menu, you should add code to the Exit menu item. Select exitToolStripMenuItem in the Class Name combo box and the Click event in the Method Name combo. Then add the following highlighted code to the Click event handler:
Private Sub exitToolStripMenuItem_Click(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles exitToolStripMenuItem.Click
‘Close the application
Me.Close()
End Sub
5.Open the Code Editor for PaintCanvas again and modify the Select Case GraphicTool statement in the DoMousePaint method as follows:
‘What tool are you using? Select Case GraphicTool
‘CirclePen
Case GraphicTools.CirclePen
‘Create a new graphics circle
Dim objGraphicsCircle As New GraphicsCircle()
‘Set the point for drawing objGraphicsCircle.SetPoint(e.X, e.Y, GraphicSize, _
objColor, True)
‘Store this for addition objGraphicsItem = objGraphicsCircle
‘HollowCirclePen
Case GraphicTools.HollowCirclePen
‘Create a new graphics circle
Dim objGraphicsCircle As New GraphicsCircle()
‘Set the point for drawing objGraphicsCircle.SetPoint(e.X, e.Y, GraphicSize, _
objColor, False)
‘Store this for addition objGraphicsItem = objGraphicsCircle
End Select
463
Chapter 14
6.Next, you need to change the GraphicsCircle class itself so that it knows when to draw a filled circle and when to draw a hollow circle. Open the Code Editor for GraphicsCircle and add the following highlighted code to the Draw method:
Public Overrides Sub Draw(ByVal graphics As System.Drawing.Graphics)
If IsFilled = True Then
‘Create a new pen
Dim objSolidBrush As New SolidBrush(Me.Color)
‘Draw the circle graphics.FillEllipse(objSolidBrush, Me.Rectangle)
Else
‘Create a pen
Dim pen As New Pen(Me.Color)
‘Use DrawEllipse instead
Dim objRectangle As Rectangle = Me.Rectangle objRectangle.Inflate(-1, -1) graphics.DrawEllipse(pen, objRectangle)
End If
End Sub
7.Finally, run the program. You should be able to select a new graphic tool from the menu and draw both filled and hollow circles, as shown in Figure 14-8.
Figure 14-8
How It Works
When the menu options are selected, click events get fired. You can respond to these messages and set the GraphicsTool property on the PaintCanvas control to a new mode. When you change the mode,
464
Programming Custom Graphics
you also need to change the check mark on the menu. The currently selected menu item will be automatically checked, but you need to uncheck the menu item that isn’t selected. You do this by setting the Checked property of the opposite menu item to False.
Private Sub HollowCircleToolStripMenuItem_Click(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles HollowCircleToolStripMenuItem.Click
‘Set the tool
Canvas.GraphicTool = PaintCanvas.GraphicTools.HollowCirclePen
‘Uncheck the Circle menu item CircleToolStripMenuItem.Checked = False
End Sub
Irrespective of the mode used, PaintCanvas.DoMousePaint still gets called whenever the mouse draws on the control. However, you do need to accommodate the new tool by changing the Select Case GraphicTool statement to look for HollowCirclePen as well as CirclePen. Depending on which is selected, you pass True (“filled”) or False (“not filled”) through to SetPoint:
‘What tool are you using? Select Case GraphicTool
‘CirclePen
Case GraphicTools.CirclePen
‘Create a new graphics circle
Dim objGraphicsCircle As New GraphicsCircle()
‘Set the point for drawing objGraphicsCircle.SetPoint(e.X, e.Y, GraphicSize, _
objColor, True)
‘Store this for addition objGraphicsItem = objGraphicsCircle
‘HollowCirclePen
Case GraphicTools.HollowCirclePen
‘Create a new graphics circle
Dim objGraphicsCircle As New GraphicsCircle()
‘Set the point for drawing objGraphicsCircle.SetPoint(e.X, e.Y, GraphicSize, _
objColor, False)
‘Store this for addition objGraphicsItem = objGraphicsCircle
End Select
In GraphicsCircle itself, choosing whether to use the FillEllipse method to draw a filled circle or use the DrawEllipse method for a hollow one is a simple determination. The only wrinkle you have to contend with is DrawEllipse; the width and height of the bounding rectangle have to be one pixel
465
