SendInput() 的问题
Issues with SendInput()
我希望在这段代码中得到一些帮助。
#include <windows.h>
#include <thread>
void keyPress(WORD keyCode)
{
INPUT input;
input.type = INPUT_KEYBOARD;
input.ki.wScan = keyCode;
input.ki.dwFlags = KEYEVENTF_SCANCODE;
SendInput(1, &input, sizeof(INPUT));
}
void keyRelease(WORD keyCode)
{
INPUT input;
input.type = INPUT_KEYBOARD;
input.ki.wScan = keyCode;
input.ki.dwFlags = KEYEVENTF_SCANCODE | KEYEVENTF_KEYUP;
SendInput(1, &input, sizeof(INPUT));
}
void CtrlPress()
{
while (true)
{
if (GetAsyncKeyState(VK_RBUTTON)) {
Sleep(1000);
keyPress(0x1D);
Sleep(3000);
keyRelease(0x1D);
}
else {
keyRelease(0x1D);;
}
}
}
int main() {
CtrlPress();
}
本质上,我想让它做的是在我按下鼠标右键后按Ctrl 1000ms,然后按住3000ms,然后松开,然后只要按住鼠标右键就可以循环。我还希望循环立即停止,如果松开鼠标右键,Ctrl 会松开。
但是,代码有问题,因为它原样大大降低了我的电脑速度。
因为您希望 Ctrl 键在释放鼠标右键时立即释放,所以您真的不应该使用Sleep()
在按下鼠标按钮时在每次循环迭代中暂停整个 1 秒/3 秒间隔,否则您可能会在松开鼠标按钮后最多延迟 4 秒才能再次执行任何操作。
我会为这样的事情使用状态机,例如:
#include <windows.h>
void keyPress(WORD keyCode)
{
INPUT input;
input.type = INPUT_KEYBOARD;
input.ki.wScan = keyCode;
input.ki.dwFlags = KEYEVENTF_SCANCODE;
SendInput(1, &input, sizeof(INPUT));
}
void keyRelease(WORD keyCode)
{
INPUT input;
input.type = INPUT_KEYBOARD;
input.ki.wScan = keyCode;
input.ki.dwFlags = KEYEVENTF_SCANCODE | KEYEVENTF_KEYUP;
SendInput(1, &input, sizeof(INPUT));
}
enum myKeyState { IsUp, IsDown, WaitingForPress };
void CtrlPress()
{
myKeyState state = IsUp;
DWORD startTime = 0;
while (true)
{
if (GetAsyncKeyState(VK_RBUTTON) < 0) {
switch (state) {
case IsUp:
startTime = GetTickCount();
state = WaitingForPress;
break;
case IsDown:
if ((GetTickCount() - startTime) >= 3000) {
keyRelease(0x1D);
startTime = GetTickCount();
state = WaitingForPress;
}
break;
case WaitingForPress:
if ((GetTickCount() - startTime) >= 1000) {
keyPress(0x1D);
startTime = GetTickCount();
state = IsDown;
}
break;
}
}
else {
if (state == IsDown) {
keyRelease(0x1D);
state = IsUp;
}
}
Sleep(0); // to avoid CPU throttling
}
}
int main() {
CtrlPress();
}
也就是说,与其使用 GetAsyncKeyState()
来 定期轮询 鼠标状态,我建议您使用 OS 来 通知 当鼠标状态改变时。在控制台应用程序中,您可以使用 SetWindowsHookEx()
为此目的安装 WH_MOUSE
或 WH_MOUSE_LL
挂钩。
我希望在这段代码中得到一些帮助。
#include <windows.h>
#include <thread>
void keyPress(WORD keyCode)
{
INPUT input;
input.type = INPUT_KEYBOARD;
input.ki.wScan = keyCode;
input.ki.dwFlags = KEYEVENTF_SCANCODE;
SendInput(1, &input, sizeof(INPUT));
}
void keyRelease(WORD keyCode)
{
INPUT input;
input.type = INPUT_KEYBOARD;
input.ki.wScan = keyCode;
input.ki.dwFlags = KEYEVENTF_SCANCODE | KEYEVENTF_KEYUP;
SendInput(1, &input, sizeof(INPUT));
}
void CtrlPress()
{
while (true)
{
if (GetAsyncKeyState(VK_RBUTTON)) {
Sleep(1000);
keyPress(0x1D);
Sleep(3000);
keyRelease(0x1D);
}
else {
keyRelease(0x1D);;
}
}
}
int main() {
CtrlPress();
}
本质上,我想让它做的是在我按下鼠标右键后按Ctrl 1000ms,然后按住3000ms,然后松开,然后只要按住鼠标右键就可以循环。我还希望循环立即停止,如果松开鼠标右键,Ctrl 会松开。
但是,代码有问题,因为它原样大大降低了我的电脑速度。
因为您希望 Ctrl 键在释放鼠标右键时立即释放,所以您真的不应该使用Sleep()
在按下鼠标按钮时在每次循环迭代中暂停整个 1 秒/3 秒间隔,否则您可能会在松开鼠标按钮后最多延迟 4 秒才能再次执行任何操作。
我会为这样的事情使用状态机,例如:
#include <windows.h>
void keyPress(WORD keyCode)
{
INPUT input;
input.type = INPUT_KEYBOARD;
input.ki.wScan = keyCode;
input.ki.dwFlags = KEYEVENTF_SCANCODE;
SendInput(1, &input, sizeof(INPUT));
}
void keyRelease(WORD keyCode)
{
INPUT input;
input.type = INPUT_KEYBOARD;
input.ki.wScan = keyCode;
input.ki.dwFlags = KEYEVENTF_SCANCODE | KEYEVENTF_KEYUP;
SendInput(1, &input, sizeof(INPUT));
}
enum myKeyState { IsUp, IsDown, WaitingForPress };
void CtrlPress()
{
myKeyState state = IsUp;
DWORD startTime = 0;
while (true)
{
if (GetAsyncKeyState(VK_RBUTTON) < 0) {
switch (state) {
case IsUp:
startTime = GetTickCount();
state = WaitingForPress;
break;
case IsDown:
if ((GetTickCount() - startTime) >= 3000) {
keyRelease(0x1D);
startTime = GetTickCount();
state = WaitingForPress;
}
break;
case WaitingForPress:
if ((GetTickCount() - startTime) >= 1000) {
keyPress(0x1D);
startTime = GetTickCount();
state = IsDown;
}
break;
}
}
else {
if (state == IsDown) {
keyRelease(0x1D);
state = IsUp;
}
}
Sleep(0); // to avoid CPU throttling
}
}
int main() {
CtrlPress();
}
也就是说,与其使用 GetAsyncKeyState()
来 定期轮询 鼠标状态,我建议您使用 OS 来 通知 当鼠标状态改变时。在控制台应用程序中,您可以使用 SetWindowsHookEx()
为此目的安装 WH_MOUSE
或 WH_MOUSE_LL
挂钩。