'7. Tips/Visual Studio'에 해당되는 글 22건

  1. 2014.11.29 AsEclipse extension
  2. 2014.11.29 Shortcut to "Navigate to ..."
  3. 2013.11.30 빌드 옵션에 따른 Web.Config / ServiceReferences.ClientConfig 구성하기
  4. 2013.09.26 How to find the public key token for a .NET DLL or assembly
  5. 2013.09.26 Remote Debugging 설정
  6. 2013.09.22 How to disable intellisense for XAML in VS2010?
  7. 2013.07.30 2010 필수 Extensions
  8. 2012.04.20 Visual Studio Macro: Locate Item in Solution Explorer on Demand
  9. 2011.10.26 자동 인덴트 기능
  10. 2009.10.22 atlcom.h에서 ClassesAllowedInStream rgclsidAllowed; 에러가 나는 경우
  11. 2009.10.20 VBScript Projects in Visual Studio
  12. 2009.10.08 Visual Studio 빌드 자동화
  13. 2009.09.23 Devenv : 명령줄에서 빌드하기
  14. 2009.03.05 Visual Studio Add-Ins Every Developer Should Download Now
  15. 2009.03.03 Visual Studio 로 인터넷익스플로어(iexplorer) 디버그 하기
  16. 2009.02.19 [Visual Studio .NET 2005] 매크로 : 주석 & 솔루션 탐색기 검색
  17. 2009.02.05 Visual Studio 그리고 Visual Assist 관련 팁 몇가지 3
  18. 2009.01.08 Visual Studio 2003 - 책갈피 & 작업 목록 바로가기 활용
  19. 2008.11.25 빌드 환경 설정 관련 매크로
  20. 2008.08.19 [Visual Studo .NET 2003 C++] Doxygen 스타일의 주석을 생성하는 Macro 코드
2014. 11. 29. 05:38

AsEclipse extension

When using eclipse, ctrl + o is very usefull to move to the member within a file. AsEclipse supports this feature. 


Here are the description for AsEclipse and link to it.


AsEclipse is an add-in for MS Visual Studio, which enables you to use some convenient Eclipse editing functions in MS Visual Studio with almost the same shortcut keys. No matter whether you are familiar with Eclipse, AsEclipse will be helpful in coding with VS.

https://visualstudiogallery.msdn.microsoft.com/99ede732-544c-4f3b-8e38-49e4b8395075/


2014. 11. 29. 05:16

Shortcut to "Navigate to ..."

To find something like class, function, or file in a solution, "Navigate to..." is very useful. 


Ctrl + , 


lets you direct to that dialog.




2013. 11. 30. 04:16

빌드 옵션에 따른 Web.Config / ServiceReferences.ClientConfig 구성하기

빌드 옵션에 따른 Web.Config / ServiceReferences.ClientConfig 구성하기


(Enabling Transforms for Web.Config and ServiceReferences.ClientConfig)


참고: 


http://www.kongsli.net/nblog/2012/01/13/enabling-web-transforms-when-debugging-asp-net-apps/

http://msdn.microsoft.com/en-us/library/vstudio/dd576348.aspx



첨부 예제 참고. 



WebConfigTest.zip



Debug / Release 옵션에 따라,


실버라이트 클라이언트와 WCF 서비스가 실행되도록 구성함.


TFS 연동과는 아직 테스트 해보지 않았으나, 구글링 해보니 아래 TFS 에 web.config 와 servicereferences.clientconfig 를 TFS 와 연동되지 않도록 하면 되지 않을까 함.


http://stackoverflow.com/questions/9741975/how-can-i-always-block-checkin-of-a-specific-file-in-tfs/9742947#9742947






2013. 9. 26. 05:41

How to find the public key token for a .NET DLL or assembly


Public Key Tokens with sn

Just run sn -T followed by your DLL or assembly. Here’s an example:

PS > sn -T "C:\dev\System.Data.SQLite.dll"

Microsoft (R) .NET Framework Strong Name Utility  Version 3.5.30729.1
Copyright (c) Microsoft Corporation.  All rights reserved.

Public key token is db937bc2d44ff139

Public Key Tokens with gacutil

If the DLL is in the GAC, you can do the same thing with gacutil:

PS > gacutil -l System.Data.SQLite
Microsoft (R) .NET Global Assembly Cache Utility. Version 4.0.30319.1
Copyright (c) Microsoft Corporation. All rights reserved.

The Global Assembly Cache contains the following assemblies:
System.Data.SQLite, Version=1.0.84.0, Culture=neutral, 
PublicKeyToken=db937bc2d44ff139, processorArchitecture=AMD64 Number of items = 1


2013. 9. 26. 05:03

Remote Debugging 설정

1. 디버깅 대상 PC 에 Microsoft Visual Studio Remote Debugger 설치


아래 링크는 2010 버전


http://www.microsoft.com/ko-kr/download/details.aspx?id=475


2. 방화벽 확인


Ports 

Protocol 

 

 135

 TCP 

 Required 

 500, 4500

 UDP

 Required if your domain policy requires network communication to be performed through IPSec


3. 디버깅 대상 PC 에서 아래 명령으로 실행


runas /user:youruserid /netonly msvsmon.exe


- msvsmon 위치 예


  C:\Program Files\Microsoft Visual Studio 20.0\Common7\IDE\Remote Debubbger\x64

  C:\Program Files\Microsoft Visual Studio 20.0\Common7\IDE\Remote Debubbger\x32


- 동일한 도메인이 아닌 경우


youruserid 의 계정이 디버깅 대상 PC 와 디버깅 PC 에 동일한 id 와 password 로 된 계정이 존재해야 함.


4. msvsmon > Tools > permissions


add user "youruserid"


(msvsmon 실행할 때 마다 해 줌)


5. 연결 정보 확인




6. Visual Studio > Debug > Attach to process


Transport : Default

Qualifier : 5번에 나오는 Server name



프로세스 목록 나오면 성공.


Remote Debuggin Across Domains 도 해보면 좋을 듯 

(http://msdn.microsoft.com/en-us/library/9y5b4b4f(v=vs.100).aspx)


참고: http://stackoverflow.com/questions/396101/remote-debugging-in-visual-studio-vs2008-windows-forms-application

 및 여기저기

2013. 9. 22. 06:42

How to disable intellisense for XAML in VS2010?

Xaml 편집 시 "Auto List Members" 옵션을 꺼두면 좀더 빠릅니다. 이를 꺼두고 필요할 때 [Ctrl] + [Space] 로 불러다 쓰면 됩니다. 자동으로 나온다고 해서 그다지 편리하지도 않고 느리기까지 하니 좋은 성능의 피시가 아니라면 꺼두시기 바랍니다.


HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\10.0\Text Editor\XAML\Auto List Members


의 값을 0으로 지정합니다. 





참고: http://stackoverflow.com/questions/6954328/how-to-disable-intellisense-for-xaml-in-vs2010


2013. 7. 30. 00:20

2010 필수 Extensions




Visual Assist X 는 유료,

나머지는 Microsoft 에서 제공하는 무료!


아래 세팅도 필수!


http://codemuri.tistory.com/entry/Visual-Studio-Macro-Locate-Item-in-Solution-Explorer-on-Demand

2012. 4. 20. 05:00

Visual Studio Macro: Locate Item in Solution Explorer on Demand

http://dvanderboom.wordpress.com/2008/03/21/visual-studio-macro-track-item-in-solution-explorer-on-demand/


위 링크에 여러가지 방법에 대해서 논의하고 있는데, 그중에서 아래 방법이 제일 간단하고 좋은 것 같습니다.


DTE.ExecuteCommand("View.TrackActivityinSolutionExplorer", True) DTE.ExecuteCommand("View.TrackActivityinSolutionExplorer", False) DTE.ExecuteCommand("View.SolutionExplorer")]


