How do I emulate holding down a keyboard key in C++ - c++

I'm making a virtual piano auto player, you just paste the sheet and it will play(presses the keys specified in the sheet), but I'm having trouble on making the code hold down a key so it syncs with the song but I don't know how, here how I press my keys:
INPUT input[1];
ZeroMemory(input, sizeof(input));
input[0].type = INPUT_KEYBOARD;
input[0].ki.wVk = x; // <-- x is = to char from a char array
SendInput(ARRAYSIZE(input), input, sizeof(INPUT));
Sleep(delay);
input[0].type = INPUT_KEYBOARD;
input[0].ki.wVk = x;// <-- x is = to char from a char array
input[0].ki.dwFlags = KEYEVENTF_KEYUP;
SendInput(ARRAYSIZE(input), input, sizeof(INPUT));
Sleep(delay);

Related

How can I select text using SendInput?

I'm making a small program to select the keyword where I've placed the caret on. I'm trying to send Shift + Ctrl + Right Arrow from my program to any active window to select the text.
The problem is the "Shift" key is not sent and the text is not selected.
How can I do it?
This is my code that I have tried:
// Generate Ctrl + Shift + RightArrow input
INPUT copyText[6];
// Set the press of the "Shift" key
copyText[0].ki.wVk = VK_SHIFT;
copyText[0].ki.dwFlags = 0; // 0 for key press
copyText[0].type = INPUT_KEYBOARD;
// Set the press of the "Ctrl" key
copyText[1].ki.wVk = VK_CONTROL;
copyText[1].ki.dwFlags = 0; // 0 for key press
copyText[1].type = INPUT_KEYBOARD;
// Set the press of the "C" key
copyText[2].ki.wVk = VK_RIGHT;
copyText[2].ki.dwFlags = 0;
copyText[2].type = INPUT_KEYBOARD;
// Set the Release of the "Shift" key
copyText[3].ki.wVk = VK_SHIFT;
copyText[3].ki.dwFlags = KEYEVENTF_KEYUP;
copyText[3].type = INPUT_KEYBOARD;
// Set the Release of the "Ctrl" key
copyText[4].ki.wVk = VK_CONTROL;
copyText[4].ki.dwFlags = KEYEVENTF_KEYUP;
copyText[4].type = INPUT_KEYBOARD;
// Set the Release of the "C" key
copyText[5].ki.wVk = VK_RIGHT;
copyText[5].ki.dwFlags = KEYEVENTF_KEYUP;
copyText[5].type = INPUT_KEYBOARD;
// Send key sequence to system
SendInput(static_cast<UINT>(std::size(copyText)), copyText, sizeof(INPUT));

Simulate double direct keyboard input in C++

