NOTE: I recommend downloading the source code along with this to clarify any confusion. I tried to add comments to help people understand it more.
First lets set up our form. For the buttons I am going to use a control array. Here’s how you create a control array. Start a new project. On form1 draw a CommandButton – VB will automatically call it Command1. Rename this control simply Buttons. Also set its index property to 0. Lastly set its caption simply to 0.
Now copy this button and paste it. This will create a second Buttons commandButton with an index of 1. Just like an array all of your Buttons controls will have an index value. We will use this later. Now copy and past this button 12 times, set each buttons caption to the same value as its index and then line them up like how a phone looks. It is important to note that you want the indexes to correspond with the correct button as later we will use this value to figure out which button was pressed. So if the index value is 2 make sure the text value for that button is also 2. Also add a text box at the top of the form where we will display the characters pressed. Just leave this textbox named Text1. See the picture for placement.
Now the code! Lets start by adding text below each number telling what characters correspond to that number. We will do that as soon as the program starts in the form load event. So double click somewhere on Form1. Then add this code:
Private Sub Form_Load()
Buttons(2).Caption = "2" + vbCrLf + "ABC"
Buttons(3).Caption = "3" + vbCrLf + "DEF"
Buttons(4).Caption = "4" + vbCrLf + "GHI"
Buttons(5).Caption = "5" + vbCrLf + "JKL"
Buttons(6).Caption = "6" + vbCrLf + "MNO"
Buttons(7).Caption = "7" + vbCrLf + "PQRS"
Buttons(8).Caption = "8" + vbCrLf + "TUV"
Buttons(9).Caption = "9" + vbCrLf + "WXYZ"
End Sub
If you notice I access each button like I would any array with an open parenthesis the index value followed by a close parenthesis. Run the program and you should see the following now.
The way a control array works is that there is only one event fired for every control in the array. So if you go back into design mode and double click on one of the buttons this code will be created for you:
Private Sub Buttons_Click(Index As Integer)
End Sub
If you notice the Integer Index is passed to the subroutine. This value tells us which button was pressed. We will be relying on this.
Now before we go any farther I want to think through some of the logic involved in handling user input. We need keep track of how many times a user has pressed a particular button. Each time they press a button we need to display the first character corresponding to that button. Further more if they press the same button more than once we need to change the current character being displayed to the next character on that button. This means we will need two global variables one to keep track of what button has been pressed and another to keep track of how many times it has been pressed. Further we need to keep track of if we have displayed the character for this button yet or not. If we have displayed the character then we need to remove it and display the next character if the same button is pressed again.
An example: If we press 2 we want to display the string ‘A’ then if we press 3 we want to add that character so we will display the string ‘AD’ but if we now press 3 again we don’t want to display ‘ADD’ we want to display ‘AE’. This is why we need 3 global variables so add this code at the top of the file:
Option Explicit
Dim NumTimesClicked As Integer
Dim LastButtonClicked As Integer
Dim HasBeenDisplayed As Boolean
These values will need to be set to initial values and reset throughout the code so I am going to create a simple helper subroutine called ResetAll().
Private Sub ResetAll()
NumTimesClicked = 0
LastButtonClicked = -1
HasBeenDisplayed = False
End Sub
Then lets have the form_load event call this to set our initial values.
Private Sub Form_Load()
Buttons(2).Caption = "2" + vbCrLf + "ABC"
Buttons(3).Caption = "3" + vbCrLf + "DEF"
Buttons(4).Caption = "4" + vbCrLf + "GHI"
Buttons(5).Caption = "5" + vbCrLf + "JKL"
Buttons(6).Caption = "6" + vbCrLf + "MNO"
Buttons(7).Caption = "7" + vbCrLf + "PQRS"
Buttons(8).Caption = "8" + vbCrLf + "TUV"
Buttons(9).Caption = "9" + vbCrLf + "WXYZ"
ResetAll
End Sub
Now going back to our event handler for our button controls lets add this code:
Private Sub Buttons_Click(Index As Integer)
' If a button without characters is clicked then exit out
If Index < 2 Or Index > 9 Then
ResetAll
Exit Sub
End If
If LastButtonClicked = Index Then
' We have been clicked before so keep track of it
If Index = 7 Or Index = 9 Then
' 7 & 9 have 4 characters so MOD 4
NumTimesClicked = (NumTimesClicked Mod 4) + 1
Else
' The rest of 3 characters so MOD 3
NumTimesClicked = (NumTimesClicked Mod 3) + 1
End If
Else
' We haven't clicked this button before so reset everything
LastButtonClicked = Index
NumTimesClicked = 1
HasBeenDisplayed = False
End If
DisplayCurrentCharacter
End Sub
So Lines 1 through 6 we simply check to see if keys were pressed that have characters if a different key was pressed then we reset our variables and we jump out of the sub. Now line 8 checks to see if last time we clicked we clicked this same button. If that’s the case then we need to increment our number of times the buttons been clicked. Now the mod function sometimes confuses people. All it does is returns the remainder of dividing by the specified value. For example lets say 2 is pressed, then NumTimesClicked = 1. Now we press 2 again: NumTimesClicked = 2. Press 2 again: NumTimesClicked = 3. Now Press 2 again NumTimesClicked = (Remainder of 4/3) = 1. So Mod allows us to loop around back to the beginning. The only other tricky thing in lines 11 through 17 is that if 7 or 9 is pressed we have 4 characters instead of 3 so we Mod by 4. Now lines 19-22 run if this is the first click on a particular button. All we do then is store what button was clicked in the LastButtonClicked variable. We also store that it has only been clicked once in the NumTimesClicked variable. And lastly we specify that we havn’t displayed this character yet in the HasBeenDisplayed variable. The last thing we do is in line 25 we call a subroutine called DisplayCurrentCharacter. We will write that next.
The sub DisplayCurrentCharacter is our largest chunk of code. What this routine does is read the value of our three global variables and display the correct character corresponding to which key was last pressed. Here is all the code:
Private Sub DisplayCurrentCharacter()
Dim curChar As String
Select Case LastButtonClicked
Case 2
Select Case NumTimesClicked
Case 1
curChar = "a"
Case 2
curChar = "b"
Case 3
curChar = "c"
End Select
Case 3
Select Case NumTimesClicked
Case 1
curChar = "d"
Case 2
curChar = "e"
Case 3
curChar = "f"
End Select
Case 4
Select Case NumTimesClicked
Case 1
curChar = "g"
Case 2
curChar = "h"
Case 3
curChar = "i"
End Select
Case 5
Select Case NumTimesClicked
Case 1
curChar = "j"
Case 2
curChar = "k"
Case 3
curChar = "l"
End Select
Case 6
Select Case NumTimesClicked
Case 1
curChar = "m"
Case 2
curChar = "n"
Case 3
curChar = "o"
End Select
Case 7
Select Case NumTimesClicked
Case 1
curChar = "p"
Case 2
curChar = "q"
Case 3
curChar = "r"
Case 4
curChar = "s"
End Select
Case 8
Select Case NumTimesClicked
Case 1
curChar = "t"
Case 2
curChar = "u"
Case 3
curChar = "v"
End Select
Case 9
Select Case NumTimesClicked
Case 1
curChar = "w"
Case 2
curChar = "x"
Case 3
curChar = "y"
Case 4
curChar = "z"
End Select
End Select
If HasBeenDisplayed = True Then
' We have already displayed once so remove it and change it
Text1.Text = Left(Text1.Text, Len(Text1.Text) - 1)
End If
' Now add the current char to the display
Text1.Text = Text1.Text + curChar
Text1.SetFocus
Text1.SelStart = Len(Text1.Text) - 1
Text1.SelLength = 1
' Set the flag so we know we have displayed this character
HasBeenDisplayed = True
End Sub
So hopefully the Select Cases make sense. All we are trying to do is store in a local variable called curChar the current character that should be displayed based off of what key they pressed and how many times they have pressed it.
Now look at lines 85-88 what we are doing here is checking if the character for this key press has already been displayed. If it has we remove that character from the end so we can put the new one one.
Then line 90 we put the new character on. And lines 91 & 92 we select the new character and set focus so that the user can see what character was just added.
Try this program out. You will notice everything works well except for one feature. What if you want to spell the word Matt? Everything works good up until Mat but than we can’t get another t because everytime we press 8 it just loops through again and again. One work around is to press a button that has no characters such as 0 or #, but this seems lame. Cell phones have a timeout future if you don’t press a key for a couple of seconds it assumes you are done and puts the cursor at the end of the word. Lets implement that. To do so simply draw a Timer control on your form. Leave its name set to Timer1 and set its Interval property to 2000. This means the control will execute approximately every 2 seconds. Double click on the control and add this code:
Private Sub Timer1_Timer()
' This gets called if nothing has been pressed for 2 seconds
Text1.SelLength = 0
Text1.SelStart = Len(Text1.Text)
ResetAll
End Sub
Also add the following code to the current routine (bold lines are the new code)
Private Sub ResetAll()
NumTimesClicked = 0
LastButtonClicked = -1
HasBeenDisplayed = False
Timer1.Enabled = False
End Sub
Private Sub DisplayCurrentCharacter()
Dim curChar As String
Timer1.Enabled = False
Select Case LastButtonClicked
Case 2
Select Case NumTimesClicked
Case 1
curChar = "a"
Case 2
curChar = "b"
Case 3
curChar = "c"
End Select
Case 3
Select Case NumTimesClicked
Case 1
curChar = "d"
Case 2
curChar = "e"
Case 3
curChar = "f"
End Select
Case 4
Select Case NumTimesClicked
Case 1
curChar = "g"
Case 2
curChar = "h"
Case 3
curChar = "i"
End Select
Case 5
Select Case NumTimesClicked
Case 1
curChar = "j"
Case 2
curChar = "k"
Case 3
curChar = "l"
End Select
Case 6
Select Case NumTimesClicked
Case 1
curChar = "m"
Case 2
curChar = "n"
Case 3
curChar = "o"
End Select
Case 7
Select Case NumTimesClicked
Case 1
curChar = "p"
Case 2
curChar = "q"
Case 3
curChar = "r"
Case 4
curChar = "s"
End Select
Case 8
Select Case NumTimesClicked
Case 1
curChar = "t"
Case 2
curChar = "u"
Case 3
curChar = "v"
End Select
Case 9
Select Case NumTimesClicked
Case 1
curChar = "w"
Case 2
curChar = "x"
Case 3
curChar = "y"
Case 4
curChar = "z"
End Select
End Select
If HasBeenDisplayed = True Then
' We have already displayed once so remove it and change it
Text1.Text = Left(Text1.Text, Len(Text1.Text) - 1)
End If
' Now add the current char to the display
Text1.Text = Text1.Text + curChar
Text1.SetFocus
Text1.SelStart = Len(Text1.Text) - 1
Text1.SelLength = 1
' Set the flag so we know we have displayed this character
HasBeenDisplayed = True
' Start the timer incase they don't click anyting for 2 seconds
Timer1.Enabled = True
End Sub
Now run the program again. You will notice that if you click a button and wait for about 2 seconds it moves the cursor to the end and works correctly.
Well that’s pretty much it. If you want to take this a step further I suggest adding some of the other fun features of a cell phone. Such as having the 0 add a space. Having the # toggle between uppercase and lowercase, having the * display special characters like .,!@, ect… Have fun with this visual basic tutorial. If you have any questions or additions feel free to leave a comment.
Source http://www.vb6.us/tutorials
Reviews:
Post a Comment