如何使用ivsfontandcolrevents
本文关键字:ivsfontandcolrevents 何使用 | 更新日期: 2023-09-27 18:01:35
微软自己的网站并没有详细说明如何使用这个界面。他们声称这是收到通知的方式,如果字体&在Visual Studio中改变颜色。
我尝试了一个看起来很明显的选择,并在我的包上实现了接口,但是没有提到我应该在我的vpackage上设置的属性。遗憾的是,这似乎还不够。
下面是我所做的一个示例:
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
工作。然而,我可以实现同样的(当字体在工具'选项'字体和颜色'文本编辑器中发生变化时得到通知),使用这里的代码。
的想法是使用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'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。限制
虽然这个解决方案对我来说是一个可用的解决方案,但它有一些问题:
- 当更改文本编辑器的字体时,
OnFontColorPreferencesChanged
事件被多次引发。我不知道IVsFontAndColorEvents
是否只会引发一次事件或有同样的问题(因为我从来没有得到它的工作)我通过引入prevFontInfo
解决了这个问题,并且不调用我的逻辑,除非这个值与fontInfo[0]不同,我刚刚读取的值 - 事件仅在文本编辑器字体和颜色发生变化时触发,但在其他任何情况下(例如环境字体或输出窗口)
- 当bold选项被更改时,该事件不会触发。然而,字体的重量似乎并没有被IDE使用…
- 当选项/字体和颜色中选择"使用默认值"时,该事件不会触发。事实上,它也不会触发当它重置为默认值手动输入它们(例如:字体大小为10)
我希望这些可能对遇到这个问题的人有用。