VSTO Word 2016: Squiggly подчеркивание без ущерба для отмены

Я работаю над инструментом анализа языка в реальном времени, который должен выделить слова, чтобы привлечь внимание писателя в Word 2016, используя надстройку VSTO, написанную на .NET4.6.1 с С#. Подумайте о проверке грамматики/орфографии, которая добавляет короткую строку под словом, чтобы показать вам, что слово имеет грамматические или орфографические ошибки. Я добавляю подобную функцию для некоторых моих собственных определенных правил.

Я искал вокруг, добавляя крутые линии, и наткнулся на Font.Underline и Font.UnderlineColor. Я установил это на диапазон слова, и, похоже, при условии, что визуальный stumili я был после, чтобы привлечь внимание. Однако есть проблема. Каждое подчеркивание я добавляю или подчеркиваю цвет, который я меняю, добавляет действие отмены в стек отмены.

Я не хочу, чтобы это произошло, или я хочу, чтобы вы могли применить действие, которое я только что сделал в коде из стека. Цель состоит в том, чтобы пользователь мог использовать CTRL + Z, чтобы удалить текст, который он изменил, и не повлиять на мой результат анализа языка.

Как мне это сделать?

Ответ 1

Я наткнулся на этот вопрос, который задает точно то же самое: Предотвратить добавление действий к слову отмены отмены ИЛИ Удалить действия из отмены CommandBarComboBox

Как отметил @Manu, тот же вопрос был задан в MSDN, где был ответ:

Метод UndoClear опустит список. Это лучшее, что вы можете сделать.

Здесь также есть аналогичный вопрос Word VSTO переопределить CTRL + Z/CTRL + Y  который предлагает маршрут Microsoft.Office.Interop.Word.UndoRecord или MessageHooks в AddIns.


После большего исследования я заметил отличную идею в конце этой темы: MSDN Нарисуйте мои собственные squigglies на документе Word, где вы отслеживаете ваших действий, а затем пропустить их в операциях отмены и повтора.

Вот отличный пример кода для транзакции undo/redo's Могу ли я создать транзакцию отмены в Word или Excel? (VSTO). Вы можете сделать этот же метод в VSTO, за исключением одной большой проблемы, как отметил Дирк Фолмар в своем ответе:

Я не думаю, что перезапись встроенных команд Word возможна только с помощью VSTO, хотя

Я перезаписал некоторые встроенные команды в VSTO с помощью событий подключения клавиатуры для перехвата команд: Как выполнить событие .Onkey в надстройке Excel, созданной с помощью Visual Studio 2010? Однако я не уверен, что вы можете воссоздать ленту, чтобы перехватывать команды кнопок. Более конкретно, Undo и Redo являются встроенными галереями в интерфейсе Ribbon, и вы ничего не можете сделать со встроенной галереей лент. И в таких версиях, как 2010, кнопки "Отменить/Повторить" находятся в строке заголовка - и вы не можете добавлять/редактировать кнопки в строке заголовка, используя VSTO:

введите описание изображения здесь

Итак, если вы заинтересованы в том, чтобы захватить команды кнопок (все, что я знаю, использует Ctrl + Z и Y), вы можете ввести код VBA, чтобы получить доступ к событиям EditUndo и EditRedo, например:

VB._VBComponent vbModule = VBProj.VBE.ActiveVBProject.VBComponents.Add(VB.vbext_ComponentType.vbext_ct_StdModule);
String functionText = "Public Sub EditUndo() \n";
functionText += "MsgBox \"Undo Happened\"\n";
functionText += "End Sub";
vbModule.CodeModule.AddFromString(functionText);

Основная проблема с этим подходом заключается в том, что Trust должен быть предоставлен.


Другой ответ в этом же QA Могу ли я создать транзакцию отмены в Word или Excel? (VSTO) - Майк Риган, который ответил через 3 месяца после Дирка. Он использовал скрытый документ и поместил его в реальный документ, когда это необходимо, чтобы любое количество действий VSTO было отменено.

