Principales respuestas
Funciones Teclado.

Pregunta
-
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 BooleanIf keyData = (Keys.Control Or Keys.Alt Or Keys.F10) Then
MessageBox.Show("Se ha pulsado la combinación de telcas Ctrl+Alt+F10.")
End IfReturn 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
Todas las respuestas
-
-
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.KeyDownKeyCombination(e.KeyValue)
End If End SubopTeclas = 1
opTeclas = 2
'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 SubopTeclas = 0
End SubLo 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í 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
-
"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 BooleanIf keyData = (Keys.Control Or Keys.Alt Or Keys.F10) Then
MessageBox.Show("Se ha pulsado la combinación de telcas Ctrl+Alt+F10.")
End IfReturn 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
-
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.
-
"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
-
-
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.
-
"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.
-
"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
-
-
-
"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. :-)