2011-05-13 20 views
6

estoy trabajando en un proyecto en el que es necesario para simular las presiones de teclas para provocar comportamientos específicos en una aplicación diferente.Envío de teclas especiales del teclado numérico como +, -,/o Intro (simulando una pulsación prolongada)

Todo está funcionando bien y muy bien, usando la función keybd_event que se importa (que puede haber mejores formas, pero funciona muy bien).

Ahora quiero agregar soporte específico para todo el teclado numérico.

Buscando e. gramo. aquí http://msdn.microsoft.com/en-us/library/dd375731(v=VS.85).aspx o en el espacio de nombres System.Windows.Input.Key, puedo encontrar fácilmente claves para Num0..Num9, así como para NumLock. Pero .. no puedo encontrar nada para Num /, Num +, NumEnter etc.

escribí una rápida froms aplicación para capturar el evento KeyDown, la salida de los parametros de eventos, y tiene algunos resultados interesantes:

e.KeyCode NumLock e.KeyData NumLock e.KeyValue 144 e.Modifiers None 
e.KeyCode Divide e.KeyData Divide e.KeyValue 111 e.Modifiers None 
e.KeyCode Multiply e.KeyData Multiply e.KeyValue 106 e.Modifiers None 
e.KeyCode Subtract e.KeyData Subtract e.KeyValue 109 e.Modifiers None 
e.KeyCode Add e.KeyData Add e.KeyValue 107 e.Modifiers None 
e.KeyCode NumLock e.KeyData NumLock e.KeyValue 144 e.Modifiers None 
e.KeyCode NumLock e.KeyData NumLock e.KeyValue 144 e.Modifiers None 
e.KeyCode Divide e.KeyData Divide e.KeyValue 111 e.Modifiers None 
e.KeyCode Multiply e.KeyData Multiply e.KeyValue 106 e.Modifiers None 
e.KeyCode Subtract e.KeyData Subtract e.KeyValue 109 e.Modifiers None 
e.KeyCode Add e.KeyData Add e.KeyValue 107 e.Modifiers None 
e.KeyCode Return e.KeyData Return e.KeyValue 13 e.Modifiers None 

La tecla Num + (y así sucesivamente) parecen ser teclas que Windows llama teclas de función (como F18 para la tecla num +). Entonces ... eso es extraño, pero está bien.

Pero .. no puedo distinguir la tecla Enter de la llave NumEnter. Esos son diferentes para mi aplicación, así que tengo que enviar códigos clave específicos para ambos.

Y esa es mi pregunta: ¿cómo puedo enviar una tecla enter-ordinaria y cómo puedo enviar una clave NumEnter?

(no sé si se hace alguna diferencia, estoy en un teclado alemán.)

Thx por cualquier idea!

+1

muy útil, pero puedo confirmar: tenemos una entrada del usuario de seguimiento de la aplicación y en este momento se produce el mismo código clave para NumEnter de introducir por lo que no podía distinguir. – Cilvic

Respuesta

0

Dado que estamos hablando de una solución al-otra-manera-ronda, la detección del evento, y yo quiero levantarlo, no tienen ni siquiera para anular el WndProc. Puedo simplemente enviar mis propios mensajes.

Desde su solución, que tenía un aspecto en SendMessage/PostMessage y, a continuación, WM_KEYDOWN y WM_KEYUP. La documentación realmente te da la información (si te ves realmente muy duro).

http://msdn.microsoft.com/en-us/library/ms646280(v=vs.85).aspx
http://msdn.microsoft.com/en-us/library/ms646281(v=vs.85).aspx

Así que mi solución (compila y ahora con la búsqueda de la ventana derecha (donde se introduce el texto)) es la siguiente:

bool keyDown = true; // true = down, false = up 
const uint WM_KEYDOWN = 0x0100; 
const uint WM_KEYUP = 0x0101; 
const int VK_RETURN = 0x0D; 

IntPtr handle = IntPtr.Zero; 
// Obtain the handle of the foreground window (active window and focus window are only relative to our own thread!!) 
IntPtr foreGroundWindow = GetForegroundWindow(); 
// now get process id of foreground window 
uint processID; 
uint threadID = GetWindowThreadProcessId(foreGroundWindow, out processID); 
if (processID != 0) 
{ 
// now get element with (keyboard) focus from process 
GUITHREADINFO threadInfo = new GUITHREADINFO(); 
threadInfo.cbSize = Marshal.SizeOf(threadInfo); 
GetGUIThreadInfo(threadID, out threadInfo); 
handle = (IntPtr)threadInfo.hwndFocus; 
} 

