I'm trying to create a Visual Studio 2022
extension to detect whenever a specific string on a .cpp
or .h
file get hovered, the project atm have only two files.
I have set a breakpoint on InitializeAsync
of ImagePackage.cs
, when i start debugging the extension it does hit and does print:
MEF components initialized successfully.
I also have set breakpoints on all functions of Image.cs
but no one gets hit.
I'm missing something anywhere to make the hover detection to work?
ImagePackage.cs
using Microsoft.VisualStudio.ComponentModelHost;
using Microsoft;
using Microsoft.VisualStudio.Shell;
using System;
using System.Runtime.InteropServices;
using System.Threading;
using Task = System.Threading.Tasks.Task;
using Microsoft.VisualStudio.Text.Classification;
using Microsoft.VisualStudio.Text.Operations;
using Microsoft.VisualStudio.Shell.Interop;
namespace Image
{
[PackageRegistration(UseManagedResourcesOnly = true, AllowsBackgroundLoading = true)]
[Guid(ImagePackage.PackageGuidString)]
[ProvideAutoLoad(UIContextGuids.NoSolution, PackageAutoLoadFlags.BackgroundLoad)] // Ensure it loads when VS starts
public sealed class ImagePackage : AsyncPackage
{
public const string PackageGuidString = "908f5230-d345-4ee5-a854-d9397bfa6ede";
#region Package Members
protected override async Task InitializeAsync(CancellationToken cancellationToken, IProgress<ServiceProgressData> progress)
{
await this.JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken);
// Get the IComponentModel service to initialize MEF components
var componentModel = (IComponentModel)await GetServiceAsync(typeof(SComponentModel));
Assumes.Present(componentModel);
var navigatorService = componentModel.GetService<ITextStructureNavigatorSelectorService>();
var formatMapService = componentModel.GetService<IEditorFormatMapService>();
Assumes.Present(navigatorService);
Assumes.Present(formatMapService);
System.Diagnostics.Debug.WriteLine("MEF components initialized successfully.");
}
#endregion
}
}
Image.cs
using System;
using System.ComponentModel.Composition;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;
using Microsoft.VisualStudio.Text;
using Microsoft.VisualStudio.Text.Editor;
using Microsoft.VisualStudio.Text.Operations;
using Microsoft.VisualStudio.Utilities;
using Microsoft.VisualStudio.Text.Classification;
using Microsoft.VisualStudio.Text.Formatting;
namespace Image
{
[Export(typeof(IMouseProcessorProvider))]
[Name("WordHoverMouseProcessorProvider")]
[ContentType("code")] //[ContentType("C/C++")]
[TextViewRole(PredefinedTextViewRoles.Editable)]
internal sealed class WordHoverMouseProcessorProvider : IMouseProcessorProvider
{
[Export(typeof(AdornmentLayerDefinition))]
[Name("WordHoverAdornmentLayer")]
[Order(After = PredefinedAdornmentLayers.Selection, Before = PredefinedAdornmentLayers.Text)]
public AdornmentLayerDefinition WordHoverAdornmentLayerDefinition;
[Import]
internal ITextStructureNavigatorSelectorService NavigatorService { get; set; }
[Import]
internal IEditorFormatMapService FormatMapService { get; set; }
public IMouseProcessor GetAssociatedProcessor(IWpfTextView wpfTextView)
{
return wpfTextView.Properties.GetOrCreateSingletonProperty(() =>
new WordHoverMouseProcessor(wpfTextView, NavigatorService.GetTextStructureNavigator(wpfTextView.TextBuffer), FormatMapService.GetEditorFormatMap(wpfTextView)));
}
}
internal class WordHoverMouseProcessor : MouseProcessorBase
{
private readonly IWpfTextView _textView;
private readonly ITextStructureNavigator _navigator;
private readonly IEditorFormatMap _formatMap;
private readonly IAdornmentLayer _adornmentLayer;
public WordHoverMouseProcessor(IWpfTextView textView, ITextStructureNavigator navigator, IEditorFormatMap formatMap)
{
_textView = textView;
_navigator = navigator;
_formatMap = formatMap;
_adornmentLayer = textView.GetAdornmentLayer("WordHoverAdornmentLayer");
}
public override void PostprocessMouseMove(MouseEventArgs e)
{
SnapshotPoint? point = GetMousePosition(e);
if (!point.HasValue)
return;
TextExtent extent = _navigator.GetExtentOfWord(point.Value);
string wordUnderMouse = extent.Span.GetText();
if (wordUnderMouse.Contains("test123"))
{
HighlightWord(extent.Span);
MessageBox.Show("Word 'test123' detected!", "Word Hover Extension");
}
else
{
ClearHighlight();
}
}
private SnapshotPoint? GetMousePosition(MouseEventArgs e)
{
Point position = e.GetPosition(_textView.VisualElement);
return _textView.TextViewLines.GetTextViewLineContainingYCoordinate(position.Y)
?.GetBufferPositionFromXCoordinate(position.X);
}
private void HighlightWord(SnapshotSpan span)
{
var properties = _formatMap.GetProperties("Selected Text");
var brush = properties["Background"] as SolidColorBrush;
if (brush != null)
{
var geometry = _textView.TextViewLines.GetMarkerGeometry(span);
if (geometry != null)
{
var drawing = new GeometryDrawing(brush, new Pen(Brushes.Red, 0.5), geometry);
drawing.Freeze();
var drawingImage = new DrawingImage(drawing);
drawingImage.Freeze();
var image = new System.Windows.Controls.Image
{
Source = drawingImage,
};
_adornmentLayer.AddAdornment(AdornmentPositioningBehavior.TextRelative, span, null, image, null);
}
}
}
private void ClearHighlight()
{
_adornmentLayer.RemoveAllAdornments();
}
}
}
.