C# 程序:查看 PageUp 热键消息映射表
1.程序功能说明
这个程序通过以下方式检测 PageUp 热键的消息映射:
-
枚举所有窗口:使用 EnumWindows API 函数遍历所有顶层窗口
-
检测热键占用:尝试注册各种修饰键组合的 PageUp 热键
-
如果注册失败,说明该组合已被占用
-
-
收集信息:对于被占用的热键组合,收集相关信息:
-
修饰键组合(Alt、Ctrl、Shift、Win)
-
关联窗口的标题和类名
-
所属进程的名称
-
-
显示结果:在表格中展示所有检测到的 PageUp 热键映射
2.运行结果
3.程序
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;namespace HotkeyInspector
{public partial class MainForm : Form{// 导入 Windows API 函数[DllImport("user32.dll")]public static extern bool RegisterHotKey(IntPtr hWnd, int id, uint fsModifiers, uint vk);[DllImport("user32.dll")]public static extern bool UnregisterHotKey(IntPtr hWnd, int id);[DllImport("user32.dll")]public static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint processId);[DllImport("user32.dll")]private static extern bool EnumWindows(EnumWindowsProc enumProc, IntPtr lParam);[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]private static extern int GetWindowText(IntPtr hWnd, System.Text.StringBuilder lpString, int nMaxCount);[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]private static extern int GetClassName(IntPtr hWnd, System.Text.StringBuilder lpClassName, int nMaxCount);// 常量定义private const int WM_HOTKEY = 0x0312;private const int MAX_TITLE_LENGTH = 256;private const int VK_PAGEUP = 0x21; // PageUp 键的虚拟键码private const int MOD_NONE = 0x0000;private const int MOD_ALT = 0x0001;private const int MOD_CONTROL = 0x0002;private const int MOD_SHIFT = 0x0004;private const int MOD_WIN = 0x0008;// 委托和结构private delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam);private List<HotkeyInfo> hotkeys = new List<HotkeyInfo>();private DataGridView dataGridView;private Button refreshButton;private Label statusLabel;public MainForm(){InitializeComponent();this.Text = "PageUp 热键消息映射查看器";this.Size = new Size(800, 600); // 设置窗体大小this.StartPosition = FormStartPosition.CenterScreen; // 居中显示this.Load += MainForm_Load;}private void MainForm_Load(object sender, EventArgs e){// 创建UI元素CreateUI();// 枚举所有窗口并查找热键EnumerateHotkeys();// 显示结果DisplayResults();}private void CreateUI(){// 创建状态标签statusLabel = new Label{Text = "PageUp 热键消息映射信息",Dock = DockStyle.Top,TextAlign = ContentAlignment.MiddleCenter,Height = 40,Font = new Font("Microsoft Sans Serif", 10, FontStyle.Bold),BackColor = Color.LightSteelBlue};this.Controls.Add(statusLabel);// 创建刷新按钮refreshButton = new Button{Text = "刷新",Dock = DockStyle.Bottom,Height = 40,Font = new Font("Microsoft Sans Serif", 9),BackColor = Color.LightGray};refreshButton.Click += (s, e) => {hotkeys.Clear();EnumerateHotkeys();DisplayResults();};this.Controls.Add(refreshButton);// 创建数据网格视图dataGridView = new DataGridView{Dock = DockStyle.Fill,ReadOnly = true,AllowUserToAddRows = false,AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill,BackgroundColor = SystemColors.Window,BorderStyle = BorderStyle.None,Font = new Font("Microsoft Sans Serif", 9)};// 添加列dataGridView.Columns.Add("Modifiers", "修饰键");dataGridView.Columns.Add("Key", "按键");dataGridView.Columns.Add("WindowTitle", "窗口标题");dataGridView.Columns.Add("ClassName", "窗口类名");dataGridView.Columns.Add("Process", "进程名");dataGridView.Columns.Add("HotkeyID", "热键ID");// 添加面板作为容器Panel panel = new Panel{Dock = DockStyle.Fill,Padding = new Padding(10)};panel.Controls.Add(dataGridView);this.Controls.Add(panel);panel.BringToFront();dataGridView.BringToFront();}private void EnumerateHotkeys(){hotkeys.Clear();// 枚举所有顶层窗口EnumWindows((hWnd, lParam) =>{// 跳过不可见窗口和没有标题的窗口if (!IsWindowVisible(hWnd) )return true;string title = GetWindowTitle(hWnd);if (string.IsNullOrEmpty(title)) return true;// 尝试注册一个虚拟热键来检测是否已被占用for (int mod = MOD_NONE; mod <= (MOD_ALT | MOD_CONTROL | MOD_SHIFT | MOD_WIN); mod++){// 只检测 PageUp 键if (RegisterHotKey(hWnd, 1, (uint)mod, VK_PAGEUP)){// 注册成功,说明这个组合没有被占用UnregisterHotKey(hWnd, 1);}else{// 注册失败,说明这个组合已被占用uint processId;GetWindowThreadProcessId(hWnd, out processId);string className = GetWindowClassName(hWnd);string processName = GetProcessName(processId);// 添加到热键列表hotkeys.Add(new HotkeyInfo{Modifiers = (uint)mod,Key = "PageUp",WindowHandle = hWnd,WindowTitle = title,ClassName = className,ProcessName = processName,HotkeyID = 0 // 实际ID未知});}}return true; // 继续枚举}, IntPtr.Zero);}[DllImport("user32.dll")][return: MarshalAs(UnmanagedType.Bool)]private static extern bool IsWindowVisible(IntPtr hWnd);private void DisplayResults(){dataGridView.Rows.Clear();if (hotkeys.Count == 0){dataGridView.Rows.Add("未检测到", "PageUp", "任何热键注册", "", "", "");return;}foreach (var hk in hotkeys){string modStr = ModifiersToString(hk.Modifiers);dataGridView.Rows.Add(modStr,hk.Key,hk.WindowTitle,hk.ClassName,hk.ProcessName,hk.HotkeyID.ToString());}}private string ModifiersToString(uint mod){List<string> parts = new List<string>();if ((mod & MOD_ALT) != 0) parts.Add("Alt");if ((mod & MOD_CONTROL) != 0) parts.Add("Ctrl");if ((mod & MOD_SHIFT) != 0) parts.Add("Shift");if ((mod & MOD_WIN) != 0) parts.Add("Win");if (parts.Count == 0) parts.Add("无");return string.Join(" + ", parts);}private string GetWindowTitle(IntPtr hWnd){System.Text.StringBuilder sb = new System.Text.StringBuilder(MAX_TITLE_LENGTH);GetWindowText(hWnd, sb, MAX_TITLE_LENGTH);return sb.ToString();}private string GetWindowClassName(IntPtr hWnd){System.Text.StringBuilder sb = new System.Text.StringBuilder(MAX_TITLE_LENGTH);GetClassName(hWnd, sb, MAX_TITLE_LENGTH);return sb.ToString();}private string GetProcessName(uint processId){try{if (processId == 0) return "系统进程";Process proc = Process.GetProcessById((int)processId);return $"{proc.ProcessName} (PID: {proc.Id})";}catch{return "未知进程";}}// 热键信息结构private struct HotkeyInfo{public uint Modifiers;public string Key;public IntPtr WindowHandle;public string WindowTitle;public string ClassName;public string ProcessName;public int HotkeyID;}//[STAThread]//static void Main()//{// Application.EnableVisualStyles();// Application.SetCompatibleTextRenderingDefault(false);// Application.Run(new MainForm());//}}
}