KeyDown() KeyPress() KeyUp()
El primer evento se pone en marcha cuando una tecla es oprimida, el segundo evento se pone en marcha al mantener oprimida una tecla, y el tercer evento se pone en marcha cuando una tecla, después de haber sido oprimida, se suelta.
En la etapa de diseño, haciendo clic dentro del espacio de la forma con el Mouse hacemos que aparezca la lista de objetos (Object) que hay en el proyecto así como los procedimientos (Proc) disponibles para cada objeto, en donde podemos ver (y acceder) a los espacios reservados para cada evento relacionado con la interacción con el teclado:
Obsérvese que, a diferencia de los eventos Load() y Click() para la forma, los cuales carececen de argumentos entre los paréntesis, el evento KeyDown() que ocurre al oprimir una tecla tiene especificados dos argumentos, la variable KeyCode y la variable Shift, ambas de tipo Integer,
Form_KeyDown (KeyCode As Integer, Shift As Integer)
Posiblemente el lector ya sospeche que el argumento KeyCode tiene algo que ver con la tecla que sea oprimida (por ejemplo, la tecla “5”) y la tecla que corresponde al argumento Shift (¡no confundir con la tecla SHIFT en el teclado, se trata de dos cosas diferentes!) que generalmente proporciona el acceso a un segundo conjunto de caracteres asociados cada uno de ellos a cada tecla (por ejemplo, el caracter “%” que se puede obtener en varios teclados en inglés al oprimir simultáneamente las teclas de “5” y SHIFT), y así es en efecto.
¿En qué tipo de situaciones nos puede ser útil inicializar ciertas acciones con la opresión de ciertas teclas>
Hemos visto ya cómo con la ayuda de algo como la ventana para diseño de menús le podemos agregar a una forma una barra de Menú con una serie de opciones y sub-opciones, y haciendo clic en cada opción (o sub-opción) podemos poner en acción el código que corresponde al evento especificado. Una cosa que podríamos hacer es elaborar una pequeña ventana que le informe al usuario sobre la acción disponible bajo ciertas teclas para iniciar ciertos eventos en un programa que haya sido elaborado con Visual Basic. Tal vez queramos que aparezca una ventana como la siguiente:
Podemos producir una ventana como la anterior recurriendo simplemente a una caja de mensaje. En las cajas de mensaje que hemos visto en las entradas previas, no parecía haber mucho espacio para meter nada más que una línea de texto. Sin embargo, podemos especificar cajas de mensaje con varias líneas de texto si recurrimos a la función de hilera Chr$() (a la cual se le proporciona como argumento el código ASCII que queremos que se imprima o que se ejecute) definiendo una nueva hilera, la hilera CrLf$ con la cual Visual Basic pueda identificar en forma conjunta un “regreso de carro” (carriage return) al principio de la línea con Chr$(13), y un salto hacia la siguiente línea con una “alimentación de línea” (line feed) con Chr$(10), en donde los enteros numéricos dados como argumentos corresponden al código ASCII que puede producir tales funcione. El siguiente código puede hacer que aparezca en la ventana de la forma la ventana anterior al hacer clic con el Mouse dentro de la forma:
Sub Form_Click ()
Dim Ayuda$
CrLf$ = Chr$(13) + Chr$(10)
Ayuda$ = Ayuda$ + "TECLAS DE ATAJOS DEX "
Ayuda$ = Ayuda$ + CrLf$ + CrLf$
Ayuda$ = Ayuda$ + "F1 Ayuda" + CrLf$ + CrLf$
Ayuda$ = Ayuda$ + "MANEJO DE ARCHIVOS DE EXPERIMENTOS:"
Ayuda$ = Ayuda$ + CrLf$ + CrLf$
Ayuda$ = Ayuda$ + "F2 Abrir archivo de experimento" + CrLf$
Ayuda$ = Ayuda$ + "F3 Guardar archivo de experimento"
Ayuda$ = Ayuda$ + CrLf$ + CrLf$
Ayuda$ = Ayuda$ + "DISTRIBUCIONES ESTADISTICAS:"
Ayuda$ = Ayuda$ + CrLf$ + CrLf$
Ayuda$ = Ayuda$ + "F4 Distribucion Hipergeometrica" + CrLf$
Ayuda$ = Ayuda$ + "F5 Distribucion Binomial" + CrLf$
Ayuda$ = Ayuda$ + "F6 Distribucion Student's t" + CrLf$
Ayuda$ = Ayuda$ + "F7 Distribucion Normal" + CrLf$
Ayuda$ = Ayuda$ + "F8 Distribucion F"
Ayuda$ = Ayuda$ + CrLf$ + CrLf$
Ayuda$ = Ayuda$ + "EXPERIMENTOS:"
Ayuda$ = Ayuda$ + CrLf$ + CrLf$
Ayuda$ = Ayuda$ + "Shift + F2 Factorial" + CrLf$
Ayuda$ = Ayuda$ + "Shift + F3 Factorial Replicado" + CrLf$
Ayuda$ = Ayuda$ + "Shift + F4 Cuadrados Latinos" + CrLf$
Ayuda$ = Ayuda$ + "Shift + F5 Cuadrados Greco-Latinos" + CrLf$
Ayuda$ = Ayuda$ + "Shift + F6 Taguchi" + CrLf$
MsgBox Ayuda$, 64, "Ayuda DEX"
End Sub
Así pues, ésta ayuda usada dentro de algún programa casero para diseño de experimentos titulado DEX nos indica las teclas de atajo que podemos oprimir para poder invocar ciertas operaciones o efectuar ciertas acciones. De acuerdo a la ayuda dada como una caja de mensaje, si oprimimos simultáneamente las teclas Shift y F4 abriremos (o haremos visible) una ventana para llevar a cabo un diseño experimental en cuadrados latinos. Pero no hemos diseñado la forma en la cual se hará tal análisis, y mucho menos hemos indicado cómo llegaremos a ella oprimiendo tal combinación de teclas. Lo más básico que podríamos esperar es que, con la simple opresión de la tecla F1 mientras la ventana de la aplicación DEX tiene el enfoque, aparezca la anterior ventana de ayuda sin necesidad de tener que hacer clic con el Mouse dentro de la ventana, habido el hecho de que en una gran mayoría de las computadoras de escritorio se ha adoptado como convención casi universal el recurrir a la tecla F1 para que ésta, de modo automático, responda de manera casi automática e inmediata como una tecla de ayuda, abriendo una ventana que le proporcione al usuario en la misma máquina información para la cual posiblemente tendría que estar consultando algún manual. ¿Pero cómo lo podemos lograr? Como ya se dijo arriba, la forma tiene especificado el evento KeyDown(). Si queremos que la forma en sí responda a un evento de este tipo no haciendo clic con el Mouse dentro de la forma sino oprimiendo la tecla F1, tenemos que meter código que corresponda a dicho evento, o sea dentro del procedimiento:
Sub Form_KeyDown (KeyCode As Integer, Shift As Integer)
End Sub
La cosa parece fácil, requiriéndose tan solo quitar el código anterior de la caja de mensaje de ayuda para meterlo en el evento Form_Keydown(). Y esto en efecto funciona, ya que en el programa simulado al oprimir cualquier tecla del teclado aparecerá la ventana de ayuda. Sin embargo, no es lo que deseamos, queremos que la ventana de ayuda apareza únicamente cuando se oprime la tecla F1, y no cualquier otra. Tendremos que especificar código para que cuando el evento KeyDown() se ejecute se filtre de alguna manera la tecla F1 sobre todas las demás. ¿Y cómo se distinguen, para propósitos de programación, una tecla de otra en un cierto tipo de teclado (por ejemplo, un teclado en inglés)? En una interacción del sistema operativo con el hardware de la máquina, cada tecla o combinación de teclas tiene asignado un cierto número hexadecimal que corresponde única y exclusivamente a cada tecla en particular, conocido como el código de la tecla (keycode). En el caso de la tecla F1, su código hexadecimal es &H70 (ya habíamos visto en una entrada previa que con el prefijo &H se le especifica a Visual Basic un número hexadecimal).
Podemos entonces designar, con la palabra reservada Const para declaración de constantes en Visual Basic, una constante con la cual le demos una representación simbólica al número hexadecimal &H70 que corresponde a la tecla F1, con una declaración como ésta:
Const TeclaF1 = &H70
De este modo, podemos usar a la constante TeclaF1 en una estructura de control para decidir que se ejecute o no cierta porción de código. La manera es usando una operación de comparación lógica como la siguiente:
If Keycode = TeclaF1 Then
Código para mostrar en la pantalla la ventana de ayuda
End If
Obsérvese que en la comparación lógica, estamos usando la misma palabra KeyCode que la que aparece siendo definida como el primer argumento en la sintaxis del evento KeyDown(). Se trata, pues, del código que corresponde a la tecla que sea oprimida por el usuario. Y si dicha tecla resulta ser la tecla F1, entonces la comparación lógica tendrá un valor lógico de True y el código que invoca a la ventana de ayuda se ejecutará.
Así pues, el código completo que aparecerá en el evento KeyDown() que corresponde a la forma que está abierta será:
Sub Form_KeyDown (KeyCode As Integer, Shift As Integer)
Dim Ayuda$
Const TeclaF1 = &H70
If KeyCode = TeclaF1 Then
CrLf$ = Chr$(13) + Chr$(10)
Ayuda$ = Ayuda$ + "TECLAS DE ATAJOS DEX "
Ayuda$ = Ayuda$ + CrLf$ + CrLf$
Ayuda$ = Ayuda$ + "F1 Ayuda" + CrLf$ + CrLf$
Ayuda$ = Ayuda$ + "MANEJO DE ARCHIVOS DE EXPERIMENTOS:"
Ayuda$ = Ayuda$ + CrLf$ + CrLf$
Ayuda$ = Ayuda$ + "F2 Abrir archivo de experimento" + CrLf$
Ayuda$ = Ayuda$ + "F3 Guardar archivo de experimento"
Ayuda$ = Ayuda$ + CrLf$ + CrLf$
Ayuda$ = Ayuda$ + "DISTRIBUCIONES ESTADISTICAS:"
Ayuda$ = Ayuda$ + CrLf$ + CrLf$
Ayuda$ = Ayuda$ + "F4 Distribucion Hipergeometrica" + CrLf$
Ayuda$ = Ayuda$ + "F5 Distribucion Binomial" + CrLf$
Ayuda$ = Ayuda$ + "F6 Distribucion Student's t" + CrLf$
Ayuda$ = Ayuda$ + "F7 Distribucion Normal" + CrLf$
Ayuda$ = Ayuda$ + "F8 Distribucion F"
Ayuda$ = Ayuda$ + CrLf$ + CrLf$
Ayuda$ = Ayuda$ + "EXPERIMENTOS:"
Ayuda$ = Ayuda$ + CrLf$ + CrLf$
Ayuda$ = Ayuda$ + "Shift + F2 Factorial" + CrLf$
Ayuda$ = Ayuda$ + "Shift + F3 Factorial Replicado" + CrLf$
Ayuda$ = Ayuda$ + "Shift + F4 Cuadrados Latinos" + CrLf$
Ayuda$ = Ayuda$ + "Shift + F5 Cuadrados Greco-Latinos" + CrLf$
Ayuda$ = Ayuda$ + "Shift + F6 Taguchi" + CrLf$
MsgBox Ayuda$, 64, "Ayuda DEX"
End If
End Sub
Tenemos, pues, la manera de hacer muchas cosas a través del teclado. Podemos, por ejemplo, usando las teclas que corresponden a las flechas (flecha hacia arriba, flecha hacia abajo, flecha hacia la izquierda, flecha hacia la derecha), “navegar” tal y como lo hacemos en una hoja de trabajo tipo Excel. Para ello podemos definir las constantes que correspondan a tales teclas, como en los ejemplos que se dan a continuación:
Const Arriba = &H26
Const Abajo = &H28
Para tomar pleno control del teclado, nos gustaría tener al alcance de la mano los valores para todas las teclas que pueda haber en el teclado. En el caso de un teclado en inglés, todas las versiones de Visual Basic incluyen un archivo usualmente llamado CONSTANT.TXT que proporciona dichos valores, aunque muchos programadores hispanos y latinoamericanos tal vez querrán “castellanizar” sus programas definiendo las teclas con sus palabras en castellano fácilmente memorizables. Visual Basic predefine con sus propios nombres los valores que corresponden a cada tecla usando el prefijo vb como acostumbra usarse en notación húngara. Es muy importante tomar en cuenta que Visual Basic en la mayoría de sus versiones no reconoce de modo automático las “constantes Visual Basic” en el diseño de un proyecto; tales constantes (al igual que cualquier otra constante que sea usada por un programa) tienen que ser declaradas de antemano para que un programa las pueda reconocer. Esto lo podemos hacer al abrir un proyecto creando lo que se conoce como un módulo estándard, el cual tiene como extensión de archivo el sufijo .BAS, yendo a la línea de menú de Visual Basic y seleccionando desde la opción “File” (Archivo) la sub-opción “New Form”, y mediante las operaciones de copiado y empastado podemos tomar todo el texto contenido en CONSTANT.TXT copiándolo al módulo estándard de Visual Basic que tendrá un nombre predeterminado como Module1.BAS (el cual podemos cambiar a algo mucho más descriptivo como CONSTANTES.BAS). Todas las declaraciones de las constantes vb, además de ser declaradas mediante el enunciado Const, están dadas usando la palabra clave Global, por ejemplo:
Global Const KEY_LBUTTON = &H1
Global Const KEY_RBUTTON = &H2
Global Const KEY_CANCEL = &H3
Con este tipo de declaración global, todas las constantes vb estarán disponibles para cualquier forma (o formas) así como para cualquier otro tipo de módulo (o módulos) que sean usados en la elaboración del código del programa de aplicación. Aunque el archivo de texto CONSTANT.TXT es un poco extenso, ello no debe causar preocupación al programador, ya que un proyecto Visual Basic puede admitir cientos o inclusive miles de líneas de código, lo cual no se ha apreciado aquí en virtud de que por fines pedagógicos y didácticos se ha tratado de mantener reducido al mínimo el tamaño de cada ejemplo mostrado.
Por completitud, a continuación se proporcionarán los valores de las teclas en el teclado, tanto los valores numéricos como las abreviaturas mnemónicas definidas como constantes vb (en conformidad con la convención de la notación húngara) dentro de Visual Basic.
Empezaremos con las teclas usadas para llevar a cabo operaciones especiales:
Valor | Constante VB | Descripcion |
---|---|---|
&H1 | vbKeyLButton | Boton izquierdo del Mouse |
&H2 | vbKeyRButton | Boton derecho del Mouse |
&H3 | vbKeyCancel | Tecla CANCEL |
&H4 | vbKeyMButton | Boton medio del Mouse |
&H8 | vbKeyBack | Tecla BACKSPACE (Atras) |
&H9 | vbKeyTab | Tecla TAB (Tabulador) |
&HC | vbKeyClear | Tecla CLEAR |
&HD | vbKeyReturn | Tecla ENTER (Intro) |
&H10 | vbKeyShift | Tecla SHIFT |
&H11 | vbKeyControl | Tecla CTRL |
&H12 | vbKeyMenu | Tecla MENU |
&H13 | vbKeyPause | Tecla PAUSE |
&H14 | vbKeyCapital | Tecla CAPS LOCK |
&H1B | vbKeyEscape | Tecla ESC |
&H20 | vbKeySpace | Tecla SPACEBAR |
&H21 | vbKeyPageUp | Tecla PAGE UP |
&H22 | vbKeyPageDown | Tecla PAGE DOWN |
&H23 | vbKeyEnd | Tecla END |
&H24 | vbKeyHome | Tecla HOME |
&H25 | vbKeyLeft | Tecla LEFT ARROW |
&H26 | vbKeyUp | Tecla UP ARROW |
&H27 | vbKeyRight | Tecla RIGHT ARROW |
&H28 | vbKeyDown | Tecla DOWN ARROW |
&H29 | vbKeySelect | Tecla SELECT |
&H2A | vbKeyPrint | Tecla PRINT SCREEN |
&H2B | vbKeyExecute | Tecla EXECUTE |
&H2C | vbKeySnapshot | Tecla SNAPSHOT (PrtScr) |
&H2D | vbKeyInsert | Tecla INS |
&H2E | vbKeyDelete | Tecla DEL |
&H2F | vbKeyHelp | Tecla HELP |
&H90 | vbKeyNumlock | Tecla NUM LOCK |
Las teclas TeclaA hasta la tecla TeclaZ son las mismas que sus equivalentes en código ASCII (véase el anexo titulado “El código ASCII” puesto al final de esta obra):
Valor | Constante VB | Descripcion |
---|---|---|
65 | vbKeyA | Tecla A |
66 | vbKeyB | Tecla B |
67 | vbKeyC | Tecla C |
68 | vbKeyD | Tecla D |
69 | vbKeyE | Tecla E |
70 | vbKeyF | Tecla F |
71 | vbKeyG | Tecla G |
72 | vbKeyH | Tecla H |
73 | vbKeyI | Tecla I |
74 | vbKeyJ | Tecla J |
75 | vbKeyK | Tecla K |
76 | vbKeyL | Tecla L |
77 | vbKeyM | Tecla M |
78 | vbKeyN | Tecla N |
79 | vbKeyO | Tecla O |
80 | vbKeyP | Tecla P |
81 | vbKeyQ | Tecla Q |
82 | vbKeyR | Tecla R |
83 | vbKeyS | Tecla S |
84 | vbKeyT | Tecla T |
85 | vbKeyU | Tecla U |
86 | vbKeyV | Tecla V |
87 | vbKeyW | Tecla W |
88 | vbKeyX | Tecla X |
89 | vbKeyY | Tecla Y |
90 | vbKeyZ | Tecla Z |
Del mismo modo, las teclas numéricas Tecla0 hasta la tecla Tecla9 son las mismas que sus equivalentes en código ASCII (véase el anexo titulado “El código ASCII” puesto al final de esta obra):
Constante | Valor | Descripcion |
---|---|---|
vbKey0 | 48 | Tecla 0 |
vbKey1 | 49 | Tecla 1 |
vbKey2 | 50 | Tecla 2 |
vbKey3 | 51 | Tecla 3 |
vbKey4 | 52 | Tecla 4 |
vbKey5 | 53 | Tecla 5 |
vbKey6 | 54 | Tecla 6 |
vbKey7 | 55 | Tecla 7 |
vbKey8 | 56 | Tecla 8 |
vbKey9 | 57 | Tecla 9 |
En la gran mayoría de los teclados modernos se incluye un conjunto de teclas que corresponden a lo que se conoce como el Pad Numérico:
Para estas teclas, los valores usados por Visual Basic en coordinación con el sistema operativo Windows son los siguientes:
Valor | Constante VB | Descripcion |
---|---|---|
&H60 | vbKeyNumpad0 | Tecla 0 |
&H61 | vbKeyNumpad1 | Tecla 1 |
&H62 | vbKeyNumpad2 | Tecla 2 |
&H63 | vbKeyNumpad3 | Tecla 3 |
&H64 | vbKeyNumpad4 | Tecla 4 |
&H65 | vbKeyNumpad5 | Tecla 5 |
&H66 | vbKeyNumpad6 | Tecla 6 |
&H67 | vbKeyNumpad7 | Tecla 7 |
&H68 | vbKeyNumpad8 | Tecla 8 |
&H69 | vbKeyNumpad9 | Tecla 9 |
&H6A | vbKeyMultiply | Tecla signo multiplicacion (*) |
&H6B | vbKeyAdd | Tecla signo más (+) key |
&H6C | vbKeySeparator | Tecla ENTER (en el Pad) |
&H6D | vbKeySubtract | Tecla signo menos (-) |
&H6E | vbKeyDecimal | Tecla punto decimal (.) |
&H6F | vbKeyDivide | Tecla signo division (/) |
Por último, se tienen las teclas de función ubicadas generalmente en la parte superior del teclado, las cuales no formaban parte de las primeras computadoras caseras pero que resultaron ser extremadamente útiles para poder incorporar funciones especializadas a los programas de aplicación (tales como la tecla F1 usada para obtener información de ayuda en los programas de aplicación):
Valor | Constante VB | Descripcion |
---|---|---|
&H70 | vbKeyF1 | Tecla F1 |
&H71 | vbKeyF2 | Tecla F2 |
&H72 | vbKeyF3 | Tecla F3 |
&H73 | vbKeyF4 | Tecla F4 |
&H74 | vbKeyF5 | Tecla F5 |
&H75 | vbKeyF6 | Tecla F6 |
&H76 | vbKeyF7 | Tecla F7 |
&H77 | vbKeyF8 | Tecla F8 |
&H78 | vbKeyF9 | Tecla F9 |
&H79 | vbKeyF10 | Tecla F10 |
&H7A | vbKeyF11 | Tecla F11 |
&H7B | vbKeyF12 | Tecla F12 |
&H7C | vbKeyF13 | Tecla F13 |
&H7D | vbKeyF14 | Tecla F14 |
&H7E | vbKeyF15 | Tecla F15 |
&H7F | vbKeyF16 | Tecla F16 |
Con mucha frecuencia, al usar una computadora casera nos vemos en la necesidad de oprimir no una sola tecla para obtener cierto resultado en la impresión de caracteres o en la ejecución de alguna acción, sino dos teclas. Un ejemplo es la necesidad de oprimir la tecla SHIFT al oprimir una letra alfabética en el teclado para lograr que se imprima dicha letra no en minúscula sino en mayúscula. ¿Cómo podemos manejar éste tipo de situaciones que involucran la opresión simultánea de dos o inclusive tres teclas en el teclado? Aquí se debe formular de antemano una advertencia: la opresión simultánea de teclas no incluye la opresión de cualquier par de teclas que haya en el teclado; cuando se oprimen las teclas “E” y “L” no esperamos que ocurra ninguna acción diferente que la que esperamos que ocurra cuando se oprimen individualmente dichas teclas; en cambio cuando se oprimen las teclas ALT y “X” hay la posibilidad (dependiendo de cómo se haya elaborado un programa de aplicación) de que ocurra alguna acción especial que la opresión de la tecla ALT o la tecla “X” por sí sola no podría lograr.
Por regla general, las teclas usadas para programar efectos especiales mediante la opresión simultánea de teclas hace uso de las teclas SHIFT, CTRL y ALT (las cuales por sí solas no hacen absolutemente nada).
Para poder hacer uso de combinaciones de ciertas teclas para poner en marcha efectos especiales, tenemos que entender lo que se tiene que llevar a cabo, y para ello tenemos que descender hasta el nivel de la palabra binaria. Resulta que en Visual Basic el argumento Shift, dependiendo del valor numérico que se le asigne es usado no solo para especificar la acción de la tecla SHIFT sino también la acción de las teclas CTRL y ALT así somo cualquier combinación de estas tres teclas. Los eventos del teclado usan el argumento Shift para determinar si las teclas SHIFT, CTRL y ALT son oprimidas, y en qué combinación. Si únicamente la tecla SHIFT es oprimida, el argumento Shift toma el valor de 1 (00000001 binario, en el caso de que la palabra binaria que representa a Shift conste de ocho bits). Si únicamente la tecla CTRL es oprimida Shift toma el valor de 2 (00000010 binario), y si la tecla ALT es oprimida Shift toma el valor de 4 (00000100 binario). Para determinar los valores que corresponden a las combinaciones de estas teclas, usamos el total de dichos valores. Por ejemplo, si SHIFT y ALT son oprimidas al mismo tiempo, Shift es igual a 5 (4+1). En la palabra binaria, los tres bits menos significativos de Shift corresponden al estado de las teclas SHIFT, CTRL y ALT como se muestra en la siguiente figura:
Cualquiera o todos los bits del argumento Shift pueden ser activados, dependiendo del estado (oprimida o no oprimida) de las teclas SHIFT, CTRL y ALT. La siguiente tabla muestra los valores y las constantes predefinidas en Visual Basic así como el significado de cada valor:
Valor binario |
Valor decimal |
Constante VB | Significado |
001 | 1 | vbShiftMask | La tecla SHIFT es oprimida |
010 | 2 | vbCtrlMask | La tecla CTRL es oprimida |
100 | 4 | vbAltMask | La tecla ALT es oprimida |
011 | 3 | vbShiftMask + vbCtrlMask |
Las teclas SHIFT y CTRL son oprimidas |
101 | 5 | vbShiftMask + vbAltMask |
Las teclas SHIFT y ALT son oprimidas |
110 | 6 | vbCtrlMask + vbAltMask |
Las teclas CTRL y ALT son oprimidas |
111 | 7 | vbCtrlMask + vbAltMask + vbShiftMask |
Las teclas SHIFT, CTRL y ALT son oprimidas |
Podemos experimentar con lo anterior abriendo un proyecto nuevo y declarando en la sección de declaraciones de la forma:
a la variable TeclaShift como una variable del tipo Integer:
Dim TeclaShift As Integer
Hecho lo anterior, metemos un control de caja de texto (Textbox) en la forma y metemos el siguiente código en el evento KeyDown() de la caja de texto:
Sub Text1_KeyDown (KeyCode As Integer, Shift As Integer)
TeclaShift = Shift And 7
Select Case TeclaShift
Case 1
Print "Oprimiste la tecla SHIFT"
Case 2
Print "Oprimiste la tecla CTRL"
Case 4
Print "Oprimiste la tecla ALT"
Case 3
Print "Oprimiste SHIFT y CTRL"
Case 5
Print "Oprimiste SHIFT y ALT"
Case 6
Print "Oprimiste CTRL y ALT"
Case 7
Print "Oprimiste SHIFT, CTRL y ALT"
End Select
End Sub
Obsérvese que en el código anterior se usa el operador lógico And para efectuar la operación lógica AND entre el argumento Shift y el valor numérico 7 el cual en los tres bits menos significativos tiene “1” en cada bit y “ceros” en el resto de la palabra binaria. El resultado de la operación lógica AND tiene el efecto de “filtrar” estos tres bits del resto de la palabra binaria Shift poniendo el resto a ceros lógicos, en una operación que se conoce como “máscara lógica” (mask). De aquí devienen abreviaturas como “vbShiftMask”, vbAltMask y vbCtrlMask anteponiéndose “vb” como prefijo de notación húngara para simbolizar una constante propia de Visual Basic.
Se ha introducido en el último ejemplo que se ha dado arriba un método nuevo que no habíamos usado en las entradas anteriores, el método Print, el cual puede poner una hilera de texto en un objeto, en este caso, en la forma (obsérvese que, en contra de lo que algunos pudieran esperar, los mensajes de texto no aparecen dentro de la caja de texto, sino fuera de la caja de texto, esto es, en la forma).
Podemos definir desde luego, en castellano, nuestras propias “máscaras” para filtrar del argumento Shift los bits que identifican cuál de las teclas SHIFT, CTRL y ALT ha sido oprimida, con algo como esto:
Constante | Valor |
MASCARA_SHIFT | 1 |
MASCARA_CTRL | 2 |
MASCARA_ALT | 4 |
Estas constantes así definidas pueden actuar como nuestras “mascarillas” de bits que podemos usar para probar cualquier combinación de teclas. Podemos poner estas constantes ya sea al nivel de un procedimiento o en la sección de Declaraciones (general) de un módulo en donde podemos usar la siguiente sintaxis para declararlas:
Global Const NombreConstante = expresión
De este modo, podemos probar para cierta condición de combinación de teclas asignando primero cada resultado a una variable Integer temporal y comparando el argumento Shift a una máscara de bit. Usamos el operador lógico And para probar si cierta condición es mayor que cero, indicando con ello que el modificador ha sido oprimido, por ejemplo:
AltAbajo = (Shift And MASCARA_ALT) > 0
El siguiente ejemplo, para el cual abrimos un proyecto nuevo y metemos una caja de texto dentro de la forma, nos demuestra un manejador genérico del teclado que responde a la tecla de función F2 y a todas las combinaciones asociadas ALT, SHIFT y CTRL:
Sub Text1_KeyDown (KeyCode As Integer, Shift As Integer)
Dim ShiftAbajo, AltAbajo, CtrlAbajo, Texto
Const TECLA_F2 = &H71
Const MASCARA_SHIFT = 1
Const MASCARA_CTRL = 2
Const MASCARA_ALT = 4
ShiftAbajo = (Shift And MASCARA_SHIFT) > 0
AltAbajo = (Shift And MASCARA_ALT) > 0
CtrlAbajo = (Shift And MASCARA_CTRL) > 0
If KeyCode = TECLA_F2 Then
If ShiftAbajo And AltAbajo And CtrlAbajo Then
Texto = "SHIFT + CTRL + ALT F2"
ElseIf ShiftAbajo And AltAbajo Then
Texto = "SHIFT + ALT F2"
ElseIf ShiftAbajo And CtrlAbajo Then
Texto = "SHIFT + CTRL F2"
ElseIf CtrlAbajo And AltAbajo Then
Texto = "CTRL + ALT + F2"
ElseIf ShiftAbajo Then
Texto = "SHIFT F2"
ElseIf CtrlAbajo Then
Texto = "CTRL + F2"
ElseIf AltAbajo Then
Texto = "ALT F2"
ElseIf Shift = 0 Then
Texto = "F2"
End If
Text1.Text = "Oprimiste " & Texto
End If
End Sub
En el código anterior, así como se pudo imprimir un mensaje distinto que corresponde a cada combinación de teclas, del mismo modo en vez de imprimir un mensaje de texto podemos poner en marcha alguna acción o serie de acciones. Esta es la manera en la cual mediante combinaciones especiales de teclas podemos agregarle funcionalidad a un teclado dándole una cantidad enorme de posibilidades adicionales por encima de las posibilidades que ofrecen por sí solas cada una de las 120 ó más teclas que pueda tener un teclado.
En las declaraciones para los eventos Sub de las teclas, hay una diferencia entre los eventos que corresponden a los dos eventos KeyDown() y KeyUp() y el evento KeyPress(), ya que mientras los primeros dos están especificados como:
KeyDown (KeyCode As Integer, Shift As Integer)
KeyUp (KeyCode As Integer, Shift As Integer)
el tercero, KeyPress(), está especificado con un solo argumento como:
KeyPress (KeyAscii As Integer)
El argumento KeyAscii nos regresa un código de tecla que corresponde al sistema ASCII (ANSI). En la elaboración de un procedimiento, podemos convertir el argumento KeyAscii dado en código ASCII al caracter ASCII que le corresponde mediante la función Chr(), y si se trata de una letra podemos convertirlo de minúsculas a mayúsculas mediante la función Ucase(), como lo muestra el siguiente ejemplo que convierte automáticamente a mayúsculas todo el texto que se vaya escribiendo en una caja de texto puesta dentro de una forma, después de que el código ASCII de la tecla oprimida ha sido convertida al caracter correspondiente:
Sub Text1_KeyPress(KeyAscii As Integer)
Char = Chr(KeyAscii)
KeyAscii = Asc(Ucase(Char))
End Sub
Si se corre este código como se indica, se encontrará que todos los caracteres serán puestos dentro de la caja de texto en letras mayúsculas sin importar en lo absoluto que desde el teclado se active o se desactive la tecla de letras mayúsculas () y sin importar tampoco que se oprima o no la tecla SHIFT. Esto nos muestra cómo es posible tomar un control directo de ciertas cosas arrebatándoselo a la máquina.
El siguiente ejemplo, para el cual abrimos un proyecto nuevo y metemos una caja de texto dentro de la forma, nos muestra la manera en la cual podemos cancelar opresiones de teclas si el caracter que corresponde a la tecla no se encuentra dentro de cierto rango (numérico):
Sub Text1_KeyPress (KeyAscii As Integer)
If KeyAscii < Asc("0") Or KeyAscii > Asc("9") Then
KeyAscii = 0
Beep
End If
End Sub
Si se corre el programa, se verá que todas las opresiones de teclas de número son reconocidas y entran en la caja de texto, pero cualquier otra cosa no provoca que aparezca nada en la caja de texto. Obsérvese que se usa aquí el enunciado Beep que ocasionará que la bocina de la computadora emita un tono audible cuando la tecla oprimida está fuera de rango.
Por regla general, usamos los procedimientos de eventos KeyDown y KeyUp para manejar cualquier opresión de tecla que no es reconocida por KeyPress, como teclas de función, teclas de edición, teclas de navegación y cualquier combinación de estas teclas con los modificadores del teclado. A diferencia de los eventos KeyDown y KeyUp, KeyPress no indica el estado físico del teclado, simplemente pasa un caracter. El argumento KeyPress interpreta lo minúsculo o mayúsculo de cada caracter como códigos de tecla separados, y por lo tanto como dos caracteres distintos; mientras que KeyDown y KeyUp interpretan lo minúsculo o mayúsculo de cada caracter mediante los argumentos Keycode que indica el estado físico de cada tecla (regresando de este modo tanto a “B” como a “b” como la misma tecla) y el argumento Shift que indica el estado se Shift+tecla y por lo tanto regresando ya sea “B” o “b.”
En la construcción de un programa de aplicación que pueda hacer algo que vaya más allá de lo que cualquier programador principiante puede elaborar, entre las cosas que se antojan deseables siempre está la incorporación de una buena ayuda a los usuarios de un programa en donde puedan aclarar sus dudas y puedan enterarse de las capacidades y opciones que ofrece el programa. A manera de ejemplo, en el Notepad (Bloc de Notas) de los sistemas operativos Windows al oprimir la tecla F1 mientras se está usando el Notepad aparece una ventana como la siguiente:
Para poder construír sistemas de ayuda de este tipo, es necesario recurrir a herramientas adicionales. En varios de los sistemas operativos Windows se incluyen compiladores que permiten tomar un archivo fuente especificado inicialmente como un archivo en un formato exótico como .RTF (Rich Text File, reconocido por procesadores de palabras como Microsoft Word), convirtiéndolo a un archivo al cual se le anexa la extensión .HLP; o sea tomando un archivo como DEX.RTF y convirtiéndolo a un archivo como DEX.HLP. De este modo podemos terminar con un archivo de ayuda como DEX.HLP, y haciendo clic con el Mouse sobre un archivo así el sistema operativo automáticamente invocará un programa ejecutable como WINHELP32.EXE (por ejemplo) que se encarga de abrir el archivo DEX.HLP produciendo algo con una presentación más profesional y mucho más rica en opciones (con la inclusión de una barra de Menú y una barra de Herramientas con botones-ícono) que la simple caja de mensaje que se dió arriba:
En un programa de ayuda como éste, al hacer clic con el Mouse en el hipervínculo “Cuadrados Latinos” bajo al rubro EXPERIMENTO puede aparecer un texto explicativo relevante al tema, como el siguiente:
Del mismo modo, al hacer clic en el botón “Calculadora”, es posible que se haga aparecer la “Calculadora” del sistema operativo Windows usualmente puesta dentro de la carpeta de los “Accesorios” o bien alguna calculadora especial diseñada por el programador. Cabe señalar que hubo un tiempo en el que este fue el medio favorito para producir libros electrónicos.
Cabe agregar que los archivos de ayuda del tipo .HLP precedieron la introducción de Windows como sistema operativo (el primer sistema operativo Windows fue Windows 95) y de hecho la tecnología y las convenciones para la construcción de archivos de ayuda al estilo de Microsoft había madurado casi en su totalidad cuando Windows era una mera interfaz visual, en la versión Windows 3.1 para DOS (el compilador para convertir archivos fuente en formato .RTF a archivos .HLP era el archivo ejecutble HC31.EXE, simbolizando Windows Help Compiler for Windows 3.1, precisamente en alusión al hecho de que tales archivos de ayuda podían ser invocados desde la interfaz visual Windows 3.1). En realidad, la transición de Windows como mera interfaz visual invocable desde la línea de comandos DOS a su nueva personalidad como sistema operativo tomando control de la máquina al ser encendida fue simplificada enormemente porque mucha de la tecnología informática para convertir a Windows en un sistema operativo pleno ya estaba desarrollada. El complemento natural desde un principio que antecedió la aparición de Windows 95 fue WinHelp.
Eventualmente, los archivos de ayuda .HLP terminaron siendo reemplazados por archivos de ayuda bajo el formato .CHM (Compiled HTML Help) compatibilizando la ayuda a lo que se acostumbra usar en los navegadores de Internet. Microsoft hubiera desesado que la gran mayoría de las páginas Web incorporaran su diseño de archivos de ayuda invocables desde una línea de menú, pero tal cosa no fue posible no solo porque Microsoft era la propietaria de este tipo de diseño en los archivos de ayuda sino porque estos archivos de ayuda resultaron ser extremadamente vulnerables al ataque de virus informáticos, y .CHM terminó cayendo víctima de los creadores de códigos maliciosos.