Click here to Skip to main content
Click here to Skip to main content

VB.NET Knob Control

, 13 Dec 2004
Rate this:
Please Sign up or sign in to vote.
A usable knob control.

Introduction

Hello this is my first article. I always wanted to make a knob control and finally I did it, so here I am going to share what I did.

This is my tutorial for making a custom knob control. I made the knob image in a 3D modeling program, then edited it in PhotoShop, removed everything but the knob itself and saved it as a .png image. I even went a little farther and made another image of a pillow bevel which sits under the knob image to make the knob look sunk in.

Now I had my graphics done. Now for the coding part, since I wanted transparency and I made a user control, I had to insert these lines:

SetStyle(ControlStyles.SupportsTransparentBackColor, True)
Me.BackColor = Color.Transparent

If you do not know where to find the constructor then look under View - Object Browser. In the browser you will see the name of your project, double click it. Then it will expand and show you the same name again - double click it. Now it should expand and say usercontrol1, double click it. You will see a Sub called new, and under the InitializeComponent() is where you place those lines, since a user control by default cannot have transparency. Now we have the transparency issue taken care of.

Now for the images that we have got, in the Solution Explorer right click the name of your project and add existing items. Add the images for the knob. Then in the Solution Explorer right click one of the images and go to its properties. Change build action to embedded resource. Do the same for the other images. I like making my images embedded, so they are built into the .dll of the control.

Here is the function to read embedded resources. Make sure to import System.IO and System.Reflection:

Protected Function GetEmbeddedResourceStream(ByVal ResourceName _
                As String) As Stream
    Return System.Reflection.Assembly.GetExecutingAssembly()._
                         GetManifestResourceStream(ResourceName)
End Function

Here is where the drawing takes place, it scales too:

Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
    e.Graphics.ScaleTransform(scales, scales)
    knobbase = New Bitmap(GetEmbeddedResourceStream("knob.knobbase.png"))
    knob = New Bitmap(GetEmbeddedResourceStream("knob.knobtop.png"))
    Me.Height = knobbase.Height * scales
    Me.Width = knobbase.Width * scales
    e.Graphics.DrawImage(knobbase, 0, 0)
    e.Graphics.ResetTransform()
    e.Graphics.ScaleTransform(scales, scales)
    e.Graphics.TranslateTransform(knob.width/2, knob.width/2)
    e.Graphics.RotateTransform(angle)
    e.Graphics.DrawImage(knob, -knob.Width \ 2, -knob.Height \ 2)
End Sub

Now we need some way of rotating the knob, when the user clicks and holds the mouse button over the knob.

Private Sub UserControl11_MouseDown(ByVal sender As Object, _
                            ByVal e As System.Windows.Forms.MouseEventArgs) _
                                                         Handles Me.MouseDown
    Dim centerofknobx As Integer = Me.Width / 2
    Dim centerofknoby As Integer = Me.Height / 2
    If knob1ismoving = False Then
    knobstartangle = Me.cur_ang
    mouseangle = Int(Math.Atan2((e.Y - centerofknoby), _
                        (e.X - centerofknobx)) * (180 / Math.PI)) + 180
    knob1ismoving = True
    End If
    If melocked = True Then knob1ismoving = False
End Sub

What was done here is that the MouseDown procedure will calculate the angle of the mouse to the center of the knob, and make the variable knob1ismoving = True unless the knob is locked.

Now while the mouse button is down and the mouse moves, we need a subroutine to track the angle's difference and apply it to the knob.

Private Sub UserControl11_MouseMove(ByVal sender As Object, _
                            ByVal e As System.Windows.Forms.MouseEventArgs) _
                                                         Handles Me.MouseMove
    If knob1ismoving = True Then
        Dim centerofknobx As Integer = Me.Width / 2
        Dim centerofknoby As Integer = Me.Height / 2
        Dim curmouseangle As Integer = Int(Math.Atan2((e.Y - centerofknoby), 
                              (e.X - centerofknobx)) * (180 / Math.PI)) + 180
        Dim difference As Integer = curmouseangle - mouseangle
        Dim knobangle As Integer = knobstartangle + difference
        angle = knobangle + (revolutions * 360)
        If locked = True Then
            If angle > maxangle Then angle = maxangle
            If angle < minangle Then angle = minangle
        End If
        If oldmouseangle > 300 And curmouseangle < 60 Then
            revolutions = revolutions + 1
            oldmouseangle = curmouseangle
        End If
        If oldmouseangle < 60 And curmouseangle > 300 Then
            revolutions = revolutions - 1
            oldmouseangle = curmouseangle
        End If
        oldmouseangle = curmouseangle
    End If
End Sub

This sub is mostly math. I made this function to know if the knob was turned more than once in either direction, because I need the knob to track multiple turns. It figures out the angle difference from the original angle then adds (revolutions + 360) to it for the final angle.

Finally, we need a subroutine to stop the knob from moving when the mouse button is released.

Private Sub UserControl11_MouseUp(ByVal sender As Object, _
                          ByVal e As System.Windows.Forms.MouseEventArgs) _
                                                         Handles Me.MouseUp
    knob1ismoving = False
End Sub

Conclusion

A knob control consists of your knob image. You track mouse movements and figure out the angle difference as the mouse moves and apply it to your knob.

I made limits on my knob....Say I wanted to control the minutes on a clock. I could limit it to 590 degrees max, then divide the current angle by 10 to get the minute. This knob makes a great slider replacement. I'm sure more features could be added such as a 'snap' feature so that it moves a certain amount of degrees at a time.

Hope you enjoyed my article. The source will run on VB.NET 2005. It shouldn't be hard to port it to 2003.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Share

About the Author

NEEDBASS
Web Developer ASR Graphics
United States United States
Your typical bored programmer.

Comments and Discussions

 
QuestionNice Pinmemberslaviboy26-Sep-12 11:43 
QuestionHow do I use this control Pinmemberjimvb21124-Apr-11 9:00 
GeneralGreat Job... Pinmemberyeahtuna7-Dec-09 14:11 
QuestionHow to use the dll Pinmemberkenobe14-Jul-09 23:05 
QuestionBackColor Transparent Not Working? Pinmemberpositivebalance2-Apr-08 19:04 
GeneralRe: BackColor Transparent Not Working? Pinmembermatjazso16-Jun-09 1:34 
GeneralThank you PinmemberGoldFishRock17-Aug-05 3:50 
GeneralRe: Thank you Pinmemberultra029-Apr-06 16:39 
GeneralRe: Thank you PinmemberGoldFishRock1-May-06 22:17 
GeneralRe: Thank you PinmemberNEEDBASS26-Dec-06 12:44 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.141216.1 | Last Updated 13 Dec 2004
Article Copyright 2004 by NEEDBASS
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid