none
Funciones Teclado. RRS feed

  • Pregunta

  • Hola...quien me puede ayudar con esto?..necesito en un formulario que con una combinacion de teclas me active X proceso...sin importar en que Control me encuentre.

     

    Gracias.

    viernes, 7 de noviembre de 2008 15:49

Respuestas

  • "Harold Cepeda" preguntó:

     

    > necesito en un formulario que con una combinacion de teclas me

    > active X proceso...sin importar en que Control me encuentre.

     

    Hola, Harold:

     

    Creo que lo mejor que puedes hacer es sobrescribir la función «ProcessCmdKey» del formulario, para que dependiendo de la combinación de teclas pulsada, se ejecute el proceso que estimes conveniente.

     

    Por ejemplo, imagina que deseas detectar si el usuario ha pulsado la combinación de teclas Ctrl+Alt+F10. En la función «ProcessCmdKey» ejecutarías algo parecido a lo siguiente:

     

    Protected Overrides Function ProcessCmdKey( _
            ByRef msg As System.Windows.Forms.Message, _
            ByVal keyData As System.Windows.Forms.Keys) As Boolean

     

            If keyData = (Keys.Control Or Keys.Alt Or Keys.F10) Then
                MessageBox.Show("Se ha pulsado la combinación de telcas Ctrl+Alt+F10.")
            End If

     

            Return MyBase.ProcessCmdKey(msg, keyData)

     

    End Function

     

    De ésta manera, no es necesario que establezcas a «True» el valor de la propiedad «KeyPreview» del formulario, y aunque el foco se encuentre en cualquier control, podrás detectar la tecla o combinación de teclas pulsadas por el usuario.

     

    Un saludo

     

    domingo, 9 de noviembre de 2008 10:00
    Moderador

