Detectando alterações de texto no Word 2016 do suplemento VSTO

Esta questão está intimamente relacionada comComo obter o evento "KeyPress" de um suplemento do Word 2010 (desenvolvido em C #)? (e de fato inclui o código de exemplo da resposta a essa pergunta), mas isso é especificamente sobre o desenvolvimento no Visual Studio (Professional) 2015 para Word 2016 em execução no Windows 10.

Estou tentando detectar quando o texto é alterado em um documento do Word a partir de um suplemento VSTO. Eu entendo de

Como obter o evento "KeyPress" de um suplemento do Word 2010 (desenvolvido em C #)? (14 de novembro de 2011)Captura de evento de keydown do MS Word usando C # (21 de outubro de 2012)Como criar um evento no MS word Keypress (24 de outubro de 2012)Como interceptar um evento de pressionamento de tecla no MSword usando o VSTO? (5 de novembro de 2012)

que não existe uma maneira orientada a eventos para fazer isso. O Word simplesmente não envia eventos quando o texto é alterado.

Vi duas soluções alternativas discutidas:

Use oWindowSelectionChange evento. Infelizmente, esse evento parece ser enviado quando a seleção é alterada pressionando as teclas de seta, usando o mouse, desfazendo ou refazendo e provavelmente outras ações, mas não ao digitar ou excluir.Use um gancho de evento de keydown de baixo nível. Isso foi discutido em várias dessas perguntas do StackOverflow e também foi chamado de "técnica amplamente difundida" emum thread em um fórum do Visual Studio em fevereiro de 2014.

Estou tentando usar o código na resposta paraComo obter o evento "KeyPress" de um suplemento do Word 2010 (desenvolvido em C #)?, e parece observar todos os eventos de pressionamento de teclaexceto aqueles enviados para o Word 2016.

Aqui está o código que estou usando, para facilitar a referência.

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

namespace KeydownWordAddIn
{
    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 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(() => {
                    Debug.WriteLine(pressedKey);
                });
                thread.Start();
            }
            return CallNextHookEx(hookId, nCode, wParam, lParam);
        }

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

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

        #region VSTO generated code
        /// <summary>
        /// Required method for Designer support.
        /// </summary>
        private void InternalStartup()
        {
            this.Startup += new System.EventHandler(ThisAddIn_Startup);
            this.Shutdown += new System.EventHandler(ThisAddIn_Shutdown);
        }
        #endregion
    }
}

Quando executo o Word 2016 com este suplemento, vejo eventos de pressionamento de tecla enviados ao navegador Edge e até ao Visual Studio, mas não ao próprio Word.

Os ganchos de teclas são impedidos de alguma forma no Word 2016 ou estou fazendo algo errado?

questionAnswers(2)

yourAnswerToTheQuestion