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?