查找和书签文本插件
一个 VS.NET 示例插件,用于查找并为所有选定文本的出现位置添加书签。该插件在代码窗口的上下文菜单中创建一个新的菜单项。
引言
这是一个 VS.NET 插件示例项目,我编写它的目的是为了能够在打开的代码文件中对所有出现的文本选择进行查找和书签。我有点懒。所以,我认为在代码窗口上下文菜单中提供此功能会很方便,而不必打开“查找”窗口或学习一堆新的键盘按键序列。
我宁愿每天使用鼠标而不是输入东西。如果你能用鼠标以及按键来完成,这会给你更多的力量。
此外,我认为这将是学习 .NET 插件以及如何对其进行编码的好方法;这就是我撰写本文的原因,以帮助其他人了解 .NET 插件。
相信我,弄清楚这些东西绝非易事。如果你相信那些很难找到的文档,它应该像泥土一样容易。但是当你真正开始编写代码并期望它工作时,就会有很多不愉快的惊喜。我不知道花了多少小时才找到如何将菜单项放在代码窗口的上下文菜单中。事实证明,你必须知道要将自己的项目添加到哪个 .NET 工具栏的名称。那么,这些内置工具栏在哪里列出?
无处可寻,我无法发现!我浏览了大量的 Office 应用程序文档、VS.NET 文档、大量的网站,但没有找到任何相关信息。你可能会认为他们至少会提供一个你需要知道的工具栏名称列表,以便添加自定义菜单项,对吧?错误 - 像往常一样。你必须费尽心思才能找到这些信息。
宏
所以,我最终编写了这个小宏,你可以用它来列出所有可用的工具栏(在 Office VSA 中称为CommandBars
)
'
Sub GetCommandBarList()
' Creates a text document listing all CommandBar names.
Dim Cmd As CommandBar
Dim CmdBars As CommandBars
Dim Doc As Document
Dim app As Application
Dim TxtDoc As TextDocument
' Create a new text document.
DTE.ItemOperations.NewFile("General\Text File")
Doc = ActiveDocument
TxtDoc = Doc.Object("TextDocument")
' get the command bars
CmdBars = DTE.CommandBars
For Each Cmd In CmdBars
If (Cmd.Name <> "") Then
TxtDoc.Selection.Text = "Name: " & Cmd.Name & vbTab & _
"Type: " & Cmd.Type.ToString() & vbLf
TxtDoc.Selection.Collapse()
End If
Next
End Sub
现有的上下文菜单属于 MsoBarTypePopup
类型。你必须使用的 CommandBar
或工具栏才能将菜单项添加到代码编辑器窗口的上下文菜单中,其名称为“Code Window”。
代码的重要部分是 Add-in Wizard 添加的 OnConnect()
- 带有将新菜单项添加到 Code Window CommandBar
的上下文菜单的代码
public void OnConnection(object application,
Extensibility.ext_ConnectMode connectMode, object addInInst,
ref System.Array custom)
{
applicationObject = (_DTE)application;
addInInstance = (AddIn)addInInst;
if( connectMode == Extensibility.ext_ConnectMode.ext_cm_UISetup )
{
object []contextGUIDS = new object[] { };
Commands commands = applicationObject.Commands;
_CommandBars commandBars = applicationObject.CommandBars;
try
{
Command command = commands.AddNamedCommand(addInInstance,
"TextFinder", "Text Finder",
"Executes the command for Text Finder",
true, 183, ref contextGUIDS,
(int)vsCommandStatus.vsCommandStatusSupported+
(int)vsCommandStatus.vsCommandStatusEnabled );
CommandBar commandBar = (CommandBar)commandBars["Code Window"];
CommandBarControl commandBarControl =
command.AddControl( commandBar, 1 );
}
catch(System.Exception /*e*/)
{
}
}
}
Add-in Wizard 添加的 QueryStatus()
方法
public void QueryStatus(string commandName,
EnvDTE.vsCommandStatusTextWanted neededText,
ref EnvDTE.vsCommandStatus status, ref object commandText)
{
if(neededText ==
EnvDTE.vsCommandStatusTextWanted.vsCommandStatusTextWantedNone)
{
if(commandName == "TextFinder.Connect.TextFinder")
{
TextSelection txt =
applicationObject.ActiveDocument.Selection as TextSelection;
if( txt.Text.Length > 0 )
status = (vsCommandStatus)vsCommandStatus.vsCommandStatusSupported
| vsCommandStatus.vsCommandStatusEnabled;
else
{
// disable if no text is selected
status = (vsCommandStatus)vsCommandStatus.vsCommandStatusLatched
| vsCommandStatus.vsCommandStatusSupported;
}
}
}
}
Add-in Wizard 添加的 Exec()
方法
public void Exec(string commandName,
EnvDTE.vsCommandExecOption executeOption, ref object varIn,
ref object varOut, ref bool handled)
{
handled = false;
if( executeOption ==
EnvDTE.vsCommandExecOption.vsCommandExecOptionDoDefault )
{
if( commandName == "TextFinder.Connect.TextFinder" )
{
handled = DoFind();
return;
}
}
}
最后,也是唯一一个你必须自己添加的方法,DoFind()
方法
private bool DoFind()
{
TextSelection txt =
applicationObject.ActiveDocument.Selection as TextSelection;
this.applicationObject.Find.FindWhat = txt.Text;
applicationObject.Find.Action = vsFindAction.vsFindActionBookmarkAll;
applicationObject.Find.Target = vsFindTarget.vsFindTargetCurrentDocument;
applicationObject.Find.MatchInHiddenText = true;
applicationObject.Find.ResultsLocation =
vsFindResultsLocation.vsFindResults1;
EnvDTE.vsFindResult res = applicationObject.Find.Execute();
return ( res.Equals( vsFindResult.vsFindResultFound ) );
}
此方法用于实际的查找和书签。它只是从 VS.NET 文本编辑器窗口中可用的现有命令中获取的。
要使用,请运行 *setup.exe* 或 *TextFinderSetup.msi* 来安装该插件。合并 *.reg* 文件以确保所有信息都正确输入到注册表中。 *.reg* 文件为 HKEY_LOCAL_MACHINE
和 HKEY_CURRENT_USER
写入注册表项。
希望你发现它既可以作为工具,也可以作为插件编程示例都很有用。