Friday, April 29, 2011

Determine state of keyboard in non-keyboard-event method call.

Hi

In a textbox.TextChanged event I want to prevent some specific (processor intensive) functionality from executing if a key is still held down. E.g. while the user is deleting large regions of text by holding down the delete key I want to prevent the code from firing if the delete key is still held down.

I looked into Control.ModifierKeys which is the closest thing a google search kicks up, but in my specific case I want to trap if the delete or backspace key are pressed - which ModifierKeys doesn't provide.

Does anyone know how to do this? Ideally something which doesn't involve me having to track the state of keyup/keydown for each and every textbox (although if there is no other way I'll do it like that)

From stackoverflow
  • Why not handle the KeyUp event instead of handling KeyPress. That way you can always be sure that the key has already been depressed and is in the process of being... errr.. released (for lack of a better word!)

    Ash : Its an idea, but initially I'm hooking into the TextChanged event on the textbox as it copes with things like Cut & Paste and text changed programatically.
  • If your wanting to known the current keyboard state (via KeyPreview), can't you attach the event on the main form.

    Then check against the stored state from the textbox event handler.

  • Overriding Control.ProcessKeyPreview should do it.

    Ash : I've just looked into this and in this case I'd rather not have to subclass the control just for this functionality.
    leppie : And why is that an issue? If 10 lines of extra code is more bothersome than fixing your problem, then there are bigger problems...
  • In the end I've resorted to the external function GetKeyboardState

    So for future reference i'm doing something along the lines:

    [DllImport("user32.dll")] public static extern int GetKeyboardState(byte[] lpKeyState);
    
    private void myFunc()
    {
        byte[] keyboardState = new byte[255];
        int keystate = GetKeyboardState(keyboardState);
    
        if (keyboardState[(int)Keys.Back] == 128)
        {
           // backspace still pressed
           return;
        }
        else if (keyboardState[(int)Keys.Delete] == 128)
        {
           // Delete key still pressed
           return;
        }
    
        // More processor intensive code ...
    }
    

    I am not sure of the function call overhead, but I'm pretty sure it will be less than the processing the function would perform were it not there.

0 comments:

Post a Comment