RawInputを登録すると、関数のすべての戻り値をチェックしますが、すべて正常ですが、更新すると、最初のCPUコアのパフォーマンスが低下し、正しく機能しません(「M」かどうかをチェックするとボタンを押すとメッセージボックスが作成されます。「M」を押すとトリガーされるだけでなく、何かを押すかマウスを動かすとトリガーされます。メッセージボックスが出ないので、ビープ音だけです。)これは、初期化に使用するコードです。
const ushort usageTable[] =
{
InputDeviceUsage::UsageMouse,
InputDeviceUsage::UsageKeyboard,
InputDeviceUsage::UsageGamepad,
};
const ulong flagsTable[] =
{
mouseFlags,
keyboardFlags,
hidFlags
};
const List<SystemDevices>& systemDevices = EnumerateSystemDevices();
List<String> deviceNames;
List<InputDeviceInfo> deviceInfo;
for(uint i = 0; i < systemDevices.Size(); i++)
{
deviceNames.Add(GetDeviceName(systemDevices[i].hDevice));
deviceInfo.Add(GetDeviceInfo(systemDevices[i].hDevice));
InputDevice device =
{
InputDeviceUsagePage::UsagePageHID,
usageTable[deviceInfo[i].dwType],
flagsTable[deviceInfo[i].dwType],
window
};
RegisteredDevices.Add(device);
Devices[systemDevices[i].hDevice] = CreateDevice(deviceInfo[i].dwType);
ここで、Listはstd :: vector <>と同等であり、これらはtypedefであり、関連する定義です。
enum InputDeviceUsagePage
{
UsagePageHID = 0x01
};
enum InputDeviceUsage
{
UsageMouse = 0x02,
UsageKeyboard = 0x06,
UsageGamepad = 0x04
};
enum InputDeviceType
{
TypeMouse = RIM_TYPEMOUSE,
TypeKeyboard = RIM_TYPEKEYBOARD,
TypeHID = RIM_TYPEHID
};
enum InputDeviceChangeBehavior
{
Arrival = GIDC_ARRIVAL,
Removal = GIDC_REMOVAL
};
enum InputDeviceDataRequest
{
PreparseData = RIDI_PREPARSEDDATA,
Name = RIDI_DEVICENAME,
Info = RIDI_DEVICEINFO
};
そしてこれは更新機能です:
try
{
InputData data;
RawDevice::UpdateUnbuffered(reinterpret_cast<HRAWINPUT>(lparam), &data);
DevicePtr it = Devices[data.header.hDevice];
if(it == nullptr)
{
DevicePtr newDevice = CreateDevice(data.header.dwType);
Devices.Add(data.header.hDevice, newDevice);
if(data.header.hDevice != null)
{
it = newDevice;
}
}
DevicePtr device = it;
device->Read(data);
switch(data.header.dwType)
{
case InputDeviceType::TypeMouse:
{
const RawMouse& mouse = static_cast<RawMouse&>(*device);
//TODO: add event handling here
break;
}
case InputDeviceType::TypeKeyboard:
{
const RawKeyboard& keyboard = static_cast<RawKeyboard&>(*device);
//TODO: add event handling here
break;
}
case InputDeviceType::TypeHID:
{
const RawHID& hid = static_cast<RawHID&>(*device);
//TODO: add event handling here
break;
}
default:
{
}
}
return(exit_success);
}
catch(...)
{
return(DefWindowProc(window, message, wparam, lparam));
}
たとえば、// TODOがある場所では、ここにイベント処理を追加します。
case InputDeviceType::TypeKeyboard:
{
const RawKeyboard& keyboard = static_cast<RawKeyboard&>(*device);
if(keyboard.KeyDown('M'))
{
MessageBox(window, L"Pressed key is 'M'", L"Input event", MB_OK);
}
break;
}
Mだけでなく、マウスの任意のキーまたはボタンを押すたびにビープ音が鳴り、メッセージボックスも表示されず、ウィンドウがビープ音を鳴らします。CPUコアが最大にロードされます。これがKeyDown( )関数:
const bool RawKeyboard::KeyDown(ushort key) const
{
if(_data.VKey == key && !(_data.Flags & KeyActions::KeyDown))
{
return(true);
}
{
return(false);
}
}
DevicePtrは基本的にRawDevice*であり、名前とDeviceInfoが含まれ、RawDeviceからRawMouse、RawKeyboard、RawHIDを継承します。これらのメンバーには、 _dataという名前のRAWMOUSE、RAWKEYBOARD、RAWHIDメンバーがあります。
編集:Updateが呼び出される場所を追加するだけです:
case WM_INPUT:
{
return(_input.Update(_mainWindow.GetHandle(), message, wparam, lparam));
}
break;
EDIT2:ReadUnbufferedメソッドを追加するのを忘れました:
void RawDevice::UpdateUnbuffered(const HRAWINPUT rawInput, RAWINPUT* data)
{
wint64 size(sizeof(RAWINPUT));
boolresult = GetRawInputData(rawInput, RID_INPUT, data, &size, sizeof(RAWINPUTHEADER));
if(result == false)
{
throw RawInputException(GetLastError(), L"GetRawInputData()");
}
}