login register Sysop! about ME  
qrcode
    최초 작성일 :    2006년 08월 12일
  최종 수정일 :    2006년 09월 07일
  작성자 :    강승호 ()
  편집자 :    강 승호
  읽음수 :    18,865

강좌 목록으로 돌아가기

필자의 잡담~

이 강좌는 VS.NET 2003 Add-in에 관한 내용입니다.
이는 VS 2005와 VS 2008에도 비슷하게 적용이 되므로, 애드인 제작에 관심이 있으신 분들이라면
한번 알아두면 매우 유용합니다(멘트를 2008년에 수정한 것이라 ^^).

추가기능(Add-in) 활용

Visual Studio .Net 2003 Add-In 강좌 1을 읽었다는 가정하에 진행하도록 하겠습니다.
이번 강좌에서는 추가기능을 활용해서 VS .NET에 새로운 기능을 추가해 보도록 하겠습니다.
이름하여 Clipboard Manager입니다.

실무에서 일을 하다 보면 복사 & 붙여넣기를 많이 사용하게 됩니다. 수 없이 복사 & 붙여넣기를 하다보면 좀 전에 복사했었던 내용을 다시 찾아서 복사해야 하는 경우가 종종 있는데요. 참 귀찮은 일이죠. 그래서 Clipboard Manager라는 놈을 통해서 그 동안 복사했던 내용을 관리하는 기능을 VS .NET에 추가해 보도록 하겠습니다. MS OFFICE에도 있는 뭐 그런 기능입니다.

Clipboard Manager의 기능을 정의해 보면 다음과 같습니다.

    1. 개발자가 Ctrl + C 명령을 실행했을 때 복사한 내용을 저장합니다.
    2. 별도의 UI를 통해 저장한 목록을 보여주고 개발자가 선택해서 원하는 곳에 붙여넣기를 할 수 있습니다.

Clipboard Manager가 실행된 모습입니다.

간단하죠? 구현도 그리 어렵지 않으니 금방 따라 할 수 있을겁니다.

자! 시작하겠습니다.

1. 파일 > 새로만들기 > 프로젝트 > 기타 프로젝트 > 확장성 프로젝트 > Visual Studio.NET 추가 기능 선택
    이름, 위치를 입력 또는 선택하고 "확인" 클릭.

2. 마법사가 나타납니다.
    프로그래밍 언어 선택, 응용프로그램 호스트 선택 을 적적하게 선택하고 "다음" 클릭

3. 이름 및 설명 입력

4. 추가 기능 옵션 선택

제일 중요한 부분입니다. 위 두 가지 옵션을 선택한 이유는 다음과 같습니다.

- 우리는 추가기능의 UI를 만들어서 사용자가 복사한 목록 중에서 원하는 항목을 선택하고 "붙여넣기"를
   클릭하도록 할 것입니다.
- 추가기능 UI 가 실행되지 않았을 때도 우리는 Clipboard Manager에 복사한 내용을 추가해야 합니다.
   그러기 위해서는 VS .NET가 실행될 때 Clipboard Manager도 로드돼야 합니다.

5. 나머지 화면은 적절하게 선택하고 "다음" 또는 "마침"을 클릭합니다.

6. 마법사에 의해 생성된 프로젝트입니다.

마법사가 생성한 소스에 Clipboard Manager를 구현하기 위한 코드를 추가해 보겠습니다.

기능을 구현하기에 앞서 알려드리자면 추가기능의 명칭이 Clipboard Manager 이지만 사실 Clipboard를 관리하거나 참조하지 않습니다. 제가 확인한 바로는 .Net Framework에서 제공하는 Clipboard 클래스는 마지막에 복사된 항목만 가지고 있더군요. 따라서 우리가 구현하려고 하는 기능과 거리가 멀기 때문에 이 클래스를 사용하지 않습니다.

