Rapido
asked on
SetKeyboardState not working (InterOp, user32.dll)
My employer has a problem with the numlock status randomly changing during data entry. I need to write a background app that polls the numlock state regularly, and re-activates it if it is randomly deactivated. I've got the polling part working perfectly, but when setting the state (SetKeyboardState returns true) the lights don't go on / off, and the effect doesn't trigger either. Here's the code I used:
First I import the functions I need from user32.dll:
[DllImport("user32.dll", CharSet=CharSet.Auto, ExactSpelling=true, CallingConvention=CallingC onvention. Winapi)]
public static extern bool SetKeyboardState( byte[] keys );
[DllImport("user32.dll", CharSet=CharSet.Auto, ExactSpelling=true, CallingConvention=CallingC onvention. Winapi)]
public static extern bool GetKeyboardState( byte[] keys );
Then I read the current state into a byte array:
Byte[] myBytes = new Byte[256];
GetKeyboardState(myBytes);
Set the relevant virtual keys to 'true':
myBytes[144] = 0; // NumLock
myBytes[145] = 0; // ScrollLock (just for testing)
myBytes[20] = 0; // CapsLock (just for testing)
And reload the changed byte array into the keyboard state:
SetKeyboardState(myBytes);
There aren't too many examples on the web, so I'm hoping someone's done this successfully before.
First I import the functions I need from user32.dll:
[DllImport("user32.dll", CharSet=CharSet.Auto, ExactSpelling=true, CallingConvention=CallingC
public static extern bool SetKeyboardState( byte[] keys );
[DllImport("user32.dll", CharSet=CharSet.Auto, ExactSpelling=true, CallingConvention=CallingC
public static extern bool GetKeyboardState( byte[] keys );
Then I read the current state into a byte array:
Byte[] myBytes = new Byte[256];
GetKeyboardState(myBytes);
Set the relevant virtual keys to 'true':
myBytes[144] = 0; // NumLock
myBytes[145] = 0; // ScrollLock (just for testing)
myBytes[20] = 0; // CapsLock (just for testing)
And reload the changed byte array into the keyboard state:
SetKeyboardState(myBytes);
There aren't too many examples on the web, so I'm hoping someone's done this successfully before.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
To import the function:
[DllImport("user32.dll", CharSet=CharSet.Auto, ExactSpelling=true, CallingConvention=CallingC onvention. Winapi)]
public static extern void keybd_event(byte bVk, byte bScan, int dwFlags, int extraInfo);
To depress, press, and depress the numlock key:
keybd_event(144, 0, 2, 0);
keybd_event(144, 0, 0, 0);
keybd_event(144, 0, 2, 0);
Turned out you need to depress it first, in case it's still being pressed during the time you want it to reactivate. Strange how MS throws about all kinds of constants, but that there pretty impossible to look up in vs.net. Oh well, problem solved in any case.
[DllImport("user32.dll", CharSet=CharSet.Auto, ExactSpelling=true, CallingConvention=CallingC
public static extern void keybd_event(byte bVk, byte bScan, int dwFlags, int extraInfo);
To depress, press, and depress the numlock key:
keybd_event(144, 0, 2, 0);
keybd_event(144, 0, 0, 0);
keybd_event(144, 0, 2, 0);
Turned out you need to depress it first, in case it's still being pressed during the time you want it to reactivate. Strange how MS throws about all kinds of constants, but that there pretty impossible to look up in vs.net. Oh well, problem solved in any case.
ASKER