Solved

USE SendInput() TO TOGGLE THE STATE OF CAPS LOCK

Posted on 2004-04-13
8
2,891 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
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

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
egit plugin on eclipse 8 129
How to Have Macro Files Automatically "Edit" 5 77
Convert number to hex in Lua 16 95
powershell try catch  and $ErrorActionPreference = continue 6 71
Does the idea of dealing with bits scare or confuse you? Does it seem like a waste of time in an age where we all have terabytes of storage? If so, you're missing out on one of the core tools in every professional programmer's toolbox. Learn how to …
A short article about a problem I had getting the GPS LocationListener working.
In this fourth video of the Xpdf series, we discuss and demonstrate the PDFinfo utility, which retrieves the contents of a PDF's Info Dictionary, as well as some other information, including the page count. We show how to isolate the page count in a…
In this seventh video of the Xpdf series, we discuss and demonstrate the PDFfonts utility, which lists all the fonts used in a PDF file. It does this via a command line interface, making it suitable for use in programs, scripts, batch files — any pl…

751 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