Red de conocimiento informático - Material del sitio web - Cómo simular la entrada del teclado para todas las aplicaciones

Cómo simular la entrada del teclado para todas las aplicaciones

1. En Microsoft Windows, el teclado y el mouse son dos fuentes estándar de entrada del usuario y, a menudo, se usan juntos en algunas operaciones superpuestas. Por supuesto, los ratones se utilizan en más aplicaciones hoy que hace 10 años. Estamos aún más acostumbrados a utilizar ratones en determinadas aplicaciones, como juegos, programas de dibujo, programas de música y navegadores web. Pero si bien podemos prescindir del mouse, no podemos quitar el teclado de una PC normal.

La forma en que los programas de Windows obtienen la entrada del teclado: la entrada del teclado se pasa al proceso de ventana del programa en forma de mensajes. De hecho, cuando se aprende por primera vez sobre los mensajes, el teclado es un ejemplo obvio del tipo de información que los mensajes deben transmitir a una aplicación.

Windows utiliza ocho mensajes diferentes para comunicar diferentes eventos del teclado. Esto puede parecer demasiado, pero (como hemos visto) el programa puede ignorar al menos la mitad de estos mensajes sin ningún problema. Además, en la mayoría de los casos, estos mensajes contienen más información del teclado de la que necesita el programa. Parte del manejo de un teclado es reconocer qué información es importante y cuál no.

2. Conceptos básicos del teclado

Aunque en muchos casos, las aplicaciones pueden usar el mouse para ingresar información, el teclado sigue siendo un dispositivo de entrada importante e irreemplazable en la PC.

Cuando se utiliza un teclado como dispositivo de entrada, se genera una interrupción cada vez que el usuario presiona o suelta una tecla, activando el controlador de teclado KEYBOARD.DRV para manejar las interrupciones del teclado. El programa KEYBOARD.DRV codifica diferentes operaciones de usuario y luego llama al módulo de usuario de Windows USER.EXE para generar mensajes de teclado y enviarlos a la cola de mensajes para su procesamiento.

1. Códigos de escaneo y códigos virtuales

Los códigos de escaneo corresponden a diferentes teclas del teclado. Cada tecla genera un código de escaneo único cuando se presiona o se suelta. Los códigos de escaneo dependen del dispositivo de hardware específico, es decir, diferentes máquinas pueden generar códigos de escaneo diferentes cuando se presiona o suelta la misma tecla. Es común que los programas utilicen código virtual independiente del dispositivo definido por el sistema de Windows. Mientras se presiona una tecla se genera un código de escaneo, el controlador de teclado KEYBOARD.DRV intercepta el código de escaneo de la tecla y lo convierte en el código virtual correspondiente, y luego codifica el código de escaneo y el código virtual juntos para formar información del teclado. Por lo tanto, el mensaje final del teclado enviado a la cola de mensajes contiene el código de escaneo y el código ficticio.

Los códigos virtuales de uso común se definen en el archivo WINDOWS.H. Los valores, símbolos constantes y significados de los códigos virtuales de uso común se muestran en la tabla.

Valor (hexadecimal) Significado del símbolo constante

01 VK_LBUTTON botón izquierdo del mouse

02 VK_RBUTTON botón derecho del mouse

03 VK_CANCEL Tecla Break Break

04 VK_MBUTTON Botón central del ratón

05-07 -- Indefinido

08 Tecla VK_BACK (Retroceso)

09 Tecla Tabulador VK_TAB

0A-0B -- Indefinido

08 Tecla VK_BACK (Retroceso)

09 Tecla Tabulador VK_TAB

0A-0B -- Indefinido

0A-0B -- Indefinido

0A-0B Indefinido

0C VK_CLEAR borrar clave

0D VK_RETURN Introducir claves

0E-0F -- indefinido

10 Tecla Mayús VK_SHIFT

11 VK_CONTROL presiona la tecla Ctrl

12 VK_MENU presiona la tecla Alt

13 VK_PAUSE Tecla de pausa

14 VK_CAPTIAL Tecla Bloq Mayús

15 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Clave 19 -- Sistema de caracteres chinos reservados

1A -- Indefinido

1B VK_ESCAPE Tecla Esc

1C-1F -- Sistema de caracteres chinos reservado

1B VK_ESCAPE Tecla Esc

1C-1F. Sistema de caracteres chinos reservado

20 Tecla de espacio VK_SPACE

21 Tecla VK_PRIOR PageUp

22 Tecla VK_NEXT PageDown

23 Tecla de fin VK_END

24 Tecla de inicio VK_HOME

25- Tecla de retención OEM

2B Tecla de ejecución VK_EXECUTE

2C Tecla de impresión de pantalla VK_SNAPSHOT

2D VK_INSERT insertar clave

2E VK_DELETE eliminar clave

2F VK_HELP clave de ayuda

30---.

39 VK_0-VK_9 Teclas numéricas 0-9

3A-40 -- Indefinido

41-5A VK_A-VK_Z Teclas de letras A-Z

