2

Last week, I decided to create a Visual Studio Extension for measuring C++ code coverage. Basically I needed it myself for my daily work. What I came up with was the project that can be found https://github.com/atlaste/CPPCoverage .

Most it works fine. However, I have some issues with adornment layers:

One of the features of the project is to create highlighting of the (un)covered code. Highlighting itself works fine, but it seems to interfere with the selection code of Visual Studio:

Demonstration of issue

The relevant code that's responsible for the highlighting:

private void HighlightCoverage(CoverageState[] coverdata, ITextViewLine line)
{
    IWpfTextViewLineCollection textViewLines = view.TextViewLines;

    int lineno = 1 + view.TextSnapshot.GetLineNumberFromPosition(line.Extent.Start);

    CoverageState covered = lineno < coverdata.Length ?
                            coverdata[lineno] : CoverageState.Irrelevant;

    if (covered != CoverageState.Irrelevant)
    {
        SnapshotSpan span = new SnapshotSpan(view.TextSnapshot, 
                                    Span.FromBounds(line.Start, line.End));
        Geometry g = textViewLines.GetMarkerGeometry(span);
        if (g != null)
        {
            GeometryDrawing drawing = (covered == CoverageState.Covered) ?
                new GeometryDrawing(coveredBrush, coveredPen, g) :
                new GeometryDrawing(uncoveredBrush, uncoveredPen, g);

            drawing.Freeze();

            DrawingImage drawingImage = new DrawingImage(drawing);
            drawingImage.Freeze();

            Image image = new Image();
            image.Source = drawingImage;

            //Align the image with the top of the bounds of the text geometry
            Canvas.SetLeft(image, g.Bounds.Left);
            Canvas.SetTop(image, g.Bounds.Top);

            layer.AddAdornment(AdornmentPositioningBehavior.TextRelative, 
                               span, null, image, null);
        }
    }
}

The complete piece of code with the right context can be found here: https://github.com/atlaste/CPPCoverage/blob/master/CoverageExt/CodeRendering/CodeCoverage.cs .

Q: Can someone please tell me how to render the blocks on the background instead of the foreground?

atlaste
  • 30,418
  • 3
  • 57
  • 87
  • PS: As a work-around I noticed you can set opacity at the layer. While that's a nice work-around, I would prefer to put the layer in the background. – atlaste Jun 09 '16 at 08:44

1 Answers1

2

Asked 7 years ago and still there is next to ZERO info about adornments and extending Visual Studio on the net.

Here is how you do it:

  1. When you create a TextAdornment class instance using VS wizard (for instance: right click on project => Add Item) you receive two files: the first one is the class with the name you picked, and the other one is

    [NameYouPicked]TextViewCreationListener.cs

  2. Find that file in solution explorer and open it.

  3. Go to your adornment definition. It should look like this:
/// <summary>
/// Defines the adornment layer for the adornment. This layer is ordered
/// after the selection layer in the Z-order
/// </summary>
[Export(typeof(AdornmentLayerDefinition))]
[Name("TextAdornment")]
[Order(After = PredefinedAdornmentLayers.Selection, Before = PredefinedAdornmentLayers.Text)]
private AdornmentLayerDefinition editorAdornmentLayer;
  1. As you can see, the order set is AFTER SELECTION. I don't know which layer is the earliest one, but I change the code this way to prevent unwanted collisions:
  [Order(Before = PredefinedAdornmentLayers.BraceCompletion)]
cubrman
  • 884
  • 1
  • 9
  • 22
  • 1
    Nice find. This is the best answer in 7 years... :-S And you're right, it's a shame that there is so little documentation; the framework is really quite nice, but the lack of documentation makes it hard to use. – atlaste Aug 30 '16 at 08:16
  • 1
    Well, once I confirm that this is the right answer, I will of course. Still, considering that it took 7 years, I don't see why I should be in a hurry now. :) – atlaste Aug 30 '16 at 08:24