vbkeySeparator not working in Access 2003

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • daved

    #1

    vbkeySeparator not working in Access 2003

    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 _
    "PeekMessag eA" (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(Ke yCode 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(MyM sg, 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
  • Tony Toews [MVP]

    #2
    Re: vbkeySeparator not working in Access 2003

    daved <daved123g@goog lemail.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

    Tony's Microsoft Access Blog - http://msmvps.com/blogs/access/

    Comment

    • daved

      #3
      Re: vbkeySeparator not working in Access 2003

      On Oct 23, 10:21 pm, "Tony Toews [MVP]" <tto...@teluspl anet.net>
      wrote:
      daved <daved1...@goog lemail.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

      Comment

      • daved

        #4
        Re: vbkeySeparator not working in Access 2003

        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(Ke yCode 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(MyM sg, 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

        Comment

        • daved

          #5
          Re: vbkeySeparator not working in Access 2003

          On Oct 23, 10:41 pm, daved <daved1...@goog lemail.comwrote :
          On Oct 23, 10:21 pm, "Tony Toews [MVP]" <tto...@teluspl anet.net>
          wrote:
          >
          daved <daved1...@goog lemail.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(Ke yCode 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(MyM sg, 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

          Comment

          Working...