2010-04-02 14 views
5

Actualmente estoy trabajando en una aplicación que requiere un comportamiento diferente en función de si el usuario presiona la tecla shift derecha o izquierda (RShiftKey, LShiftKey), sin embargo, cuando se presiona cualquiera de estas teclas Solo veo ShiftKey | Cambio..net diferencia entre teclas de desplazamiento a la derecha y shift shift

¿Hay algún problema con mi teclado? (computadora portátil) necesito un teclado/controlador de teclado nuevo para enviar los diferentes comandos clave ...

Este es un problema bastante masivo en este momento, ya que no hay forma de probar que el código funciona (aparte de las pruebas unitarias). ¿Alguien tuvo alguna experiencia con las diferentes teclas shift/alt/ctrl?

+0

veo .net, pero ¿cuál es su plataforma? WPF? Winforms? ¿Consola? Silverlight? –

+0

Lo sentimos, es un buen punto: simplemente es Winforms. Aunque creo que un golpe clave es un golpe clave, o es solo la punta de mi ingenuidad en este tema ... –

+0

Al parecer, distinguir entre izquierda y derecha pone esto en la categoría de "llave virtual" que requiere un pequeño esfuerzo adicional para trabajar con. – JYelton

Respuesta

4

no sé si este post le ayudará o no, pero parece que es posible que tenga que meterse con InteropServices y Diagnóstico:

MSDN Forum: How to send Left/Right shift key

Editar: finalmente descubierto la manera para hacer que GetAsyncKeyState() funcione, como lo revela adrianbanks.

[System.Runtime.InteropServices.DllImport("user32.dll")] 
private static extern short GetAsyncKeyState(Keys vKey); 

private void theForm_KeyDown(object sender, KeyEventArgs e) 
{ 
    if (e.KeyCode == Keys.ShiftKey) 
    { 
     if (Convert.ToBoolean(GetAsyncKeyState(Keys.LShiftKey))) 
     { 
      Console.WriteLine("Left"); 
     } 
     if (Convert.ToBoolean(GetAsyncKeyState(Keys.RShiftKey))) 
     { 
      Console.WriteLine("Right"); 
     } 
    } 
} 
+0

Hola, sí, veo esta publicación antes, pero solo habla de enviar el golpe de tecla. Lo extraño es que el teclado en sí mismo simplemente nunca envía estas "Llaves". Así que supongo que necesito modificar algo en Windows para permitir que mi teclado lo admita, u obtener un nuevo controlador, o ambos. –

5

Tome una mirada en el método Win32 GetAsyncKeyState. Se puede añadir una llamada PInvoke a ella usando:

[DllImport("user32.dll")] 
private static extern short GetAsyncKeyState(Keys key); 

y luego controlar el evento KeyDown en su formulario:

private void MyForm_KeyDown(object sender, KeyEventArgs e) 
{ 
    Console.WriteLine("Left Shift : " + (GetAsyncKeyState(Keys.LShiftKey) < 0)); 
    Console.WriteLine("Right Shift: " + (GetAsyncKeyState(Keys.RShiftKey) < 0)); 
} 
+0

Esto funciona, finalmente resolví una solución similar también. – JYelton

3

Gracias chicos, hay buena solución. Por el momento aquí está mi propio camino "hacky" de hacerlo desde la anulación de ProcessCmdKey:

public override bool ProcessCmdKey(ref Message msg, Keys keyData) 
{ 
    if (msg.LParam.ToInt32() == 0x2a0001) 
     LastShiftKey = ShiftKeys.NumericShift; 
     else if (msg.LParam.ToInt32() == 0x360001) 
      LastShiftKey = ShiftKeys.AlphaShift; 
    etc.... 
} 
+1

Esta es una solución mucho mejor que la marcada como respuesta; 'GetAsyncKeyState' no se puede confiar para dar resultados correctos (puede informar que la clave no está presionada, a pesar de que la aplicación reciba un evento), mientras que su solución aquí puede ser confiable (aunque esos códigos específicos pueden variar entre diferentes sistemas operativos)) –

2

que tenían una necesidad similar para diferenciar entre las teclas de cambio y de control izquierdo y derecho. Aquí está mi solución más larga, pero posiblemente mejor. Si desea capturar las teclas alt, tendrá que anular algunas otras cosas para evitar que activen cualquier menú (s). ((int)m.LParam & 0xFFFF) debe dar el número de repeticiones, pero nunca parece ir por encima de 2.

