Can't detect numeric keypad Enter key

daved

Dave D
Local time
Today, 10:22
Joined
Feb 10, 2008
Messages
7
SOLUTION NEEDED FOR ACCESS 2003/VBA, NOT FOR ANY VERSION OF VB.

I need to differentiate between the Enter key on the main keyboard and the numeric keypad and obviously tried using vbkeySeparator in the form's Keypress event. However, both Enter keys return KeyCode 13.

MS Q188550 (below) offers a workaround for VB only - it does not claim to fix VBA. On this basis you might expect that the bug is fixed in Access/VBA but it isn't. I have tried the fix in VB and it works fine, but including the code in an Access 2003 form doesn't work - the call to PeekMessage always returns zero. I've also tried various different values for the filter to no good effect.

Many thanks for you help
Dave


- this is the VB fix cribbed straight from the Microsoft knowledge base...


Private Declare Function PeekMessage Lib "user32" Alias _
"PeekMessageA" (lpMsg As MSG, ByVal hwnd As Long, _
ByVal wMsgFilterMin As Long, ByVal wMsgFilterMax As Long, _
ByVal wRemoveMsg As Long) As Long

Private Type POINTAPI
x As Long
y As Long
End Type

Private Type MSG
hwnd As Long
message As Long
wParam As Long
lParam As Long
time As Long
pt As POINTAPI
End Type

Const PM_NOREMOVE = &H0
Const WM_KEYDOWN = &H100
Const WM_KEYUP = &H101
Const VK_RETURN = &HD

Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer)
Dim MyMsg As MSG, RetVal As Long
' pass:
' MSG structure to receive message information
' my window handle
' low and high filter of 0, 0 to trap all messages
' PM_NOREMOVE to leave the keystroke in the message queue
' use PM_REMOVE (1) to remove it

RetVal = PeekMessage(MyMsg, Me.hwnd, 0, 0, PM_NOREMOVE)

' now, per Q77550, you should look for a MSG.wParam of VK_RETURN
' if this was the keystroke, then test bit 24 of the lparam - if ON,
' then keypad was used, otherwise, keyboard was used

If RetVal <> 0 Then
If MyMsg.wParam = VK_RETURN Then
If MyMsg.lParam And &H1000000 Then
MsgBox "Enter from Keypad pressed"
Else
MsgBox "Enter from Keyboard pressed"
End If
End If
Else
MsgBox "No message waiting, or possible problems calling PeekMessage"
End If
End Sub
 
The question is why do you want to differentiate between the two?
 
Because I'm writing an EPOS system which needs to use the numeric
keypad Enter as the totalize key, whereas the main keyboard Enter key
is used in its traditional role everywhere else. Visualize the number
pad as the data-entry keys on a cash register if it helps. The number
pad number keys send their characters to specific fields whereas the
main keyboard number (and all other) keys act in the usual way in
whatever field the user happens to be in.

Dave
 
The last time I wrote an EPOS system we used smart keyboards with swipe cards on (Digipos) if I remember rightly, and it came with a setup that you could assign an action to each individual key. Using a traditional query keyboard to act as an EPOS keyboard do not seem the right approach to me.

I can see your issue but do not have a suitable answer for you. Sorry.

David
 
Update on progress - an imperfect but tolerable solution.

I spent the last couple of days trying some keyboard hooks, They all seems to work OK in VB but as soon as I port them to Access I run into problems. I always thought that VB and VBA were essentially the same but there must be some fundamental difference somewhere. The end result is that hooks are just not reliable enough: Access would ignore the call at best and crash at worst.

However, I have discovered one thing. In Access the message queue is cleared by the time it gets to the form's KeyDown event whereas in VB it isn't and this led me to consider puting the PeekMessage call in a loop. After several attempts I've reached the following stage which works well and reliably but with the quirk that I can't get it to detect a keydown event, only keyup, unless the key is held down until the repeat comes into play which is somewhat unnatural for an Enter key.

The snippets below allow any form to call KbdFix but the code also works perfectly well if it is all in a single form's KeyDown handler, with the declarations (see above) private to the form.

' form code
Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer)
KeyCode = KbdFix(KeyCode, Me.hwnd)
...
usual key trapping code goes here
you can now use vbKeySeparator properly
...
End Sub

' common module code, together with declarations (note the new constant VK_SEPARATOR, or just use &h6C)
Public Function KbdFix(KeyCode As Integer, Hndl As Long) As Integer
Dim MyMsg As MSG, RetVal As Long
Dim keys(0 To 255) As Byte
If KeyCode = vbKeyReturn Then
Do
RetVal = PeekMessage(MyMsg, Hndl, WM_KEYDOWN, WM_KEYUP, PM_REMOVE)
If MyMsg.wParam = VK_RETURN Then
If MyMsg.lParam And &H1000000 Then
KbdFix = VK_SEPARATOR
Else
KbdFix = VK_RETURN
End If
End If
Loop Until RetVal
Else
KbdFix = KeyCode
End If
End Function
 

Users who are viewing this thread

Back
Top Bottom