Microsoft's own site does not explain in details how to use this interface. They claim that this is the way to get notified if the Fonts & Colors change in Visual Studio.
I tried what seemed to be an obvious choice and implemented the interface on my package, but there were no attributes mentioned I should set on my VSPackage. Unfortunately that doesn't seem to be enough.
Here's a sample of what I did:
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;
}
}
Unfortunately none of the IVsFontAndColorEvent members (all the methods above) get called.
Do I miss something else? Like an attribute? Or proffering the service?
I also tried serviceContainer.AddService(typeof(IVsFontAndColorEvent), this, true);
but it didn't help either.
Unfortunately I couldn't make IVsFontAndColorEvents
working. However, I could achieve the same (getting notified when the Fonts change in Tools\\Options\\Fonts and Colors\\Text Editor ) with the code found here .
The idea is to use TextManagerEvents
instead of 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
Just in case you are also interested in how to extract the font and color information, here is how I did it:
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\FontAndColors\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. Limitations
Although this solutions is a usable workaround for me, it has some problems:
OnFontColorPreferencesChanged
event is raised multiple times. I can't tell if IVsFontAndColorEvents
would raise the event only once or had the same problem (as I never got it working.) I solved this issue by introducing prevFontInfo
and don't invoke my logic unless this value is different from fontInfo[0], the values I just read. I hope some of these might be useful for someone stumbling upon this question.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.