이제 Clipboard Manager를 구현해 보도록 하겠습니다. 복사 명령이 실행되면 복사된 내용을 저장해야 하는데 어떻게 구현해야 할까요? 복사 명령이 실행되는 것을 어떻게 알 수 있을까요? 다행히 VS .NET 에서 자동화 클라이언트에 대해 여러 가지 이벤트를 제공하고 있습니다. 그 중에 CommandEvents를 사용하면 VS .NET에서 일어나는 명령 이벤트를 처리할 수 있습니다. 설명은 코드로 대신하겠습니다.

//멤버 변수 선언부에 CommandEvents 변수 선언
private CommandEvents copyEvents;

//OnConnection 메서드에 코드를 추가합니다.
public void OnConnection(object application, Extensibility.ext_ConnectMode connectMode, object addInInst, ref System.Array custom)
{
    applicationObject = (_DTE)application;
    addInInstance = (AddIn)addInInst;

    //Copy 명령: Guid: {5EFC7975-14BC-11CF-9B2B-00AA00573819}, ID: 15
    //Events.get_CommandEvents(Guid, ID)를 사용해서 복사 명령에 대해서만
    //CommandEvents 개체에 할당하였습니다.
    this.copyEvents = (EnvDTE.CommandEvents)applicationObject.Events.get_CommandEvents("{5EFC7975-14BC-11CF-9B2B-00AA00573819}", 15);
    //CommandEvents 의 AfterExecute 이벤트에 이벤트를 처리할 메서드를 등록합니다.
    //AfterExecute : 명령을 실행한 다음에 발생합니다.
    this.copyEvents.AfterExecute += new _dispCommandEvents_AfterExecuteEventHandler( copyEvents_AfterExecute );

    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, "ClipboardManager", "ClipboardManager", "Executes the command for ClipboardManager", true, 59, ref contextGUIDS, (int)vsCommandStatus.vsCommandStatusSupported+(int)vsCommandStatus.vsCommandStatusEnabled);
            CommandBar commandBar = (CommandBar)commandBars["Tools"];
            CommandBarControl commandBarControl = command.AddControl(commandBar, 1);
        }
        catch(System.Exception /*e*/)
        {}
    }
}

이벤트를 처리할 메서드를 추가합니다. 내용은 진행하면서 채워나가도록 하겠습니다.

private void copyEvents_AfterExecute(string Guid, int ID, object CustomIn, object CustomOut)
{
}

추가한 코드 중에 "복사" 명령 또는 다른 명령의 Guid, ID 를 어떻게 알아내는지 궁금하실 거라 생각됩니다. 하지만 여기에서 설명하지는 않겠습니다. 위 코드와 유사한 면도 있고 그리 어렵지 않으니 첨부한 소스로 대신하려 합니다.(Clipboard Manager 소스에 첨부)

지금까지 진행해온 내용이 Clipboard Manager에서 가장 중요한 부분이라고 할 수 있습니다.

다음으로 넘어가서 UI를 만들어 보도록 하겠습니다.

속성 및 이벤트를 다음처럼 정의 합니다.

1. ListBox
lstClipboardList.Name = "lstClipboardList";
lstClipboardList.SelectedIndexChanged += new System.EventHandler(this.lstClipboardList_SelectedIndexChanged);

2. TextBox
txtDetail.Multiline = true;
txtDetail.Name = "txtDetail";
txtDetail.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
txtDetail.Text = "";

3. Button
btnPaste.Name = "btnPaste";
btnPaste.Text = "붙여넣기";
btnPaste.Click += new System.EventHandler(this.btnPaste_Click);

4. Button
btnClose.Name = "btnClose";
btnClose.Text = "닫기";
btnClose.Click += new System.EventHandler(this.btnClose_Click);

5. Form
ControlBox = false;
Name = "ClipboardList";
ShowInTaskbar = false;
Text = "Clipboard List";
TopMost = true;

자~ UI 디자인이 끝났으면 코드를 추가해 볼까요.

//using 지시문 추가
using EnvDTE;

//멤버 변수 추가
private _DTE applicationObject;

//생성자 추가
public ClipboardList(EnvDTE._DTE applicationObject) : this()
{
    //활성화된 문서의 선택된 부분을 가져오기 위해서 DTE 개체 할당
    this.applicationObject = applicationObject;
}

