Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C#
  4. Getting a list of Key pressed

Getting a list of Key pressed

Scheduled Pinned Locked Moved C#
csharpwpf
5 Posts 2 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • K Offline
    K Offline
    Kenneth Haugland
    wrote on last edited by
    #1

    I need to know the key that is currently pressed in a C# WPF application, so:

        List PressedKeys = new List();
    
        private void Window\_KeyDown(object sender, KeyEventArgs e)
        {
            //If key is pressed this stop resending
            if (!PressedKeys.Contains(e.Key))
            {
                PressedKeys.Add(e.Key);
                txtKeysDown.Text = String.Join(", ", PressedKeys);
            }
            
        }
    
        private void Window\_KeyUp(object sender, KeyEventArgs e)
        {
            PressedKeys.Remove(e.Key);
            txtKeysDown.Text = String.Join(", ", PressedKeys);
        }
    

    This works, sort of. However, it does not give me the raw input from the keyboard so when AltGr is pressed it canges from Key.RightAlt => Key.LeftCtrl + Key.RightAlt whitch is Windows interpretation according to this: AltGr key - Wikipedia[^]. I dont want this, as I want the user to be able to "bind" any key to a spesific action. So I tried to use the user32.dll call:

    [DllImport("user32.dll", EntryPoint = "GetKeyboardState", SetLastError = true)]
    private static extern bool NativeGetKeyboardState([Out] byte[] keyStates);

        private static bool GetKeyboardState(byte\[\] keyStates)
        {
            if (keyStates == null)
                throw new ArgumentNullException("keyState");
            if (keyStates.Length != 256)
                throw new ArgumentException("The buffer must be 256 bytes long.", "keyState");
            return NativeGetKeyboardState(keyStates);
        }
    
        private static byte\[\] GetKeyboardState()
        {
            byte\[\] keyStates = new byte\[256\];
            if (!GetKeyboardState(keyStates))
                throw new Win32Exception(Marshal.GetLastWin32Error());
            return keyStates;
        }
    
        private static bool AnyKeyPressed()
        {
            byte\[\] keyState = GetKeyboardState();
            // skip the mouse buttons
            return keyState.Skip(8).Any(state => (state & 0x80) != 0);
        }
    }
    

    With the function:

        bool MyIsKeyDown(Key key)
        {
    
            return (((byte)GetKeyboardState()\[(int)key\] & 0x80) & 0x80)>0;
        }
    

    and code implementation:

        private void Window\_KeyDown(object sender, KeyEventArgs e)
        {
    
            foreach (Key
    
    K L 2 Replies Last reply
    0
    • K Kenneth Haugland

      I need to know the key that is currently pressed in a C# WPF application, so:

          List PressedKeys = new List();
      
          private void Window\_KeyDown(object sender, KeyEventArgs e)
          {
              //If key is pressed this stop resending
              if (!PressedKeys.Contains(e.Key))
              {
                  PressedKeys.Add(e.Key);
                  txtKeysDown.Text = String.Join(", ", PressedKeys);
              }
              
          }
      
          private void Window\_KeyUp(object sender, KeyEventArgs e)
          {
              PressedKeys.Remove(e.Key);
              txtKeysDown.Text = String.Join(", ", PressedKeys);
          }
      

      This works, sort of. However, it does not give me the raw input from the keyboard so when AltGr is pressed it canges from Key.RightAlt => Key.LeftCtrl + Key.RightAlt whitch is Windows interpretation according to this: AltGr key - Wikipedia[^]. I dont want this, as I want the user to be able to "bind" any key to a spesific action. So I tried to use the user32.dll call:

      [DllImport("user32.dll", EntryPoint = "GetKeyboardState", SetLastError = true)]
      private static extern bool NativeGetKeyboardState([Out] byte[] keyStates);

          private static bool GetKeyboardState(byte\[\] keyStates)
          {
              if (keyStates == null)
                  throw new ArgumentNullException("keyState");
              if (keyStates.Length != 256)
                  throw new ArgumentException("The buffer must be 256 bytes long.", "keyState");
              return NativeGetKeyboardState(keyStates);
          }
      
          private static byte\[\] GetKeyboardState()
          {
              byte\[\] keyStates = new byte\[256\];
              if (!GetKeyboardState(keyStates))
                  throw new Win32Exception(Marshal.GetLastWin32Error());
              return keyStates;
          }
      
          private static bool AnyKeyPressed()
          {
              byte\[\] keyState = GetKeyboardState();
              // skip the mouse buttons
              return keyState.Skip(8).Any(state => (state & 0x80) != 0);
          }
      }
      

      With the function:

          bool MyIsKeyDown(Key key)
          {
      
              return (((byte)GetKeyboardState()\[(int)key\] & 0x80) & 0x80)>0;
          }
      

      and code implementation:

          private void Window\_KeyDown(object sender, KeyEventArgs e)
          {
      
              foreach (Key
      
      K Offline
      K Offline
      Kenneth Haugland
      wrote on last edited by
      #2

      Ok, I found a solution here: Using Raw Input from C# to handle multiple keyboards[^] However the WPF solution won't compile and apparently has a bug, but I found a git hub project that has a working WPF solution that I updated to VS2017 here: GitHub - aelij/RawInputProcessor: Provides a way to distinguish input from multiple keyboards[^] so problem solved.

      1 Reply Last reply
      0
      • K Kenneth Haugland

        I need to know the key that is currently pressed in a C# WPF application, so:

            List PressedKeys = new List();
        
            private void Window\_KeyDown(object sender, KeyEventArgs e)
            {
                //If key is pressed this stop resending
                if (!PressedKeys.Contains(e.Key))
                {
                    PressedKeys.Add(e.Key);
                    txtKeysDown.Text = String.Join(", ", PressedKeys);
                }
                
            }
        
            private void Window\_KeyUp(object sender, KeyEventArgs e)
            {
                PressedKeys.Remove(e.Key);
                txtKeysDown.Text = String.Join(", ", PressedKeys);
            }
        

        This works, sort of. However, it does not give me the raw input from the keyboard so when AltGr is pressed it canges from Key.RightAlt => Key.LeftCtrl + Key.RightAlt whitch is Windows interpretation according to this: AltGr key - Wikipedia[^]. I dont want this, as I want the user to be able to "bind" any key to a spesific action. So I tried to use the user32.dll call:

        [DllImport("user32.dll", EntryPoint = "GetKeyboardState", SetLastError = true)]
        private static extern bool NativeGetKeyboardState([Out] byte[] keyStates);

            private static bool GetKeyboardState(byte\[\] keyStates)
            {
                if (keyStates == null)
                    throw new ArgumentNullException("keyState");
                if (keyStates.Length != 256)
                    throw new ArgumentException("The buffer must be 256 bytes long.", "keyState");
                return NativeGetKeyboardState(keyStates);
            }
        
            private static byte\[\] GetKeyboardState()
            {
                byte\[\] keyStates = new byte\[256\];
                if (!GetKeyboardState(keyStates))
                    throw new Win32Exception(Marshal.GetLastWin32Error());
                return keyStates;
            }
        
            private static bool AnyKeyPressed()
            {
                byte\[\] keyState = GetKeyboardState();
                // skip the mouse buttons
                return keyState.Skip(8).Any(state => (state & 0x80) != 0);
            }
        }
        

        With the function:

            bool MyIsKeyDown(Key key)
            {
        
                return (((byte)GetKeyboardState()\[(int)key\] & 0x80) & 0x80)>0;
            }
        

        and code implementation:

            private void Window\_KeyDown(object sender, KeyEventArgs e)
            {
        
                foreach (Key
        
        L Offline
        L Offline
        Lost User
        wrote on last edited by
        #3

        I've been using the "Keyboard" class to get the state of my keys; apparently without any issues. e.g.

        bool ok = ( Keyboard.IsKeyDown( Key.LeftShift ) || Keyboard.IsKeyDown( Key.RightShift ) );

        "(I) am amazed to see myself here rather than there ... now rather than then". ― Blaise Pascal

        K 1 Reply Last reply
        0
        • L Lost User

          I've been using the "Keyboard" class to get the state of my keys; apparently without any issues. e.g.

          bool ok = ( Keyboard.IsKeyDown( Key.LeftShift ) || Keyboard.IsKeyDown( Key.RightShift ) );

          "(I) am amazed to see myself here rather than there ... now rather than then". ― Blaise Pascal

          K Offline
          K Offline
          Kenneth Haugland
          wrote on last edited by
          #4

          That could work, but I also want it to react to a sequence of inputs like Visual Studio does. For instance, if you have selected parts of the code you can hold LeftCtrl + K, release the keys and press LeftCtrl + F, VS will format the code for you. Then KeyBoard.IsDown is not really usable. The problem is that I need to know what happened on your keyboard before windows do changes to it.

          L 1 Reply Last reply
          0
          • K Kenneth Haugland

            That could work, but I also want it to react to a sequence of inputs like Visual Studio does. For instance, if you have selected parts of the code you can hold LeftCtrl + K, release the keys and press LeftCtrl + F, VS will format the code for you. Then KeyBoard.IsDown is not really usable. The problem is that I need to know what happened on your keyboard before windows do changes to it.

            L Offline
            L Offline
            Lost User
            wrote on last edited by
            #5

            "Keyboard" is a "class"; "IsDown" is only one method; I didn't say to use it; it was an example. Anyway, what you're citing is a "sequence of key states" that translates into some operation; and has nothing to do with testing individual key states. Your problem is determining / tracking intent once a key is pressed.

            "(I) am amazed to see myself here rather than there ... now rather than then". ― Blaise Pascal

            1 Reply Last reply
            0
            Reply
            • Reply as topic
            Log in to reply
            • Oldest to Newest
            • Newest to Oldest
            • Most Votes


            • Login

            • Don't have an account? Register

            • Login or register to search.
            • First post
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • World
            • Users
            • Groups