By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
434,677 Members | 1,060 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 434,677 IT Pros & Developers. It's quick & easy.

vbkeySeparator not working in Access 2003

P: n/a
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
Oct 23 '08 #1
Share this Question
Share on Google+
4 Replies


P: n/a
daved <da*******@googlemail.comwrote:
>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.
Just curious. Why.

Tony
--
Tony Toews, Microsoft Access MVP
Please respond only in the newsgroups so that others can
read the entire thread of messages.
Microsoft Access Links, Hints, Tips & Accounting Systems at
http://www.granite.ab.ca/accsmstr.htm
Tony's Microsoft Access Blog - http://msmvps.com/blogs/access/
Oct 23 '08 #2

P: n/a
On Oct 23, 10:21*pm, "Tony Toews [MVP]" <tto...@telusplanet.net>
wrote:
daved <daved1...@googlemail.comwrote:
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.

Just curious. *Why.

Tony
--
Tony Toews, Microsoft Access MVP
* *Please respond only in the newsgroups so that others can
read the entire thread of messages.
* *Microsoft Access Links, Hints, Tips & Accounting Systems athttp://www.granite.ab.ca/accsmstr.htm
* *Tony's Microsoft Access Blog -http://msmvps.com/blogs/access/
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

Oct 23 '08 #3

P: n/a
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
Dave

Oct 25 '08 #4

P: n/a
On Oct 23, 10:41*pm, daved <daved1...@googlemail.comwrote:
On Oct 23, 10:21*pm, "Tony Toews [MVP]" <tto...@telusplanet.net>
wrote:
daved <daved1...@googlemail.comwrote:
>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.
Just curious. *Why.
Tony
--
Tony Toews, Microsoft Access MVP
* *Please respond only in the newsgroups so that others can
read the entire thread of messages.
* *Microsoft Access Links, Hints, Tips & Accounting Systems athttp://www.granite.ab.ca/accsmstr.htm
* *Tony's Microsoft Access Blog -http://msmvps.com/blogs/access/

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
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
Oct 25 '08 #5

This discussion thread is closed

Replies have been disabled for this discussion.