以下是使用DirectInput实时获取输入设备数据并记录时差的示例代码:

#include <dinput.h>
#include <vector>
#include <chrono>

#pragma comment(lib, "dinput8.lib")
#pragma comment(lib, "dxguid.lib")

// 定义输入设备类型
enum class InputDeviceType
{
    Keyboard,
    Mouse,
    Gamepad,
};

// 定义按键事件类型
enum class KeyEvent
{
    Pressed,
    Released,
};

// 定义操作事件类型
struct InputEvent
{
    InputDeviceType deviceType;
    int deviceId;
    KeyEvent keyEvent;
    BYTE keyCode;
    std::chrono::milliseconds time;
};

// 定义输入设备管理器类
class InputDeviceManager
{
public:
    InputDeviceManager(HWND hWnd);
    ~InputDeviceManager();

    bool Init();

    void Update();

    std::vector<InputEvent> GetEvents() const;

private:
    HWND m_hWnd;
    IDirectInput8* m_pDI;
    IDirectInputDevice8* m_pKeyboard;
    IDirectInputDevice8* m_pMouse;
    std::vector<IDirectInputDevice8*> m_gamepads;
    std::vector<InputEvent> m_events;

    void ProcessKeyboard();
    void ProcessMouse();
    void ProcessGamepad(IDirectInputDevice8* pDevice, int deviceId);
};

InputDeviceManager::InputDeviceManager(HWND hWnd)
    : m_hWnd(hWnd), m_pDI(nullptr), m_pKeyboard(nullptr), m_pMouse(nullptr)
{
}

InputDeviceManager::~InputDeviceManager()
{
    if (m_pDI)
    {
        if (m_pKeyboard)
        {
            m_pKeyboard->Unacquire();
            m_pKeyboard->Release();
        }

        if (m_pMouse)
        {
            m_pMouse->Unacquire();
            m_pMouse->Release();
        }

        for (auto pGamepad : m_gamepads)
        {
            pGamepad->Unacquire();
            pGamepad->Release();
        }

        m_pDI->Release();
    }
}

bool InputDeviceManager::Init()
{
    // 创建DirectInput对象
    HRESULT hr = DirectInput8Create(GetModuleHandle(nullptr), DIRECTINPUT_VERSION, IID_IDirectInput8, (void**)&m_pDI, nullptr);
    if (FAILED(hr))
    {
        return false;
    }

    // 创建键盘设备
    hr = m_pDI->CreateDevice(GUID_SysKeyboard, &m_pKeyboard, nullptr);
    if (FAILED(hr))
    {
        return false;
    }

    // 设置键盘数据格式
    hr = m_pKeyboard->SetDataFormat(&c_dfDIKeyboard);
    if (FAILED(hr))
    {
        return false;
    }

    // 设置键盘协作级别
    hr = m_pKeyboard->SetCooperativeLevel(m_hWnd, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE);
    if (FAILED(hr))
    {
        return false;
    }

    // 设置键盘缓冲区大小
    DIPROPDWORD dipdw;
    dipdw.diph.dwSize = sizeof(DIPROPDWORD);
    dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
    dipdw.diph.dwObj = 0;
    dipdw.diph.dwHow = DIPH_DEVICE;
    dipdw.dwData = 16;
    hr = m_pKeyboard->SetProperty(DIPROP_BUFFERSIZE, &dipdw.diph);
    if (FAILED(hr))
    {
        return false;
    }

    // 创建鼠标设备
    hr = m_pDI->CreateDevice(GUID_SysMouse, &m_pMouse, nullptr);
    if (FAILED(hr))
    {
        return false;
    }

    // 设置鼠标数据格式
    hr = m_pMouse->SetDataFormat(&c_dfDIMouse2);
    if (FAILED(hr))
    {
        return false;
    }

    // 设置鼠标协作级别
    hr = m_pMouse->SetCooperativeLevel(m_hWnd, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE);
    if (FAILED(hr))
    {
        return false;
    }

    // 设置鼠标缓冲区大小
    hr = m_pMouse->SetProperty(DIPROP_BUFFERSIZE, &dipdw.diph);
    if (FAILED(hr))
    {
        return false;
    }

    // 查找游戏手柄设备
    hr = m_pDI->EnumDevices(DI8DEVCLASS_GAMECTRL, [](LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef)
    {
        auto pThis = reinterpret_cast<InputDeviceManager*>(pvRef);

        IDirectInputDevice8* pDevice = nullptr;
        HRESULT hr = pThis->m_pDI->CreateDevice(lpddi->guidInstance, &pDevice, nullptr);
        if (FAILED(hr))
        {
            return DIENUM_CONTINUE;
        }

        hr = pDevice->SetDataFormat(&c_dfDIJoystick2);
        if (FAILED(hr))
        {
            pDevice->Release();
            return DIENUM_CONTINUE;
        }

        hr = pDevice->SetCooperativeLevel(pThis->m_hWnd, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE);
        if (FAILED(hr))
        {
            pDevice->Release();
            return DIENUM_CONTINUE;
        }

        DIPROPDWORD dipdw;
        dipdw.diph.dwSize = sizeof(DIPROPDWORD);
        dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
        dipdw.diph.dwObj = 0;
        dipdw.diph.dwHow = DIPH_DEVICE;
        dipdw.dwData = 16;
        hr = pDevice->SetProperty(DIPROP_BUFFERSIZE, &dipdw.diph);
        if (FAILED(hr))
        {
            pDevice->Release();
            return DIENUM_CONTINUE;
        }

        pThis->m_gamepads.push_back(pDevice);

        return DIENUM_CONTINUE;
    }, this, DIEDFL_ATTACHEDONLY);
    if (FAILED(hr))
    {
        return false;
    }

    return true;
}

