我必須使用什麼才能獲得此刻在鍵盤上按下的「所有鍵」?由於Form.KeyPress += new EventHandler()
在充滿控件時並沒有多大作用。不管我做什麼,KeyDown,KeyUp或其他什麼都不叫它,是的,我知道如何使用它們。獲取所有按下的鍵
因此,如果系統中有任何功能可以檢查按下的按鍵,那麼將返回所使用的按鍵的數組或其他東西 - 我將不勝感激,指出正確的方向。
我必須使用什麼才能獲得此刻在鍵盤上按下的「所有鍵」?由於Form.KeyPress += new EventHandler()
在充滿控件時並沒有多大作用。不管我做什麼,KeyDown,KeyUp或其他什麼都不叫它,是的,我知道如何使用它們。獲取所有按下的鍵
因此,如果系統中有任何功能可以檢查按下的按鍵,那麼將返回所使用的按鍵的數組或其他東西 - 我將不勝感激,指出正確的方向。
這聽起來像你想查詢鍵盤中所有鍵的狀態。造成這種情況的最好的功能是Win32 API調用GetKeyboardState
我不相信存在着功能的一個很好的管理等同。它的PInvoke的代碼是相當直截了當
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool GetKeyboardState(byte [] lpKeyState);
var array = new byte[256];
GetKeyboardState(array);
這將填充byte[]
與系統中的每個虛擬鍵的上/下狀態。如果高位被設置,則虛擬鍵當前被按下。將Key
映射到虛擬鍵碼是通過僅考慮數字Key
值的byte
部分來完成的。
public static byte GetVirtualKeyCode(Key key) {
int value = (int)key;
return (byte)(value & 0xFF);
}
上述工程大部分Key
值的,但你必須要小心修飾鍵。值Keys.Alt
,Keys.Control
和Keys.Shift
在這裏不起作用,因爲它們在技術上是修飾符而不是關鍵值。要使用修改器,你需要使用實際的相關鍵值Keys.ControlKey
,Keys.LShiftKey
,等...(真的沒有什麼東西,與主要結束)
所以,檢查如果特定的鍵設置可以做如下
var code = GetVirtualKeyCode(Key.A);
if ((array[code] & 0x80) != 0) {
// It's pressed
} else {
// It's not pressed
}
我相信你正在尋找PreviewKeyDown事件,如果在表單有焦點的時候按下了一個鍵,即使當前表單中有另一個子控件有焦點,它也會觸發。
如果您只需要知道應用程序處於活動狀態時的所有按鍵,無論您的應用程序中哪個控件具有焦點,就可以使用表單的KeyPreview
屬性。
只需將屬性設置爲true並訂閱表上所需的Key事件即可。現在,在將應用程序轉發到具體控件之前,您將收到所有擊鍵,允許您對自己做出反應並取消向控件的轉發,將Cancel
屬性設置爲true。
如果您需要在應用程序不是活動應用程序時收到按下的按鍵,則需要某種低級別鍵盤掛鉤。我沒有測試,但this article on CodeProject看起來相當有希望的這種情況。
我已經在JaredPar的答案上擴展了一點點。下面的方法返回當前正在按下所有鍵的集合:
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Windows.Input;
private static readonly byte[] DistinctVirtualKeys = Enumerable
.Range(0, 256)
.Select(KeyInterop.KeyFromVirtualKey)
.Where(item => item != Key.None)
.Distinct()
.Select(item => (byte)KeyInterop.VirtualKeyFromKey(item))
.ToArray();
/// <summary>
/// Gets all keys that are currently in the down state.
/// </summary>
/// <returns>
/// A collection of all keys that are currently in the down state.
/// </returns>
public IEnumerable<Key> GetDownKeys()
{
var keyboardState = new byte[256];
GetKeyboardState(keyboardState);
var downKeys = new List<Key>();
for (var index = 0; index < DistinctVirtualKeys.Length; index++)
{
var virtualKey = DistinctVirtualKeys[index];
if ((keyboardState[virtualKey] & 0x80) != 0)
{
downKeys.Add(KeyInterop.KeyFromVirtualKey(virtualKey));
}
}
return downKeys;
}
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool GetKeyboardState(byte[] keyState);
我很難翻譯VB.Net中的DistinctVirtualKeys分配。你可以更好地評論它,也可以得到錯誤,沒有'.Select(KeyInterop.KeyFromVirtualKey)'的參數嗎? – beppe9000
你想,當你運行一段特定的代碼的所有按鍵按下,或者你想在你按下鍵時發生的事件? – zimdanen
可能的重複[在winforms中實現鍵盤快捷鍵?](http://stackoverflow.com/questions/400113/best-way-to-implement-keyboard-shortcuts-in-winforms) –
說我想要MouseWheel的事件處理程序,但我希望在執行EventHandler中的某些內容時按下「Ctrl」鍵。所以如果我滾動滾輪,我只能得到鼠標滾輪的結果,而不是按鍵。 – Deukalion