2012-05-07 20 views
5

इस समय कीबोर्ड पर दबाए गए "सभी कुंजी" प्राप्त करने में सक्षम होने के लिए मुझे क्या उपयोग करना होगा? चूंकि Form.KeyPress += new EventHandler() नियंत्रण से भरे होने पर बहुत कुछ नहीं करता है। यह इससे कोई फर्क नहीं पड़ता कि मैं क्या करता हूं, न तो कीडाउन, कीप या कुछ और ... और हाँ, मुझे पता है कि उनका उपयोग कैसे करें।दबाए गए सभी कुंजियां

तो, यदि सिस्टम में कोई फ़ंक्शन है जो दबाए गए कुंजी की जांच कर सकता है, जो कि चाबियाँ या कुछ चाबियों की एक सरणी देता है - मैं सही दिशा में इंगित करने के लिए आभारी रहूंगा।

+1

आप सभी चाबियाँ दबाया जब आप कोड के किसी विशिष्ट अंश चलाना चाहते हैं, या आप एक घटना जब भी कोई कुंजी दबाने होता है कि चाहते हैं कार्य करें: निम्न विधि सभी चाबियों का संग्रह है कि वर्तमान में दबाया जा रहा है देता है? – zimdanen

+0

संभव डुप्लिकेट [Winforms में कीबोर्ड शॉर्टकट को लागू करने का सबसे अच्छा तरीका?] (Http://stackoverflow.com/questions/400113/best-way-to-implement-keyboard-shortcuts-in-winforms) –

+0

कहें कि मैं चाहता हूं MouseWheel के लिए एक इवेंटहालर, लेकिन जब मैं EventHandler में कुछ निष्पादित करता हूं तो मुझे "Ctrl" कुंजी दबाया जाना चाहिए। इसलिए यदि मैं पहिया को स्क्रॉल करता हूं तो मुझे केवल मूसहेल के परिणाम मिलते हैं, कुंजीपटल नहीं। – Deukalion

उत्तर

12

ऐसा लगता है कि आप कीबोर्ड में सभी कुंजी की स्थिति से पूछना चाहते हैं। उस के लिए सबसे अच्छा समारोह 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 
} 
इस प्रकार सेट किया गया है
+0

यह संशोधक कुंजी के लिए भी काम करता है, हालांकि आपको Keys.AltKey, ShiftKey और ControlKey का उपयोग करना होगा। –

+0

@ हंसपैसेंट अच्छी कॉल, उन प्रविष्टियों के बारे में भूल गए – JaredPar

+0

हाँ ... लेकिन जिसने पहले उन चीजों का उपयोग नहीं किया है, वह मुझे शामिल करने के लिए अच्छा हो सकता है कि मुझे किस नामस्थान की आवश्यकता है, क्यों DllImport लाल दिखाता है, क्यों GetKeyboardState कहीं नहीं मिला , आदि, आदि ... आधा बेक्ड जवाब का मतलब है कि मुझे उत्तर के लिए अधिक खोजना है, कोई जवाब नहीं है। – Deukalion

0

मेरा मानना ​​है कि आप PreviewKeyDown ईवेंट की तलाश कर रहे हैं जो फॉर्म पर ध्यान केंद्रित करते समय एक कुंजी दबाए जाने पर आग लग जाएगी, भले ही उस फ़ॉर्म के भीतर एक अन्य बच्चे का नियंत्रण वर्तमान में केंद्रित हो।

1

यदि आपका आवेदन सक्रिय होने पर आपको केवल सभी कीस्ट्रोकों को जानने की आवश्यकता है, भले ही आपके आवेदन के भीतर कौन सा नियंत्रण आपके पास है, तो आप अपने फॉर्म की KeyPreview संपत्ति का उपयोग कर सकते हैं।

बस संपत्ति को सही पर सेट करें और इच्छित फॉर्म पर वांछित कुंजी ईवेंट की सदस्यता लें। अब आपको कंक्रीट कंट्रोल पर अग्रेषित करने से पहले अपने एप्लिकेशन के भीतर सभी कीस्ट्रोक प्राप्त होंगे, जिससे आप इस पर प्रतिक्रिया कर सकते हैं और नियंत्रण में इसकी अग्रेषण रद्द कर सकते हैं Cancel संपत्ति को सत्य पर सेट करना।

यदि आपका आवेदन सक्रिय नहीं है, तो आपको दबाए गए कुंजी प्राप्त करने की आवश्यकता है, तो आपको किसी प्रकार का निम्न-स्तरीय कीबोर्ड हुक चाहिए। मैंने इसका परीक्षण नहीं किया, लेकिन this article on CodeProject इस मामले के लिए काफी आशाजनक दिखता है।

3

मैंने जेरेडपार के उत्तर पर थोड़ा सा विस्तार किया है।

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

मैं VB.Net में 'DistinctVirtualKeys' असाइनमेंट का अनुवाद करने में कठिन समय लगा रहा हूं। क्या आप इसे बेहतर टिप्पणी कर सकते हैं और मुझे यह भी त्रुटि मिलती है कि 'चयन करें (KeyInterop.KeyFromVirtualKey)' के लिए कोई पैरामीटर नहीं है? – beppe9000

संबंधित मुद्दे