void InputDeviceManager::Update()
{
    m_events.clear();

    ProcessKeyboard();
    ProcessMouse();

    for (size_t i = 0; i < m_gamepads.size(); i++)
    {
        ProcessGamepad(m_gamepads[i], static_cast<int>(i));
    }
}

std::vector<InputEvent> InputDeviceManager::GetEvents() const
{
    return m_events;
}

void InputDeviceManager::ProcessKeyboard()
{
    DIDEVICEOBJECTDATA rgdod[16];
    DWORD dwItems = 16;
    HRESULT hr = m_pKeyboard->GetDeviceData(sizeof(DIDEVICEOBJECTDATA), rgdod, &dwItems, 0);
    if (FAILED(hr))
    {
        hr = m_pKeyboard->Acquire();
        while (hr == DIERR_INPUTLOST)
        {
            hr = m_pKeyboard->Acquire();
        }
        return;
    }

    for (DWORD i = 0; i < dwItems; i++)
    {
        InputEvent event;
        event.deviceType = InputDeviceType::Keyboard;
        event.deviceId = 0;
        event.keyEvent = rgdod[i].dwData & 0x80 ? KeyEvent::Pressed : KeyEvent::Released;
        event.keyCode = rgdod[i].dwOfs;
        event.time = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch());
        m_events.push_back(event);
    }
}

void InputDeviceManager::ProcessMouse()
{
    DIDEVICEOBJECTDATA rgdod[16];
    DWORD dwItems = 16;
    HRESULT hr = m_pMouse->GetDeviceData(sizeof(DIDEVICEOBJECTDATA), rgdod, &dwItems, 0);
    if (FAILED(hr))
    {
        hr = m_pMouse->Acquire();
        while (hr == DIERR_INPUTLOST)
        {
            hr = m_pMouse->Acquire();
        }
        return;
    }

    for (DWORD i = 0; i < dwItems; i++)
    {
        InputEvent event;
        event.deviceType = InputDeviceType::Mouse;
        event.deviceId = 0;
        event.keyEvent = rgdod[i].dwData & 0x80 ? KeyEvent::Pressed : KeyEvent::Released;
        switch (rgdod[i].dwOfs)
        {
        case DIMOFS_BUTTON0:
            event.keyCode = 0;
            break;
        case DIMOFS_BUTTON1:
            event.keyCode = 1;
            break;
        case DIMOFS_BUTTON2:
            event.keyCode = 2;
            break;
        case DIMOFS_BUTTON3:
            event.keyCode = 3;
            break;
        case DIMOFS_BUTTON4:
            event.keyCode = 4;
            break;
        case DIMOFS_BUTTON5:
            event.keyCode = 5;
            break;
        case DIMOFS_BUTTON6:
            event.keyCode = 6;
            break;
        case DIMOFS_BUTTON7:
            event.keyCode = 7;
            break;
        case DIMOFS_X:
            event.keyCode = 8;
            break;
        case DIMOFS_Y:
            event.keyCode = 9;
            break;
        case DIMOFS_Z:
            event.keyCode = 10;
            break;
        case DIMOFS_RX:
            event.keyCode = 11;
            break;
        case DIMOFS_RY:
            event.keyCode = 12;
            break;
        case DIMOFS_RZ:
            event.keyCode = 13;
            break;
        default:
            continue;
        }
        event.time = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch());
        m_events.push_back(event);
    }
}

