Solved

USE SendInput() TO TOGGLE THE STATE OF CAPS LOCK

Posted on 2004-04-13
8
2,771 Views
Last Modified: 2010-08-05
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
0
Comment
Question by:suma_ds
  • 4
  • 4
8 Comments
 
LVL 48

Expert Comment

by:AlexFM
ID: 10820664
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);
    }
}
0
 
LVL 1

Author Comment

by:suma_ds
ID: 10820790
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?
0
 
LVL 48

Expert Comment

by:AlexFM
ID: 10820872
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
0
 
LVL 1

Author Comment

by:suma_ds
ID: 10821585
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
0
Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

 
LVL 48

Expert Comment

by:AlexFM
ID: 10821746
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.
0
 
LVL 1

Author Comment

by:suma_ds
ID: 10822089
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??
0
 
LVL 1

Author Comment

by:suma_ds
ID: 10822108
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
0
 
LVL 48

Accepted Solution

by:
AlexFM earned 500 total points
ID: 10822165
typedef struct tagINPUT {
  DWORD   type;
  union {
      MOUSEINPUT      mi;
      KEYBDINPUT      ki;
      HARDWAREINPUT   hi;
  };
} INPUT, *PINPUT;

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

{INPUT_KEYBOARD, {VK_CAPITAL, 0, KEYEVENTF_EXTENDEDKEY, 0, 0} }

I want to get the following result:
type = INPUT_KEYBOARD
ki.wVk = VK_CAPITAL
ki.wScan = 0
ki.dwFlags = KEYEVENTF_EXTENDEDKEY
ki.time = 0
ki.dwExtraInfo = 0

But first union member is MOUSEINPUT mi:

typedef struct tagMOUSEINPUT {
  LONG    dx;
  LONG    dy;
  DWORD   mouseData;
  DWORD   dwFlags;
  DWORD   time;
  ULONG_PTR   dwExtraInfo;
} MOUSEINPUT, *PMOUSEINPUT;

so result of initialization is:

mi.dx = INPUT_KEYBOARD
mi.dy = VK_CAPITAL
mi.mouseData = 0
mi.dwFlags = KEYEVENTF_EXTENDEDKEY
mi.time = 0
mi.dwExtraInfo = 0

Since two structures have the same memory address, KEYBDINPUT ki is filled by wrong way. This is the problem. I don't know it's solution, ask in C++ area.
0

Featured Post

Highfive Gives IT Their Time Back

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

A short article about problems I had with the new location API and permissions in Marshmallow
Although it can be difficult to imagine, someday your child will have a career of his or her own. He or she will likely start a family, buy a home and start having their own children. So, while being a kid is still extremely important, it’s also …
Viewers will learn how to properly install Eclipse with the necessary JDK, and will take a look at an introductory Java program. Download Eclipse installation zip file: Extract files from zip file: Download and install JDK 8: Open Eclipse and …
In this fifth video of the Xpdf series, we discuss and demonstrate the PDFdetach utility, which is able to list and, more importantly, extract attachments that are embedded in PDF files. It does this via a command line interface, making it suitable …

708 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now