Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
27
Help us understand the problem. What is going on with this article?
@mima_ita

Visual Studioのマクロを使用してDoxygenコメントを記述する

More than 1 year has passed since last update.

概要

Visual Studio のProfessionalEdition以上ではマクロを使用することができる。
そのマクロを使用することで、VisualStudioの操作を自動化することが可能である。
今回はVCのコードでDoxygenコメントを記述するマクロを作成する。

VisualStudio2008 Proffesionalでサンプルを記述しているが、新しいバージョンでも同等のことができる。

Vs2012から使えないの拡張機能を使う必要がある。

(2019/12/15 追記)
復活のVisualStudioのマクロ
https://qiita.com/mima_ita/items/c56d6e2657cc836af7ac
いくつかの制限付きながら拡張機能としてVisualStudioのマクロが復活しているようです。

マクロの登録方法

1.[ツール]→[マクロ]→[マクロエクスプローラ]を選択する。
macro.png

2.マクロエクスプローラにて新規にモジュールを追加する。
macro.png

3.モジュール追加のダイアログで任意の名前でモジュールを追加する。
macro.png

4.マクロエクスプローラで追加したモジュールを選択して編集を行う
macro.png

5.MicrosoftVisual Studio Macrosが起動するので以後、そこでマクロを記述する。

macro.png

選択中の項目にDoxygenコメントを記述するコード


Imports System
Imports EnvDTE
Imports EnvDTE80
Imports EnvDTE90
Imports System.Diagnostics

Public Module mdlVCSrcMacros
    ' カーソルで選択中の関数/Class/EnumにDoxgenで使用するコメントを付与します.
    ' 何も選択せずにファイルの先頭にある場合⇒ファイル用のヘッダコメント
    ' cppファイルで関数を選択して実行⇒関数用ヘッダ
    ' ※クラスのメンバはClassViewが認識していないとコメントを付与してくれない
    '   TODO:課題
    ' classを選択して実行⇒クラス用ヘッダ
    ' enumを選択して実行⇒enum用ヘッダ.
    ' 参考
    '  http://www.microsoft.com/japan/msdn/academic/Articles/fun/06/
    Sub CreateHeaderComment()
        Dim sel As TextSelection = DTE.ActiveDocument.Selection
        Dim strCom As String
        Dim myFCM As FileCodeModel = DTE.ActiveDocument.ProjectItem.FileCodeModel
        strCom = ""

        ' ファイルヘッダ.
        If sel.TopPoint.Line = 1 And sel.Text.Length = 0 Then
            sel.Text = "/**"
            sel.NewLine()
            sel.Text = " * @file" + vbTab + DTE.ActiveDocument.Name
            sel.NewLine()
            sel.Text = "* @brief" + vbTab + "Copyright(c) " + Year(Today()).ToString()
            sel.Text = vbTab + "Nikon Corporation - All rights reserved."
            sel.NewLine()
            sel.Text = "* @date" + vbTab + Format(Today(), "yyyy/MM/dd")
            sel.NewLine()
            sel.Text = "* @author" + vbTab + "作者名"
            sel.NewLine()
            sel.Text = "* @note" + vbTab + ""
            sel.NewLine()
            sel.Text = "*/"
            Exit Sub
        End If
        Dim objCodeElement As CodeElement ' コード情報取得用オブジェクト

        ' 関数ヘッダ
        objCodeElement = myFCM.CodeElementFromPoint(sel.ActivePoint, vsCMElement.vsCMElementFunction) ' ソースコード情報の取得
        If IsNothing(objCodeElement) = False Then
            If objCodeElement.Kind = vsCMElement.vsCMElementFunction Then
                ' 関数の場合.
                Dim codeFun As CodeFunction = objCodeElement
                strCom = "/**" + vbCrLf
                strCom = strCom + " * " + codeFun.Name + vbCrLf
                strCom = strCom + "* " + vbCrLf
                Dim j As Integer
                For j = 1 To codeFun.Parameters.Count
                    Dim codeParam As CodeParameter
                    codeParam = codeFun.Parameters.Item(j)
                    strCom = strCom + "* @param[in/out]" + vbTab + codeParam.Type.AsString + vbTab + codeParam.Name + vbCrLf
                Next j
                If codeFun.Parameters.Count > 1 Then
                    strCom = strCom + "* " + vbCrLf
                End If
                strCom = strCom + "* @return" + vbTab + codeFun.Type.AsString + vbCrLf
                strCom = strCom + "* @note" + vbCrLf
                strCom = strCom + "*/" + vbCrLf
                sel.MoveToPoint(objCodeElement.StartPoint)
            End If
        End If

        ' class 名
        objCodeElement = myFCM.CodeElementFromPoint(sel.ActivePoint, vsCMElement.vsCMElementClass) ' ソースコード情報の取得
        If IsNothing(objCodeElement) = False Then
            If objCodeElement.Kind = vsCMElement.vsCMElementClass Then
                strCom = "/**" + vbCrLf
                strCom = strCom + " * @class" + vbTab + objCodeElement.Name + vbCrLf
                strCom = strCom + "* @brief" + vbCrLf
                strCom = strCom + "*/" + vbCrLf
                sel.MoveToPoint(objCodeElement.StartPoint)
            End If

        End If

        ' enum 名
        objCodeElement = myFCM.CodeElementFromPoint(sel.ActivePoint, vsCMElement.vsCMElementEnum) ' ソースコード情報の取得
        If IsNothing(objCodeElement) = False Then
            If objCodeElement.Kind = vsCMElement.vsCMElementEnum Then
                strCom = "/**" + vbCrLf
                strCom = strCom + " * @enum" + vbTab + objCodeElement.Name + vbCrLf
                strCom = strCom + "* @brief" + vbCrLf
                strCom = strCom + "*/" + vbCrLf
                sel.MoveToPoint(objCodeElement.StartPoint)
            End If

        End If

        ' struct
        objCodeElement = myFCM.CodeElementFromPoint(sel.ActivePoint, vsCMElement.vsCMElementStruct) ' ソースコード情報の取得
        If IsNothing(objCodeElement) = False Then
            If objCodeElement.Kind = vsCMElement.vsCMElementStruct Then
                Dim codeStruct As CodeStruct = objCodeElement

                strCom = "/**" + vbCrLf
                strCom = strCom + " * @struct" + vbTab + objCodeElement.Name + vbCrLf
                strCom = strCom + "* @brief" + vbCrLf
                strCom = strCom + "*/" + vbCrLf
                sel.MoveToPoint(objCodeElement.StartPoint)
            End If
        End If


        If Not strCom.Length = 0 Then
            sel.StartOfLine(vsStartOfLineOptions.vsStartOfLineOptionsFirstColumn)
            sel.LineUp(True)
            sel.Text = strCom
        End If

    End Sub

