Mimic a Cell Phone Using Control Arrays

Level:
Level2

I had a request for this tutorial so I whipped it up real quick. The idea is to simulate how entering words in a cell phone works. For example if a user clicks on the 2 button three times a c shows up. Then if they click on the 3 button once a d shows up etc. It’s a fun little program to write and it teaches you how to use control arrays in Visual Basic 6 and it also teaches you how to use the timer control.

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.

Visual Basic 6 Tutorial Screen 1

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.


Visual Basic 6 Tutorial Screen 2 

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.


Visual Basic 6 Tutorial Screen 3

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.

If you enjoyed this post, subscribe for updates (it's free)

Text

If We Click 1 HOW CAN IT COME TO THE TEXT BOX !!!

How to edit the textbox, just like the cellphone cancel

How can i edit the textbox, using a cancel button place in the cellphone keypad, can anyone help, i am hard finding code to edit the textbox

to cancel

you can try by string mid function.

hWnd capture to output text in another window

I do wonder if it would be possible to expand this program in such a manner that it would enable sending the output to a selected window/component ;) I did, however, run into a bit of problem with the 0 adding a space, since the original Text1.SelLength tends to jump back an additional -1.

Mimic Question

No, you cant use this to plug into a GSM Modem, I actively develop GSM applications based on Windows CE, you have to use a serial port handler (such as MSCOMM) or API (on CE) and issue AT Commands, you can also use this way to open a GPRS connection for 2.5G Data, you can also use AT Commands for standard CSD.

Can I use this to literally

Can I use this to literally Mimic a cellphone using a GSM Modem?