Link to home
Create AccountLog in
Programming

Programming

--

Questions

--

Followers

Top Experts

Avatar of suma_ds
suma_ds

USE SendInput() TO TOGGLE THE STATE OF CAPS LOCK
hey every1...

im trying to make a caps lock alternator, so that ordinary typing will come out like: tHiS Is a tEsT

it uses a windows hook to determine when a key is pressed, and then determines whether caps lock is in effect by using GetAsyncKeyState(20) in the HookProc.

how can i use SendInput to turn caps lock on or off?

i looked this up in the msdn library, but there r so many different parameters which i dont know what to assign to :(

can some1 explain exactly how to do this? some working c++ source code would also be very helpful



thanks in advance,

suma

Zero AI Policy

We believe in human intelligence. Our moderation policy strictly prohibits the use of LLM content in our Q&A threads.


Avatar of AlexFMAlexFM

This is function I use to turn Caps Lock on/off:

// bState = TRUE - turn Caps Lock on
// bState = FALSE - turn Caps Lock off
void SetCapsLock(BOOL bState)
{
    BYTE keyState[256];

    GetKeyboardState((LPBYTE)&keyState);
    if( (bState && !(keyState[VK_CAPITAL] & 1)) ||
        (!bState && (keyState[VK_CAPITAL] & 1)) )
    {
        // Simulate a key press
        keybd_event( VK_CAPITAL,
                     0,
                     KEYEVENTF_EXTENDEDKEY | 0,
                     0 );

        // Simulate a key release
        keybd_event( VK_CAPITAL,
                     0,
                     KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP,
                     0);
    }
}

Avatar of suma_dssuma_ds

ASKER

nice... it works :)

but check out what msdn has to say about keybd_event:

"Windows NT/2000/XP:This function has been superseded. Use SendInput instead."

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/WinUI/WindowsUserInterface/UserInput/KeyboardInput/KeyboardInputReference/KeyboardInputFunctions/keybd_event.asp

will the code still be compatible with all versions of windows?

You can translate this to SendInput if you want.

VOID keybd_event(
  BYTE bVk,               // virtual-key code
  BYTE bScan,             // hardware scan code
  DWORD dwFlags,          // function options
  ULONG_PTR dwExtraInfo   // additional keystroke data
);

typedef struct tagKEYBDINPUT {
  WORD      wVk;
  WORD      wScan;
  DWORD     dwFlags;
  DWORD     time;
  ULONG_PTR dwExtraInfo;
} KEYBDINPUT, *PKEYBDINPUT;

wVk= bVk
wScan = 0
Flags are the same.
time = 0
dwExtraInfo = 0

Reward 1Reward 2Reward 3Reward 4Reward 5Reward 6

EARN REWARDS FOR ASKING, ANSWERING, AND MORE.

Earn free swag for participating on the platform.


Avatar of suma_dssuma_ds

ASKER

ok that works, but is it really necessary because:

keybd_event(VK_CAPITAL, 0, KEYEVENTF_EXTENDEDKEY | 0, 0); //caps lock key down                        
keybd_event(VK_CAPITAL, 0, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0); //caps lock key up

is a hell of a lot smaller than it's SendImput equivilant:

KEYBDINPUT keyDown;
keyDown.wVk = VK_CAPITAL;
keyDown.wScan = 0;
keyDown.time = 0;
keyDown.dwFlags = KEYEVENTF_EXTENDEDKEY | 0; //keydown
keyDown.dwExtraInfo = 0;

KEYBDINPUT keyUp;
keyUp.wVk = VK_CAPITAL;
keyUp.wScan = 0;
keyUp.time = 0;
keyUp.dwFlags = KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP; //keyup
keyUp.dwExtraInfo = 0;
                        
INPUT input[2];
input[0].type = input[1].type = INPUT_KEYBOARD;
input[0].ki = keyDown;
input[1].ki = keyUp;

SendInput(2, input, sizeof(INPUT));



now these extra lines of code would not be a problem, but as luck would have it, i need to do this inside of a dll.

the dll uses shared memory, and all variables in shared memory MUST be instalized at declaration.

i can instalize keyDown and keyUp at their declarations, but run into problems when trying to instalize a array of structures at declaration.




>> can i get away with using keybd_event instead of SendInput, and what would the disadvantages be?

>> would it be advisable to put up with the large arrays instalized each time, for the advantages gained by using SendInput?

>> if so, can u see any way to instalize the array of structures at declaration? i tried pretending it was a multidimenional array but it didnt work?


cheers... suma

This is interesting C++ problem which deservs to be discussed in C++ forum. When I tried to initialize INPUT array by the following way:

INPUT input[2] =
{
    {INPUT_KEYBOARD, {VK_CAPITAL, 0, KEYEVENTF_EXTENDEDKEY, 0, 0} },
    {INPUT_KEYBOARD, {VK_CAPITAL, 0, KEYEVENTF_EXTENDEDKEY|KEYEVENTF_KEYUP, 0, 0} }
};

I found that it's values are wrong, because it is initialized according to first union member MOUSEINPUT (you can see this in the debugger). I don't know how to initialize it using second union type.
Of course, you can initialize it by the first type, so that second type will get required values, but this is worse than using keybd_event.

Avatar of suma_dssuma_ds

ASKER

the dropdown list in my compiler indicates that the order of the variables is:

hi
ki
mi
type

so (correct me if im wrong) it should be:

INPUT input[2] =
{
    {{VK_CAPITAL, 0, KEYEVENTF_EXTENDEDKEY, 0, 0}, INPUT_KEYBOARD},
    {{VK_CAPITAL, 0, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0, 0}, INPUT_KEYBOARD }
};

now this assigns {VK_CAPITAL, 0, KEYEVENTF_EXTENDEDKEY, 0, 0} to "hi", and INPUT_KEYBOARD to "mi"

so if it was changed to:

INPUT input[2] =
{
    {0, {VK_CAPITAL, 0, KEYEVENTF_EXTENDEDKEY, 0, 0}, 0, INPUT_KEYBOARD},
    {0, {VK_CAPITAL, 0, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0, 0}, 0, INPUT_KEYBOARD }
};

then the values should be assigned correctly.

the only remaining problem is whether this it is acceptable to assign 0 (zero) to "hi" and "mi".

what do u think??

Free T-shirt

Get a FREE t-shirt when you ask your first question.

We believe in human intelligence. Our moderation policy strictly prohibits the use of LLM content in our Q&A threads.


Avatar of suma_dssuma_ds

ASKER

damn... the compiler shows KEYBDINPUT as

dwExtraInfo
dwFlags
wScan
wVk

but msdn shows it as

    WORD wVk;
    WORD wScan;
    DWORD dwFlags;
    DWORD time;
    ULONG_PTR dwExtraInfo


which is correct?

btw im using visual studio .net

ASKER CERTIFIED SOLUTION
Avatar of AlexFMAlexFM

Link to home
membership
Log in or create a free account to see answer.
Signing up is free and takes 30 seconds. No credit card required.
Create Account
Programming

Programming

--

Questions

--

Followers

Top Experts

Programming includes both the specifics of the language you’re using, like Visual Basic, .NET, Java and others, but also the best practices in user experience and interfaces and the management of projects, version control and development. Other programming topics are related to web and cloud development and system and hardware programming.