2012-05-07 40 views
5

Tôi phải sử dụng những gì để có thể nhận được "tất cả các phím" được nhấn trên bàn phím vào lúc này? Vì Form.KeyPress += new EventHandler() không làm gì nhiều khi nó chứa đầy các điều khiển. Nó không gọi nó là bất kể tôi làm gì, KeyDown, KeyUp hay bất cứ thứ gì khác ... và vâng, tôi biết cách sử dụng chúng. Vì vậy, nếu có bất kỳ chức năng nào trong hệ thống có thể kiểm tra các phím bấm, nó sẽ trả về một mảng các phím được sử dụng hoặc một cái gì đó - tôi sẽ biết ơn khi được chỉ dẫn đúng hướng.Nhận tất cả các phím được nhấn

+1

Bạn có muốn tất cả các phím được nhấn khi bạn chạy một đoạn mã cụ thể hay bạn muốn một sự kiện xảy ra mỗi khi nhấn phím? – zimdanen

+0

có thể trùng lặp của [Cách tốt nhất để thực hiện các phím tắt trong winforms?] (Http://stackoverflow.com/questions/400113/best-way-to-implement-keyboard-shortcuts-in-winforms) –

+0

Nói rằng tôi muốn có một eventhandler cho MouseWheel, nhưng tôi muốn nhấn phím "Ctrl" khi tôi thực hiện một cái gì đó trong EventHandler. vì vậy nếu tôi di chuyển bánh xe, tôi chỉ nhận được kết quả của con lăn chuột, không phải phím bấm. – Deukalion

Trả lời

12

Có vẻ như bạn muốn truy vấn trạng thái của tất cả các phím trong bàn phím. Các chức năng tốt nhất cho điều đó là Win32 API gọi GetKeyboardState

Tôi không tin rằng có một tương đương quản lý tốt các chức năng đó. Mã PInvoke cho nó là khá thẳng về phía trước

[DllImport("user32.dll")] 
[return: MarshalAs(UnmanagedType.Bool)] 
static extern bool GetKeyboardState(byte [] lpKeyState); 

var array = new byte[256]; 
GetKeyboardState(array); 

này sẽ cư byte[] với lên/xuống trạng thái của mỗi phím ảo trong hệ thống. Nếu bit cao được đặt thì khóa ảo hiện đang được nhấn. Ánh xạ một Key tới mã khóa ảo được thực hiện bằng cách chỉ xem xét phần byte của giá trị số Key.

public static byte GetVirtualKeyCode(Key key) { 
    int value = (int)key; 
    return (byte)(value & 0xFF); 
} 

Các công trình trên cho hầu hết các Key giá trị nhưng bạn cần phải cẩn thận với các phím modifier. Các giá trị Keys.Alt, Keys.ControlKeys.Shift sẽ không hoạt động ở đây vì chúng là các công cụ sửa đổi kỹ thuật chứ không phải giá trị khóa. Để sử dụng từ bổ nghĩa bạn cần phải sử dụng các giá trị quan trọng liên quan đến thực tế Keys.ControlKey, Keys.LShiftKey, vv ... (thực sự bất cứ điều gì mà kết thúc với Key)

Vì vậy, kiểm tra nếu một phím đặc biệt được thiết lập có thể được thực hiện như sau

var code = GetVirtualKeyCode(Key.A); 
if ((array[code] & 0x80) != 0) { 
    // It's pressed 
} else { 
    // It's not pressed 
} 
+0

Nó cũng hoạt động với các phím bổ trợ, tuy nhiên bạn phải sử dụng Keys.AltKey, ShiftKey và ControlKey. –

+0

@HansPassant gọi tốt, quên những mục đó – JaredPar

+0

Vâng ... Nhưng một người chưa từng sử dụng những thứ đó trước khi nó có thể là tốt để bao gồm những không gian tên tôi cần, tại sao DllImport cho thấy màu đỏ, tại sao GetKeyboardState không phải là hư không được tìm thấy , v.v. ... Câu trả lời nửa nướng có nghĩa là tôi phải tìm kiếm thêm câu trả lời bằng không có câu trả lời. – Deukalion

0

Tôi tin rằng bạn đang tìm kiếm sự kiện PreviewKeyDown sẽ kích hoạt nếu một phím được nhấn trong khi biểu mẫu có tiêu điểm, ngay cả khi một điều khiển con khác trong biểu mẫu đó hiện có tiêu điểm.

1

Nếu bạn chỉ cần biết tất cả các lần nhấn phím khi ứng dụng của bạn đang hoạt động, bất kể điều khiển nào trong ứng dụng của bạn có tiêu điểm, bạn có thể sử dụng thuộc tính KeyPreview của biểu mẫu.

Chỉ cần đặt thuộc tính thành true và đăng ký các sự kiện chính mong muốn trên biểu mẫu. Bây giờ bạn sẽ nhận được tất cả các tổ hợp phím trong ứng dụng của bạn trước khi chúng được chuyển tiếp đến điều khiển cụ thể, cho phép bạn tự phản ứng trên nó và hủy chuyển tiếp đến điều khiển được thiết lập thuộc tính Cancel thành true.

Nếu bạn cần nhận các phím được bấm trong khi ứng dụng của bạn không phải là khóa đang hoạt động, thì bạn cần một số loại móc khóa bàn phím mức thấp. Tôi đã không kiểm tra nó, nhưng this article on CodeProject trông khá hứa hẹn cho trường hợp này.

3

Tôi đã mở rộng câu trả lời của JaredPar một chút.Phương pháp sau đây trả về bộ sưu tập của tất cả các phím hiện đang được nhấn:

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); 
+0

Tôi haviong một thời gian khó dịch việc phân bổ 'DistinctVirtualKeys' trong VB.Net. Bạn có thể nhận xét nó tốt hơn và tôi cũng nhận được lỗi rằng không có tham số cho '.Select (KeyInterop.KeyFromVirtualKey)'? – beppe9000

Các vấn đề liên quan