大家在C#编程过程中,可能需要特殊的快捷键,比如我按A键就需要处理A键的相应处理方法,大家会想到使用Form中的有关键建按下的消息进行过滤,比如下面的程序:
private void Form1_KeyDown( object sender, KeyEventArgs e)
{
if (Keys.A == e.KeyCode)
{
MessageBox.Show( "A" );
}
}
private void Form1_KeyDown(object sender, KeyEventArgs e) { if (Keys.A == e.KeyCode) { MessageBox.Show("A"); } }
仅仅这样做是不行的,比如我我们的窗体有有控件并且有控件的焦点,我们还必须设置窗体属性 KeyPreview ==true才行。这样就可以解决了我们快捷键A的问题。
这样做很好的解决方案,不过我们的快捷键,做这个东西并不是这么的简单,例如我们给Button做个快捷键,那么我们就必须把程序控制代码放在主窗体中,这样做出的程序的结构都是不是很舒服。因此我们必须 想方法处理这个问题。
如果把处理快捷键消息放在各个控件之中的话,这样我们的程序就是很有简洁性,比如我们可以创建一个快捷键管理的类。我们可以使用一个委托定义,并写一个累来触发他。
public delegate void KeyDown(Keys key);
public static class KeyManager
{
public static KeyDown KeyDownEventHandler;
}
public delegate void KeyDown(Keys key); public static class KeyManager { public static KeyDown KeyDownEventHandler; }
然后在主窗体中KeyDown事件中调用委托就行了
private void Form1_KeyDown( object sender, KeyEventArgs e)
{
if (KeyManager.KeyDownEventHandler != null )
{
KeyManager.KeyDownEventHandler(e.KeyCode);
}
}
private void Form1_KeyDown(object sender, KeyEventArgs e){ if (KeyManager.KeyDownEventHandler != null) { KeyManager.KeyDownEventHandler(e.KeyCode); }}
然后我们在各自的自定义控件中调用使用这个委托,由于委托是多播的形式,就不用害怕。
public partial class UserControl1 : UserControl
{
public UserControl1()
{
InitializeComponent();
KeyManager.KeyDownEventHandler += new KeyDown(KeyDowTest);
}
void KeyDowTest(Keys key)
{
MessageBox.Show(key.ToString());
}
}
public partial class UserControl1 : UserControl{ public UserControl1() { InitializeComponent(); KeyManager.KeyDownEventHandler += new KeyDown(KeyDowTest); } void KeyDowTest(Keys key) { MessageBox.Show(key.ToString()); }}
这样就完成了快捷键基本功能的设计,比如我们可能还需要对委托调用需要更好的控制,我们可以使集合来处理他。当然我们也可以使用事件的处理方式。
public delegate void KeyDown(KeyEventArgs e);
public static class KeyManager
{
static List<KeyDown> list = new List<KeyDown>();
private static event KeyDown keyDownEventHandler;
public static event KeyDown KeyDownEventHandler
{
add { list.Add(value);}
remove { list.Remove(value); }
}
public static void KeyDown(KeyEventArgs e)
{
if (list.Count > 0)
{
foreach (KeyDown keydown in list)
{
if (e.Handled)
{
return ;
}
keydown(e);
}
}
}
}
public delegate void KeyDown(KeyEventArgs e);public static class KeyManager{ static List<KeyDown> list = new List<KeyDown>(); private static event KeyDown keyDownEventHandler; public static event KeyDown KeyDownEventHandler { add { list.Add(value);} remove { list.Remove(value); } } public static void KeyDown(KeyEventArgs e) { if(list.Count > 0) { foreach (KeyDown keydown in list) { if(e.Handled) { return; } keydown(e); } } }}
这样我们就可以通过list循环来控制是否需要执行下去。
在上一次我们了解到使用委托实现的威力,在我们这样做时,还不是多么好,还是存在耦合性,我们只不过把耦合性推到快捷键管理类中。所以我们我能不能使用更为简单的方法来实现快捷键,当然可以在.net中我们可以使用Application.AddMessageFilter(IMessageFilter filter)方法来增加一个线程消息过滤。这个接口只有一个方法,这个函数返回值为true标示不再交给其他处理程序处理,不要随便返回true,需要小心使用!!!!!!。
public class MG : IMessageFilter
{
#region IMessageFilter 成员
public bool PreFilterMessage( ref Message m)
{
int keyDown = 0x100;
if (m.Msg == keyDown)
{
MessageBox.Show(((Keys)m.WParam).ToString());
return true ;
}
return false ;
}
#endregion
}
public class MG : IMessageFilter { #region IMessageFilter 成员 public bool PreFilterMessage(ref Message m) { int keyDown = 0x100; if (m.Msg == keyDown) { MessageBox.Show(((Keys)m.WParam).ToString()); return true; } return false; } #endregion }
然后我们在我们控件使用,这样我们就可以在控件中就实现了快捷键。
public partial class UserControl1 : UserControl
{
public UserControl1()
{
InitializeComponent();
Application.AddMessageFilter( new MG());
}
}
public partial class UserControl1 : UserControl { public UserControl1() { InitializeComponent(); Application.AddMessageFilter(new MG()); } }
这里有个Message类型的参数,这个是windows消息参数,具体的内容可以查看window消息循环机制,这些消息都定义在WinUser.h头文件中 ,以WM_开头,下面是部分C++定义
#define WM_KEYFIRST 0x0100
#define WM_KEYDOWN 0x0100
#define WM_KEYUP 0x0101
#define WM_CHAR 0x0102
#define WM_DEADCHAR 0x0103
#define WM_SYSKEYDOWN 0x0104
#define WM_SYSKEYUP 0x0105
#define WM_SYSCHAR 0x0106
#define WM_SYSDEADCHAR 0x0107
#if(_WIN32_WINNT >= 0x0501)
#define WM_UNICHAR 0x0109
#define WM_KEYLAST 0x0109
#define UNICODE_NOCHAR 0xFFFF
#define WM_KEYFIRST 0x0100#define WM_KEYDOWN 0x0100#define WM_KEYUP 0x0101#define WM_CHAR 0x0102#define WM_DEADCHAR 0x0103#define WM_SYSKEYDOWN 0x0104#define WM_SYSKEYUP 0x0105#define WM_SYSCHAR 0x0106#define WM_SYSDEADCHAR 0x0107#if(_WIN32_WINNT >= 0x0501)#define WM_UNICHAR 0x0109#define WM_KEYLAST 0x0109#define UNICODE_NOCHAR 0xFFFF
另外,我们还应知道虚拟键码,大家可以参考windows程序设计这本电子书,进行消息拦截
本文来自CSDN博客,转载请标明出处:http://blog.chinaunix.net/u2/69195/showart_2149928.html