I found this c++ script that let you simulate a direct keyboard input, however, I need to simulate two inputs like [Ctrl + A]. I've been looking for ways to make it but I can't find the answer, if someone could help me or give me a clue I'd be grateful.
#include "stdafx.h"
#pragma comment(lib,"user32")
using namespace std;
int main()
{
char ch = 'a';
INPUT key;
memset(&key,0,sizeof(INPUT));//Zero the structure.
key.type = INPUT_KEYBOARD;
key.ki.dwExtraInfo = GetMessageExtraInfo();//<-- you will need to pinvoke this too.
key.ki.wScan =
static_cast<WORD>(MapVirtualKeyEx(VkKeyScanA(ch), MAPVK_VK_TO_VSC, GetKeyboardLayout(0)));//more pinvoking
key.ki.dwFlags = KEYEVENTF_SCANCODE;//<-- you will probably have to declare this constant somewhere-
//in your C# program.
//Ready to send the key-down event.
SendInput(1, &key, sizeof(INPUT));
Sleep(1000);//Wait one second before sending key-up.
//Sending key-up.
key.ki.dwExtraInfo = GetMessageExtraInfo();
key.ki.dwFlags = KEYEVENTF_SCANCODE | KEYEVENTF_KEYUP;//Key-up need be defined too, or just use the value.
SendInput(1, &key, sizeof(INPUT));
}
I've written this code, Ctrl press isn't working, however, 'W' press does.
int main()
{
Sleep(2000);
INPUT ip;
char key1 = VK_CONTROL, key2 = 'w';
ip.type = INPUT_KEYBOARD;
ip.ki.wScan = 0; // hardware scan code for key
ip.ki.time = 0;
ip.ki.dwExtraInfo = 0;
ip.ki.wScan = key1;
ip.ki.dwFlags = 0; // 0 for key press
SendInput(1, &ip, sizeof(INPUT));
// Press key2
ip.ki.wScan = key2;
ip.ki.dwFlags = 0; // 0 for key press
SendInput(1, &ip, sizeof(INPUT));
// Release key2
ip.ki.wScan = key2;
ip.ki.dwFlags = KEYEVENTF_KEYUP;
SendInput(1, &ip, sizeof(INPUT));
// Release key1
ip.ki.wScan = key1;
ip.ki.dwFlags = KEYEVENTF_KEYUP;
SendInput(1, &ip, sizeof(INPUT));
}
I've noticed if I delete the VK_CONTROL press lines, 'W' press doesn't work neither.
int main() {
Sleep(2000);
INPUT ip;
char key2 = 'w';
ip.type = INPUT_KEYBOARD;
ip.ki.wScan = 0; // hardware scan code for key
ip.ki.time = 0;
ip.ki.dwExtraInfo = 0;
// Press key2
ip.ki.wScan = key2;
ip.ki.dwFlags = 0; // 0 for key press
SendInput(1, &ip, sizeof(INPUT));
// Release key2
ip.ki.wScan = key2;
ip.ki.dwFlags = KEYEVENTF_KEYUP;
SendInput(1, &ip, sizeof(INPUT));
}
To send a ctrl-a, you need to send, in order:
key-down events
VK_CONTROL
virtual code for a
key-up events
virtual code for a
VK_CONTROL
so, using VkKeyScanExW to get the virtual scan code for 'a'
key.ki.wVk = VK_CONTROL;
/* send keystroke */
key.ki.wVk = /* the virtual key code for a that you derived */
/* send keystroke */
/* set flag to keyup */
key.ki.wVk = /* Virtual code for a */
/* send keystroke */
key.ki.wVk = VK_CONTROL;
/* send keystroke */
where VK_CONTROL is the macro defined in Windows that gives you the keyboard virtual code for ctrl. Leave wScan set to 0.
You are sending virtual codes to the scan code parameter. The scan code for w is not 'w'.
In scan code set 1 (US keyboards), w's scan code is 0x11, and left control's scan code is 0x1D. Microsoft's Keyboard Scan Code Specification details sets 1 and 2, and can be found at https://download.microsoft.com/download/1/6/1/161ba512-40e2-4cc9-843a-923143f3456c/scancode.doc. There are commonly 3 sets of scan codes, and they are enumerated various places on the web. Or, you can use a utility to capture your own keyboard's scan codes. Sharpkeys or AutoHotkey appear to be popular utilities for doing just this.

unable to do alt code (alt+11) with send_input

What I an trying to do is send the alt code alt+1 which = ☺ with send input. so i have to hold atl, press numpad 1, then let go of alt. Currently when the code runs it does hold the alt button, but has no output into the active window (notepad). I verified sendinput is working with key combos (ctrl+a) work. Num lock is turned on while this program is running. alt+f also works. I think the problem is that it is maybe sending '1' instead of numpad '1', which does not work with alt codes.
Sleep(1000 * 3);
INPUT tabinput[4];
tabinput[0].type = INPUT_KEYBOARD;
tabinput[0].ki = { VK_LMENU, 0 };
tabinput[1].type = INPUT_KEYBOARD;
tabinput[1].ki = { VK_NUMPAD1, 0 };
tabinput[2].type = INPUT_KEYBOARD;
tabinput[2].ki = { VK_NUMPAD1, 0, KEYEVENTF_KEYUP };
tabinput[3].type = INPUT_KEYBOARD;
tabinput[3].ki = { VK_LMENU, 0, KEYEVENTF_KEYUP };
SendInput(4, tabinput, sizeof(INPUT));
getchar();
You can use Unicode characters directly. If code point is less than 0xFFFF use:
input.ki.wScan = L'☺';
Some characters have code point greater than 0xFFFF, they require two key strokes for each code point, in which case use a wide string to handle it:
const wchar_t *buf = L"বাংলা ☺ 🙂 Abc";
std::vector<INPUT> vec;
for(size_t i = 0, len = wcslen(buf); i < len; i++)
{
INPUT input = { 0 };
input.type = INPUT_KEYBOARD;
input.ki.dwFlags = KEYEVENTF_UNICODE;
input.ki.wScan = buf[i];
vec.push_back(input);
input.ki.dwFlags |= KEYEVENTF_KEYUP;
vec.push_back(input);
}
SendInput(vec.size(), vec.data(), sizeof(INPUT));
the following code can be used to type unicode chars
using http://www.unicodemap.org/search.asp to find the correct code
INPUT tabinput[2];
tabinput[0].type = INPUT_KEYBOARD;
tabinput[0].ki.dwFlags = KEYEVENTF_UNICODE;
tabinput[0].ki.wVk = 0;
tabinput[0].ki.wScan = 0x00E1; // This is a Bengali unicode character
tabinput[1].type = INPUT_KEYBOARD;
tabinput[1].ki.dwFlags = KEYEVENTF_UNICODE | KEYEVENTF_KEYUP;
tabinput[1].ki.wVk = 0;
tabinput[1].ki.wScan = 0x00E1; // This is a Bengali unicode character
SendInput(2, tabinput, sizeof(INPUT));