protected override bool ProcessKeyMessage(ref Message m) 
    { 
     if ((m.Msg == WM_KEYDOWN || m.Msg == WM_KEYUP) && ((int)m.WParam == VK_CONTROL || (int)m.WParam == VK_SHIFT)) 
     { 
      KeyEventArgs e = new KeyEventArgs(Keys.None); 
      switch ((OemScanCode)(((int)m.LParam >> 16) & 0x1FF)) 
      { 
       case OemScanCode.LControl: 
        e = new KeyEventArgs(Keys.LControlKey); 
        break; 
       case OemScanCode.RControl: 
        e = new KeyEventArgs(Keys.RControlKey); 
        break; 
       case OemScanCode.LShift: 
        e = new KeyEventArgs(Keys.LShiftKey); 
        break; 
       case OemScanCode.RShift: 
        e = new KeyEventArgs(Keys.RShiftKey); 
        break; 
       default: 
        if ((int)m.WParam == VK_SHIFT) 
         e = new KeyEventArgs(Keys.ShiftKey); 
        else if ((int)m.WParam == VK_CONTROL) 
         e = new KeyEventArgs(Keys.ControlKey); 
        break; 
      } 
      if (e.KeyData != Keys.None) 
      { 
       if (m.Msg == WM_KEYDOWN) 
        OnKeyDown(e); 
       else 
        OnKeyUp(e); 
       return true; 
      } 
     } 
     return base.ProcessKeyMessage(ref m); 
    } 

    #region Scan code & window message stuff 
    const int WM_KEYDOWN = 0x100; 
    const int WM_KEYUP = 0x101; 

    const int VK_SHIFT = 0x10; 
    const int VK_CONTROL = 0x11; 
    /// <summary> 
    /// Alt key 
    /// </summary> 
    const int VK_MENU = 0x12; 

    /// <summary> 
    /// List of scan codes for standard 104-key keyboard US English keyboard 
    /// </summary> 
    enum OemScanCode 
    { 
     /// <summary> 
     /// ` ~ 
     /// </summary> 
     BacktickTilde = 0x29, 
     /// <summary> 
     /// 1 ! 
     /// </summary> 
     N1 = 2, 
     /// <summary> 
     /// 2 @ 
     /// </summary> 
     N2 = 3, 
     /// <summary> 
     /// 3 # 
     /// </summary> 
     N3 = 4, 
     /// <summary> 
     /// 4 $ 
     /// </summary> 
     N4 = 5, 
     /// <summary> 
     /// 5 % 
     /// </summary> 
     N5 = 6, 
     /// <summary> 
     /// 6^
     /// </summary> 
     N6 = 7, 
     /// <summary> 
     /// 7 & 
     /// </summary> 
     N7 = 8, 
     /// <summary> 
     /// 8 * 
     /// </summary> 
     N8 = 9, 
     /// <summary> 
     /// 9 (
     /// </summary> 
     N9 = 0x0A, 
     /// <summary> 
     /// 0) 
     /// </summary> 
     N0 = 0x0B, 
     /// <summary> 
     /// - _ 
     /// </summary> 
     MinusDash = 0x0C, 
     /// <summary> 
     /// = + 
     /// </summary> 
     Equals = 0x0D, 
     Backspace = 0x0E, 
     Tab = 0x0F, 
     Q = 0x10, 
     W = 0x11, 
     E = 0x12, 
     R = 0x13, 
     T = 0x14, 
     Y = 0x15, 
     U = 0x16, 
     I = 0x17, 
     O = 0x18, 
     P = 0x19, 
     /// <summary> 
     /// [ { 
     /// </summary> 
     LBracket = 0x1A, 
     /// <summary> 
     /// ] } 
     /// </summary> 
     RBracket = 0x1B, 
     /// <summary> 
     /// | \ (same as pipe) 
     /// </summary> 
     VerticalBar = 0x2B, 
     /// <summary> 
     /// | \ (same as vertical bar) 
     /// </summary> 
     Pipe = 0x2B, 
     CapsLock = 0x3A, 
     A = 0x1E, 
     S = 0x1F, 
     D = 0x20, 
     F = 0x21, 
     G = 0x22, 
     H = 0x23, 
     J = 0x24, 
     K = 0x25, 
     L = 0x26, 
     /// <summary> 
     /// ; : 
     /// </summary> 
     SemiColon = 0x27, 
     /// <summary> 
     /// ' " 
     /// </summary> 
     Quotes = 0x28, 
     // Unused 
     Enter = 0x1C, 
     LShift = 0x2A, 
     Z = 0x2C, 
     X = 0x2D, 
     C = 0x2E, 
     V = 0x2F, 
     B = 0x30, 
     N = 0x31, 
     M = 0x32, 
     /// <summary> 
     /// , < 
     /// </summary> 
     Comma = 0x33, 
     /// <summary> 
     /// . > 
     /// </summary> 
     Period = 0x34, 
     /// <summary> 
     ////? 
     /// </summary> 
     Slash = 0x35, 
     RShift = 0x36, 
     LControl = 0x1D, 
     LAlternate = 0x38, 
     SpaceBar = 0x39, 
     RAlternate = 0x138, 
     RControl = 0x11D, 
     /// <summary> 
     /// The menu key thingy 
     /// </summary> 
     Application = 0x15D, 
     Insert = 0x152, 
     Delete = 0x153, 
     Home = 0x147, 
     End = 0x14F, 
     PageUp = 0x149, 
     PageDown = 0x151, 
     UpArrow = 0x148, 
     DownArrow = 0x150, 
     LeftArrow = 0x14B, 
     RightArrow = 0x14D, 
     NumLock = 0x145, 
     NumPad0 = 0x52, 
     NumPad1 = 0x4F, 
     NumPad2 = 0x50, 
     NumPad3 = 0x51, 
     NumPad4 = 0x4B, 
     NumPad5 = 0x4C, 
     NumPad6 = 0x4D, 
     NumPad7 = 0x47, 
     NumPad8 = 0x48, 
     NumPad9 = 0x49, 
     NumPadDecimal = 0x53, 
     NumPadEnter = 0x11C, 
     NumPadPlus = 0x4E, 
     NumPadMinus = 0x4A, 
     NumPadAsterisk = 0x37, 
     NumPadSlash = 0x135, 
     Escape = 1, 
     PrintScreen = 0x137, 
     ScrollLock = 0x46, 
     PauseBreak = 0x45, 
     LeftWindows = 0x15B, 
     RightWindows = 0x15C, 
     F1 = 0x3B, 
     F2 = 0x3C, 
     F3 = 0x3D, 
     F4 = 0x3E, 
     F5 = 0x3F, 
     F6 = 0x40, 
     F7 = 0x41, 
     F8 = 0x42, 
     F9 = 0x43, 
     F10 = 0x44, 
     F11 = 0x57, 
     F12 = 0x58, 
    } 
    #endregion 
Cuestiones relacionadas