위 코드를 매크로로 만들어서 단축키로 지정하면 됩니다.

2011. 10. 26. 23:02

자동 인덴트 기능

2009. 10. 22. 07:00

atlcom.h에서 ClassesAllowedInStream rgclsidAllowed; 에러가 나는 경우

1>c:\program files\microsoft visual studio 9.0\vc\atlmfc\include\atlcom.h(431) : error C2146: syntax error : missing ';' before identifier 'rgclsidAllowed'
1>c:\program files\microsoft visual studio 9.0\vc\atlmfc\include\atlcom.h(431) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\program files\microsoft visual studio 9.0\vc\atlmfc\include\atlcom.h(431) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\program files\microsoft visual studio 9.0\vc\atlmfc\include\atlcom.h(6053) : error C2039: 'rgclsidAllowed' : is not a member of 'ATL::ATL_PROPMAP_ENTRY'
1>        c:\program files\microsoft visual studio 9.0\vc\atlmfc\include\atlcom.h(422) : see declaration of 'ATL::ATL_PROPMAP_ENTRY'
1>c:\program files\microsoft visual studio 9.0\vc\atlmfc\include\atlcom.h(6053) : error C2660: 'ATL::CComVariant::ReadFromStream' : function does not take 4 arguments


기존에 잘 쓰던 ATL 프로젝트가 이번에 atl 패치로 인해 컴파일이 되지 않았다.

기존에 static으로 atl을 사용하던 부분이였는데 아직 정확한 원인은 파악되지 않았지만

일단 설정에서 Use of ATL 의 옵션값을 Dynamic Link to ATL로 변경하여 사용하면 된다.

물론 atl90.dll 과 manifest를 추가로 같이 배포해야 한다.

출처 : http://ancdesign.tistory.com/59
2009. 10. 20. 05:43

VBScript Projects in Visual Studio

이 글은 아래 원문을 번역한 것이다.

http://krestenm.blogspot.com/2007/12/vbscript-projects-in-visual-studio2.html

비쥬얼 스튜디오의 디버거는 VBScript 를 디버깅하는데 있어 매우 유용한 툴이다. 비쥬얼 스튜디오는 스크립트를 조직하고 CVS, Subversion, 또는 Source Safe 와 같은 버전 제어 시스템을 가지고 있다면 스크립트의 변경을 추적하도록 할 수 있다. 비쥬얼 스튜디오는 또한 COM 개체와 기본적인 VBScript 함수에 대한 인텔리센스를 제공한다.

하지만 VBScript 프로젝트를 생성하기 위한 비쥬얼 스튜디오 프로젝트 템플릿을 찾을 수 없었다. 몇몇 사람들은 커스텀 빌드 액션을 설정하라고 추천하지만, 지금까지 검색해본 결과 아무도 시도하지 았았다. 그리하여 내가 알아낸 것을 공유하기 위해 이 블로그에 작성하였다.

VBScript 프로젝트를 위한 템플릿이 없기때문에, 비쥬얼 스튜디오에서 제공하는 가장 기본적인 템플릿을 찾기로 하였다. 그게 바로 Makefile 프로젝트이다. 이제 메뉴에서 New Project 를 선택하고 아래 그림처럼 프로젝트를 생성하라.


마법사가 뜨고 프로젝트에 대해 세부적인 설정을 할 수 있다. 하지만 그러한 설정이 필요없기 때문에 그냥 Finish 를 클릭하자.


템플릿은 전형적인 C++ 프로젝트를 위한 3개의 폴더와 readme.txt 파일을 생성하였다. 모두 필요 없기때문에 당장 제거하자.


이제 프로젝트에 새로운 VBScript 파일을 추가하자.


이제 프로젝트에서 오른쪽 마우스를 클릭하고 Properties 를 선택하라. General Page 를 선택하고 "Configuration Type" 을 "Makefile" 에서 "Utility"로 변경하라.


다음은 "Debugging" 페이지를 선택하고 "Command" 필드를 "cscript.exe" 로 설정하고 "Command Arguments" 필드를 "//X MyScript.vbs" 로 설정한다. 이것은 "CScript.exe //X MyScript.vbs" 명령어를 실행할 것이고 이것은 디버그-모드에서 스크립트를 실행할 것이다.


이제 아래 그림과 같은 코드를 추가하자. CTRL+Space 를 누르면 인텔리센스가 제공된다는 것을 기억하라.


이제 프로젝트를 실행하기 위해 "디버깅 없이 시작하기"인 Ctrl+F5 를 눌러라. 디버거 없이 시작되는 이유는 비쥬얼 스튜디오는 cscript.exe 프로세스에 디버거를 부착하려고 시도할 것이기 때문이다, 하지만 우리가 디버깅하려고 하는 것은 스크립트이다.

파라미터를 //X 로 설정했기 때문에, 스크립팅 엔진은 "Script Breakpoint" 예외를 던질 것이다, 그러면 비쥬얼 스튜디오는 Just-In-Time 디버거가 그 예외를 잡아서 그것에 대해 아래 그럼처럼 어떻게 할 지를 묻는다. 현재 비쥬얼 스튜디오 인스턴스를 선택하고 "Yes" 를 눌러라.


이제 비쥬얼 스튜디오는 스크립트에 부착할 것이고 예전에 하던데로 그것을 디버그할 수 있다. 아래 그림에서 중단점이 히트된 곳을 볼 수 있다. 또한 변수 "I" 에 대한 값도 볼 수 있다.


이것은 비쥬얼 스튜디오에서 VBScript 프로젝트를 만드는 나의 첫번째 shot 이다. 이렇게 한 후에는, 당신은 다른 setup 을 실험할 수 있다. 곧 발견하게 되겠지만 아마 당신은 솔루션 내에 좀더 많은 스크립트를 가지고 싶어 할 것이다. 이것은 스크립트를 전환할 때마다 프로젝트의 설정을 반드시 변경해야 한다. 나는 실행할 스크립트를 명시한 많은 설정(디버그와 릴리즈와 같은)을 가지거나 각 스크립트를 위한 커스텀 빌드 액션을 설정하는 것을 제안한다. 커스텀 빌드 액션을 가지는 것은 당신 편집하고 있는 액티브 파일을 컴파일 하는 CTRL+F7 을 누르는 것을 필요로 한다. "Start Without Debugger" 를 선택하면, 모든 파일을 위한 빌드 액션이 활성화 될 것이고, 각 스크립트를 위한 디버거를 선택하라는 요청을 받게 될 것이다.
2009. 10. 8. 07:17

Visual Studio 빌드 자동화

아래는 JScript 예. EnvDTE 개체 말고 devenv.exe 를 이용해서도 빌드할 수 있다. 빌드랑 빌드 성공 여부는 알 수 있는데 오류목록을 얻어오거나 출력창을 캡처하려면 좀더 작업해야 하지만 일단 뒤로 미루자.


