某天,為了給微博粉絲精靈增加個老板鍵功能,找一慣的方式,開始從網絡下手尋找: 關鍵字類似”C# 老板鍵“,一搜,一堆又一堆,然而出來的代碼,基本上都是一個樣的:
正常來說,老板鍵一般少不了:Alt+Ctrl+Shift+XX這種多組合方式,然而各類代碼就是不直接說明,也沒個提示,看來是有意隱藏,終於,還是被我發現其中的一些不為人知的隱藏屬性:
下面看一下本人修改自網絡常見的代碼:
public
delegate
void HotkeyEventHandler(
int HotKeyID);
public class SystemHotKey : System.Windows.Forms.IMessageFilter
{
List<UInt32> keyIDs = new List<UInt32>();
IntPtr hWnd;
public event HotkeyEventHandler OnHotkey;
public enum KeyFlags
{
Alt = 0x1,
Ctrl = 0x2,
Shift = 0x4,
Win = 0x8,
// 組合鍵等於值相加
Alt_Ctrl = 0x3,
Alt_Shift = 0x5,
Ctrl_Shift = 0x6,
Alt_Ctrl_Shift = 0x7
}
[DllImport( " user32.dll ")]
public static extern UInt32 RegisterHotKey(IntPtr hWnd, UInt32 id, UInt32 fsModifiers, UInt32 vk);
[DllImport( " user32.dll ")]
public static extern UInt32 UnregisterHotKey(IntPtr hWnd, UInt32 id);
[DllImport( " kernel32.dll ")]
public static extern UInt32 GlobalAddAtom(String lpString);
[DllImport( " kernel32.dll ")]
public static extern UInt32 GlobalDeleteAtom(UInt32 nAtom);
public SystemHotKey(IntPtr hWnd)
{
this.hWnd = hWnd;
}
public int RegisterHotkey(KeyFlags keyflags, System.Windows.Forms.Keys Key)
{
System.Windows.Forms.Application.AddMessageFilter( this);
UInt32 hotkeyid = GlobalAddAtom(System.Guid.NewGuid().ToString());
RegisterHotKey((IntPtr)hWnd, hotkeyid, (UInt32)keyflags, (UInt32)Key);
keyIDs.Add(hotkeyid);
return ( int)hotkeyid;
}
public void UnregisterHotkeys()
{
if (keyIDs.Count > 0)
{
System.Windows.Forms.Application.RemoveMessageFilter( this);
foreach (UInt32 key in keyIDs)
{
UnregisterHotKey(hWnd, key);
GlobalDeleteAtom(key);
}
keyIDs.Clear();
}
}
public bool PreFilterMessage( ref System.Windows.Forms.Message m)
{
if (m.Msg == 0x312)
{
if (OnHotkey != null)
{
foreach (UInt32 key in keyIDs)
{
if ((UInt32)m.WParam == key)
{
OnHotkey(( int)m.WParam);
return true;
}
}
}
}
return false;
}
}
public class SystemHotKey : System.Windows.Forms.IMessageFilter
{
List<UInt32> keyIDs = new List<UInt32>();
IntPtr hWnd;
public event HotkeyEventHandler OnHotkey;
public enum KeyFlags
{
Alt = 0x1,
Ctrl = 0x2,
Shift = 0x4,
Win = 0x8,
// 組合鍵等於值相加
Alt_Ctrl = 0x3,
Alt_Shift = 0x5,
Ctrl_Shift = 0x6,
Alt_Ctrl_Shift = 0x7
}
[DllImport( " user32.dll ")]
public static extern UInt32 RegisterHotKey(IntPtr hWnd, UInt32 id, UInt32 fsModifiers, UInt32 vk);
[DllImport( " user32.dll ")]
public static extern UInt32 UnregisterHotKey(IntPtr hWnd, UInt32 id);
[DllImport( " kernel32.dll ")]
public static extern UInt32 GlobalAddAtom(String lpString);
[DllImport( " kernel32.dll ")]
public static extern UInt32 GlobalDeleteAtom(UInt32 nAtom);
public SystemHotKey(IntPtr hWnd)
{
this.hWnd = hWnd;
}
public int RegisterHotkey(KeyFlags keyflags, System.Windows.Forms.Keys Key)
{
System.Windows.Forms.Application.AddMessageFilter( this);
UInt32 hotkeyid = GlobalAddAtom(System.Guid.NewGuid().ToString());
RegisterHotKey((IntPtr)hWnd, hotkeyid, (UInt32)keyflags, (UInt32)Key);
keyIDs.Add(hotkeyid);
return ( int)hotkeyid;
}
public void UnregisterHotkeys()
{
if (keyIDs.Count > 0)
{
System.Windows.Forms.Application.RemoveMessageFilter( this);
foreach (UInt32 key in keyIDs)
{
UnregisterHotKey(hWnd, key);
GlobalDeleteAtom(key);
}
keyIDs.Clear();
}
}
public bool PreFilterMessage( ref System.Windows.Forms.Message m)
{
if (m.Msg == 0x312)
{
if (OnHotkey != null)
{
foreach (UInt32 key in keyIDs)
{
if ((UInt32)m.WParam == key)
{
OnHotkey(( int)m.WParam);
return true;
}
}
}
}
return false;
}
}
以上有幾個要點說一下:
1:System.Windows.Forms.Application.AddMessageFilter(this);這句需要對應System.Windows.Forms.Application.RemoveMessageFilter(this);這里用完要記得取消。
由於原來的程序,只在構造函數里添加,所以取消后,再設置就會失效了,這里直接在注冊的時候給加上,取消時去掉,注意下這個效果即可。
2:熱鍵的組合:
//組合鍵等於值相加
Alt_Ctrl = 0x3,
Alt_Shift = 0x5,
Ctrl_Shift = 0x6,
Alt_Ctrl_Shift = 0x7
這個是不經意思發覺的,網上的代碼都沒有提到,估計轉的人太多了,知道的又不寫出來。
3:把Hastable變更成List<Unint32>方式。
最近事比較多,寫文都比較簡單了,大伙見諒了。