Problem in capturing and change KeyCode for input to TextBox

Alan Chan

Registered User.
Local time
Today, 15:21
Joined
Aug 28, 2013
Messages
14
Dear experts,

To facilitate input of special graphic characters such as the degree C and plus-and-minus symbols, I would like to use Alt-1 to Alt-9 key combinations, capture these keys in a KeyDown event procedure and change the keystroke to the desired graphical character code. I am using Access 2010 on Win7.

I first attempted to change the Shift integer to zero to reset the Alt-bit and set KeyCode to the desired character code, but this does not work.

Hence I try to use the second common method of setting KeyCode to zero and use SendKeys to VBA-input the desired graphic character. However, strange things happens.

The test code is as follows:

Code:
Private Sub TestTB_KeyDown(KeyCode As Integer, Shift As Integer)

Dim i As Long 

If (Shift And acAltMask) <> 0 And KeyCode <> 18 Then

' For i = 1 To 20000000 this For-loop is initially commented out 
' Next i 

MsgBox "Key changed" 
KeyCode = 0
SendKeys ("#") 
End If
End Sub

The above code as it is works OK and the '#' is successfully inputted to the TextBox field.

However, if I comment out the MsgBox statement, the program waits for about 0.3 second and then instantly fills up the entire TextBox field by a large number of '#' characters.

If I move the MsgBox statement to after the SendKeys, no '#' character is inputted to the TextBox.

If I comment out the MsgBox statement and activate the For loop at the looping count amount (but not much less), the program works fine.

It appears that there is some sort of internal timing problem inside Access.

Any suggestion for resolution is much appreciated.

Thanks.

Alan Chan
 
I've used this before:

Code:
Private Sub TargetControl_KeyDown(KeyCode As Integer, Shift As Integer)
 
 If Shift = acAltMask And KeyCode = vbKey1 Then
  Me.TargetControl = Me.TargetControl & Chr(182)  [COLOR="Red"]' inputs '¶'[/COLOR]
 End If
 
 If Shift = acAltMask And KeyCode = vbKey2 Then
  Me.TargetControl = Me.TargetControl & Chr(163)   [COLOR="Red"]'inputs '£'[/COLOR]
 End If
 
 If Shift = acAltMask And KeyCode = vbKey3 Then
  Me.TargetControl = Me.TargetControl & Chr(128)  [COLOR="Red"] 'inputs '€'[/COLOR]
 End If
 
 If Shift = acAltMask And KeyCode = vbKey4 Then
  Me.TargetControl = Me.TargetControl & Chr(174)  [COLOR="Red"] 'inputs '®'[/COLOR]
  End If
 
 If Nz(TargetControl, "") <> "" Then
  Me.TargetControl.SelStart = Len(Me.TargetControl)
 End If

End Sub
Linq ;0)>
 
Yes, I can also check the Shift status and the KeyCode to do something else.

However, the problem is to change the KeyCode or Status to change them to other characters (which cannot be directly input from the keyboard) to appear as input in the TextBox in mixing mode with other normal keyboard input characters. For example 30°C, i.e. the Alt-1 etc key combinations is used only for some graphical characters (in this case the '°' character) in inputting a text line to the TextBox.

Thanks

Alan Chan
 
Further to my response above, I recognise that you have proposed a practical way to do what I want. Thank you.

But the situation is a bit more complicated as I have over 30 TextBoxes and ComboBoxes in the Form, and use a common event handler for all these Boxes. If I can change the KeyCode as the KeyDown event and SendKeys functions are supposed to do, the KeyDown procedure does not need to identify which TextBox or ComboBox is currently On Focus and change the corresponding field data. The resulting program logic will be much simpler.

Alan Chan
 
First off, experienced Access developers stopped using SendKeys ages ago, as they have a nasty habit of doing things not intended, such as toggling the NumbersLock Key. Also, in post-2003 Access, they may or may not always work, unless you also have previous versions of Access installed on the machine. In general, the use of SendKeys is simply too unreliable.

Using the routine I gave you can easily be modified to work for any/all Controls by simply moving it to Form_KeyDown event and replacing the specific Control name with Screen.ActiveControl.

Code:
Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer)

 If Shift = acAltMask And KeyCode = vbKey1 Then
  Screen.ActiveControl = Screen.ActiveControl & Chr(182) ' inputs '¶'
 End If
 
 If Shift = acAltMask And KeyCode = vbKey2 Then
  Screen.ActiveControl = Screen.ActiveControl & Chr(163)   'inputs '£'
 End If
 
 If Shift = acAltMask And KeyCode = vbKey3 Then
  Screen.ActiveControl = Screen.ActiveControl & Chr(128)   'inputs '€'
 End If
 
 If Shift = acAltMask And KeyCode = vbKey4 Then
  Screen.ActiveControl = Screen.ActiveControl & Chr(174)   'inputs '®'
 End If

 If Nz(Screen.ActiveControl, "") <> "" Then
  Screen.ActiveControl.SelStart = Len(Screen.ActiveControl)
 End If

End Sub
You simply need to replace Chr(128), Chr(174) etc. with the actual ASCII codes for the symbols you need.

Also note that when using the Form_KeyDown event, in Form Design View, with the Form itself selected,you have to go to Properties - Events, scroll all the way to the bottom and set the KeyPreview Propertyto Yes.

Linq ;0)>
 
You are right that the SendKeys function is unreliable and what it does is quite unpredictable.

It would be good if we can just change the KeyCode and/or the Shift status byte to inject the character we want into the current text field on focus.

I am now just using the Alt key detection without changing it, and append the char to TextBox.Text (the ".Text" is necessary otherwise the new char will override every chars existing in the text field) and it works very smoothly and reliably. Fortunately Me.ActiveControl references to the TextBox or ComboBox currently On Focus so that the character can be put to the correct Box.

Thanks for the assistance.;)

Alan Chan
 

Users who are viewing this thread

Back
Top Bottom