Как использовать IVsFontAndColorEvents?

Собственный сайт Microsoft не объясняет подробно, как использовать этот интерфейс. Они утверждают, что это способ получить уведомление, если шрифты и цвета меняются в Visual Studio.

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

Вот пример того, что я сделал:

public class SceVSIPackage : Package, IVsFontAndColorEvents { public int OnApply() { return VSConstants.S_OK; } public int OnFontChanged(ref Guid rguidCategory, FontInfo[] pInfo, LOGFONTW[] pLOGFONT, uint HFONT) { return VSConstants.S_OK; } public int OnItemChanged(ref Guid rguidCategory, string szItem, int iItem, ColorableItemInfo[] pInfo, uint crLiteralForeground, uint crLiteralBackground) { return VSConstants.S_OK; } public int OnReset(ref Guid rguidCategory) { return VSConstants.S_OK; } public int OnResetToBaseCategory(ref Guid rguidCategory) { return VSConstants.S_OK; } } 

К сожалению, ни один из участников IVsFontAndColorEvent (все вышеприведенные методы) не вызван.

Я скучаю по чему-то еще? Как атрибут? Или предлагать услугу?

Я также попробовал serviceContainer.AddService(typeof(IVsFontAndColorEvent), this, true); но это тоже не помогло.

Временное решение

К сожалению, я не мог работать с IVsFontAndColorEvents . Тем не менее, я мог бы достичь того же (получать уведомление, когда шрифты меняются в Tools \ Options \ Fonts and Colors \ Text Editor ) с кодом, найденным здесь .

Идея заключается в использовании TextManagerEvents вместо IVsFontAndColorEvents :

 //using Microsoft.VisualStudio.TextManager.Interop; IVsTextManager textManager = GetService(typeof(SVsTextManager)) as IVsTextManager; if (textManager != null) { IConnectionPointContainer container = textManager as IConnectionPointContainer; if (container != null) { IConnectionPoint textManagerEventsConnection; Guid eventGuid = typeof(IVsTextManagerEvents).GUID; container.FindConnectionPoint(ref eventGuid, out textManagerEventsConnection); if (textManagerEventsConnection != null) { TextManagerEvents textManagerEvents = new TextManagerEvents(); uint textManagerCookie; textManagerEventsConnection.Advise(textManagerEvents, out textManagerCookie); if (textManagerCookie != 0) { textManagerEvents.FontColorPreferencesChanged += OnFontColorPreferencesChanged; } } } } 

Заметки

1. OnFontColorPreferencesChanged

На всякий случай вы также заинтересованы в том, как извлечь информацию о шрифте и цвете, вот как я это сделал:

 private FontInfo prevFontInfo; // Store previous FontInfo to prevent execution of the event handler multiple times. private void OnFontColorPreferencesChanged(object sender, EventArgs e) { IVsFontAndColorStorage fontAndColorStorage = GetService(typeof(SVsFontAndColorStorage)) as IVsFontAndColorStorage; if (fontAndColorStorage != null) { // GlobalValues.FontsAndColors_TextEditor is found in the registry: HKEY_USERS\.DEFAULT\Software\Microsoft\VisualStudio\[VS_VER]_Config\FontAndColo‌​rs\Text Editor, where VS_VER is the actual Visual Studio version: 10.0, 11.0, 12.0, 14.0, etc. if (fontAndColorStorage.OpenCategory(GlobalValues.FontsAndColors_TextEditor, (uint)__FCSTORAGEFLAGS.FCSF_LOADDEFAULTS) == VSConstants.S_OK) { LOGFONTW[] logFontw = new LOGFONTW[1]; // Only 1 item expected FontInfo[] fontInfo = new FontInfo[1]; // Only 1 item expected if (fontAndColorStorage.GetFont(logFontw, fontInfo) == VSConstants.S_OK && !prevFontInfo.Equals(fontInfo[0])) { prevFontInfo = fontInfo[0]; // FontInfo uses pixels as units, WPF uses points. Conversion between the two is required. double fontSize = (double)new FontSizeConverter().ConvertFrom(string.Format("{0}pt", fontInfo.wPointSize)); FontFamily fontFamily = new FontFamily(fontInfo.bstrFaceName); // There you go, you have the FontFamily and size ready to use. } fontAndColorStorage.CloseCategory(); } } } 

2. Ограничения

Хотя это решение является удобным для меня решением, оно имеет некоторые проблемы:

  • при изменении шрифта текстового редактора событие OnFontColorPreferencesChanged возникает несколько раз. Я не могу сказать, будет ли IVsFontAndColorEvents поднять событие только один раз или иметь такую ​​же проблему (как я никогда не работал). Я решил эту проблему, введя prevFontInfo и не prevFontInfo мою логику, если это значение не отличается от fontInfo [0 ], значения, которые я только что прочитал.
  • событие срабатывает только тогда, когда шрифты и цвета текстового редактора изменены, но не тогда, когда какое-либо из остальных (например, « Шрифт среды или выходное окно» )
  • событие не срабатывает при изменении жирного шрифта . Тем не менее, размер шрифта, по-видимому, не используется IDE в любом случае …
  • событие не срабатывает, когда в параметрах / шрифтах и ​​цветах выбрано «Использовать значения по умолчанию». На самом деле он не срабатывает, когда он возвращается к значениям по умолчанию, вручную вводит их (например: размер шрифта до 10)

Я надеюсь, что некоторые из них могут быть полезны для кого-то, кто наткнулся на этот вопрос.