//Clipboard List에 복사한 내용을 추가하는 public 메서드 추가
public void AddClipboard(string strText)
{
    //Connect.copyEvents_AfterExecute 에서 호출
    //클립보드 목록에 복사한 텍스트를 추가함

    lstClipboardList.Items.Insert(0, strText);
}

//Clipboard List SlectedIndexChanded 이벤트 처리 메서드 추가
private void lstClipboardList_SelectedIndexChanged(object sender, System.EventArgs e)
{
    txtDetail.Text = lstClipboardList.Items[lstClipboardList.SelectedIndex].ToString();
}

//붙여넣기 Click 이벤트 처리 메서드 추가
private void btnPaste_Click(object sender, System.EventArgs e)
{
    try
    {
        //현재 활성화된 문서의 선택된 부분을 가져옴.
        TextSelection sel = (TextSelection)applicationObject.ActiveDocument.Selection;
        //지정된 문자열을 현재 삽입 포인트에 삽입
        sel.Insert(txtDetail.Text, 2);//vsInsertFlags.vsInsertFlagsCollapseToStart
    }
    catch(Exception ex)
    {
        MessageBox.Show(ex.ToString());
    }
}

//닫기 Click 이벤트 처리 메서드 추가
private void btnClose_Click(object sender, System.EventArgs e)
{
this.Hide();
}

여기까지 UI 에 대한 코드는 완성됐습니다.
이제 Connect.cs 에서 UI를 적절하게 호출하는 코드를 추가하면 됩니다.

//멤버 변수 추가
ClipboardList oClipboardList = null;

//도구 메뉴에서 Clipboard Manager 메뉴를 클릭했을 때 실행할 코드
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 == "ClipboardManager.Connect.ClipboardManager")
        {
            if(oClipboardList == null)
                oClipboardList = new ClipboardList(applicationObject);
            oClipboardList.Show();

            handled = true;
            return;
        }
    }
}

//"복사" 명령이 실행된 후에 처리할 코드
private void copyEvents_AfterExecute(string Guid, int ID, object CustomIn, object CustomOut)
{
    string strText = "";
    if(oClipboardList == null)
        oClipboardList = new ClipboardList(applicationObject);

    strText = ((TextSelection)applicationObject.ActiveDocument.Selection).Text;
    if(strText.Length > 0)
        oClipboardList.AddClipboard(strText);
}

드디어 Clipboard Manager 구현을 마쳤네요. 이제 실행을 시켜봐야 겠죠?

설치프로젝트를 빌드합니다.

이제 여러분의 추가기능 설치프로젝트의 출력경로(추가기능프로젝트명\설치프로젝트명\debug)로 가서 Setup.exe를 실행해서 추가기능을 설치합니다. (VS .NET은 모두 닫고 설치하세요.) VS .NET를 열고 도구 메뉴를 확인해 보면 메뉴가 추가돼있는 것을 볼 수 있습니다.

우리가 구현하려고 했던 기능들이 잘 동작하는지 테스트를 해보시기 바랍니다. 부족한게 많지만 그런대로 쓸만한 추가기능(add-in)이 만들어졌다고 생각되는데 여러분은 어떤지 모르겠네요. 부족한 부분을 채워나가는 것은 여러분의 몫으로 남기면서 강좌를 마칠까 합니다. 더운 여름 건강 조심하세요.

p.s
추가기능 제거는 "프로그램 추가/제거"에서 하면 됩니다.(VS .NET 닫아야 함.)

MSDN(추가기능 관련 url)

Visual Studio 환경 확장
자동화 및 확장성 참조


DOWNLOAD : 강좌에서 사용된 소스를 다운로드 받으시려면 클릭하세요


authored by


 
 
.NET과 Java 동영상 기반의 교육사이트

로딩 중입니다...

서버 프레임워크 지원 : NeoDEEX
based on ASP.NET 3.5
Creative Commons License
{5}
{2} 읽음   :{3} ({4})