2011-07-27 21 views
9

necesito para detectar cuando un usuario presiona Ctrl + V (independientemente del foco de la ventana - mi aplicación es probable que se reduce al mínimo), pero no debe detener el funcionamiento real de pasta .Detección Ctrl + V con RegisterHotKey pero no intercepte

he intentado un par de cosas: (estoy vinculante con éxito a las pulsaciones de teclado con RegisterHotKey)

tengo:

protected override void WndProc(ref Message m) 
{ 
    if (m.Msg == 0x312) 
    hotKey(); 
    base.WndProc(ref m); 
} 

y he intentado lo siguiente:

void hotKey() 
{ 
    SendKeys.SendWait("^v"); //just puts 'v' instead of clipboard contents 
} 

y

void hotKey() 
{ 
    SendKeys.SendWait(ClipBoard.GetText()); 
    /* This works, but since Ctrl is still down, it triggers 
    * all the shortcut keys for the app, e.g. if the keyboard 
    * contains 's' then instead of putting 's' in the app, it 
    * calls Ctrl+S which makes the app think the user wants 
    * to save. 
    */ 
} 

Actualmente, la única solución de trabajo que tengo es unirme a algo diferente, p. Ctrl + B y luego llame al SendKeys.SendWait("^v"); sin embargo, esto no es ideal.

Una solución ideal sería si mi ventana no interceptara la pulsación de tecla en primer lugar, simplemente reaccionó.

+1

¿Puedes aclarar tu pregunta? Tengo problemas para entender tu intención. Usted mencionó que solo quiere detener la operación de pegado real, pero ¿por qué está tratando de enviar Ctrl + V nuevamente en su primera implementación de tecla de acceso directo()? ¿Estoy en lo cierto al asumir que desea interceptar operaciones de pegado en todo el sistema y almacenar los valores del portapapeles en su aplicación? –

+0

No, escribí "I * must not * stopped the real paste operation". Deseo detectar las operaciones de pegado en todo el sistema y luego reemplazar el contenido del portapapeles para que el usuario pueda presionar Ctrl + V varias veces y cada vez que se pegue el siguiente elemento. El programa es para ayudar a acelerar (y prevenir errores) a una persona que ingresa datos. – Ozzah

+0

Ok. Lo leí mal Puede usar ganchos de Windows para esto. Ver mi respuesta a continuación. –

Respuesta

12

Puede hacerlo aprovechando los ganchos usando SetWindowsHookEx().

HHOOK WINAPI SetWindowsHookEx(
    __in int idHook, 
    __in HOOKPROC lpfn, 
    __in HINSTANCE hMod, 
    __in DWORD dwThreadId 
); 

Básicamente, se puede establecer un enlace de teclado de bajo nivel:

_hookHandle = SetWindowsHookEx(
    WH_KEYBOARD_LL, 
    KbHookProc,     // Your keyboard handler 
    (IntPtr)0, 
    0);       // Set up system-wide hook. 

para capturar eventos de teclado de todo el sistema. Pero también le permite hacer que esos eventos de teclado pasen a otras aplicaciones. Para su caso particular, se puede definir como KbHookProc:

private static int KbHookProc(int nCode, IntPtr wParam, IntPtr lParam) 
{ 
    if (nCode >= 0) // This means we can intercept the event. 
    { 
     var hookStruct = (KbLLHookStruct)Marshal.PtrToStructure(
       lParam, 
       typeof(KbLLHookStruct)); 

     // Quick check if Ctrl key is down. 
     // See GetKeyState() doco for more info about the flags. 
     bool ctrlDown = 
       GetKeyState(VK_LCONTROL) != 0 || 
       GetKeyState(VK_RCONTROL) != 0; 

     if (ctrlDown && hookStruct.vkCode == 0x56) // Ctrl+V 
     { 
      // Replace this with your custom action. 
      Clipboard.SetText("Hi"); 
     } 
    } 

    // Pass to other keyboard handlers. Makes the Ctrl+V pass through. 
    return CallNextHookEx(_hookHandle, nCode, wParam, lParam); 
} 

que codifica una aplicación de Windows Forms rápidos y sucios para ilustrar esto. Para obtener la lista completa del código, vea http://pastebin.com/uCSvqwb4.

+0

Intenté convertir esto para ejecutarlo como una aplicación de consola, y simplemente no funcionará. Corte y pegue en una aplicación de Winforms, y funciona bien ... ¿Alguna idea de por qué? – codeputer

+1

Creo que lo tengo resuelto: ServiceWindowsHookEx requiere un bucle de mensaje dentro del hilo que está ejecutando el código, casi seguro que no tiene ningún bucle de mensaje. – codeputer

Cuestiones relacionadas