【问题标题】:MOUSEEVENTF_MOVE doesn't move to correct coordinates in-gameMOUSEEVENTF_MOVE 没有移动到游戏中的正确坐标
【发布时间】:2023-01-30 22:04:29
【问题描述】:

感觉就像我在这里用头撞墙,所以想伸出手看看是否有一些简单的解决方案是我在发疯之前首先缺少的。

问题:

  • 我的任务是为慈善活动的旧 directx11 游戏编写 TAS。我想检测像素颜色,然后移动到该像素。我通过 OpenCV 进行像素检测,但该像素的实际移动不对齐。
  • 我找到了一个功能可以满足我的要求,但它使用一个固定的数字来尝试修改我无法在我的游戏中找到的运动。
  • 我的鼠标 dpi 不影响移动,但游戏中的灵敏度会影响。
  • 游戏不喜欢 SetCursorPos,似乎拒绝该输入。

代码:

#include <iostream>
#include <Windows.h>

using namespace std;

//Magic number defines
const float constant = 0.116f;
float mouseSensitivity = 10.0f;
float modifier = mouseSensitivity * constant;

int centerScreenX = GetSystemMetrics(SM_CXSCREEN) / 2;
int centerScreenY = GetSystemMetrics(SM_CYSCREEN) / 2;

//Move mouse to center of screen
void centerMouse() {
    SetCursorPos(centerScreenX, centerScreenY);
    cout << "Moving to center of screen at(" << centerScreenX << ", " << centerScreenY << ")" << endl;
}

//Calculates actual coordinates for mouse movement based on sensitivity and a constant.
void calibrateCoordinates(int& x, int& y)
{
    if (abs(x) < 5)
        x = 0;
    else {
        x = x - centerScreenX;
        x = (int)((float)x / modifier);
    }

    if (abs(y) < 5)
        y = 0;
    else
    {
        y = y - centerScreenY;
        y = (int)((float)y / modifier);
    }
    cout << "Coordinates needed to move by (" << x << ", " << y << ")" << endl;
}


// Moves to x,y coordinates after processed into actual coordinates based on sensitivity and a constant.
void moveTo(int x, int y)
{
    SetProcessDPIAware();
    calibrateCoordinates(x, y);
    mouse_event(MOUSEEVENTF_MOVE, x, y, 0, 0);

    //Sanity check where the mouse ended up at
    POINT p;
    if (GetCursorPos(&p))
    {
        cout << "Mouse ended up at (" << p.x << ", " << p.y << ")" << endl;
    }
}


int main() {
    while (true) {
        // Check if the F19 button is pressed
        if (GetAsyncKeyState(VK_F19) & 0x8000) {

            //Hardcoded values of pixel we need to move to. Handled automatically via OpenCV in the real code. Simplified here
            int xTo = 784;
            int yTo = 686;

            //Centers mouse to line up cursor with crosshair
            centerMouse();

            //Tries to move to coords
            moveTo(xTo, yTo);
        }
    }
    return 0;
}

输出:

在 (784, 686)[4, 20, 222, 255] 找到的匹配像素 移动到屏幕中心 (1280, 720) 移动所需的坐标 (-271, -20) 鼠标最终位于 (1009, 700)

鼠标应该在 (1012, 649) 结束,以便十字准线与我想要的像素对齐。我是否只需要继续试验以找到它适用的神奇数字?还是有更简单的方法来做到这一点?谢谢

【问题讨论】:

  • 可能您需要将您的应用构建为dpi aware
  • 请参阅 this question 以获取有关如果您不让应用程序识别 DPI 会发生什么情况以及如何更正此问题的示例。尽管该问题中的问题与您的问题不同,但如果 DPI 意识确实也是您的问题,则该问题中的信息仍可能对您有所帮助。我怀疑您的问题是 GetSystemMetrics 向您提供了虚假信息,因为该功能不支持 DPI。
  • 您可以在对 mouse_event 的调用中设置 MOUSEEVENTF_ABSOLUTE 标志。
  • mouse_event() 已弃用,请改用 SendInput()
  • 跟踪当前是否有效,没有跟踪正确的像素,但如果按下键,它是否仍在与正确像素相同的方向移动?你总是需要它去屏幕的中心吗?

标签: c++ winapi mouseevent


【解决方案1】:

GetSystemMetrics 函数不支持 DPI。请改用GetSystemMetricsForDpi 以获得正确的结果。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-03
    • 1970-01-01
    • 2012-06-02
    • 1970-01-01
    相关资源
    最近更新 更多