Solved

USE SendInput() TO TOGGLE THE STATE OF CAPS LOCK

Posted on 2004-04-13
8
2,811 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
NAS Cloud Backup Strategies

This article explains backup scenarios when using network storage. We review the so-called “3-2-1 strategy” and summarize the methods you can use to send NAS data to the cloud

 
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
 
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

Netscaler Common Configuration How To guides

If you use NetScaler you will want to see these guides. The NetScaler How To Guides show administrators how to get NetScaler up and configured by providing instructions for common scenarios and some not so common ones.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Whether you've completed a degree in computer sciences or you're a self-taught programmer, writing your first lines of code in the real world is always a challenge. Here are some of the most common pitfalls for new programmers.
In this post we will learn how to connect and configure Android Device (Smartphone etc.) with Android Studio. After that we will run a simple Hello World Program.
An introduction to basic programming syntax in Java by creating a simple program. Viewers can follow the tutorial as they create their first class in Java. Definitions and explanations about each element are given to help prepare viewers for future …
With the power of JIRA, there's an unlimited number of ways you can customize it, use it and benefit from it. With that in mind, there's bound to be things that I wasn't able to cover in this course. With this summary we'll look at some places to go…

773 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