(Windows C ++)如何模拟FPS游戏中的鼠标移动?

时间:2020-07-15 17:58:10

标签: c++ windows winapi

我正在尝试模拟FPS游戏中的鼠标移动,更具体地说,是 Valorant 。我知道 SetCursorPos()函数和mouse_event()函数都可以很好地用于更改光标的位置。这在使用不断使光标居中的技术的FPS游戏中有效,但是 Valorant 似乎没有做到这一点。我编写了一个程序来不断检查光标的位置(使用GetCursorPos()),并且光标永远不会居中,如果将鼠标移到某个角然后继续移动,则角色会一直旋转。那么, Valorant 如何在光标的位置不变的情况下感觉到我在移动鼠标,以及如何在 Valorant 中模拟并模拟鼠标的移动?< / p>

顺便说一句,不用担心-我不是在作弊,只是想在freecam中进行平稳的动作以拍摄电影。

1 个答案:

答案 0 :(得分:0)

我不确定Valorant的实现方式,但是当光标的位置不变时,我可以使用RegisterRawInputDevices来获取鼠标事件:

#include <windows.h>
#include <iostream>

using namespace std;
BOOL registerTouchpadForInput(HWND hWnd)
{
    RAWINPUTDEVICE rid;
    rid.dwFlags = RIDEV_NOLEGACY | RIDEV_INPUTSINK;
    rid.usUsagePage = 1;                            
    rid.usUsage = 2;
    rid.hwndTarget = hWnd;
    return RegisterRawInputDevices(&rid, 1, sizeof(rid));
}

static LRESULT CALLBACK NVTouch_WindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    BOOL  registrationStatus = false;
    switch (message)
    {
    case WM_CREATE:
        registrationStatus = registerTouchpadForInput(hwnd);
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    case WM_INPUT:
        printf("WM_INPUT ");
        return DefWindowProc(hwnd, message, wParam, lParam);
    default:
        return DefWindowProc(hwnd, message, wParam, lParam);
    }
    return 0;
}

int main()
{
    WNDCLASSEX wndclass = {
        sizeof(WNDCLASSEX),
        CS_DBLCLKS,
        NVTouch_WindowProc,
        0,
        0,
        GetModuleHandle(0),
        LoadIcon(0,IDI_APPLICATION),
        LoadCursor(0,IDC_ARROW),
        HBRUSH(COLOR_WINDOW + 1),
        0,
        L"myclass",
        LoadIcon(0,IDI_APPLICATION)
    };
    bool isClassRegistered = false;
    isClassRegistered = RegisterClassEx(&wndclass);
    if (isClassRegistered)
    {
        HWND window = CreateWindow(wndclass.lpszClassName, NULL, 0, 0, 0, 0, 0, HWND_MESSAGE, NULL, GetModuleHandle(0), NULL);
        if (window)
        {
            ShowWindow(window, SW_SHOWDEFAULT);
            MSG msg;
            while (GetMessage(&msg, 0, 0, 0))
            {
                TranslateMessage(&msg);
                DispatchMessage(&msg);
            }
        }
    }
}

然后,使用SendInput模拟鼠标在屏幕边框处的相对移动:

INPUT buffer;
ZeroMemory(&buffer, sizeof(buffer));
buffer.type = INPUT_MOUSE;
buffer.mi.dx = 10;
buffer.mi.dy = 10;
buffer.mi.mouseData = 0;
buffer.mi.dwFlags = MOUSEEVENTF_MOVE;
buffer.mi.time = 0;
buffer.mi.dwExtraInfo = 0;
while (1)
{
    Sleep(1000);
    SendInput(1, &buffer, sizeof(INPUT));
}
相关问题