Chinaunix首页 | 论坛 | 博客

idn

  • 博客访问: 46629
  • 博文数量: 22
  • 博客积分: 1400
  • 博客等级: 上尉
  • 技术积分: 180
  • 用 户 组: 普通用户
  • 注册时间: 2008-05-14 21:30
文章分类

全部博文(22)

文章存档

2010年(9)

2009年(10)

2008年(3)

我的朋友
最近访客

分类:

2010-01-15 14:35:28


C# 快捷键 设计   

  大家在C#编程过程中,可能需要特殊的快捷键,比如我按A键就需要处理A键的相应处理方法,大家会想到使用Form中的有关键建按下的消息进行过滤,比如下面的程序:   

  1. private   void  Form1_KeyDown( object  sender, KeyEventArgs e)  
  2. {  
  3. if  (Keys.A == e.KeyCode)  
  4.    {  
  5.        MessageBox.Show( "A" );  
  6.    }  
  7. }  

仅仅这样做是不行的,比如我我们的窗体有有控件并且有控件的焦点,我们还必须设置窗体属性 KeyPreview ==true才行。这样就可以解决了我们快捷键A的问题。

这样做很好的解决方案,不过我们的快捷键,做这个东西并不是这么的简单,例如我们给Button做个快捷键,那么我们就必须把程序控制代码放在主窗体中,这样做出的程序的结构都是不是很舒服。因此我们必须 想方法处理这个问题。

如果把处理快捷键消息放在各个控件之中的话,这样我们的程序就是很有简洁性,比如我们可以创建一个快捷键管理的类。我们可以使用一个委托定义,并写一个累来触发他。   

  1. public   delegate   void  KeyDown(Keys key);  
  2. public   static   class  KeyManager  
  3. {  
  4. public   static  KeyDown KeyDownEventHandler;  
  5. }  

然后在主窗体中KeyDown事件中调用委托就行了   

  1. private   void  Form1_KeyDown( object  sender, KeyEventArgs e)  
  2. {  
  3. if  (KeyManager.KeyDownEventHandler !=  null )  
  4.    {  
  5.        KeyManager.KeyDownEventHandler(e.KeyCode);  
  6.    }  
  7. }  

  然后我们在各自的自定义控件中调用使用这个委托,由于委托是多播的形式,就不用害怕。   

  1. public  partial  class  UserControl1 : UserControl  
  2. {  
  3. public  UserControl1()  
  4.   {  
  5.      InitializeComponent();  
  6.      KeyManager.KeyDownEventHandler +=  new  KeyDown(KeyDowTest);  
  7.   }  
  8.   
  9. void  KeyDowTest(Keys key)  
  10.   {  
  11.      MessageBox.Show(key.ToString());  
  12.   }  
  13. }  

这样就完成了快捷键基本功能的设计,比如我们可能还需要对委托调用需要更好的控制,我们可以使集合来处理他。当然我们也可以使用事件的处理方式。  

  1. public   delegate   void  KeyDown(KeyEventArgs e);  
  2. public   static   class  KeyManager  
  3. {  
  4. static  List list =  new  List();  
  5. private   static   event  KeyDown keyDownEventHandler;  
  6.   
  7. public   static   event  KeyDown KeyDownEventHandler  
  8.    {  
  9.        add { list.Add(value);}  
  10.        remove { list.Remove(value); }  
  11.    }  
  12.   
  13. public   static   void  KeyDown(KeyEventArgs e)  
  14.    {  
  15. if (list.Count > 0)  
  16.       {  
  17. foreach  (KeyDown keydown  in  list)  
  18.          {  
  19. if (e.Handled)   
  20.             {  
  21. return ;  
  22.             }  
  23.             keydown(e);  
  24.          }  
  25.        }  
  26.     }  
  27. }  

这样我们就可以通过list循环来控制是否需要执行下去。

      

   


在上一次我们了解到使用委托实现的威力,在我们这样做时,还不是多么好,还是存在耦合性,我们只不过把耦合性推到快捷键管理类中。所以我们我能不能使用更为简单的方法来实现快捷键,当然可以在.net中我们可以使用Application.AddMessageFilter(IMessageFilter filter)方法来增加一个线程消息过滤。这个接口只有一个方法,这个函数返回值为true标示不再交给其他处理程序处理,不要随便返回true,需要小心使用!!!!!!。   

  1. public   class  MG : IMessageFilter  
  2. {
  3.     #region IMessageFilter 成员   
  4.   
  5. public   bool  PreFilterMessage( ref  Message m)  
  6.     {  
  7. int  keyDown = 0x100;  
  8. if  (m.Msg == keyDown)  
  9.         {  
  10.             MessageBox.Show(((Keys)m.WParam).ToString());  
  11. return   true ;  
  12.         }  
  13. return   false ;  
  14.     }
  15.     #endregion   
  16. }  

然后我们在我们控件使用,这样我们就可以在控件中就实现了快捷键。   

  1. public  partial  class  UserControl1 : UserControl  
  2.    {  
  3. public  UserControl1()  
  4.        {  
  5.            InitializeComponent();  
  6.            Application.AddMessageFilter( new  MG());  
  7.        }  
  8.     }  

这里有个Message类型的参数,这个是windows消息参数,具体的内容可以查看window消息循环机制,这些消息都定义在WinUser.h头文件中 ,以WM_开头,下面是部分C++定义   

  1. #define WM_KEYFIRST                     0x0100   
  2. #define WM_KEYDOWN                      0x0100   
  3. #define WM_KEYUP                        0x0101   
  4. #define WM_CHAR                         0x0102   
  5. #define WM_DEADCHAR                     0x0103   
  6. #define WM_SYSKEYDOWN                   0x0104   
  7. #define WM_SYSKEYUP                     0x0105   
  8. #define WM_SYSCHAR                      0x0106   
  9. #define WM_SYSDEADCHAR                  0x0107   
  10. #if(_WIN32_WINNT >= 0x0501)   
  11. #define WM_UNICHAR                      0x0109   
  12. #define WM_KEYLAST                      0x0109   
  13. #define UNICODE_NOCHAR                  0xFFFF   

另外,我们还应知道虚拟键码,大家可以参考windows程序设计这本电子书,进行消息拦截     

阅读(613) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~