I still haven't found a good way to get information about the current form image so this example does all its drawing into a Bitmap and then copies the Bitmap onto the form. It can easily get information about the Bitmap's pixels.
In the form's Paint event handler, the program checks whether the Bitmap is Nothing. If it is Nothing, the routine creates it, gets a Graphics object representing the Bitmap, and uses the Graphics object to draw pie slices on it.
After the Bitmap object exists, the Paint event handler uses the form's Graphics object's DrawImage method to display the Bitmap.
The form's Resize event handler invalidates the form so the subsequent Paint event redraws the entire form not just the area newly exposed. (Try commenting out this statement and then resize the form a few times). The Resize event handler also sets the Bitmap to Nothing so the next Paint event will make a new Bitmap. That lets the program resize the Bitmap to fit the new form size.
The MouseDown event handler gets the Bitmap's pixel color. It then loops through the colors used to draw the pie slices until it finds the one matching the pixel the user clicked. This code compares the colors' ToArgb values. It would make more sense to use the Equals method but that method doesn't consider named and unnamed colors to be equal. For example, it doesn't consider the color Color.Red to be the same as a color built by setting the red, green, and blue components to 255, 0, 0 even though those colors have the same component values.
|
Private m_Bitmap As Bitmap
Private m_Angles() As Single = {0, 10, 45, 75, 100, 130, _
170, 200, 225, 250, 270, 300, 315, 345, 360}
Private m_Colors() As Color = {Color.Blue, Color.Green, _
Color.Cyan, Color.Red, Color.Magenta, Color.Yellow, _
Color.White, Color.Gray, Color.LightBlue, _
Color.LightGreen, Color.LightCyan, Color.Pink, _
Color.Maroon, Color.LightYellow, Color.SkyBlue}
' Draw pie slices. Note that the DrawPie
' and FillPie methods draw using degrees
' clockwise from horizontal.
Private Sub Form1_Paint(ByVal sender As Object, ByVal e As _
System.Windows.Forms.PaintEventArgs) Handles _
MyBase.Paint
Dim gr As Graphics = e.Graphics
' See if we have a bitmap saved.
If m_Bitmap Is Nothing Then
' Make the new bitmap.
m_Bitmap = New Bitmap( _
Me.ClientSize.Width, _
Me.ClientSize.Height, _
gr)
' Draw on the bitmap.
Dim i As Integer
Dim bitmap_gr As Graphics = _
Graphics.FromImage(m_Bitmap)
For i = m_Angles.GetLowerBound(0) To _
m_Angles.GetUpperBound(0) - 1
bitmap_gr.FillPie( _
New SolidBrush(m_Colors(i)), _
5, 5, _
Me.ClientSize.Width - 10, _
Me.ClientSize.Height - 10, _
m_Angles(i), m_Angles(i + 1) - m_Angles(i))
bitmap_gr.DrawPie(Pens.Black, 5, 5, _
Me.ClientSize.Width - 10, _
Me.ClientSize.Height - 10, _
m_Angles(i), m_Angles(i + 1) - m_Angles(i))
Next i
End If
' Draw the bitmap.
gr.DrawImage(m_Bitmap, 0, 0)
End Sub
' Force a redraw of everything.
Private Sub Form1_Resize(ByVal sender As Object, ByVal e As _
System.EventArgs) Handles MyBase.Resize
Invalidate()
m_Bitmap = Nothing
End Sub
Private Sub Form1_MouseDown(ByVal sender As Object, ByVal e _
As System.Windows.Forms.MouseEventArgs) Handles _
MyBase.MouseDown
Dim i As Integer
Dim clicked_color As Color = m_Bitmap.GetPixel(e.X, e.Y)
' Find the slice clicked.
For i = m_Angles.GetLowerBound(0) To _
m_Angles.GetUpperBound(0) - 1
If m_Colors(i).ToArgb = clicked_color.ToArgb Then
MsgBox("Slice " & i.ToString)
Exit For
End If
Next i
End Sub
|