zoukankan      html  css  js  c++  java
  • 做了个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~
  • 相关阅读:
    XAF 有条件的对象访问权限
    XAF 顯示 UnInplace Report(設置自定義條件顯示報表,不是根據選擇ListView記錄條件顯示報表)
    XAF 如何自定义PivotGrid单元格显示文本?
    XAF 如何布局详细视图上的按钮
    XAF How to set size of a popup detail view
    XAF Delta Replication Module for Devexpress eXpressApp Framework
    XAF 帮助文档翻译 EasyTest Basics(基础)
    XAF 用户双击ListView记录时禁止显示DetailView
    XAF How to enable LayoutView mode in the GridControl in List Views
    XAF 如何实现ListView单元格批量更改?
  • 原文地址:https://www.cnblogs.com/wj/p/929026.html
Copyright © 2011-2022 走看看