如何实现按键触发用户自定义坐标,适配多显示器键鼠操作?
三联屏场景下动态设置热键对应坐标的实现方案
问题背景
我正在编写一款辅助工具,用于快速访问无快捷键的功能,当前通过全局热键控制鼠标移动到固定坐标并执行点击操作,核心代码如下:
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保存,之后按热键直接执行对应键鼠操作。
实现方案
核心思路
- 本地存储坐标配置:用JSON文件保存两个点击坐标,程序启动时读取配置,判断是否已完成设置。
- 坐标采集模式切换:首次触发热键且无配置时,进入采集流程,通过监听F2键获取用户指定的坐标点。
- 分支执行逻辑:有配置时直接执行键鼠操作;无配置时引导用户完成坐标采集,保存后自动执行一次操作。
完整代码示例
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
相关产品推荐
相关产品推荐

