二.实现右击查看Api Help

2020-01-09  本文已影响0人  dududuwei

二.实现右击查看Api Help

2.1 添加一个Command

 首先我们要实现的是在代码编辑界面右击出现SolidWorks Api Help的上下文命令,首先我们需要添加一个自定义命令,在解决方案管理器中的VSIX项目右击,添加 => 新建项 => Extensibility => Command

如图所示:


ApiHelpCommand.png

选择确定,我们项目中出现如下文件

HelpSource.png

2.2 获取用户选择位置和内容

protected override async Task InitializeAsync(CancellationToken cancellationToken, IProgress<ServiceProgressData> progress)
{
      // When initialized asynchronously, the current thread may be a background thread at this point.
      // Do any initialization that requires the UI thread after switching to the UI thread.
      await this.JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken);
      await ApiHelpCommand.InitializeAsync(this);
}
 private void Execute(object sender, EventArgs e)
        {
            ThreadHelper.ThrowIfNotOnUIThread();

            //初始化窗口
            SolidWorksToolBoxCommand.Instance.Execute(null, null);

            //查询选择的命名空间

            TextViewSelection selection = GetSelectionAsync(ServiceProvider);
            string activeDocumentPath = GetActiveFilePath(ServiceProvider);
            ViewApiHelp(activeDocumentPath, selection);
        }

可以看在在此函数中我激活了SolidWorksToolBoxCommand以便显示Api,这部分在下面介绍。然后通过GetSelectionAsync获取用户选择的内容或者光标位置,
接下来GetActiveFilePath来获取当前编辑的文件路径。有了文件路径和选择位置与选择内容,我们就可以对解决方案进行预编译从而获取当先用户选择内容的Symbol信息。
关于Symbol信息,可以了解关于Rosly的相关知识,关于Roslyn将在下一节介绍。

private TextViewSelection GetSelectionAsync(Microsoft.VisualStudio.Shell.IAsyncServiceProvider serviceProvider)
        {
            var ServiceResult = serviceProvider.GetServiceAsync(typeof(SVsTextManager)).GetAwaiter().GetResult();
           // service.Wait();
         
            var textManager = ServiceResult as IVsTextManager2;
            IVsTextView view;
            int result = textManager.GetActiveView2(1, null, (uint)_VIEWFRAMETYPE.vftCodeWindow, out view);
            //获取缓存视图
            IVsTextLines lines;
            view.GetBuffer(out lines);
            //获取选中位置
            view.GetSelection(out int startLine, out int startColumn, out int endLine, out int endColumn);//end could be before beginning

            lines.GetPositionOfLineIndex(startLine, startColumn, out int StartPostion);
            lines.GetPositionOfLineIndex(endLine, endColumn, out int EndPostion);


            var start = new TextViewPosition(startLine, startColumn,StartPostion);
            var end = new TextViewPosition(endLine, endColumn,EndPostion);

            view.GetSelectedText(out string selectedText);

            TextViewSelection selection = new TextViewSelection(start, end, selectedText);
            return selection;
        }
        private string GetActiveFilePath(Microsoft.VisualStudio.Shell.IAsyncServiceProvider serviceProvider)
        {
            ThreadHelper.ThrowIfNotOnUIThread();
            var serviceResult = serviceProvider.GetServiceAsync(typeof(DTE)).GetAwaiter().GetResult() ;
            //service.Wait();
            DTE2 applicationObject = serviceResult as DTE2;
            Assumes.Present(applicationObject);
            return applicationObject.ActiveDocument.FullName;
        }
public struct TextViewSelection
    {
        public TextViewPosition StartPosition { get; set; }
        public TextViewPosition EndPosition { get; set; }
        public string Text { get; set; }

        public TextViewSelection(TextViewPosition a, TextViewPosition b, string text)
        {
            StartPosition = TextViewPosition.Min(a, b);
            EndPosition = TextViewPosition.Max(a, b);
            Text = text;
        }
    }


    public struct TextViewPosition
    {
        private readonly int _column;
        private readonly int _line;
        private readonly int _postion;
        public TextViewPosition(int line, int column,int postion)
        {
            _line = line;
            _column = column;
            _postion = postion;
        }

        public int Line { get { return _line; } }
        public int Column { get { return _column; } }

        public int Postion { get { return _postion; } }
        public static bool operator <(TextViewPosition a, TextViewPosition b)
        {
            if (a.Line < b.Line)
            {
                return true;
            }
            else if (a.Line == b.Line)
            {
                return a.Column < b.Column;
            }
            else
            {
                return false;
            }
        }

        public static bool operator >(TextViewPosition a, TextViewPosition b)
        {
            if (a.Line > b.Line)
            {
                return true;
            }
            else if (a.Line == b.Line)
            {
                return a.Column > b.Column;
            }
            else
            {
                return false;
            }
        }

        public static TextViewPosition Min(TextViewPosition a, TextViewPosition b)
        {
            return a > b ? b : a;
        }

        public static TextViewPosition Max(TextViewPosition a, TextViewPosition b)
        {
            return a > b ? a : b;
        }
    }

