split keyboard input logic into platform specific code

This commit is contained in:
Robin Appelman
2018-11-09 00:07:31 +01:00
parent ac0df69c9b
commit 0c6a7ff498
8 changed files with 274 additions and 155 deletions
@@ -0,0 +1,20 @@
#include "KeyboardInputDummy.h"
namespace advsettings {
void KeyboardInputDummy::sendKeyboardInput(QString input)
{
// noop
}
void KeyboardInputDummy::sendKeyboardEnter()
{
// noop
}
void KeyboardInputDummy::sendKeyboardBackspace(int count)
{
// noop
}
}
@@ -0,0 +1,19 @@
#ifndef KEYBOARDINPUTDUMMY_H
#define KEYBOARDINPUTDUMMY_H
#include "../KeyboardInput.h"
// application namespace
namespace advsettings {
class KeyboardInputDummy : public KeyboardInput
{
public:
virtual void sendKeyboardInput(QString input) override;
virtual void sendKeyboardEnter() override;
virtual void sendKeyboardBackspace(int count) override;
};
}
#endif // KEYBOARDINPUTDUMMY_H
@@ -0,0 +1,140 @@
#include "KeyboardInputWindows.h"
#include <Windows.h>
namespace advsettings {
void fillKiStruct(INPUT& ip, WORD scanCode, bool keyup) {
ip.type = INPUT_KEYBOARD;
ip.ki.wVk = scanCode;
if (keyup) {
ip.ki.dwFlags = KEYEVENTF_KEYUP;
} else {
ip.ki.dwFlags = 0;
}
ip.ki.wScan = 0;
ip.ki.dwExtraInfo = 0;
ip.ki.time = 0;
};
void KeyboardInputWindows::sendKeyboardInput(QString input)
{
int len = input.length();
if (len > 0) {
LPINPUT ips = new INPUT[len * 5 + 3];
unsigned ii = 0;
bool shiftPressed = false;
bool ctrlPressed = false;
bool altPressed = false;
for (int i = 0; i < len; i++) {
short tmp = VkKeyScan(input.at(i).toLatin1());
WORD c = tmp & 0xFF;
short shiftState = tmp >> 8;
bool isShift = shiftState & 1;
bool isCtrl = shiftState & 2;
bool isAlt = shiftState & 4;
if (isShift && !shiftPressed) {
fillKiStruct(ips[ii++], VK_SHIFT, false);
shiftPressed = true;
} else if (!isShift && shiftPressed) {
fillKiStruct(ips[ii++], VK_SHIFT, true);
shiftPressed = false;
}
if (isCtrl && !ctrlPressed) {
fillKiStruct(ips[ii++], VK_CONTROL, false);
ctrlPressed = true;
} else if (!isCtrl && ctrlPressed) {
fillKiStruct(ips[ii++], VK_CONTROL, true);
ctrlPressed = false;
}
if (isAlt && !altPressed) {
fillKiStruct(ips[ii++], VK_MENU, false);
altPressed = true;
} else if (!isAlt && altPressed) {
fillKiStruct(ips[ii++], VK_MENU, true);
altPressed = false;
}
fillKiStruct(ips[ii++], c, false);
fillKiStruct(ips[ii++], c, true);
}
if (shiftPressed) {
fillKiStruct(ips[ii++], VK_SHIFT, true);
shiftPressed = false;
}
if (ctrlPressed) {
fillKiStruct(ips[ii++], VK_CONTROL, true);
ctrlPressed = false;
}
if (altPressed) {
fillKiStruct(ips[ii++], VK_MENU, true);
altPressed = false;
}
if (!SendInput(ii, ips, sizeof(INPUT))) {
char *err;
auto errCode = GetLastError();
if (!FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
errCode,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // default language
(LPTSTR)&err,
0,
NULL)){
LOG(ERROR) << "Error calling SendInput(): Could not get error message (" << errCode << ")";
} else {
LOG(ERROR) << "Error calling SendInput(): " << err;
}
}
delete ips;
}
}
void KeyboardInputWindows::sendKeyboardEnter()
{
LPINPUT ips = new INPUT[2];
fillKiStruct(ips[0], VK_RETURN, false);
fillKiStruct(ips[1], VK_RETURN, true);
if (!SendInput(2, ips, sizeof(INPUT))) {
char *err;
auto errCode = GetLastError();
if (!FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
errCode,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // default language
(LPTSTR)&err,
0,
NULL)) {
LOG(ERROR) << "Error calling SendInput(): Could not get error message (" << errCode << ")";
} else {
LOG(ERROR) << "Error calling SendInput(): " << err;
}
}
delete ips;
}
void KeyboardInputWindows::sendKeyboardBackspace(int count)
{
if (count > 0) {
LPINPUT ips = new INPUT[count * 2];
for (int i = 0; i < count; i++) {
fillKiStruct(ips[2 * i], VK_BACK, false);
fillKiStruct(ips[2 * i + 1], VK_BACK, true);
}
if (!SendInput(2 * count, ips, sizeof(INPUT))) {
char *err;
auto errCode = GetLastError();
if (!FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
errCode,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // default language
(LPTSTR)&err,
0,
NULL)) {
LOG(ERROR) << "Error calling SendInput(): Could not get error message (" << errCode << ")";
} else {
LOG(ERROR) << "Error calling SendInput(): " << err;
}
}
delete ips;
}
}
}
@@ -0,0 +1,19 @@
#ifndef KEYBOARDINPUTWINDOWS_H
#define KEYBOARDINPUTWINDOWS_H
#include "../KeyboardInput.h"
// application namespace
namespace advsettings {
class KeyboardInputWindows : public KeyboardInput
{
public:
virtual void sendKeyboardInput(QString input) override;
virtual void sendKeyboardEnter() override;
virtual void sendKeyboardBackspace(int count) override;
};
}
#endif // KEYBOARDINPUTWINDOWS_H