zoukankan      html  css  js  c++  java
  • 在WPF中如何注册热键(转)

     

    WPF注册热键大荟萃

     

    源码下载:http://www.cnblogs.com/dabaopku/archive/2010/02/22/1671267.html

     

    研究了一晚上,终于搞定了啦~~~~~

    首先完整复制下面的第一篇文章中的代码

      

    然后以下代码是

      

    private void Register(object sender, RoutedEventArgs e)
     {
    IntPtr handle=new WindowInteropHelper(this).Handle;
    int id = 1000;
    bool r=HotKey.RegisterHotKey(handle, id,(uint)HotKey.KeyFlags.MOD_CONTROL, (uint)System.Windows.Forms.Keys.F12);
     MessageBox.Show(r.ToString()+" "+handle.ToString()+" ");
    HotKey.InstallHotKeyHook(this);
    }

    其中Id随意取值,好像都没有问题

      

    一直受第三篇文章干扰(说实在的,确实让人恼火,它的RegisterHotkey(Keys Key, KeyFlags keyflags)

     


    明明是Key在前 keyflags在后,可是带入APi的

     

    结底还是自己不够细心,足足浪费了半小时,郁闷!)

    RegisterHotKey后却是反过来的,结果我也跟着他的弄反了control和F12,归根

      

    然后反注册就很简单了,唉,累死了~~

     

     

     

    在WPF中如何注册热键

    来源:http://www.cnblogs.com/zengezenge/archive/2009/07/09/1519582.html

    不说废话,直接看代码吧,其关键就是 System.Windows.Interop.HwndSource类。

    第一步:注册热键,需要使用API函数,具体的参照网上的其它文章。唯一需要注意的是需要使用KeyInterop.VirtualKeyFromKey函数将

    WPF的Key枚举转化为API函数可以使用的VirtualKeyCode :


         /// <summary>
            
    /// 注册热键处理函数
            
    /// </summary>
            
    /// <param name="hWnd">用于处理热键消息的窗体句柄</param>
            
    /// <param name="id">热键的编号</param>
            
    /// <param name="controlKey">控制键</param>
            
    /// <param name="virtualKey">热键的虚键编码</param>
            
    /// <returns>
            
    ///     <c>true</c>:注册成功<br/>
            
    ///     <c>false</c>:注册失败
            
    /// </returns>
            
    /// <remarks></remarks>
            
    /// <history>
            
    /// [ZengE]               2009-7-8 22:28    创建
            
    /// </history>
            [System.Runtime.InteropServices.DllImport("user32")]
            
    public static extern bool RegisterHotKey(IntPtr hWnd, int id, uint controlKey, uint virtualKey);

            
    /// <summary>
            
    /// 注销指定的热键
            
    /// </summary>
            
    /// <param name="hWnd">用于处理热键消息的窗体句柄</param>
            
    /// <param name="id">要注销的热键编号</param>
            
    /// <returns>
            
    ///     <c>true</c>:注销成功<br/>
            
    ///     <c>false</c>:注销失败
            
    /// </returns>
            
    /// <remarks></remarks>
            
    /// <history>
            
    /// [ZengE]               2009-7-8 22:30    创建
            
    /// </history>
            [System.Runtime.InteropServices.DllImport("user32")]
            
    public static extern bool UnregisterHotKey(IntPtr hWnd, int id);

     第二步:注册热键处理函数,主要的难点就在这里,在.NET的WinForm程序中一般使用重写Form的WinProc方法或者注册IMessageFilter来实现的,

    但是在WPF中以上两种方式都无法获得热键消息的处理机会,除非是在WPF程序中隐藏一个常规的Form(最开始就是这么弄得,后来觉得实在是太丑陋了)


     1        /// <summary>
     2        /// 安装热键处理挂钩
     3        /// </summary>
     4        /// <param name="window">The window.</param>
     5        /// <returns>
     6        ///     <c>true</c>:安装成功<br/>
     7        ///     <c>false</c>:安装失败
     8        /// </returns>
     9        /// <value>消息源</value>
    10        /// <remarks></remarks>
    11        /// <history>
    12        /// [ZengE]               2009-7-8 23:57    创建
    13        /// </history> 

    14        public static bool InstallHotKeyHook( Window window )
    15        {
    16            //判断组件是否有效
    17            if ( null == window )
    18            {
    19                //如果无效,则直接返回
    20                return false;
    21            }

    22
    23            //获得窗体的句柄
    24            System.Windows.Interop.WindowInteropHelper helper = new System.Windows.Interop.WindowInteropHelper( window );
    25
    26            //判断窗体句柄是否有效
    27            if ( IntPtr.Zero == helper.Handle )
    28            {
    29                //如果句柄无效,则直接返回
    30                return false;
    31            }

    32
    33            //获得消息源
    34            System.Windows.Interop.HwndSource source = System.Windows.Interop.HwndSource.FromHwnd( helper.Handle );
    35
    36            //判断消息源是否有效
    37            if ( null == source )
    38            {
    39                //如果消息源无效,则直接返回
    40                return false;
    41            }

    42
    43            //挂接事件
    44            source.AddHook( HotKeyHook );
    45
    46            //返回安装成功
    47            return true;
    48        }

    49
    50        /// <summary>
    51        /// 热键处理过程
    52        /// </summary>
    53        /// <param name="hwnd">触发消息的窗口句柄</param>
    54        /// <param name="msg">要被处理的消息编号</param>
    55        /// <param name="wParam">消息参数</param>
    56        /// <param name="lParam">消息参数</param>
    57        /// <param name="handled">消息是否被处理</param>
    58        /// <returns></returns>
    59        /// <remarks></remarks>
    60        /// <history>
    61        /// [ZengE]               2009-7-8 23:54    创建
    62        /// </history> 

    63        private static IntPtr HotKeyHook( IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled )
    64        {
    65            //判断是否为热键消息
    66            if ( msg == WM_HOTKEY )
    67            {
    68
    69            }

    70
    71            //返回
    72            return IntPtr.Zero;
    73        }

    74
    75        /// <summary>
    76        /// 热键消息编号
    77        /// </summary> 

    78        private const int WM_HOTKEY = 0x0312;

     

     以上代码在Windows2008下测试通过。

     

     

     

     

     

     在c#中使用全局快捷键

    来源:http://hi.baidu.com/55csharp/blog/item/de6fef88efcebdbb0e24442f.html

    由于.net并没有提供快捷键的库,所以要使用该功能得通过api实现。

    在winapi中,注册和注销全局快捷键分别是通过RegisterHotKey和UnregisterHotKey函数实现。在c#中直接使用该api显得不够简洁,这里我提供了一个友好点的封装。

    代码如下:

        static class Hotkey
        {
            系统api#region 系统api
            [DllImport("user32.dll")]
            [return: MarshalAs(UnmanagedType.Bool)]
            static extern bool RegisterHotKey(IntPtr hWnd, int id, HotkeyModifiers fsModifiers, Keys vk);

            [DllImport("user32.dll")]
            static extern bool UnregisterHotKey(IntPtr hWnd, int id);
            #endregion

            /**//// <summary> 
            /// 注册快捷键 
            /// </summary> 
            /// <param name="hWnd">持有快捷键窗口的句柄</param> 
            /// <param name="fsModifiers">组合键</param> 
            /// <param name="vk">快捷键的虚拟键码</param> 
            /// <param name="callBack">回调函数</param> 
            public static void Regist(IntPtr hWnd, HotkeyModifiers fsModifiers, Keys vk, HotKeyCallBackHanlder callBack)
            {
                int id = keyid++;
                if (!RegisterHotKey(hWnd, id, fsModifiers, vk))
                    throw new Exception("regist hotkey fail.");
                keymap[id] = callBack;
            }

            /**//// <summary> 
            /// 注销快捷键 
            /// </summary> 
            /// <param name="hWnd">持有快捷键窗口的句柄</param> 
            /// <param name="callBack">回调函数</param> 
            public static void UnRegist(IntPtr hWnd, HotKeyCallBackHanlder callBack)
            {
                foreach (KeyValuePair<int, HotKeyCallBackHanlder> var in keymap)
                {
                    if (var.Value == callBack)
                        UnregisterHotKey(hWnd, var.Key);
                }
            }

            /**//// <summary> 
            /// 快捷键消息处理 
            /// </summary> 
            public static void ProcessHotKey(System.Windows.Forms.Message m)
            {
                if (m.Msg == WM_HOTKEY)
                {
                    int id = m.WParam.ToInt32();
                    HotKeyCallBackHanlder callback;
                    if (keymap.TryGetValue(id, out callback))
                    {
                        callback();
                    }
                }
            }

            const int WM_HOTKEY = 0x312;
            static int keyid = 10;
            static Dictionary<int, HotKeyCallBackHanlder> keymap = new Dictionary<int, HotKeyCallBackHanlder>();

            public delegate void HotKeyCallBackHanlder();
        }

        enum HotkeyModifiers
        {
            MOD_ALT = 0x1,
            MOD_CONTROL = 0x2,
            MOD_SHIFT = 0x4,
            MOD_WIN = 0x8
        }

    这里通过Hotkey类实现功能的封装,使用非常简单。下面为参考测试代码。

            void Test()
            {
                MessageBox.Show("Test");
            }

            protected override void WndProc(ref Message m)
            {
                base.WndProc(ref m);
                Hotkey.ProcessHotKey(m);
            }

            private void button1_Click(object sender, EventArgs e)
            {
                Hotkey.UnRegist(this.Handle, Test);
            }

    当程序form1启动时,注册了两个快捷键Alt+T和Ctrl+Shift+K,单击button1的时候会注销快捷键Alt+T。代码比较简单,这里就不多介绍了。

    注:快捷键是通过消息触发的,因此要重载WndProc函数,在里面添加对快捷键回调消息的处理方法Hotkey.ProcessHotKey(m)。

    C# 设置全局热键

    来源:http://www.cnblogs.com/lhking/archive/2009/03/16/1413245.html


    using System;
    using
     System.Collections.Generic;
    using
     System.ComponentModel;
    using
     System.Data;
    using
     System.Drawing;
    using
     System.Text;
    using
     System.Windows.Forms;
    using
     System.Runtime.InteropServices;
    using
     System.Collections;

    namespace
     HotKey1
    {
        
    public partial class
     Form1 : Form
        {
            
    public
     Form1()
            {
                InitializeComponent();
            }
            
    public delegate void HotkeyEventHandler(int
     HotKeyID);
            
    private int
     Hotkey1;
            
    public class
     Hotkey : System.Windows.Forms.IMessageFilter
            {
                Hashtable keyIDs 
    = new
     Hashtable();
                IntPtr hWnd;

                
    public event
     HotkeyEventHandler OnHotkey;

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

                }
                [DllImport(
    "user32.dll")]
                
    public static extern
     UInt32 RegisterHotKey(IntPtr hWnd, UInt32 id, UInt32 fsModifiers, UInt32 vk);

                [DllImport(
    "user32.dll"
    )]
                
    public static extern
     UInt32 UnregisterHotKey(IntPtr hWnd, UInt32 id);

                [DllImport(
    "kernel32.dll"
    )]
                
    public static extern
     UInt32 GlobalAddAtom(String lpString);

                [DllImport(
    "kernel32.dll"
    )]
                
    public static extern
     UInt32 GlobalDeleteAtom(UInt32 nAtom);

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

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

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

                
    public bool PreFilterMessage(ref
     System.Windows.Forms.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
    ;
                }
            }

            
    public void OnHotkey(int HotkeyID) //Ctrl+F2隐藏窗体,再按显示窗体。

            {
                
    if (HotkeyID ==
     Hotkey1)
                {
                    
    if (this.Visible == true
    )
                        
    this.Visible = false
    ;
                    
    else

                        
    this.Visible = true;
                }
                
    else

                {
                    
    this.Visible = false;
                }
            }

            
    private void Form1_Load(object
     sender, EventArgs e)
            {
                Hotkey hotkey;
                hotkey 
    = new Hotkey(this
    .Handle);
                Hotkey1 
    = hotkey.RegisterHotkey(System.Windows.Forms.Keys.F2, Hotkey.KeyFlags.MOD_CONTROL);   //定义快键(Ctrl + F2)

                hotkey.OnHotkey += new HotkeyEventHandler(OnHotkey);
            }
        }
    }

     


  • 相关阅读:
    使用uWSGI+Nginx+Supervisor部署管理Django应用程序
    Django REST framework使用ViewSets的自定义路由实现过程
    【转】nginx配置:location配置方法及实例详解
    Python模块的动态加载机制
    【转】Django中的request与response对象
    【转】Django Middleware
    【转】请求处理机制其三:view层与模板解析
    朝花夕拾
    买了台robosense的激光雷达,待开箱
    热力学量微分关系式总结+助记 Lebal:Research
  • 原文地址:https://www.cnblogs.com/dabaopku/p/1670793.html
Copyright © 2011-2022 走看看