2.3 把命令添加到右击上下文

添加修改Menuns和Groups节点为如下

   <Menus>
      <Menu guid="guidDuSolidWorksToolsPackageCmdSet" id="TopLevelMenu" priority="0x700" type="Menu">
        <Parent guid="guidSHLMainMenu" id="IDG_VS_MM_TOOLSADDINS" />
        <Strings>
          <ButtonText>TestMenu</ButtonText>
          <CommandName>DuSolidWorksTools</CommandName>
        </Strings>
      </Menu>
    </Menus>
    <Groups>
      <Group guid="guidDuSolidWorksToolsPackageCmdSet" id="MyMenuGroup" priority="0x0600">
        <Parent guid="guidDuSolidWorksToolsPackageCmdSet" id="TopLevelMenu" />
      </Group>
      <Group guid="guidDuSolidWorksToolsPackageCmdSet1" id="EditorContextMenuGroup"
    priority="0x0600">
        <Parent guid="guidSHLMainMenu" id="IDM_VS_CTXT_CODEWIN" />
      </Group>
    </Groups>

修改ApiHelpCommand的Button节点

<Button guid="guidDuSolidWorksToolsPackageCmdSet1" id="cmdidApiHelpCommand" priority="0x0100" type="Button">
        <Parent guid="guidDuSolidWorksToolsPackageCmdSet1" id="EditorContextMenuGroup" />
        <Strings>
          <ButtonText>查看SolidWork Api Help</ButtonText>
        </Strings>
      </Button>

添加属性名为EditorContextMenuGroup的IDSymbol节点

 <Symbols>
    <!-- This is the package guid. -->
    <GuidSymbol name="guidDuSolidWorksToolsPackage" value="{21021241-9eee-4786-8127-afbb981f4553}" />

    <!-- This is the guid used to group the menu commands together -->
    <GuidSymbol name="guidDuSolidWorksToolsPackageCmdSet" value="{b3980047-d67e-4178-844c-b883ff10d8dc}">
      <IDSymbol name="MyMenuGroup" value="0x1020" />
      <IDSymbol name="SolidWorksToolBoxCommandId" value="0x0100" />
      <IDSymbol name="TopLevelMenu" value="0x1021" />
    </GuidSymbol>

    <GuidSymbol name="guidImages" value="{c5867eda-3d13-4abf-bec9-b07184e0f0d0}">
      <IDSymbol name="bmpPic1" value="1" />
      <IDSymbol name="bmpPic2" value="2" />
      <IDSymbol name="bmpPicSearch" value="3" />
      <IDSymbol name="bmpPicX" value="4" />
      <IDSymbol name="bmpPicArrows" value="5" />
      <IDSymbol name="bmpPicStrikethrough" value="6" />
    </GuidSymbol>

    <GuidSymbol value="{ddac09a6-b74e-4ed3-9f5c-88e93dbc3dec}" name="guidDuSolidWorksToolsPackageCmdSet1">
      <IDSymbol value="256" name="cmdidApiHelpCommand" />
      <IDSymbol value="4128" name="EditorContextMenuGroup" />
    </GuidSymbol>
  
    <GuidSymbol value="{ed215d58-bbc8-40d4-b557-a69d4ea32273}" name="guidImages1">
      <IDSymbol name="bmpPic1" value="1" />
      <IDSymbol name="bmpPic2" value="2" />
      <IDSymbol name="bmpPicSearch" value="3" />
      <IDSymbol name="bmpPicX" value="4" />
      <IDSymbol name="bmpPicArrows" value="5" />
      <IDSymbol name="bmpPicStrikethrough" value="6" />
    </GuidSymbol>
  </Symbols>

2.4 运行Visual Studio

点击运行,Visual Studio将启动另外一个实例,打开一个文件,在编辑器右击,可以看到出现了一个查看SolidWork Api Help的选项。
如果想获取到Api帮助,我们需要使用Roslyn来对解决方案进行预编译,从而解析当前Api的类型信息,命名空间,再根据这些信息来定位Api的位置。

上一篇下一篇

猜你喜欢

热点阅读