int lParam = 1 << 24; // this specifies NumPad key (extended key) 
lParam |= (keyDown) ? 0 : (1 << 30 | 1 << 31); // mark key as pressed if we use keyup message 
PostMessage(handle, (keyDown) ? WM_KEYDOWN : WM_KEYUP, VK_RETURN, lParam); // send enter 

Esperamos que sea útil para otra persona también. Como fue el consejo de Vendetta para mí.

Y ... si tiene una solución mejor, ¡dígalo!

3

encontré este here funciona para mí!

protected override void WndProc(ref Message m) 
{ 
    if (m.Msg == 256 && m.WParam.ToInt32() == 13) 
    { // WM_KEYDOWN == 256, Enter == 13 
     if ((m.LParam.ToInt32() >> 24) == 0) 
     { 
      MessageBox.Show("main enter pressed!"); 
     } 
     else 
     { 
      MessageBox.Show("numpad enter pressed!"); 
     } 
     } 
     else 
     { 
     base.WndProc(ref m); 
     } 
} 
+0

mucho, eso fue realmente útil. Aunque es lo contrario a lo que estoy buscando :) tiene toda la información para resolver mi problema. Voy a escribir una respuesta de inmediato .. –

+0

¡Muchas gracias a tus respuestas! Especialmente para su idea, Vendetta! Ya que está hablando de una solución al otro lado del camino, detectando el evento, y quiero subirlo, ni siquiera tengo que anular el WndProc. Puedo simplemente enviar mis propios mensajes. De su solución, eché un vistazo a SendMessage, y luego WM_KEYDOWN y WM_KEYUP. La documentación realmente te da la información (si te ves realmente muy duro). http://msdn.microsoft.com/en-us/library/ms646280(v=vs.85).aspx http://msdn.microsoft.com/en-us/library/ms646281(v=vs .85) .aspx –

+0

Así que mi solución (compila pero no ha sido probada) es así: enter bool keyDown; // true = down, false = up const uint WM_KEYDOWN = 0x0100; const uint WM_KEYUP = 0x0101; const int VK_RETURN = 0x0D; // Obtenga el control de la ventana activa. IntPtr handle = GetForegroundWindow(); int lParam = 1 << 24; // esto especifica la tecla NumPad (tecla extendida) lParam | = (keyDown)? 0: (1 << 30 | 1 << 31); // marcamos la tecla presionada si utilizamos el mensaje de teclado PostMessage (handle, (keyDown)? WM_KEYDOWN: WM_KEYUP, VK_RETURN, lParam); –

1

gracias a andreas por proporcionar el comienzo de una solución. Aquí hay una versión más completa:

[DllImport("user32.dll")] 
private static extern IntPtr PostMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam); 
[DllImport("user32.dll")] 
private static extern IntPtr GetForegroundWindow(); 
[DllImport("user32.dll")] 
private static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId); 
[DllImport("user32.dll")] 
private static extern bool GetGUIThreadInfo(uint idThread, out GUITHREADINFO lpgui); 

public struct GUITHREADINFO 
{ 
    public int cbSize; 
    public int flags; 
    public int hwndActive; 
    public int hwndFocus; 
    public int hwndCapture; 
    public int hwndMenuOwner; 
    public int hwndMoveSize; 
    public int hwndCaret; 
    public System.Drawing.Rectangle rcCaret; 
} 

private void sendNumpadEnter() 
{ 
    bool keyDown = true; // true = down, false = up 
    const uint WM_KEYDOWN = 0x0100; 
    const uint WM_KEYUP = 0x0101; 
    const int VK_RETURN = 0x0D; 

    IntPtr handle = IntPtr.Zero; 
    // Obtain the handle of the foreground window (active window and focus window are only relative to our own thread!!) 
    IntPtr foreGroundWindow = GetForegroundWindow(); 
    // now get process id of foreground window 
    uint processID; 
    uint threadID = GetWindowThreadProcessId(foreGroundWindow, out processID); 
    if (processID != 0) 
    { 
     // now get element with (keyboard) focus from process 
     GUITHREADINFO threadInfo = new GUITHREADINFO(); 
     threadInfo.cbSize = Marshal.SizeOf(threadInfo); 
     GetGUIThreadInfo(threadID, out threadInfo); 
     handle = (IntPtr)threadInfo.hwndFocus; 
    } 

    int lParam = 1 << 24; // this specifies NumPad key (extended key) 
    lParam |= (keyDown) ? 0 : (1 << 30 | 1 << 31); // mark key as pressed if we use keyup message 

    PostMessage(handle, (keyDown) ? WM_KEYDOWN : WM_KEYUP, VK_RETURN, lParam); // send enter 
} 
no
Cuestiones relacionadas