win32函数实现windows热键


首先实现一个热键处理的类,内部调用win32API实现热键的基本操作


using System;
using System.Collections;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace xxx
{
    public delegate void HotkeyEventHandler(int hotKeyID);

    public class HotkeyHelper : IMessageFilter
    {
        public event HotkeyEventHandler OnHotkey;

        public enum KeyFlags
        {
            MOD_NONE = 0x0,
            MOD_ALT = 0x1,
            MOD_CONTROL = 0x2,
            MOD_SHIFT = 0x4,
            MOD_WIN = 0x8
        }

        private class NativeMethods
        {
            private NativeMethods()
            {
            }

            #region WIN32 API

            /// 
            /// 如果函数执行成功,返回值不为0。
            /// 如果函数执行失败,返回值为0。要得到扩展错误信息,调用GetLastError。.NET方法:Marshal.GetLastWin32Error()
            /// 
            /// 要定义热键的窗口的句柄
            /// 定义热键ID(不能与其它ID重复) 
            /// 标识热键是否在按Alt、Ctrl、Shift、Windows等键时才会生效
            /// 定义热键的内容,WinForm中可以使用Keys枚举转换,
            /// WPF中Key枚举是不正确的,应该使用System.Windows.Forms.Keys枚举,或者自定义正确的枚举或int常量
            /// 
            [DllImport("user32.dll", SetLastError = true)]
            public static extern bool RegisterHotKey(
            IntPtr hWnd,
            UInt32 id,
            UInt32 fsModifiers,
            UInt32 vk
            );

            /// 
            /// 取消注册热键
            /// 
            /// 要取消热键的窗口的句柄
            /// 要取消热键的ID
            /// 
            [DllImport("user32.dll", SetLastError = true)]
            public static extern bool UnregisterHotKey(
            IntPtr hWnd,
            UInt32 id
            );

            /// 
            /// 向全局原子表添加一个字符串,并返回这个字符串的唯一标识符,成功则返回值为新创建的原子ID,失败返回0
            /// 
            /// 
            /// 
            [DllImport("kernel32", SetLastError = true)]
            public static extern UInt32 GlobalAddAtom(string lpString);

            /// 
            /// 从全局原子表删除指定一个字符串,并返回这个字符串的唯一标识符,失败返回0
            /// 
            /// 
            /// 
            [DllImport("kernel32", SetLastError = true)]
            public static extern UInt32 GlobalDeleteAtom(UInt32 nAtom);

            /// 
            /// 定义了辅助键的名称(将数字转变为字符以便于记忆,也可去除此枚举而直接使用数值)
            /// 
            public enum KeyFlags
            {
                MOD_NONE = 0x0,
                MOD_ALT = 0x1,
                MOD_CONTROL = 0x2,
                MOD_SHIFT = 0x4,
                MOD_WIN = 0x8
            }

            #endregion WIN32 API
        }

        private Hashtable keyIDs = new Hashtable();
        private IntPtr hWnd;

        public HotkeyHelper(IntPtr hWnd)
        {
            this.hWnd = hWnd;
            Application.AddMessageFilter(this);
        }

        public UInt32 RegisterHotkey(Keys Key, KeyFlags keyflags)
        {
            if (keyIDs.Contains(Key))
                return (UInt32)keyIDs[Key];
            UInt32 hotkeyid = NativeMethods.GlobalAddAtom(System.Guid.NewGuid().ToString());
            NativeMethods.RegisterHotKey((IntPtr)hWnd, hotkeyid, (UInt32)keyflags, (UInt32)Key);
            keyIDs.Add(Key, hotkeyid);
            return (UInt32)hotkeyid;
        }

        public void UnregisterHotkeys()
        {
            //Application.RemoveMessageFilter(this);
            foreach (UInt32 key in keyIDs.Values)
            {
                NativeMethods.UnregisterHotKey(hWnd, key);
                NativeMethods.GlobalDeleteAtom(key);
            }
            keyIDs.Clear();
        }

        public bool PreFilterMessage(ref Message m)
        {
            if (m.Msg == 0x312)
            {
                if (OnHotkey != null)
                {
                    foreach (UInt32 key in keyIDs.Values)
                    {
                        if ((UInt32)m.WParam == key)
                        {
                            OnHotkey((int)m.WParam);
                            return true;
                        }
                    }
                }
            }
            return false;
        }
    }
}

调用时候,先注册所需要的键值

UInt32 FlagHotKey = HotkeyHelper.RegisterHotkey(Keys.T, HotkeyHelper.KeyFlags.MOD_SHIFT);

在窗口的构造函数或load方法中注册热键处理函数

HotkeyHelper.OnHotkey += new HotkeyEventHandler(OnHotkey);

        private void OnHotkey(int hotkeyID)
        {
            if (hotkeyID == FlagHotKey)
            {
                //do sth
            }
        }

参考http://blog.csdn.net/testcs_dn/article/details/25050233