status of caps lock and num lock

how can i get the status of the num lock and caps lock keys from a vba function and hence include them on a form as either a label or a textbox.

Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Jim Dettman (Microsoft MVP/ EE MVE)President / OwnerCommented:
Option Compare Database
Option Explicit

Const ModuleName = "KeyboardFunctions"

'Key Codes from constant.txt in c:\access directory.

Global Const KEY_LBUTTON = &H1
Global Const KEY_RBUTTON = &H2
Global Const KEY_CANCEL = &H3
Global Const KEY_MBUTTON = &H4    ' NOT contiguous with L & RBUTTON
Global Const KEY_BACK = &H8
Global Const KEY_TAB = &H9
Global Const KEY_CLEAR = &HC
Global Const KEY_RETURN = &HD
Global Const KEY_SHIFT = &H10
Global Const KEY_CONTROL = &H11
Global Const KEY_MENU = &H12
Global Const KEY_PAUSE = &H13
Global Const KEY_CAPITAL = &H14
Global Const KEY_ESCAPE = &H1B
Global Const KEY_SPACE = &H20
Global Const KEY_PRIOR = &H21
Global Const KEY_NEXT = &H22
Global Const KEY_END = &H23
Global Const KEY_HOME = &H24
Global Const KEY_LEFT = &H25
Global Const KEY_UP = &H26
Global Const KEY_RIGHT = &H27
Global Const KEY_DOWN = &H28
Global Const KEY_SELECT = &H29
Global Const KEY_PRINT = &H2A
Global Const KEY_EXECUTE = &H2B
Global Const KEY_SNAPSHOT = &H2C
Global Const KEY_INSERT = &H2D
Global Const KEY_DELETE = &H2E
Global Const KEY_HELP = &H2F

' KEY_A thru KEY_Z are the same as their ASCII equivalents: 'A' thru 'Z'
' KEY_0 thru KEY_9 are the same as their ASCII equivalents: '0' thru '9'

Global Const KEY_NUMPAD0 = &H60
Global Const KEY_NUMPAD1 = &H61
Global Const KEY_NUMPAD2 = &H62
Global Const KEY_NUMPAD3 = &H63
Global Const KEY_NUMPAD4 = &H64
Global Const KEY_NUMPAD5 = &H65
Global Const KEY_NUMPAD6 = &H66
Global Const KEY_NUMPAD7 = &H67
Global Const KEY_NUMPAD8 = &H68
Global Const KEY_NUMPAD9 = &H69
Global Const KEY_MULTIPLY = &H6A
Global Const KEY_ADD = &H6B
Global Const KEY_SEPARATOR = &H6C
Global Const KEY_SUBTRACT = &H6D
Global Const KEY_DECIMAL = &H6E
Global Const KEY_DIVIDE = &H6F
Global Const KEY_F1 = &H70
Global Const KEY_F2 = &H71
Global Const KEY_F3 = &H72
Global Const KEY_F4 = &H73
Global Const KEY_F5 = &H74
Global Const KEY_F6 = &H75
Global Const KEY_F7 = &H76
Global Const KEY_F8 = &H77
Global Const KEY_F9 = &H78
Global Const KEY_F10 = &H79
Global Const KEY_F11 = &H7A
Global Const KEY_F12 = &H7B
Global Const KEY_F13 = &H7C
Global Const KEY_F14 = &H7D
Global Const KEY_F15 = &H7E
Global Const KEY_F16 = &H7F

Global Const KEY_NUMLOCK = &H90

Global Const KEY_GREYMINUS = 45
Global Const KEY_GREYPLUS = 43

Declare Function saGetKeyState Lib "user32" Alias "GetKeyState" (ByVal intVirtKey As Integer) As Integer
Declare Sub saGetKeyboardState Lib "user32" Alias "GetKeyBoardState" (ByVal strKeyState As String)
Declare Sub saSetKeyboardState Lib "user32" Alias "SetKeyboardState" (ByVal strKeyState As String)

Function IsCapsLockSet() As Integer
    IsCapsLockSet = IIf(saGetKeyState(KEY_CAPITAL), True, False)
End Function

Function IsNumLockSet() As Integer
    IsNumLockSet = IIf(saGetKeyState(KEY_NUMLOCK), True, False)
End Function

Sub SetCapsLock(fTurnOn As Integer)
    SetKeyState KEY_CAPITAL, fTurnOn
End Sub

Sub SetKeyState(intKey As Integer, fTurnOn As Integer)
    Dim strBuffer As String * 256

    saGetKeyboardState strBuffer
    Mid(strBuffer, intKey + 1, 1) = Chr$(IIf(fTurnOn, 1, 0))
    saSetKeyboardState strBuffer
End Sub

Sub SetNumLock(fTurnOn As Integer)
    SetKeyState KEY_NUMLOCK, fTurnOn
End Sub


Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
russelldavAuthor Commented:
great little function,

thanks there.

my only problem now is that obviously if the key state changes you have to re-run that function to get the change noticed.

is there any way of putting an ontimer event that will re-draw my form. i can then use this to check the status of the keys and also update the time (currently =Time() ).

Jim Dettman (Microsoft MVP/ EE MVE)President / OwnerCommented:
<<is there any way of putting an ontimer event that will re-draw my form. i can then use this to check the status of the keys and also update the time (currently =Time() ).

 Sure.  ou can use OnTimer to do all that.  I would not set the interval for much less then a second or two though.

russelldavAuthor Commented:

a second is jsut about ok (havnt tested with all functionality yet) but anything shorter and the display starts to go craszy.

thanks again
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Microsoft Access

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.