如何使用IVsFontAndColorEvents?

时间:2015-07-07 13:01:08

标签: c# visual-studio fonts colors vspackage

Microsoft自己的site没有详细说明如何使用此界面。他们声称这是获得通知的方式,如果字体& 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);,但也没有帮助。

1 个答案:

答案 0 :(得分:1)

解决方法

不幸的是我无法让IVsFontAndColorEvents工作。但是,我可以使用找到的代码here实现相同的效果(在工具\选项\字体和颜色\文本编辑器中更改字体时收到通知)。

我的想法是使用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解决了这个问题并且没有调用我的逻辑,除非这个值与fontInfo [0]不同,我刚读过的值。
  • 仅当文本编辑器字体和颜色发生更改时才会触发事件,但是当其他任何字体和颜色发生更改时(例如环境字体输出窗口) EM>)
  • 更改粗体选项时,不会触发事件。尽管如此,IDE似乎还没有使用字体重量......
  • 选项/字体和颜色中选择“使用默认值”时,不会触发事件。事实上,当它通过手动输入(例如:字体大小为10)重置为默认值时,它不会触发。

我希望其中一些对于绊倒这个问题的人有用。