Virtual key codes

I have a c++ console program. Ho can I simulate the "é" character ?
Code:
// Set up a generic keyboard event.
ip.type = INPUT_KEYBOARD;
ip.ki.wScan = 0; // hardware scan code for key
ip.ki.time = 0;
ip.ki.dwExtraInfo = 0;
ip.ki.wVk = 0x45; //e
ip.ki.dwFlags = 0;
SendInput(1, &ip, sizeof(INPUT));
ip.ki.dwFlags = KEYEVENTF_KEYUP;
SendInput(1, &ip, sizeof(INPUT));
How do I convert it to the "é" instead of "e"?
Thanks.
Per the KEYBDINPUT documentation, you can use the KEYEVENTF_UNICODE flag:
INPUT ip[2];
// Set up a generic keyboard event.
ip[0].type = INPUT_KEYBOARD;
ip[0].ki.dwFlags = KEYEVENTF_UNICODE; // We want to send a Unicode key code.
ip[0].ki.wScan = 0x00E9; // Unicode value of é
ip[0].ki.time = 0;
ip[0].ki.dwExtraInfo = 0;
ip[0].ki.wVk = 0; // Ignored
ip[1] = ip[0]; // Duplicate entry
ip[1].ki.dwFlags |= KEYEVENTF_KEYUP; // but make it key up
SendInput( 2, ip, sizeof(ip[0]));
(If you are ambitious, you can make that final "2" be your favourite ARRAY_COUNT macro or template function.)

How to print/press '#' using keybd_event function?

To press 'a' code is
keybd_event(VkKeyScan(64),0,0,0);
Releasing key code is
keybd_event(VkKeyScan(64),0,KEYEVENTF_KEYUP,0);
For pressing '#' i need combination of two key - SHIFT & 2 , but i don't know how.
keybd_event (https://msdn.microsoft.com/en-us/library/windows/desktop/ms646304(v=vs.85).aspx)
Try the following:
Press Shift
Press 2
Release 2
Release Shift
Addendum
I just checked my own code where I did the same thing... keybd_event is deprecated (as stated on the site you linked), you should use SendInput instead.
This are my two functions to send the key press and release:
void sendKeyDown(unsigned char keyCode)
{
INPUT input;
input.type = INPUT_KEYBOARD;
input.ki.wVk = keyCode;
input.ki.dwFlags = 0;
input.ki.time = 0;
input.ki.dwExtraInfo = 0;
SendInput(1, &input, sizeof(INPUT));
}
void sendKeyUp(unsigned char keyCode)
{
INPUT input;
input.type = INPUT_KEYBOARD;
input.ki.wVk = keyCode;
input.ki.dwFlags = KEYEVENTF_KEYUP;
input.ki.time = 0;
input.ki.dwExtraInfo = 0;
SendInput(1, &input, sizeof(INPUT));
}
And this should then give you an #:
sendKeyDown(VK_SHIFT);
sendKeyDown(0x32);
sendKeyUp(0x32);
sendKeyUp(VK_SHIFT);
Please check the 0x32, I can't reliably test it at the moment to be the key 2.