You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现按键触发用户自定义坐标,适配多显示器键鼠操作?

三联屏场景下动态设置热键对应坐标的实现方案

问题背景

我正在编写一款辅助工具,用于快速访问无快捷键的功能,当前通过全局热键控制鼠标移动到固定坐标并执行点击操作,核心代码如下:

KeyboardHook hook = new KeyboardHook();

hook.KeyPressed +=
new EventHandler<KeyPressedEventArgs>(hook_KeyPressed);

hook.RegisterHotKey(TestBox.ModifierKeys.Control, Keys.D1);

void hook_KeyPressed(object sender, KeyPressedEventArgs e)
{
    Process[] p = Process.GetProcessesByName(".......");
    if (p.Count() > 0)
        SetForegroundWindow(p[0].MainWindowHandle);
    RightMouseClick(2000,110);
    System.Threading.Thread.Sleep(200);
    LeftMouseClick(2060,120);
}

当前功能正常,但固定坐标仅适配右侧显示器,切换到左侧显示器后坐标失效。需要实现逻辑:首次按热键时检查是否已设置坐标,未设置则引导用户依次移动鼠标到两个目标点按F2保存,之后按热键直接执行对应键鼠操作。

实现方案

核心思路

  1. 本地存储坐标配置:用JSON文件保存两个点击坐标,程序启动时读取配置,判断是否已完成设置。
  2. 坐标采集模式切换:首次触发热键且无配置时,进入采集流程,通过监听F2键获取用户指定的坐标点。
  3. 分支执行逻辑:有配置时直接执行键鼠操作;无配置时引导用户完成坐标采集,保存后自动执行一次操作。

完整代码示例

using System;
using System.IO;
using System.Linq;
using System.Windows.Forms;
using System.Text.Json;

public class ClickCoordinates
{
    public int RightClickX { get; set; }
    public int RightClickY { get; set; }
    public int LeftClickX { get; set; }
    public int LeftClickY { get; set; }
    public bool IsConfigured { get; set; } = false;
}

public class YourToolClass
{
    private ClickCoordinates _coords;
    private int _collectStep = 0; // 0:未开始采集 1:采集右键点 2:采集左键点
    private const string ConfigFilePath = "click_coords_config.json";

    public YourToolClass()
    {
        // 初始化配置
        if (File.Exists(ConfigFilePath))
        {
            string configJson = File.ReadAllText(ConfigFilePath);
            _coords = JsonSerializer.Deserialize<ClickCoordinates>(configJson);
        }
        else
        {
            _coords = new ClickCoordinates();
        }

        // 注册全局热键
        KeyboardHook hook = new KeyboardHook();
        hook.KeyPressed += Hook_KeyPressed;
        hook.RegisterHotKey(TestBox.ModifierKeys.Control, Keys.D1);
        hook.RegisterHotKey(ModifierKeys.None, Keys.F2); // 注册F2用于坐标采集
    }

    private void Hook_KeyPressed(object sender, KeyPressedEventArgs e)
    {
        // 原热键触发逻辑
        if (e.Modifier == TestBox.ModifierKeys.Control && e.Key == Keys.D1)
        {
            if (_coords.IsConfigured)
            {
                ExecuteClickOperations();
            }
            else
            {
                MessageBox.Show("请将鼠标移至第一个右键点击位置,按F2确认");
                _collectStep = 1;
            }
        }
        // F2采集坐标逻辑
        else if (e.Modifier == ModifierKeys.None && e.Key == Keys.F2 && _collectStep > 0)
        {
            Point currentMousePos = Cursor.Position;
            if (_collectStep == 1)
            {
                _coords.RightClickX = currentMousePos.X;
                _coords.RightClickY = currentMousePos.Y;
                MessageBox.Show("第一个点已保存,请移至第二个左键点击位置,按F2确认");
                _collectStep = 2;
            }
            else if (_collectStep == 2)
            {
                _coords.LeftClickX = currentMousePos.X;
                _coords.LeftClickY = currentMousePos.Y;
                _coords.IsConfigured = true;
                
                // 保存配置到本地文件
                string saveJson = JsonSerializer.Serialize(_coords);
                File.WriteAllText(ConfigFilePath, saveJson);
                
                MessageBox.Show("坐标配置完成,即将执行操作");
                _collectStep = 0;
                ExecuteClickOperations();
            }
        }
    }

    private void ExecuteClickOperations()
    {
        Process[] targetProcess = Process.GetProcessesByName(".......");
        if (targetProcess.Any())
            SetForegroundWindow(targetProcess[0].MainWindowHandle);
        
        RightMouseClick(_coords.RightClickX, _coords.RightClickY);
        System.Threading.Thread.Sleep(200);
        LeftMouseClick(_coords.LeftClickX, _coords.LeftClickY);
    }

    // 保留原有的鼠标点击实现方法
    private void RightMouseClick(int x, int y)
    {
        // 原右键点击逻辑代码
    }

    private void LeftMouseClick(int x, int y)
    {
        // 原左键点击逻辑代码
    }

    // 导入SetForegroundWindow的API声明(如果之前没有的话)
    [System.Runtime.InteropServices.DllImport("user32.dll")]
    private static extern bool SetForegroundWindow(IntPtr hWnd);
}

关键细节说明

  • 配置持久化:使用JSON文件存储坐标,程序重启后无需重复采集,适配多显示器切换场景。
  • 采集流程控制:通过_collectStep变量跟踪采集进度,分步引导用户完成两个坐标点的设置。
  • 全局键监听:同时注册原功能热键和F2采集键,确保采集操作能在任意窗口触发。

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 13:35:19