Todas las respuestas

  • hola, no probaste con el metodo keypress del formulario? capturas la combinacion de teclas q necesitas y haces tu proceso.
    viernes, 7 de noviembre de 2008 17:57
  • Amigo Harold,

     

    lei tu pregunta hace rato, y me tomé la libertad de averiguar la forma (al menos la que a mí se me ocurrió) de hacer lo que necesitas Imagino que habrán otros métodos, tal vez más sencillos, pero este funciona perfecto, y además no es tan complejo.

     

    El código queda así:

     

     

    'Dimenciono una variable que determinar  si se hace la combinación de teclas

    '(en este caso, de 3 teclas nada más)

    Dim opTeclas As Short = 0

     

    'El evento encargado de comprobar las teclas oprimidas mientras están oprimidas

    Private Sub TextBox1_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles TextBox1.KeyDown

    'La evaluación de esta condición tiene como objetivo no cargar

    'demasiado la ejecución del programa

    If e.KeyValue = 17 Or e.KeyValue = 18 Or e.KeyValue = 65 Then

    'Llamo al procedimiento que se encargar 

    'de verificar la combinación de teclas

    KeyCombination(e.KeyValue)

    End If

    End Sub

     

    'Procedimiento que activar  el evento que quieres que se ejecute

    'al hacer la combinación de teclas respectiva (en este ejemplo, Ctrl+Alt+A)

    Private Sub KeyCombination(ByVal Tecla As Integer)

    If Tecla = 17 Then 'Evalúo si se presionó Ctrl

    opTeclas = 1

    End If

    If opTeclas = 1 Then 'Evalúo si Ctrl sigue presionada

    If Tecla = 18 Then 'Evalúo si se presionó Alt

    opTeclas = 2

    End If

    End If

    If opTeclas = 2 Then 'Evalúo si Ctrl y Alt siguen presionadas

    If Tecla = 65 Then 'Evalúo si se presionó A

    'Las 3 teclas están presionadas, así que

    'llamas al evento que quieres ejecutar (por ejemplo,

    'Button1_Click()) o escribes el código del

    'procedimiento directamente

    '(en este caso, muestro un Message en pantalla)

    MessageBox.Show("Acabas de presionar Ctrl + Alt + A")

    End If

    End If

    End Sub

     

    'Evento que se ejecuta cuando la tecla presionada es soltada

    Private Sub TextBox1_KeyUp(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles TextBox1.KeyUp

    'Deshabilito la combinación de teclas

    opTeclas = 0

    End Sub

     

     

    Lo primero que diré, es que intenté hacer este mismo procedimiento en Form1_KeyPress y Form1_KeyDown pero no resultó, así que lo apliqué a los controles, pero es igual funcional. Déjame explicarte primero en qué consiste el proceso.

     

    Como ves, no es nada del otro mundo, solo es necesario llamar a un procedimiento al que nombré KeyCombination que a su vez llamará o ejecutará el evento que quieras ejecutar a través de la combinación.

     

    La variable declarada al inicio (opTeclas) debe estar fuera de todo procedimiento, debajo de la primera línea que por defecto trae todo formulario (Public Class Form1), pues su valor debe ser visto en dos eventos distintos. La función de esa variable es sencillamente contar cuántas teclas se han oprimido simultáneamente. Observa que al soltar una tecla el evento que se ejecuta bajo dicha acción (TextBox1_KeyUp) inmediatamente establece el valor de opTeclas en 0, pues la combinación se debe romper al soltar una tecla.

     

    En TextBox1_KeyDown efectúo el llamado al proceso KeyCombinatión, pero notarás que lo hago después de evaluar si se ha presionado una de las teclas implicadas en la combinación. Si no lo hiciera, de todas maneras el código funcionaría. ¿Por qué lo hago entonces? Sencillamente, para evitar que se ejecute el KeyCombination cada vez que oprimes una tecla cualquiera. ¡Imagínate la sobrecarga que tendría tu aplicación si ejecutaras todo ese proceso! Si escribieras una cadena de texto de unas 30 letras, el código de KeyCombination se ejecutaría las mismas 30 veces, eso más las veces que oprimas las teclas para borrar y la barra espaciadora. Así que la condición le da mayor eficiencia a la ejecución del código, llamando al KeyCombination solo al presionar las teclas implicadas.

     

    El procedimiento KeyCombination es en verdad muy simple. Solo necesita recibir un valor (que se almacena en el parámetro Tecla) del evento que lo llamó. Este valor es e.KeyValue, como notas en la línea en que lo llamo:

     

     

    Private Sub TextBox1_KeyDown...

    If...

    KeyCombination(e.KeyValue)

     

     

    Si no sabes de donde sale e.KeyValue, pues fíjate que en la declaración del evento TextBox1_KeyDown, el segundo parámetro encerrado entre paréntesis se llama e (ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs). Pues bien, al activarse el evento TextBox1_KeyDown, el parámetro e almacena la descripción de la tecla presionada, y entre todo lo que almacena, está el valor de dicha tecla, que se extrae con e.KeyValue. Ese es el valor que envío para KeyCombination, para efectuar su respectivo análisis.

     

    La serie de evaluaciones contenidas dentro de este procedimiento, sencillamente son para determinar el orden en que las teclas son presionadas, y si se presionan simultaneamente.

    Si las presionas en otro orden no sucederá nada, y eso es importante. Y como mencioné más arriba, si sueltas una de las teclas antes de presionar las tres juntas el evento TextBox1_KeyUp se activa y rompe la secuencia de teclas oprimidas al mismo tiempo (almacenada en opTeclas).

     

    Una vez que la última tecla (en este caso: A) se oprime, escribes el código correspondiente a la función que quieres que se ejecute con tu "Hot Key", o combinación de teclas.

     

    Ahora, en tu pregunta especificaste que quieres que tu Hot Key funcione desde cualquier control, y yo solo lo apliqué a un TextBox. Pero no te preocupes, diseñé el método para usarlo con cualquier control. Lo único que tienes que hacer es asociar los demás controles al evento TextBox1_KeyDown y TextBox1_KeyUp, claro está, siempre y cuando ese evento esté disponible para el control que asociarás. Si no sabes cómo se hace, te explico; es facilísimo.

     

    Lo único que debes hacer es agrupar con comas el nombre del control seguido de un .KeyDown o .KeyUp, según el evento, al final de la línea de declaración del evento.

    Para que lo entiendas bien, así es como debe quedar (asumiendo que los otros controles son dos TextBox más, y un ComboBox):

     

    Private Sub TextBox1_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles TextBox1.KeyDown, TextBox2.KeyDown, TextBox3.KeyDown, ComboBox1.KeyDown

     

    y para el KeyUp:

     

    Private Sub TextBox1_KeyUp(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles TextBox1.KeyUp, TextBox2.KeyUp, TextBox3.KeyUp, ComboBox1.KeyUp

     

    Así de simple es. Solo debes tener cuidado de no escribir lo mismo con un control que no tenga ese evento. Por ejemplo, un PictureBox no admite ninguno de los eventos que implican el teclado, pues no es un control seleccionable, y lo mismo pasa con un Label, entre otros más. Si le aplicas el evento KeyDown (PictureBox1.KeyDown) o KeyUp (PictureBox1.KeyUp) te dará error. Pero para saber que el control que asocias sí admite uno de estos eventos, solo ve que cuando coloques el punto justo después de su nombre y presiones la K, la ayuda contextual te muestre el evento correspondiente. Si no está, no lo escribas.

     

    Así pues, una vez asociados tus controles, tu Hot Key funcionará al estar en cualquiera de ellos; el evento KeyDown llamará a KeyCombination, y se ejecutará el mismo código para todos. Esa es la gran ventaja de asociar controles y usar procedimientos que se llamen desde otra parte del código. Te ahorras ufff, muchísimas líneas.

     

    Bueno, creo que la explicación está completa. De hecho, puede que me haya excedido un poco, pero no me gusta dejar lagunas. Es posible que el compañero que hace la pregunta no tenga mucha experiencia, así que es mejor para él entender cada detalle para luego poder implementar por sí solo un método como este más adelante y usando la misma lógica, verdad Harold? Jejé! Para mí no tiene sentido usar un código sin entender cómo funciona, y pues no quiero contribuir a que le pase a otros.

     

    Bueno sr. Harold, espero haber podido ayudar. Yo he recibido ya mucha ayuda aquí, y quiero corresponder eso lo más que pueda. Cualquier cosa solo pegue un grito que yo u otro miembro del foro le ayudará.

     

    Ah! olvidaba recordarte que si la respuesta te ha sido de ayuda la marques como respondida. Estamos en contacto.

     

     

     

    • Propuesto como respuesta eliabc123 miércoles, 6 de enero de 2010 16:32
    domingo, 9 de noviembre de 2008 6:44
  • "Harold Cepeda" preguntó:

     

    > necesito en un formulario que con una combinacion de teclas me

    > active X proceso...sin importar en que Control me encuentre.

     

    Hola, Harold:

     

    Creo que lo mejor que puedes hacer es sobrescribir la función «ProcessCmdKey» del formulario, para que dependiendo de la combinación de teclas pulsada, se ejecute el proceso que estimes conveniente.

     

    Por ejemplo, imagina que deseas detectar si el usuario ha pulsado la combinación de teclas Ctrl+Alt+F10. En la función «ProcessCmdKey» ejecutarías algo parecido a lo siguiente:

     

    Protected Overrides Function ProcessCmdKey( _
            ByRef msg As System.Windows.Forms.Message, _
            ByVal keyData As System.Windows.Forms.Keys) As Boolean

     

            If keyData = (Keys.Control Or Keys.Alt Or Keys.F10) Then
                MessageBox.Show("Se ha pulsado la combinación de telcas Ctrl+Alt+F10.")
            End If

     

            Return MyBase.ProcessCmdKey(msg, keyData)

     

    End Function

     

    De ésta manera, no es necesario que establezcas a «True» el valor de la propiedad «KeyPreview» del formulario, y aunque el foco se encuentre en cualquier control, podrás detectar la tecla o combinación de teclas pulsadas por el usuario.

     

    Un saludo

     

    domingo, 9 de noviembre de 2008 10:00
    Moderador
  •  

    Eso SoftJaén! Qué buena tu respuesta! A eso me refería cuando dije al principio que de seguro habían otros métodos más sencillos. Lo que pasa es que llevo apenas como dos semanas trabajando con el VB Express, de modo que no lo conozco bien. Lo que he aprendido ha sido a través de las librerías de MSDN, así que a mí también me ayuda mucho tu respuesta.

     

    Ahora, quisiera preguntar de donde sacaste esa función ProcessCmdKey, y cómo funciona. ¿Hay otras funciones similares que estén en expectación mientras se ejecuta una aplicación? Por favor, esa información sería muy útil.

    domingo, 9 de noviembre de 2008 18:10
  • "Jason Friedman" preguntó:

     

    > donde sacaste esa función ProcessCmdKey, y cómo funciona

     

    ¿Que de dónde me he sacado la función? Desde luego, no me la he sacado de la "chistera".

     

    La función «ProcessCmdKey» se incluye en la clase «Form», y se utiliza para procesar una tecla de comando, reemplazando (Overrides) a la función del mismo nombre que se encuentra en la clase «ContainerControl», que es la clase base de la que hereda directamente la clase «Form». Y en cuanto a su funcionamiento es automático: una vez que la incluyas en el módulo de la clase «Form», se ejecutará cuando se desencadene un evento de teclado.

     

    La clase «Form» dispone de numerosos métodos reemplazables que pueden sernos útiles en determinadas circunstancias, pero, ¡claro! Hay que conocerlos y estudiarlos a fondo.

     

    En el siguiente enlace encontrarás una breve descripción de los métodos de la clase «Form». Fíjate en aquellos cuyo nombre comienza por «On» o por «Process»:

     

    http://msdn.microsoft.com/es-es/library/system.windows.forms.form_methods.aspx

     

    Un saludo
    domingo, 9 de noviembre de 2008 19:46
    Moderador
  •  

    Ah ya veo. Sí, como dices debo conocer bien los métodos del teclado. Pero dime algo: ¿la función original qué función cumple? Porque tengo entendido que Overrides sobreescribe una función de una clase ya establecida. Entonces, ¿qué es lo que sobreescribes?
    domingo, 9 de noviembre de 2008 20:24
  •  

    Amigo, aun no respondes. Quiero hacerte otra pregunta ya que de seguro podrás ayudarme. Tiene qué ver con el teclado también. Me urge restringir el uso de ciertas teclas en algunos controles ComboBox, de modo que solo se puedan elegir los items, y no copiar texto. ¿Hay algún código, o mejor aún, se puede establecer por alguna propiedad?

     

    Por favor, esto sí me gustaría saberlo. La pregunta anterior no importa.

     

    domingo, 9 de noviembre de 2008 22:20
  • "Jason Friedman" preguntó:

     

    > ¿la función original qué función cumple?

     

    Pues como te comenté anteriormente, dicha función procesa una tecla de comando, tal y como así se indica en la ayuda de Visual Studio.

     

    > Porque tengo entendido que Overrides sobreescribe una función de

    > una clase ya establecida. Entonces, ¿qué es lo que sobreescribes?

     

    Cuando se sobrescribe algo, se está reemplazando el método o propiedad original por una implementación que nosotros mismos estamos realizando del mismo método o propiedad con igual nombre.

     

    Imagina que los ingenieros de Microsoft desarrollaron inicialmente la función «ProcessCmdKey» dentro de la clase «Control», y escribieron dentro de ella código fuente para detectar la pulsación de una tecla cualquiera. Como bien podrás comprender, ese código fuente yo lo desconozco, por tanto, no te puedo decir exactamente lo que hace la función. Simplemente sé que automáticamente se desencadena la función «ProcessCmdKey» durante el preprocesamiento de mensajes para controlar las teclas de comando, por lo que me imagino que algún evento de la clase «Control» será el "culpable" de llamar a la mencionada función.

     

    Pero al reemplazar nosotros mismos el método dentro de una clase «Form», nos aprovechamos que dicha función se ejecuta automáticamente para escribir dentro de ella nuestro propio código fuente, para detectar, por ejemplo, la combinación de teclas pulsadas por el usuario, que es el tema principal de esta conversación.

     

    lunes, 10 de noviembre de 2008 10:08
    Moderador
  • "Jason Friedman" escribió:

     

    > Amigo, aun no respondes

     

    Amigo, te diré que en los años que llevo participando en foros y grupos de noticias públicos de Microsoft, suelo responder cuando tengo tiempo libre. Pero no esperes que esté pendiente de tus mensajes o respuestas, o de los de cualquier otro usuario, porque también tengo otras ocupaciones que atender, quizás más importantes que en las que ahora mismo me encuentro. ¿OK?

     

    > Me urge restringir el uso de ciertas teclas en algunos controles ComboBox,

    > de modo que solo se puedan elegir los items, y no copiar texto.

    > ¿Hay algún código, o mejor aún, se puede establecer por alguna propiedad?

     

    Si he entendido bien tu mensaje, parece ser que deseas que el usuario solamente pueda elegir los elementos (items) existentes en el control ComboBox. Si es así, simplemente tienes que especificar el valor «ComboBoxStyle.DropDownList» a la propiedad «DropDownStyle» del control ComboBox:

     

    ComboBox1.DropDownStyle = ComboBoxStyle.DropDownList

     

     

     

    lunes, 10 de noviembre de 2008 10:23
    Moderador
  •  

    Muchas Gracias    SoftJaén.... Funciona Perfecto y era exactamente lo que necesitava....Se aprende demasiado todos los dias.
    miércoles, 12 de noviembre de 2008 19:56
  •  

    Muchas Gracias por Ayudarme.....Me funciono bien.

     

     

     

    Gracias..

    miércoles, 12 de noviembre de 2008 19:58
  • "Harold Cepeda" escribió:

     

    > Muchas Gracias    SoftJaén.... Funciona Perfecto y era exactamente

    > lo que necesitava....Se aprende demasiado todos los dias.

     

    Me alegro de que te funcione. Pero si lo estimas conveniente, marca la respuesa como satisfactoria para que ésta conversación quede finalizada. :-)

     

    jueves, 13 de noviembre de 2008 15:50
    Moderador