5B-5F - - Indefinido

60-69 VK_NUMPAD0-VK_NUMPAD9 Teclas numéricas 0-

6A VK_MULTIPLY * tecla (multiplicación)

6B VK_ADD + tecla (suma)

p>

6C VK_SEPAPATOR Tecla separadora

6E VK_SUBTRACT - Tecla (signo menos)

6F VK_DECIMAL Tecla (decimal)

70-87 VK_DIVIDE / Tecla (división)

88-8F VK_F1-VK_F24 Teclas de función F1-F24

90 Tecla de bloqueo numérico VK_NUMBERLOCK

91 Tecla de bloqueo de desplazamiento VK_SCROLL

92-B9 -- Indefinido

BA-C0 -- OEM reservado

C1-DA -- Indefinido

DB_E4 -- OEM reservado

E5 -- Indefinido

E6 -- OEM reservado

E7-E8 -- Indefinido

E9-F5 - - OEM reservado

F6-FE - Indefinido

2. Enfoque de entrada

Al mismo tiempo, es posible que se estén ejecutando varios programas diferentes en Windows. Esto significa que existen varias ventanas en. al mismo tiempo. En este momento, el teclado está ocupado por varias ventanas, pero solo una ventana puede recibir mensajes del teclado. Esta ventana que puede recibir mensajes del teclado se llama ventana con foco de entrada.

La ventana con foco de entrada debe ser la ventana actualmente activa o una ventana secundaria de la ventana activa, con su título y borde resaltados para distinguirla de otras ventanas. También puede ser un ícono en lugar de la ventana con foco de entrada, en cuyo caso Windows también enviará información al ícono, pero en un formato ligeramente diferente.

Un procedimiento de ventana puede hacer que un formulario gane o pierda el foco de entrada enviando mensajes WM_SETFOCUS y WM_KILLFOCUS. Los programas también pueden determinar cuándo un formulario gana o pierde el foco de entrada capturando los mensajes WM_SETFOCUS y WM_KILLFOCUS. El mensaje WM_SETFOCUS indica que la ventana está ganando el foco de entrada y el mensaje WM_KILLFOCUS indica que la ventana está perdiendo el foco de entrada.

3. Mensajes de teclado

Los mensajes de teclado se dividen en mensajes clave del sistema y mensajes clave que no son del sistema. La información clave del sistema es la información clave generada por la combinación de la tecla de popa y otras teclas. El mensaje WM_SYSKEYDOWN se genera cuando se presiona la tecla del sistema y el mensaje WM_SYSKEYUP se genera cuando se suelta la tecla del sistema. Las combinaciones de teclas que consisten en el botón izquierdo y otras teclas se utilizan a menudo para seleccionar entre menús de programas y menús del sistema, o para cambiar entre diferentes programas. Por lo tanto, la información clave del sistema debe dejarse en manos de Windows. Los programas escritos por el usuario generalmente no procesan información clave del sistema, sino que la envían a la función DefWindowProc. Si el usuario desea procesar la información de la clave del sistema, debe enviarla a la función DefWindowProc después de procesar la información de la clave del sistema para que el sistema Windows pueda funcionar correctamente.

Alguna información clave se puede convertir en información de caracteres, como teclas de letras, teclas numéricas, etc. Algunas teclas solo generan información de clave pero no información de caracteres, como la tecla Mayús, la tecla Insertar, etc. La función TranslateMessage en el bucle de mensajes puede convertir información clave en información de caracteres.

Cuando la función GetMessage captura el mensaje WM_SYSKEYDOWN o el mensaje WM_KEYDOWN, la función TranslateMessage determinará si la clave que generó el mensaje se puede convertir en un mensaje de caracteres. Si es así, el mensaje se convertirá en un mensaje de caracteres y luego el carácter convertido. El mensaje se enviará a través de la función DispatchMessage. Enviado a la cola de mensajes. Hay cuatro tipos de información de caracteres***, como se muestra en la siguiente tabla.

Caracteres caracteres del sistema caracteres que no son del sistema

Caracteres binarios WM_SYSCHAR WM_CHAR

Caracteres muertos WM_SYSDEADCHAR WM_DEADCHAR

Esto es causado por algunos teclados especiales Windows generalmente ignora los mensajes generados por caracteres inactivos causados ​​por pulsaciones de teclas. Windows generalmente ignora los mensajes generados por caracteres inactivos.

Los mensajes de Windows generalmente se pasan a los controladores de mensajes a través de variables de estructura MSG. Para mensajes de teclado, los campos más importantes en las variables de estructura MSG son los campos lParam y wParam. Para información que no es de caracteres, el campo wParam almacena el código de clave virtual de la clave; para información de caracteres, el campo wParam no almacena el código ASCII del carácter. De hecho, una variable lParam de 32 bits se divide en seis partes, que registran la siguiente información relevante: el número de repeticiones, el código de escaneo OEM, el indicador de clave extendido, el indicador de clave relacionado, el estado de la última pulsación de tecla y el estado. de la última pulsación de tecla. El significado de cada bit en el campo lParam se muestra en la tabla.

