serious-code.net  ±è¼º¹Î/FavoriteApps/VisualStudioMacro UserPreferences
 
Private HelpContents Search Diffs Info Edit Subscribe XML Print View Up
Option Strict Off
Option Explicit Off

Imports System
Imports System.Diagnostics
Imports System.Collections
Imports System.Text
Imports EnvDTE
Imports EnvDTE80
Imports Microsoft.VisualBasic
Imports Microsoft.VisualBasic.ControlChars


Public Module Utility

    Sub CollapseNode(ByRef item As UIHierarchyItem)
        ' CollapseAll ¿¡¼­ »ç¿ëÇϱâ À§ÇÑ ÇÔ¼ö
        Dim objSubItem As UIHierarchyItem
        For Each objSubItem In item.UIHierarchyItems
            If (objSubItem.UIHierarchyItems.Expanded = True) Then
                CollapseNode(objSubItem)
                objSubItem.UIHierarchyItems.Expanded = False
            End If
        Next

    End Sub

    Sub CollapseAll()
        ' ¼Ö·ç¼Ç ÀͽºÇ÷η¯¿¡ ÆîÃÄÁø ³ëµåµéÀ» ¸ðµÎ Á¢´Â´Ù.

        Dim objSolutionExplorer As UIHierarchy
        objSolutionExplorer = DTE.Windows.Item(EnvDTE.Constants.vsext_wk_SProjectWindow).Object()

        ' Check if there is any open solution
        If (objSolutionExplorer.UIHierarchyItems.Count = 0) Then
            ' MsgBox("Nothing to collapse. You must have an open solution.")
            Return
        End If

        ' Get the top node (the name of the solution)
        Dim UIHSolutionRootNode As UIHierarchyItem
        UIHSolutionRootNode = objSolutionExplorer.UIHierarchyItems.Item(1)

        CollapseNode(UIHSolutionRootNode)

        ' Select the solution node, or else when you click on the solution window
        ' scrollbar, it will synchronize the open document with the tree and pop
        ' out the corresponding node which is probably not what you want.
        UIHSolutionRootNode.Select(vsUISelectionType.vsUISelectionTypeSelect)
    End Sub

    Sub FindInSolution()
        ' ÇöÀç ÆíÁý ÁßÀÎ ÆÄÀÏÀ» ¼Ö·ç¼Ç ÀͽºÇ÷η¯¿¡¼­ ã¾Æ¼­ ÇÏÀ̶óÀÌÆ®½ÃŲ´Ù.
        p = DTE.Properties("Environment", "ProjectsAndSolution").Item("TrackFileSelectionInExplorer")
        p.value = 1
        p.value = 0
    End Sub


    Sub GetFriendFile()
        ' H <--> CPP ÆÄÀÏ Àüȯ

        strCurrentFileName = Application.ActiveDocument.FullName
        strNewFileName = ""

        If (UCase(Right(strCurrentFileName, 2)) = ".H") Then
            strNewFileName = Left(strCurrentFileName, Len(strCurrentFileName) - 2) + ".CPP"
        ElseIf (UCase(Right(strCurrentFileName, 4)) = ".CPP") Then
            strNewFileName = Left(strCurrentFileName, Len(strCurrentFileName) - 4) + ".H"
        End If

        On Error Resume Next
        If strNewFileName <> "" Then
            Application.Documents.Open(strNewFileName)
            If (Err.Number <> 0) Then
                MsgBox("Error opening corresponding file - " & Err.Description)
            End If
        End If

    End Sub

    Function Strip(ByVal strLine As String)
        ' ¹®ÀÚ¿­ Á¿ìÀÇ °ø¹éÀ» Á¦°ÅÇÑ´Ù.
        If Len(strLine) > 0 Then
            nBegin = 1
            nEnd = Len(strLine)
            For i = 1 To Len(strLine)
                c = Mid(strLine, i, 1)
                If c <> " " And c <> Tab And c <> Lf And c <> Cr Then
                    nBegin = i
                    Exit For
                End If
            Next
            For i = 1 To Len(strLine)
                c = Mid(strLine, Len(strLine) - i + 1, 1)
                If c <> " " And c <> Tab And c <> Lf And c <> Cr Then
                    nEnd = Len(strLine) - i + 1
                    Exit For
                End If
            Next
            Return Mid(strLine, nBegin, nEnd - nBegin + 1)
        Else
            Return ""
        End If
    End Function

    Sub Split(ByVal strLine As String, ByVal strSeperators As String, ByRef objLines As Generic.List(Of String))
        ' ¹®ÀÚ¿­À» ÅäÅ«ÀÇ ¸ñ·ÏÀ¸·Î ºÐ¸®ÇÑ´Ù. ±¸ºÐÀÚ´Â ¿©·¯ °³°¡ µÉ ¼ö ÀÖ´Ù.
        strToken = ""
        For i = 1 To Len(strLine)
            strChar = Mid(strLine, i, 1)
            If InStr(strSeperators, strChar) > 0 Then
                If Len(strToken) > 0 Then
                    objLines.Add(strToken)
                End If
                strToken = ""
            Else
                strToken = strToken + strChar
            End If
        Next
        If Len(strToken) > 0 Then
            objLines.Add(strToken)
        End If
    End Sub


    Sub PadLeft(ByRef objLines As Generic.List(Of String), ByVal strPad As String)
        ' ¹®ÀÚ¿­ Áß¿¡ Á¦ÀÏ ±ä ³ðÀ» ±âÁØÀ¸·Î ªÀº ³ðµéÀÇ ¿ÞÂÊ¿¡´Ù ÁÖ¾îÁø ÆÐµù ¹®ÀÚ¿­À» ºÙÀδÙ.
        nMaxLength = 0
        For Each strLine In objLines
            If Len(strLine) > nMaxLength Then
                nMaxLength = Len(strLine)
            End If
        Next
        For i = 0 To objLines.Count - 1
            strLine = objLines.Item(i)
            nMargin = nMaxLength - Len(strLine)
            For m = 1 To nMargin
                strLine = strPad + strLine
            Next
            objLines.Item(i) = strLine
        Next
    End Sub

    Sub PadRight(ByRef objLines As Generic.List(Of String), ByVal strPad As String)
        ' ¹®ÀÚ¿­ Áß¿¡ Á¦ÀÏ ±ä ³ðÀ» ±âÁØÀ¸·Î ªÀº ³ðµéÀÇ ¿À¸¥ÂÊ¿¡´Ù ÁÖ¾îÁø ÆÐµù ¹®ÀÚ¿­À» ºÙÀδÙ.
        nMaxLength = 0
        For Each strLine In objLines
            If Len(strLine) > nMaxLength Then
                nMaxLength = Len(strLine)
            End If
        Next
        For i = 0 To objLines.Count - 1
            strLine = objLines.Item(i)
            nMargin = nMaxLength - Len(strLine)
            For m = 1 To nMargin
                strLine = strLine + strPad
            Next
            objLines.Item(i) = strLine
        Next
    End Sub

    Function GetSelectedText()
        ' ÇöÀç ¼±ÅÃµÈ ¹®ÀÚ¿­À» ¹ÝȯÇÑ´Ù.
        Dim objSel As TextSelection
        If (DTE.ActiveDocument Is Nothing) Then Return ""
        objSel = DTE.ActiveDocument.Selection()
        Return objSel.Text
    End Function

    Sub InsertText(ByVal strText As String)
        ' ÇöÀç ij·µÀÌ ÀÖ´Â °÷¿¡´Ù ÁÖ¾îÁø ¹®ÀÚ¿­À» »ðÀÔÇÑ´Ù.
        Dim objSel As TextSelection
        Dim objRanges As TextRanges
        Dim objStartPt As EditPoint
        objSel = ActiveDocument().Selection
        objRanges = objSel.TextRanges
        objStartPt = objRanges.Item(1).StartPoint.CreateEditPoint()
        objStartPt.Insert(strText)
    End Sub

    Sub ReplaceSelectedText(ByVal strText As String)
        ' ÇöÀç ¼±ÅÃµÈ ¹®ÀÚ¿­À» ÁÖ¾îÁø ¹®ÀÚ¿­·Î ġȯÇÑ´Ù.
        Dim objSel As TextSelection
        Dim objRanges As TextRanges
        Dim objStartPt As EditPoint
        objSel = ActiveDocument().Selection
        objRanges = objSel.TextRanges
        objStartPt = objRanges.Item(1).StartPoint.CreateEditPoint()
        objSel.Text = ""
        objStartPt.Insert(strText)
    End Sub


    Sub DecorateSourceFile()
        ' H, CPP ÆÄÀÏ¿¡´Ù ±âº» ÁÖ¼®À» Áý¾î³Ö´Â´Ù.
        Dim objStream As New StringBuilder
        Dim strFileName As String
        Dim strFileExt As String
        Dim strClassName As String
        Dim strIncludeGuard As String
        Dim strSelected As String
        Dim nPos As Integer

        ' ¼öÁ¤ »çÇ×µé. Çʿ信 µû¶ó ¼öÁ¤ÇÑ´Ù.
        Dim strAuthor As String = "excel96"
        Dim strDateString As String = CStr(Year(Now())) + "." + CStr(Month(Now())) + "." + CStr(Day(Now()))
        Dim strCommentLine As String = "////////////////////////////////////////////////////////////////////////////////////////////////////"
        Dim bUsePragmaOnce As Boolean = True
        Dim strClassNamePrefix As String = "c"
        Dim strPchName As String = "PCH.h"

        ' ÆÄÀÏ À̸§À» È®ÀÎÇÑ´Ù.
        strFileName = ActiveDocument().Name
        If strFileName = "" Then
            If MsgBox("ó¸® ÁßÀÎ ÆÄÀÏ¿¡ È®ÀåÀÚ°¡ ¾ø½À´Ï´Ù." + Lf + _
            "C/C++ ¼Ò½º ÆÄÀÏÀÌ ¸Â½À´Ï±î?", 4) = MsgBoxResult.Cancel Then
                Exit Sub
            End If
            strFileName = "NoFileNameGiven.h"
        End If

        ' ÆÄÀÏ À̸§À» ºÐ¸®Çϰí, Ŭ·¡½º À̸§À» »ý¼ºÇÑ´Ù.
        strFileExt = UCase(Right(strFileName, Len(strFileName) - InStrRev(strFileName, ".")))
        strFileName = Left(strFileName, Len(strFileName) - Len(strFileExt) - 1)
        strClassName = strClassNamePrefix + strFileName

        ActiveDocument().Selection.StartOfDocument(False)

        ' ÆÄÀÏÀÇ È®ÀåÀÚ¿¡ µû¶ó ¾Ë¸ÂÀº 󸮸¦ ÇØÁØ´Ù.
        If strFileExt = "H" Or strFileExt = "HPP" Then
            strIncludeGuard = "__" + UCase(strFileName) + "_" + strFileExt + "__" + Lf

            ' ÆÄÀÏ Çì´õ Ãß°¡.
            objStream.Append(strCommentLine + Lf)
            objStream.Append("/// \file " + ActiveDocument().Name + Lf)
            objStream.Append("/// \author " + strAuthor + Lf)
            objStream.Append("/// \date " + strDateString + Lf)
            objStream.Append(strCommentLine + Lf + Lf)

            ' ÀÎŬ·çµå °¡µå Ãß°¡.
            If bUsePragmaOnce Then
                objStream.Append("#pragma once" + Lf + Lf)
            Else
                objStream.Append("#ifndef " + strIncludeGuard + "#define " + strIncludeGuard + Lf + Lf)
            End If

            ' Ŭ·¡½º ¼³¸í¹® Ãß°¡.
            objStream.Append(strCommentLine + Lf)
            objStream.Append("/// \class " + strClassName + Lf)
            objStream.Append("/// \brief " + Lf)
            objStream.Append(strCommentLine + Lf + Lf)

            ' Ŭ·¡¼­ ¼±¾ð ¹× »ý¼ºÀÚ & ¼Ò¸êÀÚ Ãß°¡.
            objStream.Append("class " + strClassName + Lf)
            objStream.Append("{" + Lf)
            objStream.Append("private:" + Lf + Lf)
            objStream.Append("public:" + Lf)
            objStream.Append(Tab + "/// \brief »ý¼ºÀÚ" + Lf)
            objStream.Append(Tab + strClassName + "();" + Lf + Lf)
            objStream.Append(Tab + "/// \brief ¼Ò¸êÀÚ" + Lf)
            objStream.Append(Tab + "virtual ~" + strClassName + "();" + Lf + Lf + Lf)
            objStream.Append("public:" + Lf + Lf)
            objStream.Append("private:" + Lf)
            objStream.Append(Tab + "/// \brief º¹»ç »ý¼º ±ÝÁö" + Lf)
            objStream.Append(Tab + strClassName + "(const " + strClassName + "&) {}" + Lf + Lf)
            objStream.Append(Tab + "/// \brief ´ëÀÔ ±ÝÁö" + Lf)
            objStream.Append(Tab + strClassName + "& operator = (const " + strClassName + "&) { return *this; }" + Lf)
            objStream.Append("};" + Lf)

            ' ÀÎŬ·çµå °¡µå ¸¶¹«¸®.
            If Not bUsePragmaOnce Then
                objStream.Append(Lf + "#endif //" + strIncludeGuard)
            End If
        ElseIf strFileExt = "C" Or strFileExt = "CPP" Or strFileExt = "CC" Then
            ' ÆÄÀÏ Çì´õ Ãß°¡.
            objStream.Append(strCommentLine + Lf)
            objStream.Append("/// \file " + ActiveDocument().Name + Lf)
            objStream.Append("/// \author " + strAuthor + Lf)
            objStream.Append("/// \date " + strDateString + Lf)
            objStream.Append(strCommentLine + Lf + Lf)

            ' ÀÎŬ·çµå ÆÄÀÏ Ãß°¡.
            objStream.Append("#include " + CStr(Quote) + strPchName + CStr(Quote) + Lf)
            objStream.Append("#include " + CStr(Quote) + strFileName + ".h" + CStr(Quote) + Lf)
            objStream.Append(Lf)

            ' »ý¼ºÀÚ Ãß°¡.
            objStream.Append(strCommentLine + Lf)
            objStream.Append("/// \brief »ý¼ºÀÚ" + Lf)
            objStream.Append(strCommentLine + Lf)
            objStream.Append(strClassName + "::" + strClassName + "()" + Lf)
            objStream.Append("{" + Lf)
            objStream.Append("}" + Lf + Lf)

            ' ¼Ò¸êÀÚ Ãß°¡.
            objStream.Append(strCommentLine + Lf)
            objStream.Append("/// \brief ¼Ò¸êÀÚ" + Lf)
            objStream.Append(strCommentLine + Lf)
            objStream.Append(strClassName + "::~" + strClassName + "()" + Lf)
            objStream.Append("{" + Lf)
            objStream.Append("}" + Lf + Lf)
        End If

        InsertText(objStream.ToString())
    End Sub

    Sub AddFunctionDescriptionEx()
        ' ÇÔ¼ö ¼³¸íÀ» Ãß°¡ÇÑ´Ù.
        Dim objSel As TextSelection
        Dim strHeader As String
        Dim strParams As String
        Dim strFunctionName As String
        Dim strDescription As String
        Dim strReturnType As String
        Dim strCommentLine As String
        Dim iPrm, iPrmA As Integer
        Dim p, l As Integer

        If (ActiveDocument() Is Nothing) Then
            Exit Sub
        End If

        strCommentLine = "////////////////////////////////////////////////////////////////////////////////////////////////////"

        If ActiveDocument().Language = EnvDTE.Constants.dsCPP Or ActiveDocument().Language = "CSharp" Then
            objSel = DTE.ActiveDocument.Selection()
            Strip(objSel.Text)
            strHeader = ""

            If objSel.Text <> "" Then
                strHeader = Strip(objSel.Text)
            End If

            'Get the function return type. 
            If strHeader <> "" Then
                If ActiveDocument().Language = "CSharp" Then
                    'skip the protection info (public/private ...) 
                    strHeader = Right(strHeader, Len(strHeader) - InStr(strHeader, " "))
                End If
                Reti = InStr(strHeader, " ")
                Loc1 = InStr(strHeader, "(")
                If Reti < Loc1 Then
                    strReturnType = Left(strHeader, Loc1 - 1)
                    strHeader = Right(strHeader, Len(strHeader) - Reti)
                End If
                strReturnType = Left(strReturnType, InStr(strReturnType, " "))

                'Get the function name. 
                Loc1 = InStr(strHeader, "(") - 1
                Loc2 = InStr(strHeader, ")")

                If Loc1 > 0 And Loc2 > 0 Then 'make sure there is a '(' and a ')' 
                    strFunctionName = Left(strHeader, Loc1)
                    strHeader = Right(strHeader, Len(strHeader) - Len(strFunctionName))

                    'Do we have storage type on the return type? 
                    Strip(strFunctionName)
                    If InStr(strFunctionName, " ") <> 0 Then
                        strReturnType = strReturnType + Left(strFunctionName, InStr(strFunctionName, " "))
                        strFunctionName = Right(strFunctionName, Len(strFunctionName) - InStr(strFunctionName, " "))
                    End If

                    'Get the function parameters. 
                    iPrm = 0
                    iPrmA = 0
                    strParams = strHeader

                    'Count the number of parameters. 
                    Do While InStr(strParams, ",") <> 0
                        iPrm = iPrm + 1
                        strParams = Right(strParams, Len(strParams) - InStr(strParams, ","))
                    Loop

                    'Store the parameter list in the array. 
                    If iPrm > 0 Then ' If multiple params. 
                        iPrm = iPrm + 1
                        iPrmA = iPrm
                        ReDim ParamArr(iPrm)

                        Do While InStr(strHeader, ",") <> 0
                            ParamArr(iPrm - 1) = Left(strHeader, InStr(strHeader, ",") - 1)
                            'Remove brace from first parameter. 
                            If InStr(ParamArr(iPrm - 1), " (") <> 0 Then
                                p = iPrm - 1
                                l = Len(ParamArr(p))
                                ParamArr(p) = Right(ParamArr(p), (l - (l - (l - InStr(ParamArr(p), " (")))))
                                Strip(ParamArr(iPrm))
                            End If
                            strHeader = Right(strHeader, Len(strHeader) - InStr(strHeader, ","))
                            iPrm = iPrm - 1
                        Loop
                        ParamArr(iPrm - 1) = strHeader


                        'Remove trailing brace from last parameter. 
                        If InStr(ParamArr(iPrm - 1), ")") <> 0 Then
                            ParamArr(iPrm - 1) = Left(ParamArr(iPrm - 1), InStr(ParamArr(iPrm - 1), ")") - 1)
                            Strip(ParamArr(iPrm - 1))
                        End If
                    Else 'Possibly one param. 

                        ReDim ParamArr(1)
                        strHeader = Right(strHeader, Len(strHeader) - 1) ' Strip the first brace. 
                        Strip(strHeader)
                        ParamArr(0) = Strip(strHeader)
                        If InStr(ParamArr(0), ")") <> 1 Then
                            ParamArr(0) = Left(ParamArr(0), InStr(ParamArr(0), ")") - 1)
                            Strip(ParamArr(0))
                            iPrmA = 1
                        End If
                    End If

                    'Position the cursor one line above the selected text. 
                    DTE.ActiveDocument.Selection.LineUp()
                    DTE.ActiveDocument.Selection.LineDown()
                    DTE.ActiveDocument.Selection.StartOfLine()
                    objSel = DTE.ActiveDocument.Selection()
                    'selection.text = Lf 

                    strDescription = strCommentLine + CStr(Lf)
                    strDescription += "/// \brief " + CStr(Lf)

                    If (iPrmA <> 0) Then
                        strDescription += "/// " + CStr(Lf)
                    End If

                    'Print the parameter list. 
                    Last = iPrmA
                    Do While iPrmA <> 0
                        'Remove a line feed from any of the arguments. 
                        If InStr(ParamArr(iPrmA - 1), CStr(Lf)) <> 0 Then
                            p = iPrmA - 1
                            l = Len(ParamArr(p))
                            ParamArr(p) = Right(ParamArr(p), (l - (l - (l - InStr(ParamArr(p), CStr(Lf))))))
                            Strip(ParamArr(iPrmA - 1))
                        End If

                        ParamArr(iPrmA - 1) = Strip(ParamArr(iPrmA - 1))

                        'If there are 2+ parameters, the first parameter will 
                        'have a '(' prepended to it, remove it here: 
                        If iPrmA = Last And Last <> 1 Then
                            ParamArr(iPrmA - 1) = Right(ParamArr(iPrmA - 1), Len(ParamArr(iPrmA - 1)) - 1)
                        End If

                        SpaceIndex = InStrRev(ParamArr(iPrmA - 1), " ")
                        StarIndex = InStrRev(ParamArr(iPrmA - 1), "*")
                        AmpIndex = InStrRev(ParamArr(iPrmA - 1), "&")

                        RealIndex = System.Math.Max(SpaceIndex, StarIndex)
                        RealIndex = System.Math.Max(RealIndex, AmpIndex)

                        RealParam = Strip(Right(ParamArr(iPrmA - 1), Len(ParamArr(iPrmA - 1)) - RealIndex))

                        If (Len(RealParam) > 0 And InStr(RealParam, "void") = 0) Then
                            strDescription = strDescription + "/// \param " + RealParam + " " + CStr(Lf)
                        End If

                        iPrmA = iPrmA - 1
                    Loop

                    strReturnType = Strip(strReturnType)

                    If (Len(strReturnType) > 0 And InStr(strReturnType, "void") = 0) Then
                        strDescription += "/// \return " + strReturnType + CStr(Lf)
                    End If

                    strDescription += strCommentLine + CStr(Lf)

                    objSel = DTE.ActiveDocument.Selection()
                    objSel.Text = strDescription
                Else
                    MsgBox("It is possible that the function you are trying to work with has a syntax error.")
                End If
            End If

        Else
            MsgBox("You need to have an active C/C++ document open" + CStr(Lf) + "with the function prototype selected.")
        End If
    End Sub

    Sub AddMemberGroupDescription()
        ' ±×·ì ÁÖ¼®À» Áý¾î³Ö´Â´Ù.
        InsertText(Tab + "/// \name Simple getter & setter" + Lf + Tab + "/// \{ " + Lf + Tab + "/// \brief " + Lf + Tab + "/// \} " + Lf)
    End Sub

    Sub WrapStringWithTcharMacro()
        ' ÇöÀç ¼±ÅÃµÈ ¹®ÀÚ¿­À» _T() ¸ÅÅ©·Î·Î °¨½Ñ´Ù.
        Dim objRanges As TextRanges
        Dim objStartPt As EditPoint
        Dim objEndPt As EditPoint

        objRanges = ActiveDocument().Selection.TextRanges
        objStartPt = objRanges.Item(1).StartPoint.CreateEditPoint()
        objEndPt = objRanges.Item(objRanges.Count).EndPoint.CreateEditPoint()

        ' ¹®ÀÚ¿­ÀÇ Ã³À½À» ã´Â´Ù.
        While objStartPt.GetText(-1) <> """" Or objStartPt.GetText(-2) = "\"""
            objStartPt.CharLeft(1)
        End While
        objStartPt.CharLeft(1)

        ' ¹®ÀÚ¿­ÀÇ ³¡À» ã´Â´Ù.
        While objEndPt.GetText(1) <> """" Or objEndPt.GetText(-1) = "\"
            objEndPt.CharRight(1)
        End While
        objEndPt.CharRight(1)

        If objStartPt.GetText(-3) <> "_T(" Then
            ' ÀÌ¹Ì _T ¸ÅÅ©·Î·Î °¨½Î¿© ÀÖ´Â ¹®ÀÚ¿­ÀÌ ¾Æ´Ï¶ó¸é °¨½ÎÁØ´Ù.
            objStartPt.Insert("_T(")
            objEndPt.Insert(")")
        Else
            ' _T ¸ÅÅ©·Î·Î °¨½ÎÀÎ »óŶó¸é ¸ÅÅ©·Î¸¦ Á¦°ÅÇÑ´Ù.
            objStartPt.Delete(-3)
            objEndPt.Delete(1)
        End If
    End Sub

    Function ParseVariableDeclarations( _
        ByVal strText As String, ByRef colTypes As Collection, ByRef colNames As Collection, ByRef colComments As Collection)
        ' º¯¼ö ¼±¾ð¹®À» ÆÄ½ÌÇØ¼­, º¯¼ö ŸÀÔ + º¯¼ö À̸§ + ÁÖ¼®À¸·Î ºÐ¸®½ÃŲ´Ù.

        arrLines = strText.Split(Lf)
        For Each line In arrLines
            strLine = line

            ' ÁÂ¿ì °ø¹é Á¦°Å
            strLine = Strip(strLine)
            If Len(strLine) = 0 Then Continue For

            ' ¹®ÀÚ¿­ ¾È¿¡ ÀÖ´Â 2°³ ÀÌ»óÀÇ ½ºÆäÀ̽º¸¦ Çϳª·Î ¸¸µç´Ù.
            Do
                nSpacePos = InStr(strLine, "  ")
                If nSpacePos <> 0 Then
                    strLine = Replace(strLine, "  ", " ")
                Else
                    Exit Do
                End If
            Loop

            ' ¹®ÀÚ¿­ ¾È¿¡ ÀÖ´Â ÅÇÀ» ½ºÆäÀ̽º·Î ġȯÇÑ´Ù.
            Do
                nSpacePos = InStr(strLine, vbTab)
                If nSpacePos <> 0 Then
                    strLine = Replace(strLine, vbTab, " ")
                Else
                    Exit Do
                End If
            Loop

            ' ¶óÀÎ Á¦ÀÏ Ã³À½ ³ª¿À´Â ';' ±ÛÀÚ¿Í ';' ±ÛÀÚ ¾Õ¿¡¼­ Á¦ÀÏ Ã³À½ ³ªÅ¸³ª´Â ' ' ±ÛÀÚ¸¦ ã´Â´Ù.
            bSuccess = False
            nSemicolonPos = InStr(strLine, ";")
            If nSemicolonPos <> 0 Then
                nSpacePos = InStrRev(strLine, " ", nSemicolonPos)
                If nSpacePos <> 0 Then
                    bSuccess = True
                End If
            End If

            ' µÎ ±ÛÀÚ ¸ðµÎ¸¦ ã¾Ò´Ù¸é, º¯¼ö ¼±¾ð¹®À̶ó°í ÇÒ ¼ö ÀÖ´Ù.
            If bSuccess Then
                strVarType = Strip(Mid(strLine, 1, nSpacePos))
                strVarName = Strip(Mid(strLine, nSpacePos, nSemicolonPos - nSpacePos))
                strVarComment = ""

                If nSemicolonPos <> 0 Then
                    strVarComment = Strip(Mid(strLine, nSemicolonPos + 1, Len(strLine) - nSemicolonPos))
                End If

                strVarType = Strip(Replace(strVarType, vbTab, " "))
                strVarName = Strip(Replace(strVarName, vbTab, " "))
                strVarComment = Strip(Replace(strVarComment, vbTab, " "))

                If strVarType <> "" And strVarName <> "" Then
                    colTypes.Add(strVarType)
                    colNames.Add(strVarName)
                    colComments.Add(strVarComment)
                End If
            End If
        Next

    End Function

    Function ParseVariableDeclarationsEx( _
        ByVal strText As String, ByRef colTypes As Collection, ByRef colNames As Collection, ByRef colComments As Collection, ByRef colWholeComments As Collection)
        ' º¯¼ö ¼±¾ð¹®À» ÆÄ½ÌÇØ¼­, º¯¼ö ŸÀÔ + º¯¼ö À̸§ + ÁÖ¼®À¸·Î ºÐ¸®½ÃŲ´Ù.

        arrLines = strText.Split(Lf)
        For Each