C全局响应Ctrl+Alt+鼠标右键

科技玩点原始事 2024-02-21 05:19:36
一、简述

某些应用,我们希望全局自定义热键。按键少了会和别的应用程序冲突,按键多了可定用户操作不便。因此我计划左手用Ctrl+Alt,右手用鼠标右键呼出我自定义的菜单。

我使用键盘和鼠标事件进行简单测试(Ctrl+鼠标右键),发现并不能成功。

RegisterHotKey(hWnd, HOTKEY_ID, (int)Modifiers.Control, (int)Keys.RButton);

因此只好使用“钩子”。

二、添加引用

using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Runtime.InteropServices;using System.Text;using System.Threading.Tasks;using System.Windows.Forms;using System.Diagnostics;

三、定义变量

private const int WH_MOUSE_LL = 14;private const int WM_RBUTTONDOWN = 0x0204;private const int VK_CONTROL = 0x11;private const int VK_MENU = 0x12;private HookProc mouseProc;private IntPtr hookId = IntPtr.Zero;public event EventHandler HotkeyPressed;

四、编写过程

private IntPtr SetMouseHook(HookProc proc){ using (Process curProcess = Process.GetCurrentProcess()) using (ProcessModule curModule = curProcess.MainModule) { return SetWindowsHookEx(WH_MOUSE_LL, proc, GetModuleHandle(curModule.ModuleName), 0); }}private IntPtr MouseHookCallback(int nCode, IntPtr wParam, IntPtr lParam){ if (nCode >= 0 && wParam == (IntPtr)WM_RBUTTONDOWN) { int ctrl_keyState = GetAsyncKeyState(VK_CONTROL); int alt_keyState = GetAsyncKeyState(VK_MENU); // 检查Ctrl键和Alt键是否同时按下 if ((ctrl_keyState < 0) & (alt_keyState < 0)) { HotkeyPressed?.Invoke(this, EventArgs.Empty); // 返回非零值以阻止事件传递给其他窗口 return new IntPtr(1); } } return CallNextHookEx(hookId, nCode, wParam, lParam);}private delegate IntPtr HookProc(int code, IntPtr wParam, IntPtr lParam);[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]private static extern IntPtr SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hMod, uint dwThreadId);[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)][return: MarshalAs(UnmanagedType.Bool)]private static extern bool UnhookWindowsHookEx(IntPtr hhk);[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]private static extern IntPtr GetModuleHandle(string lpModuleName);[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]private static extern short GetAsyncKeyState(int vKey);private void HotkeyExample_HotkeyPressed(object sender, EventArgs e){ Console.WriteLine("Ctrl+Alt+鼠标右键被按下"); // 可以执行其他操作... if (this.WindowState == FormWindowState.Minimized) { POINT M_Point = GetMousePosition(); this.WindowState = FormWindowState.Normal; } else { this.WindowState = FormWindowState.Minimized; }}

五、调用

private void Form1_Load(object sender, EventArgs e){ this.HotkeyPressed += HotkeyExample_HotkeyPressed; mouseProc = MouseHookCallback; hookId = SetMouseHook(mouseProc);}private void Form1_FormClosed(object sender, FormClosedEventArgs e){ UnhookWindowsHookEx(hookId);}

六、运行效果

通过以上代码,自定义窗体顺利弹出,而且并不会与别的程序冲突,满足了需求。

0 阅读:0

科技玩点原始事

简介:感谢大家的关注