0

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という名前のRAWMOUSERAWKEYBOARDRAWHIDメンバーがあります。

編集: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()");
        }
    }
4

1 に答える 1

0

メッセージ ループは、アプリケーションを更新する前に、キュー内のすべてのメッセージを処理する必要があります。

アプリに切り替える最初のメッセージをポップしているように聞こえます。msg キューを満たし、1 つのメッセージを取得し、さらにキューを満たします...要点はわかります

于 2014-03-18T18:41:27.123 に答える