2011-11-14 12 views
14

¿Cómo puedo "atrapar" el evento KeyPress de un complemento de Word 2010 desarrollado en C#?¿Cómo obtener el evento "KeyPress" de un complemento de Word 2010 (desarrollado en C#)?

Nota: No estoy buscando soluciones "complejas" como enganchar cosas, pero para el bonito y ordenado .NET incluso desde el modelo de objetos.

El objeto de la aplicación que tengo "en mis manos" es:

Microsoft.Office.Interop.Word.Application

Saludos

+0

autohotkey: http://stackoverflow.com/questions/31470984/capturing-keydown-event-of-ms-word – wideweide

Respuesta

17

Lamentablemente no está incorporado nada en la API de Palabra o VSTO que puede recoger trazos de teclas, se puede encontrar más información al respecto here

He estado buscando una solución factible durante algún tiempo, pero lo mejor que pude encontrar fue manejarla a través de la API de Windows utilizando ganchos , Lo más probable es que se llega a la misma conclusión por lo que aquí está un ejemplo:

Usted tendrá que añadir una directiva using a los siguientes grupos:

using System; 
using System.Diagnostics; 
using System.Runtime.InteropServices; 
using System.Threading; 
using System.Windows.Forms; 

y aquí está el gancho:

public partial class ThisAddIn 
    { 
     private const int WH_KEYBOARD_LL = 13; 
     private const int WM_KEYDOWN = 0x0100; 

     private static IntPtr hookId = IntPtr.Zero; 
     private delegate IntPtr HookProcedure(int nCode, IntPtr wParam, IntPtr lParam); 
     private static HookProcedure procedure = HookCallback; 

     [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
     private static extern IntPtr GetModuleHandle(string lpModuleName); 

     [DllImport("user32.dll", SetLastError = true)] 
     private static extern bool UnhookWindowsHookEx(IntPtr hhk); 

     [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
     private static extern IntPtr SetWindowsHookEx(int idHook, HookProcedure lpfn, IntPtr hMod, uint dwThreadId); 

     [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
     private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam); 

     private void ThisAddIn_Startup(object sender, System.EventArgs e) 
     { 
      hookId = SetHook(procedure); 
     } 

     private void ThisAddIn_Shutdown(object sender, System.EventArgs e) 
     { 
      UnhookWindowsHookEx(hookId); 
     } 

     private static IntPtr SetHook(HookProcedure procedure) 
     { 
      using (Process process = Process.GetCurrentProcess()) 
      using (ProcessModule module = process.MainModule) 
       return SetWindowsHookEx(WH_KEYBOARD_LL, procedure, GetModuleHandle(module.ModuleName), 0); 
     } 

     private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam) 
     { 
      if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN) 
      { 
       int pointerCode = Marshal.ReadInt32(lParam); 
       string pressedKey = ((Keys)pointerCode).ToString(); 

       //Do some sort of processing on key press 
       var thread = new Thread(() => { MessageBox.Show(pressedKey); }); 
       thread.Start(); 
      } 
      return CallNextHookEx(hookId, nCode, wParam, lParam); 
     } 

     private void InternalStartup() 
     { 
      this.Startup += new System.EventHandler(ThisAddIn_Startup); 
      this.Shutdown += new System.EventHandler(ThisAddIn_Shutdown); 
     } 
    } 
+0

¿Por qué el código de procesamiento está dentro de un hilo? En mis propias pruebas, CallNextHookEx parece fallar si el procesamiento NO está enhebrado, pero no puedo encontrar ninguna documentación sobre _why_. –

+1

El código anterior no está atrapando el tipo de carácter en MS Word, simplemente fuera de la palabra –

0

Puede intentar usar el Excel WebBrowser Control en lugar del System.Windows.Forms WebBrowser; que maneja el reenvío de clave especial como TAB, DEL, CTRL + V, etc.

Para que el cambio del contructor WebBrowser desde

new System.Windows.Forms.WebBrowser(); 

a

new Microsoft.Office.Tools.Excel.Controls.WebBrowser(); 

que tendría que añadir referencias a su proyecto: Proyecto/Agregar referencia/Extensiones seleccione Microsoft.Tools.Outlook & Microsoft.Tools.Outlook.v4.0.Utilities

Cuestiones relacionadas