4

I am trying to catch events when user is typing in Word in my Add-in and I have the following code

delegate IntPtr HookProc(int nCode, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll", CharSet=CharSet.Auto)]
static extern IntPtr SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hMod, int dwThreadId);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr GetModuleHandle(string lpModuleName);
[DllImport("user32.dll")]
static extern bool UnhookWindowsHookEx(IntPtr hhk);
[DllImport("user32.dll")]
static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);
const int WH_KEYBOARD_LL = 13;
const int WM_KEYDOWN = 256;
static IntPtr hook;
static void Main()
{
    HookProc hp = new HookProc(HookCallback);
    hook = SetWindowsHookEx( WH_KEYBOARD_LL, hp, GetModuleHandle(Process.GetCurrentProcess().MainModule.ModuleName), 0 );
    //UnhookWindowsHookEx( hook );
    //GC.KeepAlive( hp );
}
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();
        var thread = new Thread(() => { MessageBox.Show(pressedKey); });
        thread.Start();
    }
    return CallNextHookEx(hook, nCode, wParam, lParam);
}

generally it works when I type in any application except in the instance of MS Word which runs the add-in. Any ideas why is the Word ignored?

Thanks

m3div0
  • 1,556
  • 3
  • 17
  • 32

1 Answers1

1

I have a similar issue, though the only solution (and a bad one) appears to be:

  • Create a separate process
  • Use shared memory or some other simple communications method to inform the DLL / VSTO running in Word.

(other David) - can you respond to this if you have a better solution, as the one I've outlined above, while it'll work - is appallingly bad. I'm hoping there's a far better explanation for why Word blocks keypresses originating within the app.

David Ford
  • 695
  • 1
  • 6
  • 13
  • Hi, this works for me. I do not see keypresses while in my COM plugin for Word, but if I move my hook to a completely different process, I see Word keypresses. Thanks! – mdiehl13 Sep 28 '15 at 09:53
  • Hi, I haven't found any other solution and I still don't know why word blocks its own hooks. However, back then, I've decided to choose different approach and therefore I abandoned the idea of monitoring keypresses from addin. – m3div0 Sep 28 '15 at 13:59
  • One other comment. I used to use a timer in Word to check where the cursor's position is (if it changed, then the user was typing). Something similar to: _doc.ActiveWindow.Selection.Range.End/Start (note, you can't do that directly since you need to get handles to each one and dispose of them immediately after). Anyway, a problem with this method is that if you check more often than once every 1-2 seconds, Word will return the same location. Even if the location has changed! It's not reliable. – mdiehl13 May 22 '16 at 02:39