locked
VSIX: Add Custom Items to the Fonts and Colors Dialog under the Output Window Category RRS feed

  • Question

  • I want to add a custom color item to the Fonts and Colors Dialog under the "Output Window" category. All the examples and suggestions I received else where suggest decorating an EditorFormatDefinition class with UserVisible(true). This almost works. It adds the item to the F&C dialog, but under the Text Editor category. How does one add a custom color definition to "Ouput Window" category?

    Monday, November 28, 2011 3:24 PM

Answers

  • Adding items to the "Output Window" category of the fonts and color dialog is not supported. Sorry. There is no way of doing this. The only category that is extensible is "Text Editor" which can either be extended via MEF the same way you are doing or by proferring the IVsProvideColorableItems service in your language service package.

    The IVsFontAndColorStorage interfaces/services are used to manipulate the categories in the dialog, but they only support modification of existing items (they don't support addition). The flow of the data is something like the following in VS:

    Consumer (e.g. Fonts & Colors dialog) -> IVsFontAndColorStorage -> IVsFontAndColorCacheManager -> IVsFontAndColorDefaultsProvider -> IVsFontAndColorDefaults

    The contents of a category are determined by what the IVsFontAndColorDefaults provides at the time the fonts and colors cache manager is building the cache of the items. Once the items of a category are populated, the only way to update them is to invalidate the cache (and provide the new elements in the IVsFontAndColorDefaults).

    The "Text Editor" category is special in that it extends the above data flow further as such:

    ... -> IVsFontAndColorDefaultsProvider -> IVsFontAndColorDefaults (for Text Editor)

                                                                           |

                                                                           | -> IVsProvideColorableItems

                                                                           |

                                                                           | -> MEF

                                                                           |

                                                                           | -> Core Editor Items

    All other categories are not extensible :(

    You may be wondering then, why an element defined via an EditorFormatDefinition is available in a text editor that does not belong to the "Text Editor" category. Well, let's forget all the data above for a second and look at things solely from the point of view of the editor. The editor uses the IEditorFormatMap and IClassificationFormatMap interfaces to store colors and font properties. These work based off of EditorFormatDefinition and ClassificationFormatDefinition MEF exports. The exports are really *definitions* and they are available in all instances of the editor and classification format maps (of course they are lazily initialized). So as long as you have an EditorFormatDefinition, you can inquire about its colors in any editor format map, irrespective of what appearance category it belongs to and that's why your items work in the Output Window category.

    The caveat is that editor's VS integration code, takes color values from the IVsFontAndColorStorage and overrides the default values of the EditorFormatDefiniton(s) in the Text Editor category, otherwise they would just be the default values defined in the export. The same, however, does not happen for the Output Window, for instance.

    If you really want to make this work, you have the following option:

    1) Define desired EditorFormatDefiniton(s) with UserVisible = false

    2) Define your own category in the Fonts and Colors dialog by proferring the IVsFontAndDefaultsProvider service

    3) At run-time, grab the editor format map corresponding to the Output Window, and set the color values of the definitions of step 1 based on what the user has set them on the items that you have defined at step 2.

    -Ameen

    Thursday, December 1, 2011 8:35 PM

