65.9K
CodeProject 正在变化。 阅读更多。
Home

Microsoft Visual Studio 2005 Doxygen 插件

starIconstarIconstarIconstarIconstarIcon

5.00/5 (1投票)

2010 年 6 月 26 日

CPOL

6分钟阅读

viewsIcon

37772

downloadIcon

672

MSVS 插件用于 Doxygen 文档系统。

引言

此 MSVS 插件允许选择加载解决方案中包含的多个文件并将它们传递给 Doxygen。它还提供了选择项目名称和目标文件夹的可用性。所有其他 Doxygen 选项都可以通过插件执行的 Doxywizard 进行设置。我尽量做得简单,以便将来扩展,下次会完成。

必备组件

用法

  1. Microsoft Visual Studio 2005
  2. Doxygen。从 http://www.stack.nl/~dimitri/doxygen/download.html#latestsrc 下载

构建源代码

  1. Boost(我使用了 boost.1.38.0)。从 https://boost.ac.cn/下载
  2. WTL 80。从 http://www.microsoft.com/downloads/details.aspx?familyid=E5BA5BA4-6E6B-462A-B24C-61115E846F0C&displaylang=en下载

描述

Doxygen 插件可以从 MSVS IDE 的“工具”菜单运行。

此选项卡允许选择用于文档生成的文件的

dxaddin_files.JPG

这用于 Doxygen 的原始设置

dxaddin_opts.JPG

Doxygen 可执行文件”&“Doxywizard 可执行文件

它们在插件启动时被搜索。但如果需要,我留了一个手动选择的选项。

名称”用于文档生成,可以在 Doxywizard 中更改。

Doxygen 配置文件

运行 Doxywizard 时,您可以微调生成的文档的选项,并为不同目的保存各种配置文件。然后,您可以选择所需的配置并运行 Doxygen。

输出目录”是告诉 Doxygen 将文档放在哪里。在 Doxywizard 模式下也可以更改。

代码

MSVS 插件架构

首先,我将尝试解释(并理解我自己)MSVS 插件架构的一些重要方面。

让我们看这张图

msvs_addin.JPG

预加载插件*

(*) 仅当您在注册脚本(Addin.rgs)中使用 CommandPreload 标志设置为“1”时,才会发生这种情况。它表示您的插件必须预加载以设置 UI。之后,插件将被卸载。

重要:请记住,所有已初始化的类成员和局部对象将在 UI 设置完成后被销毁。

第一次创建对象<CConnect>是为了提供设置 UI 的可用性,这可以在 OnConnect( ConnectMode == ext_cm_UISetup ) 中完成。此时,我们将我们的控件添加到菜单栏(这也可以通过“Visual Studio Add-in Wizard”完成)。命令是使用 EnvDTE80::Commands2 接口的 AddNamedCommand2 方法创建的。存储创建的命令是没有意义的,因为它只在第一次运行时创建一次,并由 MSVS IDE 环境保存。稍后,我将展示如何获取它以便在“Add-in Manager”中取消选中我们的插件的可用性时将其删除。

之后,我们收到 OnDisconnection( RemoveMode == ext_dm_UISetupComplete ),它告诉我们“插件在用户界面设置后被卸载”(MSDN)。

最后,我们的对象将被销毁。调用 FinalRelease() 和随后的对象析构函数调用告诉我们这一点。

加载插件

UI 设置完成后,插件将第二次加载(如果设置了 CommandPreload)(构造函数和 FinalConstruct() 的新调用表明了这一点)。

现在我们将收到 OnConnect (ConnectMode == ext_cm_CommandLine )。此时,我们的插件已被 MSVS 环境加载。

下一项是 OnAddInsUpdate(),它“在插件加载或从 Visual Studio 集成开发环境 (IDE) 卸载时发生”(MSDN)。我们可以通过分析 OnConnection() 的最后一次调用中的 ConnectMode::ext_ConnectMode 参数和 OnDisconnection() 方法中的 RemoveMode::ext_DisconnectMode 来检测其类型(加载/卸载)。

最后是 OnStartupComplete。它“在设置为在 Visual Studio 启动时加载的插件加载时发生”。

检查/取消选中“Add-in Manager”中的可用性通知

取消选中可用性

当我们在“Add-in Manager”中取消选中插件时,我们会收到 OnDisconnect( RemoveMode == ext_dm_UserClosed )。此时,我们可以从菜单栏中删除我们的项目。

如果我们将 CommandPreload 标志设置为“1”(参见“预加载插件”),那么我们没有指向我们命令的变量,需要手动获取它。这是这样做的

IfFailGoCheck(m_pDTE->get_Commands(&pCommands), pCommands);
CComQIPtr< EnvDTE::Command > dx_cmd;
IfFailGoCheck( pCommands->Item( CComVariant
	( "DoxygenAddin.Connect.DoxygenAddin" ), 0, &dx_cmd ), dx_cmd );
dx_cmd->Delete();  