Все еще не решает проблему предотвращения записи действия в Истории отмены.


Я попробовал ключ реестра, чтобы ограничить UndoHistory до 0 и reset обратно до 100 (чтобы отключить Историю при добавлении действия), но она появляется только для Excel https://support.microsoft.com/en-gb/kb/211922

Там может быть недокументированный ключ реестра, чтобы полностью отключить историю отмены/повтора, но он будет прочитан только Word при запуске. Я думал, что ключ UndoHistory, содержащий число, будет прочитан перед каждым Undo/Redo, но не удастся с этим подходом вообще.


Нелегкая проблема для решения есть большие ограничения, поэтому может быть проще:

a) Примите, что надстройка надстройки заклинания/грамматика включена в список отмены/повтора (поражение).

b) Разработайте, где строка/текст находится на экране, и покажите прозрачную подсказку, освещающую проблему. Это намного сложнее, чем кажется, и является менее идеальным, вот два отличных ответа, которые помогут вам в этом методе: Обнаружение изменений текста в Word 2016 из надстройки VSTO или гораздо более простой подход для определения позиций XY из этого потока электронной почты Microsoft: https://groups.google.com/forum/#!topic/microsoft.public.word.vba.general/pKq4PsqD3cM

//position dialog relative to word insertion point (caret)
int left = 0;
int top = 0;
int width = 0;
int height = 0;
MSWord.Range r = Globals.ThisDocument.Application.Selection.Range;
MSWord.Window w = Globals.ThisDocument.ActiveWindow;

w.GetPoint(out left, out top, out width, out height, r);

frmPopUp newForm = new frmPopUp();
newForm.SetDesktopLocation( left + width + 2, top - newForm.Height + height );

c) Блокируйте события Undo/Redo с помощью клавиатуры с помощью Transactional Undo/Redo's и позволяйте пользователям видеть атомарное Undo/Redo с помощью кнопок. Было бы чрезвычайно изворотным удалять кнопки Undo/Redo, и это приведет к кучам Where Where Undo button? поддержки. Так что не делайте этого, если вам интересно, настройка инструментария быстрой настройки может быть выполнена из файлов ".qat". Ссылка: https://support.microsoft.com/en-us/kb/926805

d) Используйте крючок мыши и обнаруживайте, когда нажаты кнопки отмены/повтора. Вот код для подключения мыши, обратите внимание, что это не понравится с корпоративными продуктами Антивируса, и я не рекомендую его: https://blogs.msdn.microsoft.com/andreww/2009/02/24/message-hooks-in-add-ins/или https://github.com/gmamaladze/globalmousekeyhook.

e) Попробуйте перехватить необработанные сообщения Windows, например Excel CustomTaskPane с помощью элемента управления WebBrowser - проблемы с клавиатурой/фокусом просто остерегаться согласно моему комментарию ссылаясь на ОШИБКА: Невозможно выбрать даты на DatePicker, которые выходят за пределы плавающей надстройки VSTO, что сообщения в Office иногда показывают странное поведение.

Ответ 2

К сожалению, не похоже, что есть легкое решение этой проблемы. Из того, что я видел, у вас есть два варианта:

  • Вы можете очистить весь стек отменить, используя Document.UndoClear. Однако это не будет очень удобным для пользователя, поскольку все предыдущие действия больше не находятся в списке отмены.
  • Работайте с классом UndoRecord. Между вашими вызовами StartCustomRecord и EndCustomRecord все действия в вашем коде генерируют только один элемент в стеке отмены. CTRL + Z по-прежнему будет влиять на анализ вашего языка, но весь стек отмены не будет таким же загрязненным, как раньше.

Я знаю, что это не то, что вы хотите, но даже у Microsoft MVP нет лучшего решения.

Ответ 3

Возможно, вам стоит подумать об использовании SmartTags...