zoukankan      html  css  js  c++  java
  • WPF获得全局窗体句柄,并响应全局键盘事件

    场景

    wpf窗体运行后,只能捕获当前Active窗体的按键事件,如果要监听windows全局事件,并对当前窗口事件响应.

    第一步:导入Winows API

        public class Win32
        {
            [DllImport("User32.Dll")]
            public static extern void SetWindowText(int h, String s);
    
            /// <summary>
            /// 如果函数执行成功,返回值不为0。
            /// 如果函数执行失败,返回值为0。要得到扩展错误信息,调用GetLastError。.NET方法:Marshal.GetLastWin32Error()
            /// </summary>
            /// <param name="hWnd">要定义热键的窗口的句柄</param>
            /// <param name="id">定义热键ID(不能与其它ID重复)  </param>
            /// <param name="fsModifiers">标识热键是否在按Alt、Ctrl、Shift、Windows等键时才会生效</param>
            /// <param name="vk">定义热键的内容,WinForm中可以使用Keys枚举转换,
            /// WPF中Key枚举是不正确的,应该使用System.Windows.Forms.Keys枚举,或者自定义正确的枚举或int常量</param>
            /// <returns></returns>
            [DllImport("user32.dll", SetLastError = true)]
            public static extern bool RegisterHotKey(
                IntPtr hWnd,
                int id,
                KeyModifiers fsModifiers,
                int vk
                );
    
            /// <summary>
            /// 取消注册热键
            /// </summary>
            /// <param name="hWnd">要取消热键的窗口的句柄</param>
            /// <param name="id">要取消热键的ID</param>
            /// <returns></returns>
            [DllImport("user32.dll", SetLastError = true)]
            public static extern bool UnregisterHotKey(
                IntPtr hWnd,
                int id
                );
    
            /// <summary>
            /// 向全局原子表添加一个字符串,并返回这个字符串的唯一标识符,成功则返回值为新创建的原子ID,失败返回0
            /// </summary>
            /// <param name="lpString"></param>
            /// <returns></returns>
            [DllImport("kernel32", SetLastError = true)]
            public static extern short GlobalAddAtom(string lpString);
    
            [DllImport("kernel32", SetLastError = true)]
            public static extern short GlobalDeleteAtom(short nAtom);
    
            /// <summary>
            /// 定义了辅助键的名称(将数字转变为字符以便于记忆,也可去除此枚举而直接使用数值)
            /// </summary>
            [Flags()]
            public enum KeyModifiers
            {
                None = 0,
                Alt = 1,
                Ctrl = 2,
                Shift = 4,
                WindowsKey = 8
            }
            /// <summary>
            /// 热键的对应的消息ID
            /// </summary>
            public const int WmHotkey = 0x312;
        }
    View Code

     第二步:注册快捷键

            /// <summary>
            /// 注册快捷集合
            /// </summary>
            readonly Dictionary<string, short> hotKeyDic = new Dictionary<string, short>();
    
            public MainWindow()
            {
                InitializeComponent();
    
                this.Loaded += (sender, e) =>
                {
                    var wpfHwnd = new WindowInteropHelper(this).Handle;
    
                    var hWndSource = HwndSource.FromHwnd(wpfHwnd);
                    //添加处理程序
                    if (hWndSource != null) hWndSource.AddHook(MainWindowProc);
    
                    hotKeyDic.Add("Alt-S", Win32.GlobalAddAtom("Alt-S"));
                    hotKeyDic.Add("Alt-D", Win32.GlobalAddAtom("Alt-D"));
                    Win32.RegisterHotKey(wpfHwnd, hotKeyDic["Alt-S"], Win32.KeyModifiers.Alt, (int)System.Windows.Forms.Keys.S);
                    Win32.RegisterHotKey(wpfHwnd, hotKeyDic["Alt-D"], Win32.KeyModifiers.Alt, (int)System.Windows.Forms.Keys.D);
                };
            }
    View Code

    第三步:响应快捷键事件

            /// <summary>
            /// 响应快捷键事件
            /// </summary>
            /// <param name="hwnd"></param>
            /// <param name="msg"></param>
            /// <param name="wParam"></param>
            /// <param name="lParam"></param>
            /// <param name="handled"></param>
            /// <returns></returns>
            private IntPtr MainWindowProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
            {
                switch (msg)
                {
                    case Win32.WmHotkey:
                        {
                            int sid = wParam.ToInt32();
                            if (sid == hotKeyDic["Alt-S"])
                            {
                                MessageBox.Show("按下Alt+S");
                            }
                            else if (sid == hotKeyDic["Alt-D"])
                            {
                                MessageBox.Show("按下Alt+D");
                            }
                            handled = true;
                            break;
                        }
                }
    
                return IntPtr.Zero;
            }
    View Code
  • 相关阅读:
    hdu 5387 Clock (模拟)
    CodeForces 300B Coach (并查集)
    hdu 3342 Legal or Not(拓扑排序)
    hdu 3853 LOOPS(概率DP)
    hdu 3076 ssworld VS DDD(概率dp)
    csu 1120 病毒(LICS 最长公共上升子序列)
    csu 1110 RMQ with Shifts (线段树单点更新)
    poj 1458 Common Subsequence(最大公共子序列)
    poj 2456 Aggressive cows (二分)
    HDU 1869 六度分离(floyd)
  • 原文地址:https://www.cnblogs.com/lizzie-xhu/p/4235936.html
Copyright © 2011-2022 走看看