none
global keyboard hook does not work in word 2016 . why? how can i make it work ? RRS feed

  • Question

  • Hi . I'm trying to right an addin for word using vsto to get the keydown event and identify it .then if the key was shift+( then replace ( with () and put the cursor in the middle of them so that the user will be able to write in the middle after openningparenthesis . the code i found works fine in word  2010 and 2007 but in higher versions you have to open the onscreen keyboard to make it work

    this is my code:

    using System;
    using System.Diagnostics;
    using System.Runtime.InteropServices;
    using System.Threading;
    using System.Windows.Forms;
    using Word = Microsoft.Office.Interop.Word;
    
    namespace Word2016AddIn
    {
    
        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);
           
    
            [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(HookCallback);
            }
    
            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 IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
            {
                try
                {
                    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(() =>
                        {
                            
    
                            if (Control.ModifierKeys != 0 && pointerCode == 48 && Keys.Shift != 0)
                            {
                                //    
                                Microsoft.Office.Interop.Word.Selection currentSelection = Application.Selection;
                                if (currentSelection.Type == Word.WdSelectionType.wdSelectionIP)
                                {
    
                                    currentSelection.TypeBackspace();
                                    currentSelection.TypeText("()");
                                    currentSelection.MoveLeft(1);
    
                                    pointerCode = 0;
                                }
                                else
                                    if (currentSelection.Type == Word.WdSelectionType.wdSelectionNormal)
                                {
                                    currentSelection.TypeBackspace();
                                    currentSelection.MoveLeft(1);
                                    currentSelection.TypeText("()");
                                    pointerCode = 0;
    
                                }
                                else
                                {
                                    // Do nothing.
                                }
                            }
                            else
                            {
    
                            }
    
                        });
                        thread.Start();
                    }
                    
                }
                catch
                {
    
                }
    
                return CallNextHookEx(hookId, nCode, wParam, lParam);
            }
    
            private void InternalStartup()
            {
                this.Startup += new System.EventHandler(ThisAddIn_Startup);
                this.Shutdown += new System.EventHandler(ThisAddIn_Shutdown);
            }
        }
    
    }


    Monday, July 10, 2017 6:25 AM

All replies

  • Hello,

    I could reproduce your issue in Office 2016. And it works with Office 2010. In Office 2016, the HookCallback doesn't fire when pressing any keys. After researching, the issue does exists in Office 2013 and Office 2016. I suggest you submit your feedback on https://officespdev.uservoice.com/

    Regards,

    Celeste


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Thursday, July 13, 2017 1:35 AM
    Moderator
  • Thank you Celeste Li.
    Saturday, July 15, 2017 4:07 AM
  • You are welcome. If you have any new issues related to Office object model, please feel free to post new threads here.


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Tuesday, July 18, 2017 9:40 AM
    Moderator