function test () {
    // Codes here.
    
    try {
        var dte2 = new ActiveXObject("VisualStudio.Solution.8.0");
        
        var dte = dte2.DTE;
        
        var vsSolution = dte2.DTE.Solution;
        
        vsSolution.Open ("C:\\Documents and Settings\\yim.jihoon\\My Documents\\Visual Studio 2005\\Projects\\HtmlTest\\HtmlTest.sln");
        
        vsSolution.SolutionBuild.Build(true);
        
        var nErrorCount = vsSolution.SolutionBuild.LastBuildInfo;
        var output = dte.Windows.item("{34E76E81-EE4A-11D0-AE2E-00A0C90FFFC3}");
        Log.Print(output.Caption);
        //var activePain = output.OutputWindowPanes.item(0);
        //var textDocument = activePain.TextDocument;
        //var sel = output.Selection;
        
        //sel.StartOfDocument()
        //sel.EndOfDocument(True)
        
        //Log.Print(sel.Text);
        
        var win;
        var en;
        en = new Enumerator(dte.Windows);
        for ( ; !en.atEnd() ; en.moveNext() )
        {
            win = en.item();
            Log.Print(win.Caption);
            Log.Print(win.ObjectKind);
        }

        
        vsSolution.Close(false);
        vsSolution.DTE.Quit();
    
       } catch(e)
       {
           Log.Print(e.description);
       }
    
    // if you want to continue running next script, return true.
    // Otherwise return false to quit running.
    return true;    
}


2009. 9. 23. 00:08

Devenv : 명령줄에서 빌드하기

Devenv.exe 를 이용하면 도스 명령어에서 빌드 및 수행을 할 수 있다.

아래는 그 사용예.

 devenv "C:\Documents and Settings\someuser\My Documents\Visual Studio\Projects\MySolution\MySolution.sln" /build Debug /project "CSharpWinApp\CSharpWinApp.csproj" /projectconfig Debug

자세한 내용은 MSDN 참고

출처 : ms-help://MS.VSCC.v80/MS.MSDN.v80/MS.VisualStudio.v80.ko/dv_vscmds/html/ced21627-7653-455b-8821-3e31c6a448cf.htm


2009. 3. 5. 03:55

Visual Studio Add-Ins Every Developer Should Download Now


http://msdn.microsoft.com/en-us/magazine/cc300778.aspx

위 링크에는 Visual Studio를 사용하는 개발자라면 Visual Studio Add-In으로 지금 당장 다운로드 해야 되는 것들에 대해서 10가지를 소개하고 있다.

이 중에 눈에 띄는게 pInvoke랑 CopySourceAsHtml 이다.

pInvodk는 메소드 시그너처를 쉽게 알아낼 수 있도록 도움을 주는 애드인이다. 아래 그림처럼 Beep이란 메소드에 대해서 아래와 같이 보여준다.



다운로드 : http://www.pinvoke.net/

CopySourceAsHtml 은 비쥬얼 스튜디오 편집기에서 보이는 포맷 그대로를 다른 곳으로 복사할 수 있게 해준다. 만약 나처럼 블로그를 운영하여 코드를 이쁘게 복사하고 싶은 일이 많을 경우 반드시 설치하자~! 


다운로드(영문판) : http://www.jtleigh.com/people/colin/software/CopySourceAsHtml/

Visual Studio 2005 한글판을 사용하는 경우 아래 링크에서 한글판을 다운받자.

http://www.simpleisbest.net/archive/2006/12/26/1484.aspx
2009. 3. 3. 00:21

Visual Studio 로 인터넷익스플로어(iexplorer) 디버그 하기


원래 되는 기능이었겠지만 웹쪽엔 그닥 관심도 없었고 경험도 없었던지라 잘 몰랐었는데, Visual Studio로 html 내에 작성된 VBScript나 JavaScript 를 디버깅할 수 있다는 걸 알게 되었다. "디버그>프로세스에 연결" 기능을 활용한 것인데 이미 떠있는 프로세스에 대한 디버깅을 지원하므로 아주 유용한 기능이다. 근데 잘 모르거나 경험이 없다면 거의 쓰지 않는 기능이다. 나도 학생때 부터 지금까지 Visual Studio 6.0에 걸쳐 2005를 한 8년 넘게 다루고 있는것 같은데... 이제서야 직접 다루게 된다...ㅋ

1. Script가 포함된 html 문서를 작성한후, 인터넷 익스플로어로 연다.

 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
    <title>Untitled Page</title>
</head>
<body>

<script>
var xmlhttp=null;

  var xmlhttp = new ActiveXObject("Msxml2.XMLHTTP.5.0");
  xmlhttp.Open("POST", "http://localhost", true);
  xmlhttp.onreadystatechange= HandleStateChange;
  xmlhttp.Send();

function HandleStateChange()
{
  if (xmlhttp.readyState == 4)
  {
    WScript.Echo("Result = " + xmlhttp.responseXML.xml);
  }
}
</script>
</body>
</html>




2. Visual Studio 를 실행하고 "디버그>프로세스에 연결" 을 실행한 후 해당 프로세스인 iexplorer.exe를 선택한다.

3. 그러면 html 문서가 Visual Studio 내에 보일것이고, 원하는 스크립트 위치에 디버깅을 건다.



4. 열려있는 인터넷 익스플로어에서 F5 (리로드) 를 실행한다.

5. 그러면 아래와 같이 디버깅 할 수 있음을 볼 수 있다.




과정은 위와 같이 간단한데 중요한건 "프로세스에 연결" 기능을 사용하는 것이다. 이 기능은 여러모로 활용이 가능하니 알고는 있어야 한다.
2009. 2. 19. 13:38

[Visual Studio .NET 2005] 매크로 : 주석 & 솔루션 탐색기 검색

Visual Studio 2005 에서 사용하는 매크로입니다.

1. C++에서 클래스 및 함수에 대해 Doxygen 스타일의 주석 템플릿을 생성합니다. 함수 정의 부를 선택하거나, 클래스 선언부를 선택하여 MakeCommentForDoxygen 매크로를 수행하면 됩니다.

2. 현재 활성화된 파일을 솔루션에서 찾고자 하는 경우에 FindInSolutionExplorer 매크로를 수행하면 바로 찾아갑니다. 이 기능은 옵션에서 항상 켜지게 해놓을 수도 있으나 그렇게 하면 저에게는 가끔 여러모로 불편하므로 그 기능을 Off 시켜놓고 이 매크로를 사용합니다.

-> 이 기능은 다음 링크를 참고하자. 



Imports System
Imports EnvDTE
Imports EnvDTE80
Imports EnvDTE90

Public Module Utilities
    Public Sub TrackProjectItem()
        Dim solution As Solution2 = DTE.Solution
        If Not solution.IsOpen OrElse DTE.ActiveDocument Is Nothing Then Return

        solution.FindProjectItem(DTE.ActiveDocument.FullName).ExpandView()

        Dim FileName As String = DTE.ActiveDocument.FullName

        Dim SolutionExplorerPath As String
        Dim items As EnvDTE.UIHierarchyItems = DTE.ToolWindows.SolutionExplorer.UIHierarchyItems
        Dim item As Object = FindItem(items, FileName, SolutionExplorerPath)

        If item Is Nothing Then
            MsgBox("Couldn't find the item in Solution Explorer.")
            Return
        End If

        DTE.Windows.Item(Constants.vsWindowKindSolutionExplorer).Activate()
        DTE.ActiveWindow.Object.GetItem(SolutionExplorerPath).Select(vsUISelectionType.vsUISelectionTypeSelect)
    End Sub

    Public Function FindItem(ByVal Children As UIHierarchyItems, ByVal FileName As String, ByRef SolutionExplorerPath As String) As Object
        For Each CurrentItem As UIHierarchyItem In Children
            Dim TypeName As String = Microsoft.VisualBasic.Information.TypeName(CurrentItem.Object)
            If TypeName = "ProjectItem" Then
                Dim projectitem As EnvDTE.ProjectItem = CType(CurrentItem.Object, EnvDTE.ProjectItem)
                Dim i As Integer = 1
                While i <= projectitem.FileCount
                    If projectitem.FileNames(i) = FileName Then
                        SolutionExplorerPath = CurrentItem.Name
                        Return CurrentItem
                    End If
                    i = i + 1
                End While
            End If

            Dim ChildItem As UIHierarchyItem = FindItem(CurrentItem.UIHierarchyItems, FileName, SolutionExplorerPath)
            If Not ChildItem Is Nothing Then
                SolutionExplorerPath = CurrentItem.Name + "\" + SolutionExplorerPath
                Return ChildItem
            End If
        Next
    End Function
