Не совсем вопрос, но я не знал, как / где его опубликовать.
Я искал более свежий способ захвата ввода с клавиатуры и мыши в моей программе и наткнулся на множество наполовину решения и попробуйте эту ссылку и даже загляните в документы MSDN, что привело меня в уныние. Сырая клавиатура ввода, кажется, работает, но мышь не дает ничего очевидного с помощью щелчков мыши или движения. Я собираюсь рассказать о том, как использовать dinput для sh получения входных данных. ИМХО, это лучшее, потому что у него нет задержки удержания клавиш из настроек Windows, а dinput8 включен в Windows 10 SDK. Вот упрощенная версия моей программы, которая должна объяснить, что вам нужно делать. Этот API не работает с программированием на XBox, и есть XInput для всех других типов «игровых» устройств, которые вы, возможно, должны учитывать. Для клавиатуры и мыши используйте dinput8, поскольку он все еще работает через 20 лет.
Включите заголовок dinput C: \ Program Files (x86) \ Windows Kits \ 10 \ Include \ 10.0.18362.0 \ um
#include <dinput.h>
Библиотека находится в C: \ Program Files (x86) \ Windows Kits \ 10 \ Lib \ 10.0.18362.0 \ xm или x64 в зависимости от вашей сборки.
Вам потребуется настроить обратный вызов в вашем main.exe для перечисления устройств. Хотя ваш не будет выглядеть точно так же, как мой, вы получите представление о том, что вам нужно делать. По какой-то причине я получаю четыре предмета назад; две клавиатуры и две мыши. Я должен использовать generi c названные "Keyboard" и "Mouse". Я предполагаю, что это низкоуровневые Windows имена для двух устройств.
bool CALLBACK InputEnumCallback(LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef)
{
// making instance of an object that holds the device information.
// items to note are the lpddi->guidInstance and the instance name.
CDeviceInstance* deviceInstance = new CDeviceInstance((GUID*)&lpddi->guidInstance, lpddi->tszInstanceName);
// need to save the device items to some kind of list
globalObjects->inputDevice->devices->Add(deviceInstance, deviceInstance->instanceName->GetText());
return true;
}
Затем вам нужно создать интерфейс для dinput
hr = DirectInput8Create(GetModuleHandle(nullptr), DIRECTINPUT_VERSION, IID_IDirectInput8, (void**)&dinput, nullptr);
Использовать этот ссылочный указатель перечислить подключенные устройства. Обратите внимание, что это то, что вызывает функцию обратного вызова, определенную ранее.
globalObjects->inputDevice->dinput->EnumDevices(DI8DEVCLASS_ALL, (LPDIENUMDEVICESCALLBACK)InputEnumCallback, nullptr, DIEDFL_ATTACHEDONLY);
Теперь создайте объекты мыши и клавиатуры.
// The mouse
void CMouseDevice::MakeMouse(const char* m)
{
// searching the list from the enumeration
CLinkListNode<CDeviceInstance>* lln = inputDevice->devices->Search(m);
if (lln == nullptr)
{
return;
}
// creating the device from the guidInstance
hr = inputDevice->dinput->CreateDevice(lln->element->guidInstance, &device, nullptr);
if (hr < 0)
{
errorLog->WriteError("CMouseDevice::MakeMouse::CreateDevice:%s\n", errorLog->GetComErrorMessage(hr));
return;
}
// window->hWnd is the window handle
hr = device->SetCooperativeLevel(window->hWnd, DISCL_BACKGROUND | DISCL_NONEXCLUSIVE);
if (hr < 0)
{
errorLog->WriteError("CMouseDevice::MakeMouse::SetCooperativeLevel:%s\n", errorLog->GetComErrorMessage(hr));
return;
}
hr = device->SetDataFormat(&c_dfDIMouse);
if (hr < 0)
{
errorLog->WriteError("CMouseDevice::MakeMouse::SetDataFormat:%s\n", errorLog->GetComErrorMessage(hr));
return;
}
hr = device->Acquire();
if (hr < 0)
{
errorLog->WriteError("CMouseDevice::MakeMouse::Acquire:%s\n", errorLog->GetComErrorMessage(hr));
return;
}
}
// The keyboard - same idea as the mouse
void CKeyboardDevice::MakeKeyboard(const char* dn)
{
CLinkListNode<CDeviceInstance>* lln = inputDevice->devices->Search(dn);
if (lln == nullptr)
{
return;
}
hr = inputDevice->dinput->CreateDevice(lln->element->guidInstance, &device, nullptr);
if (hr < 0)
{
errorLog->WriteError("CKeyboardDevice::MakeKeyboard::CreateDevice:%s\n", errorLog->GetComErrorMessage(hr));
return;
}
hr = device->SetCooperativeLevel(window->hWnd, DISCL_BACKGROUND | DISCL_NONEXCLUSIVE);
if (hr < 0)
{
errorLog->WriteError("CKeyboardDevice::MakeKeyboard::SetCooperativeLevel:%s\n", errorLog->GetComErrorMessage(hr));
return;
}
hr = device->SetDataFormat(&c_dfDIKeyboard);
if (hr < 0)
{
errorLog->WriteError("CKeyboardDevice::MakeKeyboard::SetDataFormat:%s\n", errorLog->GetComErrorMessage(hr));
return;
}
hr = device->Acquire();
if (hr < 0)
{
errorLog->WriteError("CKeyboardDevice::MakeKeyboard::Acquire:%s\n", errorLog->GetComErrorMessage(hr));
return;
}
}
И, наконец, вот как вы читаете мышь и клавиатуру. Поместите эти два вызова функций в верхней части основного l oop, чтобы вы могли захватить пользовательский ввод.
Мышь
// the mouse state
// the DIMOUSESTATE structure has the x,y position changes and z for the scroll wheel
// you can use x and y to help with camera rotations if you are doing 3d
hr = device->GetDeviceState(sizeof(DIMOUSESTATE), &state);
// loop through the state items to see what buttons on the mouse are down
// It will read all the buttons. There is DIMOUSESTATE2 which holds eight buttons.
for (UINT k = 0; k < CMouseDevice::BUTTON_COUNT; k++)
{
// is the mouse button down
if (state.rgbButtons[k])
{
keyMap[k]->nbr = k;
keyMap[k]->count++;
}
else
{
keyMap[k]->count = 0;
}
}
Клавиатура
// the keyboard state - KEY_COUNT = 256
hr = device->GetDeviceState(CKeyboardDevice::KEY_COUNT, &keys);
// you can loop through your keys just like the mouse buttons
for (UINT k = 0;k < CKeyboardDevice::KEY_COUNT;k++)
{
// is the key down
if (keys[k])
{
keyMap[k]->nbr = k;
keyMap[k]->count++;
}
else
{
keyMap[k]->count = 0;
}
}
Указатель на ссылку на устройство является переменной-членом в объектах моих программ, поэтому убедитесь, что они уникальны в ваших. Мышь и клавиатура являются клавишами прямого ввода, а не виртуальными клавишами, поэтому при тестировании на нажатие клавиши обязательно используйте клавишу DIK_ (клавиша прямого ввода), определенную в dinput.h
Обязательно отпустите устройства, когда закрытие основной программы.
if (device)
{
device->Release();
device = 0;
}
Вот и все для dinput, и я надеюсь, что этот пост поможет всем, кто переживает нежелательные необработанные функции ввода для мыши и клавиатуры. Большое спасибо Microsoft за сохранение API dinput8.lib все эти годы, включая Windows 10.
Happy Coding!