• C#的Hotkey简单封装


    本来听说winapi里面的RegisterHotKey有时候不好使,于是打算用hook键盘消息来做hook key,结果发现hook那里处理消息那里还挺麻烦,也想会不会造成系统的额外开销比较大,所以最后用RegisterHotKey来封装了一下,测试没有问题,还是可以的。(winform)
    下面的代码包括一个Textbox的处理,和一个封装了api的类。Textbox那里就是处理用户定义的热键的界面表示,比如用户按键的时候会出现"Ctrl+Alt+A"之类的,Api封装那里做了处理,只管Register好了,不用管UnRegister,当注册一个一样的Id的hotkey,会自动先UnRegister原来的,然后最后关闭窗口的时候,调用一下HotkeyHelper.Dispose()就可以了。还希望多加建议。here we go..

    Textbox部分:(Key hotkeyVk = null;)
            private void txbHotKey_KeyDown(object sender, KeyEventArgs e)
            {
                txbHotKey.Text 
    = string.Empty;

                
    if (e.Control)
                {
                    txbHotKey.Text 
    += "Ctrl+";
                }
                
    if (e.Alt)
                {
                    txbHotKey.Text 
    += "Alt+";
                }
                
    if (e.Shift)
                {
                    txbHotKey.Text 
    += "Shift+";
                }

                
    if (e.KeyCode >= Keys.A && e.KeyCode <= Keys.Z)
                {
                    
    if (e.Modifiers != Keys.None)
                    {
                        txbHotKey.Text 
    += e.KeyCode.ToString();
                        hotkeyVk 
    = e.KeyCode;
                    }
                }
                
    else if (e.KeyCode >= Keys.D0 && e.KeyCode <= Keys.D9)
                {
                    
    if (e.Modifiers != Keys.None)
                    {
                        txbHotKey.Text 
    += e.KeyCode.ToString().Remove(01);
                        hotkeyVk 
    = e.KeyCode;
                    }
                }
                
    else if (e.KeyCode >= Keys.NumPad0 && e.KeyCode <= Keys.NumPad9)
                {
                    
    if (e.Modifiers != Keys.None)
                    {
                        txbHotKey.Text 
    += e.KeyCode.ToString().Replace("Pad""");
                        hotkeyVk 
    = e.KeyCode;
                    }
                }
                
    else if (e.KeyCode >= Keys.F1 && e.KeyCode <= Keys.F12)
                {
                    txbHotKey.Text 
    += e.KeyCode.ToString();
                    hotkeyVk 
    = e.KeyCode;
                }

                e.SuppressKeyPress 
    = false;
                e.Handled 
    = true;
            }

            
    private void txbHotKey_KeyPress(object sender, KeyPressEventArgs e)
            {
                e.Handled 
    = true;
            }

            
    private void txbHotKey_KeyUp(object sender, KeyEventArgs e)
            {
                CheckHotkey();
            }

            
    void txbHotKey_LostFocus(object sender, EventArgs e)
            {
                CheckHotkey();
            }

            
    private void CheckHotkey()
            {
                
    if (txbHotKey.Text.EndsWith("+"|| txbHotKey.Text == string.Empty)
                {
                    txbHotKey.Text 
    = "";
                }
            }

            
    private void btnHotKey_Click(object sender, EventArgs e)
            {
                
    string hotkey = txbHotKey.Text.Replace("+""");
                
    if (hotkey != "" && hotkey != string.Empty)
                {
                    
    uint modifies = 0;
                    
    if (hotkey.Contains("Ctrl"))
                    {
                        modifies 
    |= HotkeyHelper.MOD_CONTROL;
                        hotkey 
    = hotkey.Replace("Ctrl""");
                    }
                    
    if (hotkey.Contains("Alt"))
                    {
                        modifies 
    |= HotkeyHelper.MOD_ALT;
                        hotkey 
    = hotkey.Replace("Alt""");
                    }
                    
    if (hotkey.Contains("Shift"))
                    {
                        modifies 
    |= HotkeyHelper.MOD_SHIFT;
                        hotkey 
    = hotkey.Replace("Shift""");
                    }
                    GameProvider.HotkeyHelper.RegisterHotKey(
    this.Handle, hotkeyId, modifies, (uint)hotkeyVk);
                }
            }

    HotkeyHelper部分:
    using System;
    using System.Collections.Generic;
    using System.Text;

    using GFSucker.Game.Utility;

    namespace GFSucker.Game.Provider
    {
        
    public class HotkeyHelper : IDisposable
        {
            
    public const int MOD_ALT = 0x1;
            
    public const int MOD_CONTROL = 0x2;
            
    public const int MOD_SHIFT = 0x4;
            
    public const int MOD_WIN = 0x8;
            
    public const int WM_HOTKEY = 0x312;

            
    private Dictionary<int, Hotkey> dicHotkeys;

            
    public HotkeyHelper()
            {
                dicHotkeys 
    = new Dictionary<int, Hotkey>();
            }

            
    public bool RegisterHotKey(IntPtr hWnd, int id, uint fsModifiers, uint vk)
            {
                
    if (dicHotkeys.ContainsKey(id))
                {
                    
    if (dicHotkeys[id].IsRegistered)
                    {
                        UnregisterHotKey(dicHotkeys[id].HWnd, id);      
    // unregister firstly
                        dicHotkeys[id].IsRegistered = false;
                    }
                    dicHotkeys[id].HWnd 
    = hWnd;                         // set the new hwnd (normally should be the same)
                }
                
    else
                {
                    dicHotkeys.Add(id, 
    new Hotkey(hWnd, false));
                }

                dicHotkeys[id].IsRegistered 
    = WinApi.RegisterHotKey(hWnd, id, fsModifiers, vk);

                
    return dicHotkeys[id].IsRegistered;
            }

            
    private bool UnregisterHotKey(IntPtr hWnd, int id)
            {
                
    return WinApi.UnregisterHotKey(hWnd, id);
            }

            
    #region Hotkey Information
            
    class Hotkey
            {
                
    public Hotkey(IntPtr hWnd, bool isRegistered)
                {
                    _HWnd 
    = hWnd;
                    _IsRegistered 
    = isRegistered;
                }

                
    private IntPtr _HWnd;

                
    public IntPtr HWnd
                {
                    
    get { return _HWnd; }
                    
    set { _HWnd = value; }
                }

                
    private bool _IsRegistered;

                
    public bool IsRegistered
                {
                    
    get { return _IsRegistered; }
                    
    set { _IsRegistered = value; }
                }
            }
            
    #endregion

            
    #region IDisposable 成员

            
    public void Dispose()
            {
                
    foreach (int id in dicHotkeys.Keys)
                {
                    
    if (dicHotkeys[id].IsRegistered)
                    {
                        UnregisterHotKey(dicHotkeys[id].HWnd, id);
                    }
                }
            }

            
    #endregion
        }
    }

    Winapi声明:
            [DllImport("user32.dll")]
            [
    return: MarshalAs(UnmanagedType.Bool)]
            
    public static extern bool RegisterHotKey(IntPtr hWnd, int id, uint fsModifiers, uint vk);

            [DllImport(
    "user32.dll")]
            [
    return: MarshalAs(UnmanagedType.Bool)]
            
    public static extern bool UnregisterHotKey(IntPtr hWnd, int id);

    Override winform窗体的WndProc:(就是接受到hotkey信息的时候,做你想做的东西)
            protected override void WndProc(ref Message m)
            {
                
    base.WndProc(ref m);

                
    if (m.Msg == HotkeyHelper.WM_HOTKEY)
                {
                    MainForm mainform 
    = this.Parent.Parent.Parent.Parent.Parent.Parent.Parent.Parent.Parent as MainForm;
                    
    if (mainform != null)
                    {
                        
    if (mainform.WindowState == FormWindowState.Minimized)
                        {
                            mainform.WindowState 
    = FormWindowState.Normal;
                        }
                        mainform.Activate();
                    }
                }
            }



    因为直接从程序中copy出来的,代码没有很多注释,不过都是非常浅显易懂的东西,名字看上去还是一目了然的,另外说一句,我觉得如果重构得比较好的代码是不需要做过多的注释的,代码本身就是注释,注释用在解释一些比较混乱的行为意图。希望对大家有帮助咯。bye~
  • 相关阅读:
    AnyVal与AnyRef
    安装Zookeeper
    Kafka
    ZooKeeper总结
    Idea中JDK为1.8,还提示Diamond types are not supported at this language level
    Hive 和 Mysql
    Spark练习代码
    响应状态码
    http简介
    csrf
  • 原文地址:https://www.cnblogs.com/inspurhaitian/p/1239194.html
Copyright © 2020-2023  润新知