Search notes:

Examples for Visual Basic for Application accessing the Windows API: key press

The following example needs the VBA declarations of the Windows API which can be found here.
'
'  https://stackoverflow.com/questions/11153995/is-there-any-event-that-fires-when-keys-are-pressed-when-editing-a-cell
'
'  call trackKeyPressInit
'  call stopKeyWatch
'
'  TODO: Win 64 Api -> https://msdn.microsoft.com/en-us/VBA/Language-Reference-VBA/articles/ptrsafe-keyword
'
option explicit

private bExitLoop as boolean

sub trackKeyPressInit()

    dim msgMessage           as MSG
    dim propagateKeyPress    as boolean
    dim iKeyCode             as integer
    dim lXLhwnd              as long

    on error GoTo errHandler:
    
    application.enableCancelKey = xlErrorHandler
        
  ' initialize this boolean flag.
    bExitLoop = False
        
  ' get the app hwnd.
    lXLhwnd = FindWindow("XLMAIN", application.caption)
        
    do
        WaitMessage
        
      ' Check for a key press and remove it from the msg queue.
      
        if PeekMessage (msgMessage, lXLhwnd, WM_KEYDOWN, WM_KEYDOWN, PM_REMOVE) Then
        
          ' strore the virtual key code for later use.
            iKeyCode = msgMessage.wParam
            
          ' translate the virtual key code into a char msg.
            TranslateMessage msgMessage
            call PeekMessage(msgMessage, lXLhwnd, WM_CHAR, WM_CHAR, PM_REMOVE)
            
          ' for some obscure reason, the following
          ' keys are not trapped inside the event handler
          ' so we handle them here.
          
            if iKeyCode = vbKeyBack   then SendKeys "{BS}"
            if iKeyCode = vbKeyReturn then SendKeys "{ENTER}"
            
            propagateKeyPress = true
            
          ' The VBA RaiseEvent statement does not seem to return ByRef arguments
          ' so we call a KeyPress routine rather than a propper event handler.
            call keyPressed(byVal msgMessage.wParam, byVal iKeyCode, propagateKeyPress)
            
          ' if the key pressed is allowed post it to the application.
            if propagateKeyPress then
               call PostMessage(lXLhwnd, msgMessage.Message, msgMessage.wParam, 0)
            end if
        end if
    errHandler:
      ' allow the processing of other msgs.
        doEvents
    loop until bExitLoop

end sub

sub stopKeyWatch()
    bExitLoop = true
end sub



private sub keyPressed(byVal KeyAscii          as integer, _
                       byVal KeyCode           as integer, _
                       byRef propagateKeyPress as boolean)

    debug.print keyAscii
    
    if chr(keyAscii) = "9" then
       bExitLoop = true
    end if
    
    if chr(keyAscii) = "8" then
       propagateKeyPress = false
    end if
       

 '  if Not Intersect(Target, Range("A1:D10")) Is Nothing Then
 '      if Chr(KeyAscii) Like "[0-9]" Then
 '          MsgBox MSG & Range("A1:D10").Address(False, False) _
 '          & """ .", vbCritical, TITLE
 '          Cancel = True
 '      end If
 '  end If

End Sub

Github repository WinAPI-4-VBA, path: /examples/key-press.bas

See also

Other examples

Index