All replies

  • Here's my first attempt. Didn't work. No exception thrown.

            [Import]
            internal IClassificationFormatMapService ClassificationFormatMapService;
    
    
                    var formatMap = ClassificationFormatMapService.GetClassificationFormatMap(FontsAndColorsCategory.Outputwindow);
                    var type = ClassificationRegistry.GetClassificationType(OutputClassificationDefinitions.BuildHead);
                    formatMap.AddExplicitTextProperties(type, formatMap.GetExplicitTextProperties(type));
    
    


     

    Tuesday, November 29, 2011 12:23 AM
  • Classification is for Editor, I'm doubt if you can add a category into OutputWindow, which is not an editer but a toolwindow.


    • Edited by Li Yifeng Tuesday, November 29, 2011 9:21 AM typo
    Tuesday, November 29, 2011 9:20 AM
  • Is the OutputWindow really a tool window? My extension uses EditorFormatDefinitions to color the output window which works nicely.
    Tuesday, November 29, 2011 1:17 PM
  • Hello ,

    As far as I know, we can add the item to editor category, I'm not sure if we can do what you want.

    I am trying to involve someone familiar with this topic to further look at this issue. There might be some time delay. Appreciate your patience.

    Thank you for your understanding and support.

    Yi


    Yi Feng Li [MSFT]
    MSDN Community Support | Feedback to us
    Wednesday, November 30, 2011 10:14 AM
  • Thanks for your persistence. I've posted this project on CodePlex.  (http://vscoloroutput.codeplex.com). That might put things in context.
    Wednesday, November 30, 2011 2:15 PM
  • I've never done this, and it's not very MEF-ey (though most of the VS extensibility surface has no MEF exposure), but you might be able to get SVsFontAndColorStorage (as IVsFontAndColorStorage) and then open the Output Windows Fonts and Colors category and call SetItem to add items under said category.  The GUID for the Output Window category is list in the DefGuidList class as guidOutputWindowFontCategory.

    Ryan

    Thursday, December 1, 2011 12:07 AM
  • Ryan, based on your suggestion I did the following:

     

    var store = Package.GetGlobalService(typeof(SVsFontAndColorStorage)) as IVsFontAndColorStorage;
    store.OpenCategory(DefGuidList.guidOutputWindowFontCategory,
        (uint)(__FCSTORAGEFLAGS.FCSF_LOADDEFAULTS |
            __FCSTORAGEFLAGS.FCSF_NOAUTOCOLORS |
                __FCSTORAGEFLAGS.FCSF_PROPAGATECHANGES));
    store.SetItem(OutputClassificationDefinitions.BuildHead,
        new [] {new ColorableItemInfo {bForegroundValid = 1, crForeground = 0xffff0000}});
    
    

     

    The item did not appear in the F&C dialog but it did actually affect the color of my classifier. The default color for my custom "BuildHead" item is Green. In the code above, I've specified Blue. And when I run the extension, the "BuildHead" classified items appear in Blue.

    This is good progress in my opinion. I would still like to see a solution with the colors appearing in the F&C dialog under the Output Window category but now at least I can change the color at runtime. If I had to, I could write my own options page to facilitate color changes. Thanks!

     


    Thursday, December 1, 2011 3:01 AM
  • Adding items to the "Output Window" category of the fonts and color dialog is not supported. Sorry. There is no way of doing this. The only category that is extensible is "Text Editor" which can either be extended via MEF the same way you are doing or by proferring the IVsProvideColorableItems service in your language service package.

    The IVsFontAndColorStorage interfaces/services are used to manipulate the categories in the dialog, but they only support modification of existing items (they don't support addition). The flow of the data is something like the following in VS:

    Consumer (e.g. Fonts & Colors dialog) -> IVsFontAndColorStorage -> IVsFontAndColorCacheManager -> IVsFontAndColorDefaultsProvider -> IVsFontAndColorDefaults

    The contents of a category are determined by what the IVsFontAndColorDefaults provides at the time the fonts and colors cache manager is building the cache of the items. Once the items of a category are populated, the only way to update them is to invalidate the cache (and provide the new elements in the IVsFontAndColorDefaults).

    The "Text Editor" category is special in that it extends the above data flow further as such:

    ... -> IVsFontAndColorDefaultsProvider -> IVsFontAndColorDefaults (for Text Editor)

                                                                           |

                                                                           | -> IVsProvideColorableItems

                                                                           |

                                                                           | -> MEF

                                                                           |

                                                                           | -> Core Editor Items

    All other categories are not extensible :(

    You may be wondering then, why an element defined via an EditorFormatDefinition is available in a text editor that does not belong to the "Text Editor" category. Well, let's forget all the data above for a second and look at things solely from the point of view of the editor. The editor uses the IEditorFormatMap and IClassificationFormatMap interfaces to store colors and font properties. These work based off of EditorFormatDefinition and ClassificationFormatDefinition MEF exports. The exports are really *definitions* and they are available in all instances of the editor and classification format maps (of course they are lazily initialized). So as long as you have an EditorFormatDefinition, you can inquire about its colors in any editor format map, irrespective of what appearance category it belongs to and that's why your items work in the Output Window category.

    The caveat is that editor's VS integration code, takes color values from the IVsFontAndColorStorage and overrides the default values of the EditorFormatDefiniton(s) in the Text Editor category, otherwise they would just be the default values defined in the export. The same, however, does not happen for the Output Window, for instance.

    If you really want to make this work, you have the following option:

    1) Define desired EditorFormatDefiniton(s) with UserVisible = false

    2) Define your own category in the Fonts and Colors dialog by proferring the IVsFontAndDefaultsProvider service

    3) At run-time, grab the editor format map corresponding to the Output Window, and set the color values of the definitions of step 1 based on what the user has set them on the items that you have defined at step 2.

    -Ameen

    Thursday, December 1, 2011 8:35 PM
  • Oddly, I actually understand most of this which means I'm clearly spending way too much time writing extensions. :)

    OK, plan B. I'll go with the custom category option. Thanks...

    Thursday, December 1, 2011 10:40 PM