做了个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( 0 1 );
                    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~

你可能感兴趣的:(做了个C#的Hotkey简单封装,希望对大家有帮助)