2011-12-10 14 views
5

Mi objetivo es implementar un controlador personalizado de la tecla Control + S para conectar un método de guardado personalizado en una aplicación de winforms.WinForms - Capturando la combinación de pulsaciones de teclas usando ProcessCmdKey VS KeyDown

Hay varias formas de lograr esto basadas en mi R & D. Primero, probé el controlador de eventos KeyPress obvio. Esto no fue lo suficientemente potente como para capturar las pulsaciones de teclas que necesito (no fue llamado en el nivel Editor, que es lo que necesitaba).

La segunda opción que se ve mejor es la anulación protegida bool ProcessCmdKey (ref Message msg, Keys keyData) anular. Esto funciona: intercepta el clic de la tecla CTRL, pero aparentemente necesito escribir código adicional para mantener el hecho de que la tecla CTRL está presionada e interceptar la siguiente tecla presionada (que sería S en mi caso) y luego realizar la acción personalizada.

protected override bool ProcessCmdKey(ref Message msg, Keys keyData) 
    { 
     if (keyData == (Keys.S | Keys.Control)) 
     { 
      // This is never called 
     } 
     else if (keyData == (Keys.Menu | Keys.Alt)) 
     { 
      // this is called each time I hit CTRL 
     } 
     return true; 
    } 

Parece que se llama a ProcessCmdKey inmediatamente después de presionar la tecla CTRL.

Este post sugiere la creación de una clase KeyTracker que persistirá las teclas pulsadas y hacer lo que tiene que hacer:

Capture Key Sequence via ProcessCmdKey

que parece como una buena opción, pero antes de que yo cave en un implemento un recuerdo patrón de seguimiento, ¿alguien tiene información sobre cómo lograr esta característica aparentemente común?

Otro patrón utiliza la función API GetKeyboardState:

Capture multiple key downs in C#

Esto parece interesante, aunque no estoy seguro de que será la suite mis necesidades.

[DllImport ("user32.dll")] 

public static extern int GetKeyboardState (byte [] keystate);

private void Form1_KeyDown(object sender, KeyEventArgs e) 
{ 
    byte[] keys = new byte[255]; 

    GetKeyboardState (keys); 

    if(keys[(int)Keys.Up] == 129 && keys[(int)Keys.Right] == 129) 
    { 
     Console.WriteLine ("Up Arrow key and Right Arrow key down."); 
    } 
} 

Gracias por echar un vistazo a mi problema.

ACTUALIZACIÓN

He añadido tres eventos para la entrega de llaves a mis Datapanel. VS no selecciona ninguno de estos eventos cuando configuro puntos de interrupción en los eventos, así que esto es lo que me lleva a pensar que ProcessCmdKey es mi mejor opción.

Si pudiera conseguir estos eventos para el trabajo, que sería bueno también:

 // Ctrl + S: Save Support 
     this.ParentForm.KeyPreview = true; 
     this.KeyPress    += new KeyPressEventHandler(DataPanel_KeyPress); 
     this.KeyDown    += new KeyEventHandler(DataPanel_KeyDown); 
     this.PreviewKeyDown  += new PreviewKeyDownEventHandler(DataPanel_PreviewKeyDown); 

Ninguno de estos acontecimientos parecen estar atrapados al pulsar ninguna tecla:

void DataPanel_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e) 
    { 
     if (e.KeyCode == (Keys.S | Keys.Control)) 
     { 
      SessionManager.Trace.AddTrace("You Hit Save!!"); 
     } 
    } 

    void DataPanel_KeyDown(object sender, KeyEventArgs e) 
    { 
     if (e.KeyCode == (Keys.S | Keys.Control)) 
     { 
      SessionManager.Trace.AddTrace("You Hit Save!!"); 
     } 
    } 

    void DataPanel_KeyPress(object sender, KeyPressEventArgs e) 
    { 
     var key = e.KeyChar; 
    } 

ACTUALIZACIÓN

He resuelto el problema utilizando un simple evento KeyUp y la bandera de KeyPreview:

void ShipmentDataPanel_KeyUp(object sender, KeyEventArgs e) 
    { 
     if (e.Control && e.KeyCode == Keys.S) 
     { 
      MessageBox.Show("Control + S Key Hit!"); 
     } 
    } 

Gracias.

+0

posible duplicado de [Mejor manera de poner en práctica los atajos de teclado en Windows Forms?] (Http://stackoverflow.com/questions/400113/best-way-to-implement -keyboard-shortcuts-in-winforms) –

Respuesta

3

Establezca KeyPreview propiedad de nuestro formulario en true. El resumen de esta propiedad dice: "Obtiene o establece un valor que indica si el formulario recibirá eventos clave antes de pasar el evento al control que tiene el foco". Luego use el evento KeyUp. A menos que KeyPressed, también proporciona información sobre teclas especiales como las teclas de control.

+0

Gracias - Lo intentaré en este momento. ¿Sabes a mano si KeyPreview funcionará con la anulación de ProcessCmdKey()? – nocarrier

+0

Por cierto, estoy trabajando en el nivel de DataPanel, así que supongo que agregaré la propiedad KeyPreview a mi ParentForm. Ejemplo: this.ParentForm.KeyPreview = true; – nocarrier

+0

He agregado una actualización a mi pregunta. Agregué los eventos de KeyPress que sugirió, pero mi DataPanel no parece querer suscribirse a ellos. KeyPreview tampoco parece afectar el evento ProcessCmdKey (aún se inicia con presionar tecla CTRL). – nocarrier

0

He resuelto esto haciendo,

if(e.KeyData==(Keys.S | Keys.Control)) 
Cuestiones relacionadas