Significado del bit

0-15 Número acumulado de repeticiones de teclas

16-23 Código de escaneo OEM

24 Si se trata de un modelo extendido tecla

p>

25-28 Indefinido

Si 29 ​​es una tecla asociada y si la tecla Alt se presiona al mismo tiempo.

30 Último estado de la clave, 0 significa que se levantó el último estado de la clave, 1 significa que se presionó el último estado de la clave

31 Estado de transición

La secuencia de pulsación de teclas es diferente y la información generada también es diferente. Por ejemplo, al presionar y soltar la tecla 1, el proceso de lectura producirá secuencialmente los tres datos que se muestran en la tabla. Mensaje generado al presionar la tecla 1 y el valor de wParam

Mensaje valor de la variable wParam

WM_KEYDOWN código virtual 1

WM_CHAR código ASCII "1"

WM_KEYUP código ficticio 1

Si presiona la tecla Shift y luego presiona y suelta la tecla 1, la información que se muestra en la tabla se genera en secuencia. Información generada al presionar 1 y valor de wParam después de presionar la tecla Shift

Información valor de la variable wParam

Código virtual WM_KEYDOWN VK_SHIFT

Código virtual WM_KEYDOWN VK_1

WM_CHAR código ASCII "1"

WM_KEYUP código virtual VK_1

WM_KEYUP código virtual VK_SHIF

Ejemplo de aplicación de teclado

A continuación se muestra Un ejemplo de aplicación que ilustra cómo manejar mensajes de teclado en programación real.

#include

#include

//Variables globales

RECT rc //Registra el área rectangular del desplazamiento; screen

int xChar, yChar; //Coordenadas del punto de entrada de texto

WNDCLASSEX wnd; //Variable de estructura de clase de ventana

char szAppName[ ] = "Programa de monitoreo de mensajes de teclado";//Nombre de clase de ventana

/Declaración de función

LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

BOOL MyRegisterClass (HINSTANCE hInstance);

BOOL InitInstance(HINSTANCE hInstance,int iCmdShow);

//Función: WinMain

//Rol: Función de entrada

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR szCmdLine,int iCmdShow)

{

MSG msg;

if( !MyRegisterClass( hInstance))

{

return FALSE;

}

if(!InitInstance(hInstance,iCmdShow))

{

devuelve FALSO;

}

mientras (GetMessage (&msg, NULL, 0, 0))

{

TranslateMessage (&msg);

DispatchMessage (&msg );

}

return msg.wParam;

}

// Función: ShowKey

// Propósito: mostrar información clave en la ventana

void ShowKey (HWND hwnd, int iType ,char * szMessage,WPARAM wParam, LPARAM lParam)

{

Carbón estático *szFormat[2] ={"%-14s %3d %c %6u %4d %5s % 5s %6s %6s",

"%-14s %3d %c %6u %4d %5s %5s %6s %6s" };

char szBuffer[80];

HDC hdc;

ScrollWindowEx(hwnd, 0, -yChar, &rc,&rc,NULL,NULL,SW_INVALIDATE).

hdc = GetDC (hwnd)

p>

SelectObject (hdc, GetStockObject (SYSTEM_FIXED_FONT));

TextOut (hdc,

xChar,

rc.bottom - yChar,

p>

szBuffer,

wsprintf szBuffer,

szFormat[iType],

szMessage, //mensaje

wParam, //v

código de clave virtual

(BYTE) (iType ?wParam :' '), // Mostrar valor del carácter

LOWORD (lParam), // Número de repeticiones

HIWORD (lParam) & 0xFF, // Código de escaneo de teclado OEM

// Determinar si se deben usar las teclas extendidas del teclado mejorado

(PSTR) (0x01000000 & lParam ?Sí ":"No "),

//Determinar si usar la tecla ALT al mismo tiempo

(PSTR) (0x20000000 & lParam ? "Sí": "No") ,

( PSTR) (0x40000000 & lParam ?"Press" : "Lift"),

//Juzga la pulsación de tecla anterior

(PSTR) (0x80000000 & lParam ? "pressed" : "raised"))

//¿Juzgar el estado de transición?

);

ReleaseDC (hwnd, hdc); ?

ValidateRect (hwnd, NULL ?

}

// Función: WndProc

/ / Función: Procesar mensajes desde la ventana principal

LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)

{

static char szTop[] = "Caracteres clave del mensaje Conteo repetido Código de escaneo Código de extensión ALT Estado anterior Estado de conversión";

static char szUnd[] = "_______ __ ____ _____ ______ ___ _______ ______";

/En ventana Mostrar texto como título del mensaje

HDC hdc;

PAINTSTRUCT ps;

TEXTMETRIC tm;

switch (iMsg)

{

case WM_CREATE: //Creación de ventana de procesamiento&tm);

xChar = tm.WM_CREATE: //Creación de ventana de procesamiento&tm);