Как сказал @ Реми Лебо, вы можете использовать SetWindowsHookEx () для обнаружения клавиши со стрелкой.
Вот пример:
#define _WIN32_WINNT 0x0400
#pragma comment( lib, "user32.lib" )
#include <Windows.h>
#include <conio.h>
#include <stdio.h>
#include <iostream>
#include <string>
using namespace std;
HHOOK hKeyboardHook;
string something1;
string something2;
string something3;
__declspec(dllexport) LRESULT CALLBACK KeyboardEvent(int nCode, WPARAM wParam, LPARAM lParam)
{
DWORD SHIFT_key = 0;
DWORD CTRL_key = 0;
DWORD ALT_key = 0;
if ((nCode == HC_ACTION) && ((wParam == WM_SYSKEYDOWN) || (wParam == WM_KEYDOWN)))
{
KBDLLHOOKSTRUCT hooked_key = *((KBDLLHOOKSTRUCT*)lParam);
DWORD dwMsg = 1;
dwMsg += hooked_key.scanCode << 16;
dwMsg += hooked_key.flags << 24;
int key = hooked_key.vkCode;
if (key == 40)
{
cout << "You pressed the Down Arrow Key" << endl;
}
}
return CallNextHookEx(hKeyboardHook, nCode, wParam, lParam);
}
void MessageLoop()
{
MSG message;
while (GetMessage(&message, NULL, 0, 0))
{
TranslateMessage(&message);
DispatchMessage(&message);
}
}
DWORD WINAPI my_HotKey(LPVOID lpParm)
{
HINSTANCE hInstance = GetModuleHandle(NULL);
if (!hInstance) hInstance = LoadLibrary((LPCSTR)lpParm);
if (!hInstance) return 1;
hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, (HOOKPROC)KeyboardEvent, hInstance, NULL);
MessageLoop();
UnhookWindowsHookEx(hKeyboardHook);
return 0;
}
int main(int argc, char** argv)
{
HANDLE hThread;
DWORD dwThread;
HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);
DWORD mode = 0;
GetConsoleMode(out, &mode);
SetConsoleMode(out, mode &~ENABLE_LINE_INPUT);
hThread = CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)my_HotKey, (LPVOID)argv[0], NULL, &dwThread);
std::cout << "Type something: " << endl;
cin >> something1 ;
std::cout << "Type something again: " << endl;
cin >> something2;
std::cout << "Type something one more time: " << endl;
cin >> something3;
/* uncomment to hide console window */
//ShowWindow(FindWindowA("ConsoleWindowClass", NULL), false);
//Used for test:
std::cout<< "----" << something1;
std::cout << "-------" << something2;
std::cout << "----------" << something3;
if (hThread) return WaitForSingleObject(hThread, INFINITE);
else return 1;
}
Отладка:
Если вы не знаете, как пользоваться крючком, обратитесь к официальной документации.
Ссылка: Использование хуков
Вам нужно создать еще один поток для размещения MessageLoop
, потому что оба входных потока MessageLoop
и cin
имеют механизмы блокировки.
Примечание: Из-за механизма кэширования самой консоли, для некоторых эффектов клавиш со стрелками, таких как ввод символов, нажатие стрелки вверх очистит символы. Пожалуйста, попробуйте сами.