End Module




 Imports System
Imports EnvDTE
Imports EnvDTE80
Imports System.Diagnostics

Public Module Module1

    Function InsertNewLine(ByRef doc As Document, ByVal str As String)

        doc.Selection.NewLine()

        doc.Selection.StartOfLine()

        doc.Selection.Text = str

    End Function

    Enum DocType
        CPPSOURCE = 0
        CPPHEADER = 1
        RESOURCE = 2
        ETC = 3
    End Enum

    Function GetDocType(ByVal strName As String) As DocType
        Dim strUpperName As String
        strUpperName = UCase(strName)

        If InStr(strUpperName, UCase(".h")) > 0 Then
            GetDocType = DocType.CPPHEADER
        ElseIf InStr(strUpperName, UCase(".cpp")) > 0 Then
            GetDocType = DocType.CPPSOURCE
        Else
            GetDocType = DocType.ETC
        End If
    End Function

    Function GetHItemsType(ByVal strName As String) As DocType
        Dim strUpperName As String
        strUpperName = UCase(strName)
        If strUpperName = UCase("Source Files") Then
            GetHItemsType = DocType.CPPSOURCE
        ElseIf strUpperName = UCase("Header files") Then
            GetHItemsType = DocType.CPPHEADER
        ElseIf strUpperName = UCase("Resource Files") Then
            GetHItemsType = DocType.RESOURCE
        Else
            GetHItemsType = DocType.ETC
        End If
    End Function

    Function SelectItem(ByRef win As Window, ByRef UIChildItemList As UIHierarchyItems, ByRef doc As Document) As Boolean
        Dim uiProjectItem As UIHierarchyItem
        Dim blExpanded As Boolean

        Dim UISolutionItem As UIHierarchyItem
        UISolutionItem = UIChildItemList.Item(1)

        For Each uiProjectItem In UISolutionItem.UIHierarchyItems
            If uiProjectItem.UIHierarchyItems.Count <> 0 Then
                If (uiProjectItem.Name = doc.ProjectItem.ContainingProject.Name) Then

                    Dim uiSubItem As UIHierarchyItem
                    For Each uiSubItem In uiProjectItem.UIHierarchyItems
                        Dim type1 As DocType
                        Dim type2 As DocType

                        type1 = GetDocType(doc.Name)
                        type2 = GetHItemsType(uiSubItem.Name)

                        If type1 = type2 Then
                            Dim uiItem As UIHierarchyItem
                            For Each uiItem In uiSubItem.UIHierarchyItems
                                If uiItem.Name = doc.Name Then
                                    win.Activate()
                                    uiItem.Select(vsUISelectionType.vsUISelectionTypeSelect)
                                    GoTo END_SELECTITEM
                                End If
                            Next
                        End If
                    Next

                    GoTo END_SELECTITEM
                End If
            End If
        Next
