You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

C++游戏菜单返回后模拟点击实现求助(SendInput()用法)

如何用SendInput()模拟鼠标点击触发主菜单动画

嘿,刚好我之前做过类似的Windows平台输入模拟,来给你一步步讲清楚怎么用SendInput()实现你要的功能!

首先,先明确核心:SendInput()是Windows API里用来模拟键盘、鼠标输入的函数,完全能满足你回到主菜单后触发点击动画的需求。下面是具体的实现步骤和代码示例:

1. 前置准备

首先要确保你的代码包含Windows头文件:

#include <windows.h>

因为SendInput是Windows专属API,这个头文件是必须的。

2. 理解模拟点击的本质

一次完整的鼠标左键点击需要两个事件:左键按下左键抬起。SendInput需要把这两个事件打包成INPUT结构体数组,一次性发送给系统。

另外要注意:SendInput使用的是规范化屏幕坐标(范围0到65535),而不是我们平时用的像素坐标,所以需要把你要点击的主菜单按钮的像素坐标转换成这种规范化坐标。

3. 编写模拟点击的函数

这里我们写一个通用的函数,传入你要点击的屏幕像素坐标(x, y),就能模拟一次左键点击:

void simulateMouseClick(int x, int y) {
    // 获取屏幕分辨率,用来转换规范化坐标
    int screenWidth = GetSystemMetrics(SM_CXSCREEN);
    int screenHeight = GetSystemMetrics(SM_CYSCREEN);

    // 把像素坐标转换成规范化坐标(0-65535)
    INPUT input[2] = {0};

    // 第一个事件:鼠标移动到目标位置(确保点击位置准确)
    input[0].type = INPUT_MOUSE;
    input[0].mi.dx = (LONG)((x / (double)screenWidth) * 65535.0);
    input[0].mi.dy = (LONG)((y / (double)screenHeight) * 65535.0);
    input[0].mi.dwFlags = MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE;

    // 第二个事件:左键按下
    input[1].type = INPUT_MOUSE;
    input[1].mi.dx = (LONG)((x / (double)screenWidth) * 65535.0);
    input[1].mi.dy = (LONG)((y / (double)screenHeight) * 65535.0);
    input[1].mi.dwFlags = MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_ABSOLUTE;

    // 发送按下事件
    SendInput(2, input, sizeof(INPUT));

    // 稍微延迟一下,模拟真实点击的间隔
    Sleep(50);

    // 第三个事件:左键抬起
    INPUT releaseInput = {0};
    releaseInput.type = INPUT_MOUSE;
    releaseInput.mi.dx = (LONG)((x / (double)screenWidth) * 65535.0);
    releaseInput.mi.dy = (LONG)((y / (double)screenHeight) * 65535.0);
    releaseInput.mi.dwFlags = MOUSEEVENTF_LEFTUP | MOUSEEVENTF_ABSOLUTE;

    // 发送抬起事件
    SendInput(1, &releaseInput, sizeof(INPUT));
}

4. 结合你的游戏场景使用

假设你已经有返回按钮的处理代码,比如:

void onBackButtonClicked() {
    // 你的返回主菜单逻辑:隐藏How to play菜单,显示主菜单
    hideHowToPlayMenu();
    showMainMenu();

    // 这里添加模拟点击!
    // 替换成你主菜单上触发动画的按钮的客户端坐标(比如Play按钮的中心坐标400,300)
    POINT btnPos = {400, 300};
    // 把游戏窗口内的客户端坐标转换成屏幕坐标
    ClientToScreen(gameWindowHandle, &btnPos);

    // 确保主菜单完全渲染后再点击,加个短延迟
    Sleep(100);

    // 模拟点击
    simulateMouseClick(btnPos.x, btnPos.y);
}

这里的gameWindowHandle是你的游戏窗口句柄,你应该已经有这个变量了。

5. 注意事项

  • 权限问题:如果你的游戏是以管理员权限运行的,那么你的程序也需要以管理员权限启动,否则SendInput可能无法生效。
  • 延迟调整Sleep()的时间可以根据你的菜单动画加载速度调整,确保主菜单完全显示后再触发点击。
  • 坐标准确性:一定要确认转换后的屏幕坐标是正确的,不然点击会偏离目标位置。

这样就能完美实现你要的效果:回到主菜单后自动模拟一次点击,触发菜单的播放动画啦!

内容的提问来源于stack exchange,提问作者Javier Guerra

火山引擎 最新活动