4

I'm trying to send a CTRL+SHIFT+END key stroke to a control, in a C++ application written with Embarcadero. I'm using the code below:

tagINPUT ip;
ip.type = INPUT_KEYBOARD;
ip.ki.wScan = 0;
ip.ki.time = 0;
ip.ki.dwExtraInfo = 0;

// Appui sur Ctrl
ip.ki.wVk = VK_CONTROL;
ip.ki.dwFlags = 0;
SendInput(1, &ip, sizeof(INPUT));

// Appui sur Shift
ip.ki.wVk = VK_SHIFT;
ip.ki.dwFlags = 0;
SendInput(1, &ip, sizeof(INPUT));

// Appui sur End
ip.ki.wVk = VK_END;
ip.ki.dwFlags = 0;
SendInput(1, &ip, sizeof(INPUT));

Application->ProcessMessages();

// Relacher End
ip.ki.wVk = VK_END;
ip.ki.dwFlags = KEYEVENTF_KEYUP;
SendInput(1, &ip, sizeof(INPUT));

// Relacher Shift
ip.ki.wVk = VK_SHIFT;
ip.ki.dwFlags = KEYEVENTF_KEYUP;
SendInput(1, &ip, sizeof(INPUT));

// Relacher Ctrl
ip.ki.wVk = VK_CONTROL;
ip.ki.dwFlags = KEYEVENTF_KEYUP;
SendInput(1, &ip, sizeof(INPUT));

However, it appears to be working like if there was no action on the CTRL and SHIFT keys.

What am I missing ?

Werner Henze
  • 16,404
  • 12
  • 44
  • 69
C. MARIN
  • 95
  • 9
  • sendinput is not part of the standard c++, you should include more tags to your question, if you leave it like this you should include the code to that sendinput function, but I am guessing that you don´t have it, not everyone that uses c++ uses Embarcadero. – exs Jul 05 '17 at 11:39
  • To be honest, I'm using the SendInput that was coming from theproject, enclosed in a win32.h file. This was done by someone else that is no longer in my company, so I cannot give any accurate idea of what it does. – C. MARIN Jul 05 '17 at 11:48
  • It's used for synthesizing keystrokes – Asesh Jul 05 '17 at 11:54
  • Ok, this I got it. Now, why does it synthesize keystrokes as if the Ctrl and Shift were not hit, despite the SendInput I wrote in the code included in my question ? – C. MARIN Jul 05 '17 at 12:14
  • Look for other examples here on SO for how to do this properly. I know there are some, but I don't have time to do your search for you right now. Search for `SendInput`. – 500 - Internal Server Error Jul 05 '17 at 13:51
  • 2
    You should not do multiple `SendInput()` calls but instead pass an array with all the input you want to send in a **single** `SendInput()` call. – zett42 Jul 05 '17 at 14:03
  • I will try it, I thought about it. However some other bugs are keeping me away from that solution. Tomorrow is another day. – C. MARIN Jul 05 '17 at 14:11
  • It's really important that you put all the events in an array and make one call to SendInput – David Heffernan Jul 05 '17 at 16:45
  • Does important mean mandatory ? I mean: could that be the actual reason for it does not work ? Kinda odd behaviour for SendInput... – C. MARIN Jul 06 '17 at 08:19
  • You can do it wrong if you want. The documentation explains the consequences of doing it wrong. – David Heffernan Jul 06 '17 at 18:13
  • Well, I tried using an array of tagINPUT and one single SendInput, and the result is exactly the same as previously: the form reacts like if only the END key was hit. – C. MARIN Jul 19 '17 at 13:51

2 Answers2

4

The problem is, that the VK_END key is an extended key. So you should declare this in the flags:

eip.ki.dwFlags = 0;
ip.ki.wVk = VK_END;
ip.ki.dwFlags = 0;
ip.ki.dwFlags = ip.ki.dwFlags | 1;
SendInput(1, &ip, sizeof(INPUT));

Application->ProcessMessages();

// Relacher End
ip.ki.wVk = VK_END;
ip.ki.dwFlags = KEYEVENTF_KEYUP;
ip.ki.dwFlags = ip.ki.dwFlags | 1;
SendInput(1, &ip, sizeof(INPUT));

Note that I used 1 for setting the flag as I don't know if you have a constant defined in your C++, but assume there is a constant someplace.

HerrJoebob
  • 2,264
  • 16
  • 25
iamjoosy
  • 3,299
  • 20
  • 30
  • Thanks a lot, I bet this is exactly the answer I needed :) I'll try it out quite soon and will tell wether it works or not (it surely well, I think). – C. MARIN Nov 17 '17 at 15:38
0

Just add KEYEVENTF_EXTENDEDKEY flag to dwFlags

input.ki.dwFlags |= KEYEVENTF_EXTENDEDKEY;

Unfortunately, Win32 doesn't provide any way to determine if a key is extended. Here I just used a vector

    extended_keys << VK_INSERT;
    extended_keys << VK_DELETE;
    extended_keys << VK_HOME;
    extended_keys << VK_END;
    extended_keys << VK_PRIOR;
    extended_keys << VK_NEXT;
    extended_keys << VK_LEFT;
    extended_keys << VK_UP;
    extended_keys << VK_DOWN;
    extended_keys << VK_RIGHT;

and checked if it's inside the list add the flag

Pazel1374
  • 218
  • 3
  • 14