End Module

DTEインターフェイスを経由することで、VisualStudioの操作がおこなえる。
http://msdn.microsoft.com/ja-jp/library/envdte.dte.aspx

現在選択中のコードの要素を列挙


        ''' ソース ファイル内のコード要素または構成体を表します
        Dim myFCM As FileCodeModel = DTE.ActiveDocument.ProjectItem.FileCodeModel
        Dim objCodeElement As CodeElement
        For Each objCodeElement In myFCM.CodeElements
            MsgBox(objCodeElement.FullName & ":" & objCodeElement.Kind)
        Next

CodeElement インターフェイス
http://msdn.microsoft.com/ja-jp/library/envdte.codeelement.aspx

kindを見ることで、Inculdeなのか、関数なのか、クラスなのか判断することができる。

カーソルの座標とKindからコードの要素を取得


Dim myFCM As FileCodeModel = DTE.ActiveDocument.ProjectItem.FileCodeModel
Dim objCodeElement As CodeElement ' コード情報取得用オブジェクト
objCodeElement = myFCM.CodeElementFromPoint(sel.ActivePoint, vsCMElement.vsCMElementFunction) ' ソースコード情報の取得

この関数はカーソルの位置とKindの種類をもとにしてコード要素を取得する。
条件があわなければnullとなる。

カーソルの位置を関数の先頭にあわせて文字を記述する


Dim sel As TextSelection = DTE.ActiveDocument.Selection

'コード要素の先頭に移動
sel.MoveToPoint(objCodeElement.StartPoint)

'一列目に移動
sel.StartOfLine(vsStartOfLineOptions.vsStartOfLineOptionsFirstColumn)

' 一行うえへ
sel.LineUp(True)

' 文字を記録
sel.Text = "XXXXXXXXXXXXXXX"

マクロの実行方法

1.ソースコードの任意の箇所を選択。

macro.png

2.マクロエクスプローラの「CreateHeaderComment()」をダブルクリックする。
3.マクロが実行されると以下のようにDoxygenコメントが付与される。
macro.png

ショートカットの登録

作成したマクロはショートカットキーに割り当てることができる。

1. [ツール] メニューの [オプション] をクリックして、[オプション] ダイアログ ボックスを表示する。
2.[環境] フォルダーの [キーボード] をクリックする。
3.[以下の文字列を含むコマンドを表示] ボックスにマクロ名を入力して絞りこみ、選択する。
macro.png

4.[ショートカット キー] ボックスをクリックし、特定のキーの組み合わせ押し「割り当て」ボタンをクリックする

以降設定したキーの組み合わせで、指定のマクロが動作する。

方法: マクロを実行する
http://msdn.microsoft.com/ja-jp/library/vstudio/a0003t62%28v=vs.100%29.aspx

応用

この記事でVisualStudioの自動化が行えることを説明した。

VisualStudioのマクロを使う例としては以下のようなことが考えられる。
・あるルールに従って、自動でコードを作成する。
・プロジェクトの設定を自動で行う
・プロジェクトエクスプローラーからファイルを選択してバージョン管理ソフトにコミットしたり、元に戻したりする。

27
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
mima_ita

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
27
Help us understand the problem. What is going on with this article?