void InputDeviceManager::ProcessGamepad(IDirectInputDevice8* pDevice, int deviceId)
{
    DIDEVICEOBJECTDATA rgdod[16];
    DWORD dwItems = 16;
    HRESULT hr = pDevice->GetDeviceData(sizeof(DIDEVICEOBJECTDATA), rgdod, &dwItems, 0);
    if (FAILED(hr))
    {
        hr = pDevice->Acquire();
        while (hr == DIERR_INPUTLOST)
        {
            hr = pDevice->Acquire();
        }
        return;
    }

    for (DWORD i = 0; i < dwItems; i++)
    {
        InputEvent event;
        event.deviceType = InputDeviceType::Gamepad;
        event.deviceId = deviceId;
        event.keyEvent = rgdod[i].dwData & 0x80 ? KeyEvent::Pressed : KeyEvent::Released;
        switch (rgdod[i].dwOfs)
        {
        case DIJOFS_X:
            event.keyCode = 0;
            break;
        case DIJOFS_Y:
            event.keyCode = 1;
            break;
        case DIJOFS_Z:
            event.keyCode = 2;
            break;
        case DIJOFS_RX:
            event.keyCode = 3;
            break;
        case DIJOFS_RY:
            event.keyCode = 4;
            break;
        case DIJOFS_RZ:
            event.keyCode = 5;
            break;
        case DIJOFS_SLIDER(0):
            event.keyCode = 6;
            break;
        case DIJOFS_SLIDER(1):
            event.keyCode = 7;
            break;
        case DIJOFS_POV(0):
            event.keyCode = 8;
            break;
        case DIJOFS_POV(1):
            event.keyCode = 9;
            break;
        case DIJOFS_POV(2):
            event.keyCode = 10;
            break;
        case DIJOFS_POV(3):
            event.keyCode = 11;
            break;
        case DIJOFS_BUTTON0:
            event.keyCode = 12;
            break;
        case DIJOFS_BUTTON1:
            event.keyCode = 13;
            break;
        case DIJOFS_BUTTON2:
            event.keyCode = 14;
            break;
        case DIJOFS_BUTTON3:
            event.keyCode = 15;
            break;
        case DIJOFS_BUTTON4:
            event.keyCode = 16;
            break;
        case DIJOFS_BUTTON5:
            event.keyCode = 17;
            break;
        case DIJOFS_BUTTON6:
            event.keyCode = 18;
            break;
        case DIJOFS_BUTTON7:
            event.keyCode = 19;
            break;
        case DIJOFS_BUTTON8:
            event.keyCode = 20;
            break;
        case DIJOFS_BUTTON9:
            event.keyCode = 21;
            break;
        case DIJOFS_BUTTON10:
            event.keyCode = 22;
            break;
        case DIJOFS_BUTTON11:
            event.keyCode = 23;
            break;
        case DIJOFS_BUTTON12:
            event.keyCode = 24;
            break;
        case DIJOFS_BUTTON13:
            event.keyCode = 25;
            break;
        case DIJOFS_BUTTON14:
            event.keyCode = 26;
            break;
        case DIJOFS_BUTTON15:
            event.keyCode = 27;
            break;
        default:
            continue;
        }
        event.time = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch());
        m_events.push_back(event);
    }
}

// 示例程序
int main()
{
    // 创建窗口
    HWND hWnd = CreateWindow(L"STATIC", L"DirectInput Example", WS_OVERLAPPEDWINDOW, 100, 100, 800, 600, nullptr, nullptr, nullptr, nullptr);
    if (!hWnd)
    {
        return 1;
    }

    // 初始化输入设备管理器
    InputDeviceManager inputDeviceManager(hWnd);
    if (!inputDeviceManager.Init())
    {
        return 1;
    }

    // 主循环
    while (true)
    {
        // 处理消息队列
        MSG msg;
        while (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }

        // 更新输入设备状态
        inputDeviceManager.Update();

        // 获取当前的输入事件
        auto events = inputDeviceManager.GetEvents();

        // 处理输入事件
        for (const auto& event : events)
        {
            // 记录事件时差
            std::chrono::milliseconds deltaTime = event.time - m_lastTime;
            m_lastTime = event.time;

            // 处理按键事件
            if (event.deviceType == InputDeviceType::Keyboard)
            {
                if (event.keyEvent == KeyEvent::Pressed)
                {
                    // 处理按键按下事件
                }
                else if (event.keyEvent == KeyEvent::Released)
                {
                    // 处理按键释放事件
                }
            }
            else if (event.deviceType == InputDeviceType::Mouse)
            {
                if (event.keyEvent == KeyEvent::Pressed)
                {
                    // 处理鼠标按键按下事件
                }
                else if (event.keyEvent == KeyEvent::Released)
                {
                    // 处理鼠标按键释放事件
                }
            }
            else if (event.deviceType == InputDeviceType::Gamepad)
            {
                // 处理游戏手柄事件
            }
        }
    }

    return 0;
}

以上代码可以实时获取键盘、鼠标、游戏手柄的输入数据,并记录每个输入事件的时差。你可以根据具体需求,添加按键事件的处理逻辑,或者将输入事件记录下来以便后续回放模拟操作

我是想做一个使用DirectInput实时获取输入设备的数据包括操作直接的间隔时差并且记录下来 然后利用DirectInput库的模拟函数做1比1的回放模拟操作 请用C++帮忙实现一下

原文地址: https://www.cveoy.top/t/topic/delO 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录