重要:“ DoxygenAddin.Connect.DoxygenAddin ”是命令的完整名称。它由两部分组成:类“ DoxygenAddin.Connect ”的完整名称和命令的名称“ DoxygenAddin ”。 EnvDTE::CommandDelete() 方法将其从菜单栏中删除。

如果我们的命令不是在 OnConnection( ConnectMode == ext_cm_UISetup ) 中创建的,那么我们可以通过显式调用已创建 EnvDTE::Command 对象中的 EnvDTE::Command::Delete() 来删除它。

检查可用性

当我们再次选中它时,会调用 OnConnection( ConnectMode == ext_cm_AfterStartup )。我们所要做的就是使用 EnvDTE80::Commands2 接口的 AddNamedCommand2 方法重新添加我们的控件菜单按钮,就像之前所做的那样。

不幸的是,它仅在加载任何解决方案时才能正常工作。当我移除没有加载解决方案的按钮时,我无法再次添加它,:-(。为什么会这样——我不知道。如果有人能解释一下——我将很高兴:)。

插件可用性(启用/禁用)

另一个问题是,我不想在没有解决方案存在时执行我的插件。为此编写了 CSolutionEventsSink 类。它继承了 IDispEventImpl__uuidof(EnvDTE::_dispSolutionEvents),并接收“Opened”和“BeforeClosing”解决方案事件。

BEGIN_SINK_MAP(SolutionEventsSink)
  SINK_ENTRY_EX(1, __uuidof(EnvDTE::_dispSolutionEvents), 1, Opened)
  SINK_ENTRY_EX(1, __uuidof(EnvDTE::_dispSolutionEvents), 2, BeforeClosing)
END_SINK_MAP()   

上面的代码可以轻松解决这个问题,但我对深入研究它感兴趣。我感兴趣的是如何在运行时在一个类中接收所有 dispids、函数名称以及其中其他信息,以便执行动态建议。

BEGIN_SINK_MAPSINK_ENTRY_EX 声明了 _GetSinkMap() static 方法并创建了 static 数组 _ATL_EVENT_ENTRY 条目,其中包含通过 dispids 将事件与用户回调关联所需的信息。

我们的 sink 类派生自 IDispEventImpl 及其父类 IDispEventSimpleImpl 包含 static 对象类型为 CComTypeInfoHolder。从它获取 ITypeInfo 有助于我们接收 EnvDTE::_dispSolutionEvents 的所有类型信息。现在我们可以创建 _ATL_EVENT_ENTRY 条目数组,运行时。

在对 EnvDTE::SolutionEvents 对象感兴趣的事件进行建议后,我所要做的就是在 CConnect::QueryStatus 中检查解决方案的当前状态,并使菜单项启用或禁用。

CConnect::CheckHasSolution() 有助于确定在解决方案已存在时插件是否在“Add-in Manager”中被选中。这可以通过分析 EnvDTE::_Solution 项计数属性(EnvDTE::_Solution 对象始终存在,但可能包含也可能不包含子项)来轻松完成。

重要

看看 CSolutionEventsSink 类的声明

class CSolutionEventsSink : public IDispEventImpl< 1, CSolutionEventsSink
 , &__uuidof( EnvDTE::_dispSolutionEvents ), &EnvDTE::LIBID_EnvDTE, 8, 0 >

8 - 是类型库的主版本号。由于它是在 MSVS 8.0 下构建的,所以这个数字表示其主版本号。在其他版本的 MSVS IDE 中,它会有所不同。

获取解决方案项

获取解决方案项相对简单。我们可以从 EnvDTE80::DTE2 获取 EnvDTE::_Solution 对象。然后获取其中项目的数量(EnvDTE::_Solution::get_Count())以及所有 EnvDTE::Project 对象。同样,您可以从 EnvDTE::Project 对象获取 EnvDTE::ProjectItems

唯一有趣的是确定 EnvDTE::ProjectItems 是否指向一个文件。这是通过分析其 Kind 属性来完成的。 EnvDTE::vsProjectItemKindPhysicalFile 指出这一点。

重要如果您将文件加载到空的 IDE 中,它也会创建一个解决方案(EnvDTE::_Solution)、项目(EnvDTE::Project)和项目项(EnvDTE::ProjectItems)(未在“解决方案资源管理器”中显示),因此您可以轻松获取它。

超出范围

CCBTreeViewCtrl

为了查看和选择用于文档生成的文件的,我使用了 CCBTreeViewCtrl 类,它扩展了 WTL::CTreeViewCtrlEx

它为其父类增加了 3 个新功能

  1. 通过父级选择/取消选择整个分支
  2. 当子项状态不同时,父项会呈灰色显示
  3. ParseTree() 方法,有助于处理来自指定项的所有子项

Boost::spirit 解析

它看起来并不简单,难以理解和使用,但当你得到你想要的结果时,它看起来很棒,:).

pugi::pugixml

轻量级且直观的 XML 解析库。

© . All rights reserved.