0

I am working on creating a keypad for a VB.Net Application I am working on. The Keypad's purpose is to help users who are using the app on a touchpad station that does not have a mouse or keyboard.

This is the code I have used to set up the Keypad:

Public Class Keypad

    Private Sub Keypad_Load(sender As Object, e As Event Args) Handles MyBase.Load
        Me.TopMost = True
    End Sub

    Protected Overrides ReadOnly Property CreateParams As CreateParams
        Get
            Const WS_EX_NOACTIVATE As Int32 = &H8000000
            Dim cp As CreateParams = MyBase.CreateParams
            cp.ExStyle = cp.ExStyle Or WS_EX_NOACTIVATE
            Return cp
        End Get
    End Property

    Private Sub btn0_Click(sender As Object, e As EventArgs) Handles btn0.Click
        SendKeys.Send("0")
    End Sub

    Private Sub btn1_Click(sender As Object, e As EventArgs) Handles btn1.Click
        SendKeys.Send("0")
    End Sub

    'all other button methods are the same as above

So the Keypad itself is a simply setup. Standard Numpad 1-9 layout, as well as a 'Clear' and 'Enter' button.

I am currently having the following problems with the Keypad:

  1. While in the VB.Net I have created the Keypad for, attempting to use the Keypad does nothing. However if I open Notepad and have given focus to Notepad, using the Keypad will type numbers into Notepad.

  2. The Login Screen for the Application is setup as a Dialogue Window, and I am unable to modify that (legacy code issues). This means the Keypad is both unmovable, and unusable while the Login Screen is open.

  3. The 'Clear' Button is suppose to remove all data in whatever form element has focus when the button is selected. However, I am not exactly sure how to program this, and how to make it so that it doesn't completely bug out the Keypad if the user has a non VB.Net application focused when the key is pressed.

EDIT: After doing some testing, it turns out the Keypad works fine if I set it up as a completely separate Project. So it turns out the issue seems to be the Keypad Form being part of the initial project I was creating it for.

Skitzafreak
  • 1,797
  • 7
  • 32
  • 51
  • @MartinParkin Because I have been asked by management to create a Keypad to use with the app instead :P – Skitzafreak Jan 30 '19 at 16:59
  • For your first problem, are you sure the focus is set to something that can receive input? I mean a Textbox or something like that . – preciousbetine Jan 30 '19 at 17:59
  • @preciousbetine Yes I am selecting a Textbox and then pressing the Button. Could the problem be that the Button has changed to the item that has focus by the time it hits the `SendKey` method? How would I stop that from happening? – Skitzafreak Jan 30 '19 at 18:01
  • In the first line of the buttons click event, try giving the Focus back to the textbox with `Textbox.Focus` – preciousbetine Jan 30 '19 at 18:12
  • @preciousbetine Okay, that fixes my issue. Kind of. The problem now however is that I will be opening and closing multiple forms that can use the Keypad. So just putting `TextBox.Focus` doesn't exactly help figure out which specific element needs the focus. Is there a `SelectLastFocus` method or something I can use? I can't seem to find one. – Skitzafreak Jan 30 '19 at 18:15

1 Answers1

1

This is a solution that doesn't use SendKeys. No worries about Focus. Instead I send the TextBox that is to receive the input to a field in the KeyPad. Now the KeyPad form knows where to send the input. I have assigned one handler to all the keyPad buttons. The cast sender back to Button and use the .Text property of the button.

Public Class KeyPad
    Public TextOutputControl As TextBox
    Private Sub KeyPad_Click(sender As Object, e As EventArgs) Handles Button1.Click, Button2.Click, Button3.Click
        Dim ClickedAmount As String = DirectCast(sender, Button).Text
        TextOutputControl.Text &= ClickedAmount
    End Sub
End Class

The on each form that wants to use the keypad...

Private Sub btnShowKeyPad_Click(sender As Object, e As EventArgs) Handles btnShowKeyPad.Click
    KeyPad.Show()
    KeyPad.TextOutputControl = TextBox1
End Sub

Of course the TextBox can have any name you wish.

EDIT

To use with a DataGridView cell change the data type of TextOutputControl to Object. You will need to check what type of object was passed in and send the data back accordingly.

Public Class KeyPad
    Public TextOutputControl As Object
    Private Sub KeyPad_Click(sender As Object, e As EventArgs) Handles Button1.Click, Button2.Click, Button3.Click
        Dim ClickedAmount As String = DirectCast(sender, Button).Text
        Dim t As Type = TextOutputControl.GetType
        Dim tTexBox As Type = GetType(TextBox)
        If t.Equals(GetType(TextBox)) Then
            DirectCast(TextOutputControl, TextBox).Text &= ClickedAmount
        Else
            Dim s = CStr(DirectCast(TextOutputControl, DataGridViewCell).Value)
            s &= ClickedAmount
            DirectCast(TextOutputControl, DataGridViewCell).Value = s
        End If
    End Sub
End Class

Then in the form with the DataGridView...

Private Sub btnShowKeyPad_Click(sender As Object, e As EventArgs) Handles btnShowKeyPad.Click
    KeyPad.Show()
    'KeyPad.TextOutputControl = TextBox1
    KeyPad.TextOutputControl = DataGridView1.CurrentCell
End Sub
Mary
  • 14,926
  • 3
  • 18
  • 27
  • What would I do if there were Cells of a DataGridView that I wanted to use with the Keypad? Not just Textboxes. – Skitzafreak Jan 30 '19 at 19:29
  • 1
    Hadn't though about that. I will edit answer to show a few thoughts. – Mary Jan 30 '19 at 19:34
  • I don't think I understand your solution. – preciousbetine Feb 01 '19 at 12:59
  • @preciousbetine I will try to explain. What part is not clear? – Mary Feb 01 '19 at 23:55
  • I understand it now, but there's no need for the type casting. Simply use an object and it's text property. Although you won't see `sender.Text` as an option but it works.With that you can even use a wider range of controls. – preciousbetine Feb 02 '19 at 06:02
  • @preciousbetine Object does not have a .Text property or a .Value property. I do the Cast to access the properties of the underlying type. – Mary Feb 02 '19 at 06:07
  • @preciousbetine Well, I just did and it will not compile with Option Strict on. Don't you keep Option Strict on? – Mary Feb 02 '19 at 06:20
  • And there would still be a focus problem because once the keypad is shown, the `TextOutputControl` is set to something. And changing the focus to another control does not automatically change `TextOutputControl` to that control. – preciousbetine Feb 02 '19 at 06:24
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/187775/discussion-between-mary-and-preciousbetine). – Mary Feb 02 '19 at 06:25