vinczemarton
vinczemarton

Reputation: 8156

Find out which reference is clicked in a Visual Studio extension

I'm developing a Visual Studio extension where I add elements to the right click (context) menu of the references in a project. This is done by defining a Group with the parent of IDM_VS_CTXT_REFERENCE.

I want to show-hide the menu elements depending on which reference was clicked, so I define my menu item as an OleMenuCommand:

if (commandService != null)
{
    var menuCommandID = new CommandID(CommandSet, CommandId);
    var menuItem = new OleMenuCommand(this.MenuItemCallback, menuCommandID);

    menuItem.BeforeQueryStatus += (sender, args) =>
    {
        var button = (OleMenuCommand)sender;
        button.Visible = this.CommandVisible();
    };

    commandService.AddCommand(menuItem);
}

I have trouble implementing the CommandVisible method. Let's say for the example's sake that I want to show the menu if the reference's name starts with A. How would I do that?

I feel like I'm trapped in interop hell stumbling blindly over arbitrary ids, guids and non-existant/incomprehensible documentation.

I have managed to dig out the project my reference is in as an IVsProject and some id for the reference, but calling GetMkDocument returns nothing (it works with files in the project but not with references).

How do I do this? Where can I find documentation on how to do this?

Upvotes: 1

Views: 296

Answers (1)

Paul Swetz
Paul Swetz

Reputation: 2254

Finally got it. Once you have the IVsHierarchy and itemid of the selected item this line will get you the name you want in the out param.

hierarchy.GetProperty(itemid, (int)__VSHPROPID.VSHPROPID_Name, out name);

full code

object name;
uint  itemid = VSConstants.VSITEMID_NIL;
IVsMultiItemSelect multiItemSelect = null;
IntPtr hierarchyPtr = IntPtr.Zero;
IntPtr selectionContainerPtr = IntPtr.Zero;
try
{
    var monitorSelection = Package.GetGlobalService( typeof( SVsShellMonitorSelection ) ) as IVsMonitorSelection;
    monitorSelection.GetCurrentSelection( out hierarchyPtr, out itemid, out multiItemSelect, out selectionContainerPtr );
    hierarchy = Marshal.GetObjectForIUnknown( hierarchyPtr ) as IVsHierarchy;    
    hierarchy.GetProperty(itemid, (int)__VSHPROPID.VSHPROPID_Name, out name);
}finally
{
     if (selectionContainerPtr != IntPtr.Zero)
         Marshal.Release( selectionContainerPtr );

      if (hierarchyPtr != IntPtr.Zero)
          Marshal.Release( hierarchyPtr );
}

Upvotes: 4

Related Questions