赞
踩
某些应用,我们希望全局自定义热键。按键少了会和别的应用程序冲突,按键多了可定用户操作不变。因此我计划左手用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);
- }
通过以上代码,自定义窗体顺利弹出,而且并不会与别的程序冲突,满足了需求。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。