END_SELECTITEM:
    End Function

    Sub FindInSolutionExplorer()
        Dim lCount As Long
        Dim i As Long
        Dim win As Window
        lCount = Application.Windows.Count

        Dim w1 As Window
        w1 = DTE.Windows.Item(Constants.vsWindowKindSolutionExplorer)

        Dim doc As Document
        doc = ActiveDocument

        Dim UIHItem As UIHierarchy
        Dim file As UIHierarchyItem

        UIHItem = w1.Object

        SelectItem(w1, UIHItem.UIHierarchyItems, doc)
    End Sub

 

    Function GetParam(ByVal str As String) As String

        Dim iIndexFound As Integer

        Dim strTemp As String

 

        strTemp = Trim(str)

        iIndexFound = InStr(str, " ", CompareMethod.Text)

        If iIndexFound > 0 Then

            GetParam = Trim(Right(strTemp, Len(strTemp) - iIndexFound))

        Else

            GetParam = strTemp

        End If

    End Function

 

    Function RemoveComment(ByVal str As String) As String

        Dim iCommentPrefixFound As Integer

        Dim iCommentPostfixFound As Integer

        Dim strTemp As String

 

        RemoveComment = str

        iCommentPrefixFound = InStr(RemoveComment, "/*", CompareMethod.Text)

        While iCommentPrefixFound > 0

            strTemp = Right(RemoveComment, Len(RemoveComment) - iCommentPrefixFound + 1)

            iCommentPostfixFound = InStr(strTemp, "*/", CompareMethod.Text)

            If iCommentPostfixFound > 0 Then

                RemoveComment = Left(RemoveComment, iCommentPrefixFound - 1)

                strTemp = Right(strTemp, Len(strTemp) - iCommentPostfixFound - 1)

                RemoveComment = RemoveComment & strTemp

            Else

                RemoveComment = Left(RemoveComment, iCommentPrefixFound - 1)

                Exit While

            End If

            iCommentPrefixFound = InStr(RemoveComment, "/*", CompareMethod.Text)

        End While

 

    End Function

 

    Sub MakeCommentForDoxygen()

        Dim strDelimFormat As String = "//////////////////////////////////////////////////////////////////////////"

        Dim strBriefFormat As String = "/// @brief" & CStr(Chr(9)) & CStr(Chr(9))

        Dim strAuthorFormat As String = "/// @author" & CStr(Chr(9)) & CStr(Chr(9))

        Dim strVersionFormat As String = "/// @version" & CStr(Chr(9)) & "v1.0"

        Dim strDateFormat As String = "/// @date" & CStr(Chr(9)) & CStr(Chr(9))

        Dim strRemarkFormat As String = "/// @remark" & CStr(Chr(9)) & CStr(Chr(9))

        Dim strReturnFormat As String = "/// @return" & CStr(Chr(9)) & CStr(Chr(9))

        Dim strParamFormat As String = "/// @param" & CStr(Chr(9))

        Dim FuncAll As String = DTE.ActiveDocument.Selection.Text

        Dim iIndexFound As Integer

        Dim strTemp As String

        Dim strInput As String

        Dim strClass As String = "Class"

        Dim currentDate As Date

 

        Dim strBriefDesc As String

 

        FuncAll = RemoveComment(FuncAll)    ' /* */ 로 끝나는 주석을 제거함.

 

        ' 선택된 텍스트를 가져옴

        FuncAll = FuncAll.Replace(CStr(CStr(Chr(9))), " ")

        FuncAll = Trim(FuncAll.Replace(CStr(vbCrLf), ""))

 

        Dim curDocument As Document

        curDocument = ActiveDocument   ' 현재 다큐먼트를 저장

 

 

        ' 클래스인지 함수 인지 검사

        iIndexFound = InStr(UCase(FuncAll), UCase(strClass), CompareMethod.Text)

        Dim iTemp As Integer

        iTemp = iIndexFound - 1

        If iTemp > 0 Then

            strTemp = Mid(FuncAll, iIndexFound - 1, 1)  ' class 키워드 앞에 다른 문자가 붙으면 클래스가 아님.

            If strTemp <> " " Then

                iIndexFound = 0

            End If

        End If

 

        If iIndexFound > 0 Then ' 클래스이다

            strTemp = Right(FuncAll, FuncAll.Length - iIndexFound - Len(strClass) + 1)

            iIndexFound = InStr(strTemp, ":", CompareMethod.Text)

            If (iIndexFound > 0) Then

                strTemp = Left(strTemp, iIndexFound - 1)

                strTemp = Trim(strTemp)

            End If

 

            If strTemp.Length <> 0 Then

                ' 클래스 주석을 추가하자

                ' 입력을 먼저 받고 입력이 있을 경우에만 아래를 추가하자

                ' Brief

                'strInput = InputBox("Insert a brief into " & strTemp)        ' 현재 strTemp는 클래스 명이다

                'strTemp = Trim(strInput)

                'If strTemp.Length = 0 Then

                '    Exit Sub

                'End If

 

                ' Delimitor

                curDocument.Selection.GotoLine(curDocument.Selection.TopLine)

                curDocument.Selection.StartOfLine(EnvDTE.vsStartOfLineOptions.vsStartOfLineOptionsFirstText)

                InsertNewLine(curDocument, strDelimFormat)

 

                ' brief 추가

                strBriefDesc = strBriefFormat & strInput

                InsertNewLine(curDocument, strBriefDesc)

 

                ' version

                InsertNewLine(curDocument, strVersionFormat)

 

                ' Date

                currentDate = Date.Now

                strTemp = strDateFormat & Trim(CStr(currentDate.Year())) & "/" & Trim(CStr(currentDate.Month())) & "/" & Trim(CStr(currentDate.Day()))

                InsertNewLine(curDocument, strTemp)

 

                ' Author

                strTemp = System.Security.Principal.WindowsIdentity.GetCurrent().Name()

                iIndexFound = InStr(strTemp, "\", CompareMethod.Text)

                If iIndexFound > 0 Then

                    strTemp = Right(strTemp, Len(strTemp) - iIndexFound)

                End If

                strTemp = strAuthorFormat & strTemp

                InsertNewLine(curDocument, strTemp)

 

                ' Delimitor

                InsertNewLine(curDocument, strDelimFormat)

                curDocument.Selection.NewLine()

            End If

        Else    ' 함수인지 검사

            iIndexFound = InStr(FuncAll, "(", CompareMethod.Text)

            If iIndexFound > 0 Then

                Dim strFunc As String

                Dim strReturn As String

                Dim strParams As String

                Dim strReturnDesc As String

 

                strFunc = Left(FuncAll, iIndexFound - 1)    ' 괄호앞 전체

                strTemp = Right(FuncAll, Len(FuncAll) - iIndexFound)   ' 괄호 이후 뒤쪽

 

                ' strFunc에서 반환값 추출

                iIndexFound = InStrRev(strFunc, " ", -1, CompareMethod.Text)

                If iIndexFound > 0 Then

                    strReturn = Trim(Left(strFunc, iIndexFound))

                Else

                    strReturn = ""

                End If

 

                iIndexFound = InStr(strTemp, ")", CompareMethod.Text)

                If iIndexFound > 0 Then

                    strParams = Trim(Left(strTemp, iIndexFound - 1))

 

                    Dim strParamList As String()

                    Dim strParamDesc As String()

                    Dim iParamCount As Integer = 0

                    Dim iCount As Integer

 

                    ' 파라미터 갯수 파악하기

                    If Len(strParams) <> 0 Then

                        strTemp = strParams

 

                        iIndexFound = InStr(strTemp, ",", CompareMethod.Text)

                        If iIndexFound > 0 Then

                            ' 파라미터가 1개 이상이다

 

                            ' 콤마 갯수를 센 후에 어레이를 잡고 파라미터를 대입하자 (무식하지만 귀찮다)

                            Dim iCommaCount As Integer = 0

                            While iIndexFound > 0

                                iCommaCount = iCommaCount + 1

                                strTemp = Right(strTemp, Len(strTemp) - iIndexFound)

                                iIndexFound = InStr(strTemp, ",", CompareMethod.Text)

                            End While

 

                            iParamCount = iCommaCount + 1

                            ReDim strParamList(iParamCount)

                            strTemp = strParams

                            iIndexFound = InStr(strTemp, ",", CompareMethod.Text)

                            iCount = 1

                            While iIndexFound > 0

                                strParamList(iCount) = Trim(Left(strTemp, iIndexFound - 1))

                                strTemp = Right(strTemp, Len(strTemp) - iIndexFound)

                                iIndexFound = InStr(strTemp, ",", CompareMethod.Text)

                                iCount = iCount + 1

                            End While

 

                            strParamList(iCount) = Trim(strTemp)

 

                        Else

                            iParamCount = 1

                            ReDim strParamList(iParamCount)

                            strParamList(iParamCount) = strTemp

                        End If

                    End If

 

                    ' Brief 얻기

                    'strBriefDesc = InputBox("Insert a brief into " & strFunc)

                    'If Len(strBriefDesc) = 0 Then

                    '    Exit Sub

                    'End If

 

                    ReDim strParamDesc(iParamCount)

                    ' 파라미터에 대한 brief 얻기

                    'For iCount = 1 To iParamCount

                    '    If iParamCount <> 1 Or UCase(strParamList(1)) <> "VOID" Then

                    '        strParamDesc(iCount) = InputBox("Insert a brief into " & strParamList(iCount))

                    '    End If

                    'Next iCount

 

                    ' Return에 대한 brief 얻기

                    'If Len(strReturn) <> 0 And UCase(strReturn) <> "VOID" Then

                    '    strReturnDesc = InputBox("Inser a brief into the return value")

                    'End If

 

                    ' Delimitor

 

                    curDocument.Activate()

                    curDocument.Selection.GotoLine(curDocument.Selection.TopLine)

                    curDocument.Selection.StartOfLine(EnvDTE.vsStartOfLineOptions.vsStartOfLineOptionsFirstText)

                    InsertNewLine(curDocument, strDelimFormat)

 

                    ' brief 추가

                    strBriefDesc = strBriefFormat & strBriefDesc

                    InsertNewLine(curDocument, strBriefDesc)

 

                    ' 파라미터에 대한 정보 추가

                    For iCount = 1 To iParamCount

                        If iParamCount <> 1 Or UCase(strParamList(1)) <> "VOID" Then

                            strTemp = GetParam(strParamList(iCount))

                            strTemp = strParamFormat & strTemp & CStr(Chr(9)) & strParamDesc(iCount)

                            InsertNewLine(curDocument, strTemp)

                        End If

                    Next

 

                    If Len(strReturn) <> 0 And UCase(strReturn) <> "VOID" Then

                        ' Return 추가

                        strReturnDesc = strReturnFormat & strReturnDesc

                        InsertNewLine(curDocument, strReturnDesc)

                    End If

 

                    InsertNewLine(curDocument, strRemarkFormat)

 

                    ' Delimitor

                    InsertNewLine(curDocument, strDelimFormat)

 

                    curDocument.Selection.NewLine()

                    curDocument.Selection.StartOfLine()

                End If

            End If

        End If

 

        curDocument.Save()

 

        'Temp = FuncAll.IndexOf("(")

        'If Temp < 0 Then Exit Sub

 

    End Sub

 

End Module


 



2009. 2. 5. 23:02

Visual Studio 그리고 Visual Assist 관련 팁 몇가지


Visual Studio 2005를 사용하며, 그와 더불어 없어서는 안될 Addin인 Visual Assist를 함께 사용한다.

Visual Assist의 VA View 창에서 Files in solution 메뉴를 자주 이용하는데, 이 기능을 이용해서 파일은 금방 찾아가는데 이 파일과 관련된 솔루션 탐색기가 활성화 되지 않았다.

분명 Visual Studio 에서 제공하는 기능일 텐데 도저히 못찾았다.

그래서 답답한 마음에 그냥 매크로를 만들어 쓰기로 해서 두어시간 투자해서 솔루션 탐색기를 뒤적거려서 활성화된 문서의 트리 아이템을 찾는 매크로를 작성했다. 매크로 작성 후 약간의 성취감을 느끼며 기뻐한 찰나...

그 기능이 역시나 Visual Studio 에서 이미 제공하고 있다는 것을 알게 되엇다. 설정법은 간단했다. ㅜㅜ

예는 .. Visual Studio 2005의 경우임. (2003이나 6.0은 한번 찾아 보시길)

1. 도구 > 옵션 에서 아래 그림과 같이 ...

"솔루션 탐색기에서 활성화된 항목 추적"이란 항목을 체크하면 된다...^^;

그리고 Visual Assist를 사용하시는 분들은... 아래 단축키는 반드시 활용하자.

1. 커서가 있는 위치의 심볼을 찾아가기 -> Alt + G

2. .h 와 .cpp 파일 전환하기 -> Alt + O

3. 뒤로 가기 -> Alt + Left Arrow

4. 앞으로 가기 -> Ctrl + - (Visual Studio 6.0은 Alt + Right Arrow가 먹힘)

5. Open File in Solution 대화상자 열기 -> Shift + Alt + O

6. Find Symbol 대화상자 열기 -> Shift + Alt + S

[업데이트] 2009-05-13

유용한 단축키 : 가끔 Visual Assist 의 인텔리전트 기능이 제대로 동작하지 않아 -> 나 . 을 쳤을때 멤버 목록이 보이지 않으면, Ctrl + J 단축키를 누르면 바로 나타난다.

파라미터 정보를 보여주는 단축키는 Ctrl + Shift + Space 이다.
Quick Info 는 해당 함수 또는 변수 위에서 Ctrl + K, Ctrl + I

그리고 몇가지 더 소개하면,

///       -> 이렇게 세번 누르면 /////...라인을 넣어준다
//-       -> 이렇게 누르면 현재 로그온한 사용자 이름과 시간을 자동으로 입력하여 보다 편리하게 주석을 입력할 수 있다. 


2009. 1. 8. 16:02

Visual Studio 2003 - 책갈피 & 작업 목록 바로가기 활용


책갈피를 이용하면 한 문서내에서 여기저기 탐색할 수 있다

Ctrl + K, Ctrl + K 로 설정/해제한 후, (편집 > 책갈피 > 책갈피 설정/해제)



설정된 책갈피 사이를 Ctrl + P (previous), Ctrl + N (Next) 를 이용하여 탐색할 수 있다. (툴바에도 있음)



하지만 이 책갈피는 파일과 파일 사이는 왔다 갔다 할 수 없다.

이럴 경우 편집 > 책갈피 > 작업 목록 바로가기 추가/제거 (Ctrl + K, Ctrl + H)

를 이용하여 설정하면 중단점이 설정되는 곳에 화살표 같은 아이콘이 설정되며
동시에 작업 목록창에 바로가기로 등록된다.

만약 작업 목록창에서 보이지 않는 경우 오른쪽 마우스를 눌러 컨텍스트 메뉴를 나타낸후

작업 표시 > 바로 가기

를 선택해주면 작업 목록창에 나타난다.



이와같이 설정되면 작업 목록의 해당 위치를 더블클릭하면 지정한 위치를 탐색할 수 있다.

몰랐다면 자주 활용하자. 활용만 잘 하면 소스 가독 시간을 줄여 줄것이다.
2008. 11. 25. 11:33

빌드 환경 설정 관련 매크로

매크로는 프로젝트의 속성 페이지 대화 상자에서 문자열을 입력할 있는 모든 부분에 사용할 있습니다. 매크로는 /소문자를 구분하지 않습니다.

매크로

설명

$(RemoteMachine)

디버그 속성 페이지에서 원격 컴퓨터 속성의 값으로 설정합니다. 자세한 내용은 C/C++ 디버그 구성에 대한 프로젝트 설정 변경을 참조하십시오.

$(ConfigurationName)

현재 프로젝트 구성의 이름(: "Debug")

$(PlatformName)

현재 프로젝트 플랫폼의 이름(: "Win32")

$(Inherit)

프로젝트 빌드 시스템에서 작성한 명령줄에 상속된 속성이 나타나는 순서를 지정합니다. 기본적으로 상속된 속성은 현재 속성의 뒤에 나타납니다.1

$(NoInherit)

상속될 모든 속성이 상속되지 않도록 합니다. $(NoInherit) 사용하면 동일한 속성에 대한 모든 $(Inherit) 무시됩니다.1

$(ParentName)

프로젝트 항목을 포함하는 항목의 이름. 부모 폴더 이름이나 프로젝트 이름입니다.

$(RootNameSpace)

응용 프로그램을 포함하는 네임스페이스(있을 경우)

$(IntDir)

중간 파일에 지정된 디렉터리 경로로서 프로젝트 디렉터리에 대해 상대적인 경로입니다. 경로는 중간 디렉터리 속성의 값이 됩니다.

$(OutDir)

출력 파일 디렉터리의 경로로서 프로젝트 디렉터리에 대해 상대적인 경로입니다. 경로는 출력 디렉터리 속성의 값이 됩니다.

$(DevEnvDir)

드라이브 + 경로로 정의되는 Visual Studio .NET 설치 디렉터리로서 뒤에는 백슬래시(\) 붙습니다.

$(InputDir)

드라이브 + 경로로 정의되는 입력 파일의 디렉터리로서 뒤에는 백슬래시(\) 붙습니다. 해당 프로젝트가 입력 파일인 경우 매크로는 $(ProjectDir) 같습니다.

$(InputPath)

드라이브 + 경로 + 기본 이름 + 파일 확장명으로 정의되는 입력 파일의 절대 경로 이름입니다. 해당 프로젝트가 입력 파일인 경우 매크로는 $(ProjectPath) 같습니다.

$(InputName)

입력 파일의 기본 이름입니다. 해당 프로젝트가 입력 파일인 경우 매크로는 $(ProjectName) 같습니다.

$(InputFileName)

기본 이름 + 파일 확장명으로 정의되는 입력 파일의 파일 이름입니다. 해당 프로젝트가 입력 파일인 경우 매크로는 $(ProjectFileName) 같습니다.

$(InputExt)

입력 파일의 파일 확장명입니다. 파일 확장명 앞에는 '.' 붙습니다. 해당 프로젝트가 입력 파일인 경우 매크로는 $(ProjectExt) 같습니다.

$(ProjectDir)

드라이브 + 경로로 정의되는 프로젝트의 디렉터리로서 뒤에는 백슬래시(\) 붙습니다.

$(ProjectPath)

드라이브 + 경로 + 기본 이름 + 파일 확장명으로 정의되는 프로젝트의 절대 경로 이름입니다.

$(ProjectName)

프로젝트의 기본 이름입니다.

$(ProjectFileName)

기본 이름 + 파일 확장명으로 정의되는 프로젝트의 파일 이름입니다.

$(ProjectExt)

프로젝트의 파일 확장명입니다. 파일 확장명 앞에는 '.' 붙습니다.

$(SolutionDir)

드라이브 + 경로로 정의되는 솔루션의 디렉터리로서 뒤에는 백슬래시(\) 붙습니다.

$(SolutionPath)

드라이브 + 경로 + 기본 이름 + 파일 확장명으로 정의되는 솔루션의 절대 경로 이름입니다.

$(SolutionName)

솔루션의 기본 이름입니다.

$(SolutionFileName)

기본 이름 + 파일 확장명으로 정의되는 솔루션의 파일 이름입니다.

$(SolutionExt)

솔루션의 파일 확장명입니다. 파일 확장명 앞에는 '.' 붙습니다.

$(TargetDir)

드라이브 + 경로로 정의되는 빌드용 기본 출력 파일의 디렉터리로서 뒤에는 백슬래시(\) 붙습니다.

$(TargetPath)

드라이브 + 경로 + 기본 이름 + 파일 확장명으로 정의되는 빌드용 기본 출력 파일의 절대 경로 이름입니다.

$(TargetName)

빌드용 기본 출력 파일의 기본 이름입니다.

$(TargetFileName)

기본 이름 + 파일 확장명으로 정의되는 빌드용 기본 출력 파일의 파일 이름입니다.

$(TargetExt)

빌드용 기본 출력 파일의 파일 확장명입니다. 파일 확장명 앞에는 '.' 붙습니다.

$(VSInstallDir)

Visual Studio .NET 설치한 디렉터리입니다.

$(VCInstallDir)

Visual C++ .NET 설치한 디렉터리입니다.

$(FrameworkDir)

.NET Framework 설치한 디렉터리입니다.

$(FrameworkVersion)

Visual Studio에서 사용되는 .NET Framework 버전입니다. $(FrameworkDir) 함께 사용하면 Visual Studio에서 사용되는 .NET Framework 버전의 전체 경로를 나타냅니다.

$(FrameworkSDKDir)

.NET Framework SDK 설치한 디렉터리입니다. .NET Framework SDK Visual Studio .NET 함께 또는 별도로 설치될 있습니다.

$(WebDeployPath)

배포 루트에서 프로젝트 출력이 속한 상대 경로. RelativePath 반환하는 값과 같은 값을 반환합니다.

$(WebDeployRoot)

<localhost> 절대 경로(: c:\inetpub\wwwroot)

$(SafeParentName)

올바른 이름 형식에서 바로 상위 항목의 이름. 예를 들어, 폼은 .resx 파일의 상위 항목입니다.

$(SafeInputName)

올바른 클래스 이름으로 정의되는 파일 이름(확장명은 제외)

1. 속성 상속 방법을 확인하려면 속성에 대해 명령줄 속성 페이지 사용합니다. 속성 상속에 대한 자세한 내용은 속성 페이지를 사용하여 프로젝트 설정 지정 참조하십시오. 사용 예제는 $(Inherit) $(NoInherit) 사용 참조하십시오.

 

2008. 8. 19. 21:02

[Visual Studo .NET 2003 C++] Doxygen 스타일의 주석을 생성하는 Macro 코드

클래스 및 함수등을 선택한 후 아래 매크로를 수행하면

주석을 달기 위한 입력 대화상자가 뜨며 그 대화상자에다가 정보를 입력하면 Doxygen과 호환되는 주석을 생성한다.

사용법 :

1. 아래 그림과 같이 주석을 할 함수나 클래스를 선택한다.

사용자 삽입 이미지

2. 매크로 탐색기에서 해당 매크로, 만약 아래의 코드를 그대로 사용하였다면 MakeCommentForDoxygen을 실행한다. 아래 작성된 코드를 매크로 탐색기에다가 붙여 넣으면 된다.

사용자 삽입 이미지


3. 그러면 아래와 같이 클래스나 함수에 대한 간단한 개요와 파라미터와 반환형에 대한 개요을 적을 수 있는 입력상자를 띄운다. 그 입력상자에 원하는 정보를 넣어준다.

 > 함수의 간단한 개요 (Brief)
사용자 삽입 이미지

 > 파라미터 i의 개요
사용자 삽입 이미지

 > 파라미터 c의 개요
사용자 삽입 이미지

 > 반환형의 개요
사용자 삽입 이미지

4. 위와 같이 입력하면, 아래와 같은 주석을 생성한다.

사용자 삽입 이미지


5. 이렇게 입력한 주석들을 이용하여 Doxgen 을 가지고 문서를 생성하면 각각의 함수나 코멘트에 대한 설명을 볼 수 있다. (Doxygen은 Java의 API Document와 같은 문서를 생성하게 해준다. 자세한 정보는 Doxygen 사이트 참고. 무료 툴이다.)

<매크로 코드>

Imports EnvDTE
Imports System.Diagnostics
Imports System
Imports Microsoft.VisualBasic.ControlChars
Public Module Module1
    Function InsertNewLine(ByRef doc As Document, ByVal Str As String)
        doc.Selection.NewLine()
        doc.Selection.StartOfLine()
        doc.Selection.Text = Str
    End Function

    Function GetParam(ByVal str As String) As String
        Dim iIndexFound As Integer
        Dim strTemp As String
        strTemp = Trim(str)
        iIndexFound = InStr(str, " ", CompareMethod.Text)
        If iIndexFound > 0 Then
            GetParam = Trim(Right(strTemp, Len(strTemp) - iIndexFound))
        Else
            GetParam = strTemp
        End If
    End Function
    Function RemoveComment(ByVal str As String) As String
        Dim iCommentPrefixFound As Integer
        Dim iCommentPostfixFound As Integer
        Dim strTemp As String
        RemoveComment = str
        iCommentPrefixFound = InStr(RemoveComment, "/*", CompareMethod.Text)
        While iCommentPrefixFound > 0
            strTemp = Right(RemoveComment, Len(RemoveComment) - iCommentPrefixFound + 1)
            iCommentPostfixFound = InStr(strTemp, "*/", CompareMethod.Text)
            If iCommentPostfixFound > 0 Then
                RemoveComment = Left(RemoveComment, iCommentPrefixFound - 1)
                strTemp = Right(strTemp, Len(strTemp) - iCommentPostfixFound - 1)
                RemoveComment = RemoveComment & strTemp
            Else
                RemoveComment = Left(RemoveComment, iCommentPrefixFound - 1)
                Exit While
            End If
            iCommentPrefixFound = InStr(RemoveComment, "/*", CompareMethod.Text)
        End While
    End Function
    Sub MakeCommentForDoxygen()
        Dim strDelimFormat As String = "//////////////////////////////////////////////////////////////////////////"
        Dim strBriefFormat As String = "/// @brief" & Tab & Tab
        Dim strAuthorFormat As String = "/// @author" & Tab & Tab
        Dim strVersionFormat As String = "/// @version" & Tab & "v1.0"
        Dim strDateFormat As String = "/// @date" & Tab & Tab
        Dim strRemarkFormat As String = "/// @remark" & Tab & Tab
        Dim strReturnFormat As String = "/// @return" & Tab & Tab
        Dim strParamFormat As String = "/// @param" & Tab
        Dim FuncAll As String = DTE.ActiveDocument.Selection.Text
        Dim iIndexFound As Integer
        Dim strTemp As String
        Dim strInput As String
        Dim strClass As String = "Class"
        Dim currentDate As Date
        Dim strBriefDesc As String
        FuncAll = RemoveComment(FuncAll)    ' /* */ 로 끝나는 주석을 제거함.
        ' 선택된 텍스트를 가져옴
        FuncAll = FuncAll.Replace(CStr(Tab), " ")
        FuncAll = Trim(FuncAll.Replace(CStr(CrLf), ""))
        Dim curDocument As Document
        curDocument = ActiveDocument   ' 현재 다큐먼트를 저장

        ' 클래스인지 함수 인지 검사
        iIndexFound = InStr(UCase(FuncAll), UCase(strClass), CompareMethod.Text)
        Dim iTemp As Integer
        iTemp = iIndexFound - 1
        If iTemp > 0 Then
            strTemp = Mid(FuncAll, iIndexFound - 1, 1)  ' class 키워드 앞에 다른 문자가 붙으면 클래스가 아님.
            If strTemp <> " " Then
                iIndexFound = 0
            End If
        End If
        If iIndexFound > 0 Then ' 클래스이다
            strTemp = Right(FuncAll, FuncAll.Length - iIndexFound - Len(strClass) + 1)
            iIndexFound = InStr(strTemp, ":", CompareMethod.Text)
            If (iIndexFound > 0) Then
                strTemp = Left(strTemp, iIndexFound - 1)
                strTemp = Trim(strTemp)
            End If
            If strTemp.Length <> 0 Then
                ' 클래스 주석을 추가하자
                ' 입력을 먼저 받고 입력이 있을 경우에만 아래를 추가하자
                ' Brief
                strInput = InputBox("Insert a brief into " & strTemp)        ' 현재 strTemp는 클래스 명이다
                strTemp = Trim(strInput)
                If strTemp.Length = 0 Then
                    Exit Sub
                End If
                ' Delimitor
                curDocument.Selection.GotoLine(curDocument.Selection.TopLine)
                curDocument.Selection.StartOfLine(EnvDTE.vsStartOfLineOptions.vsStartOfLineOptionsFirstText)
                InsertNewLine(curDocument, strDelimFormat)
                ' brief 추가
                strBriefDesc = strBriefFormat & strInput
                InsertNewLine(curDocument, strBriefDesc)
                ' version
                InsertNewLine(curDocument, strVersionFormat)
                ' Date
                currentDate = Date.Now
                strTemp = strDateFormat & Trim(Str(currentDate.Year())) & "/" & Trim(Str(currentDate.Month())) & "/" & Trim(Str(currentDate.Day()))
                InsertNewLine(curDocument, strTemp)
                ' Author
                strTemp = System.Security.Principal.WindowsIdentity.GetCurrent().Name()
                iIndexFound = InStr(strTemp, "\", CompareMethod.Text)
                If iIndexFound > 0 Then
                    strTemp = Right(strTemp, Len(strTemp) - iIndexFound)
                End If
                strTemp = strAuthorFormat & strTemp
                InsertNewLine(curDocument, strTemp)
                ' Delimitor
                InsertNewLine(curDocument, strDelimFormat)
                curDocument.Selection.NewLine()
            End If
        Else    ' 함수인지 검사
            iIndexFound = InStr(FuncAll, "(", CompareMethod.Text)
            If iIndexFound > 0 Then
                Dim strFunc As String
                Dim strReturn As String
                Dim strParams As String
                Dim strReturnDesc As String
                strFunc = Left(FuncAll, iIndexFound - 1)    ' 괄호앞 전체
                strTemp = Right(FuncAll, Len(FuncAll) - iIndexFound)   ' 괄호 이후 뒤쪽
                ' strFunc에서 반환값 추출
                iIndexFound = InStrRev(strFunc, " ", -1, CompareMethod.Text)
                If iIndexFound > 0 Then
                    strReturn = Trim(Left(strFunc, iIndexFound))
                Else
                    strReturn = ""
                End If
                iIndexFound = InStr(strTemp, ")", CompareMethod.Text)
                If iIndexFound > 0 Then
                    strParams = Trim(Left(strTemp, iIndexFound - 1))
                    Dim strParamList As String()
                    Dim strParamDesc As String()
                    Dim iParamCount As Integer = 0
                    Dim iCount As Integer
                    ' 파라미터 갯수 파악하기
                    If Len(strParams) <> 0 Then
                        strTemp = strParams
                        iIndexFound = InStr(strTemp, ",", CompareMethod.Text)
                        If iIndexFound > 0 Then
                            ' 파라미터가 1개 이상이다
                            ' 콤마 갯수를 센 후에 어레이를 잡고 파라미터를 대입하자 (무식하지만 귀찮다)
                            Dim iCommaCount As Integer = 0
                            While iIndexFound > 0
                                iCommaCount = iCommaCount + 1
                                strTemp = Right(strTemp, Len(strTemp) - iIndexFound)
                                iIndexFound = InStr(strTemp, ",", CompareMethod.Text)
                            End While
                            iParamCount = iCommaCount + 1
                            ReDim strParamList(iParamCount)
                            strTemp = strParams
                            iIndexFound = InStr(strTemp, ",", CompareMethod.Text)
                            iCount = 1
                            While iIndexFound > 0
                                strParamList(iCount) = Trim(Left(strTemp, iIndexFound - 1))
                                strTemp = Right(strTemp, Len(strTemp) - iIndexFound)
                                iIndexFound = InStr(strTemp, ",", CompareMethod.Text)
                                iCount = iCount + 1
                            End While
                            strParamList(iCount) = Trim(strTemp)
                        Else
                            iParamCount = 1
                            ReDim strParamList(iParamCount)
                            strParamList(iParamCount) = strTemp
                        End If
                    End If
                    ' Brief 얻기
                    strBriefDesc = InputBox("Insert a brief into " & strFunc)
                    If Len(strBriefDesc) = 0 Then
                        Exit Sub
                    End If
                    ReDim strParamDesc(iParamCount)
                    ' 파라미터에 대한 brief 얻기
                    For iCount = 1 To iParamCount
                        If iParamCount <> 1 Or UCase(strParamList(1)) <> "VOID" Then
                            strParamDesc(iCount) = InputBox("Insert a brief into " & strParamList(iCount))
                        End If
                    Next iCount
                    ' Return에 대한 brief 얻기
                    If Len(strReturn) <> 0 And UCase(strReturn) <> "VOID" Then
                        strReturnDesc = InputBox("Inser a brief into the return value")
                    End If
                    ' Delimitor
                    curDocument.Activate()
                    curDocument.Selection.GotoLine(curDocument.Selection.TopLine)
                    curDocument.Selection.StartOfLine(EnvDTE.vsStartOfLineOptions.vsStartOfLineOptionsFirstText)
                    InsertNewLine(curDocument, strDelimFormat)
                    ' brief 추가
                    strBriefDesc = strBriefFormat & strBriefDesc
                    InsertNewLine(curDocument, strBriefDesc)
                    ' 파라미터에 대한 정보 추가
                    For iCount = 1 To iParamCount
                        If iParamCount <> 1 Or UCase(strParamList(1)) <> "VOID" Then
                            strTemp = GetParam(strParamList(iCount))
                            strTemp = strParamFormat & strTemp & Tab & strParamDesc(iCount)
                            InsertNewLine(curDocument, strTemp)
                        End If
                    Next
                    If Len(strReturn) <> 0 And UCase(strReturn) <> "VOID" Then
                        ' Return 추가
                        strReturnDesc = strReturnFormat & strReturnDesc
                        InsertNewLine(curDocument, strReturnDesc)
                    End If
                    InsertNewLine(curDocument, strRemarkFormat)
                    ' Delimitor
                    InsertNewLine(curDocument, strDelimFormat)
                    curDocument.Selection.NewLine()
                    curDocument.Selection.StartOfLine()
                End If
            End If
        End If
        curDocument.Save()
        'Temp = FuncAll.IndexOf("(")
        'If Temp < 0 Then Exit Sub
    End Sub
End Module