大家在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