본문 바로가기
프로그래밍/설계공부

제 9 장. Add-In COM Object 사용하기

by 건우아빠유리남편 2009. 7. 23.
반응형

제 9 장. Add-In COM Object 사용하기

Add-In COM Object의 기본 개념

StarUML™에 새로운 기능을 추가하고자 할 때 이전 'Chapter 3. Hello world Example'에서 보았듯이 간단한 Script 코드를 정의할 수도 있지만, 좀 더 복잡하거나 유용한 기능을 제공하기 위해서는 COM 개체를 지원하는 프로그램 개발 환경을 사용하는 것이 나을 것이다. StarUML™ Add-In COM Object를 구현할 때 Visual C++, Delphi, C#, Visual Basic 등과 같이 COM 기술을 지원하는 어떤 프로그램 환경을 선택하던지 상관이 없다.

StarUML™ Add-In COM Object를 구현할 때 지켜야 하는 가장 중요한 점은 StarUML™이 정의하고 있는 IStarUMLAddIn 인터페이스를 구현해야 한다는 것이다.
IStarUMLAddIn 인터페이스는 위의 그림과 같이 IUnknown을 상속하며 InitializeAddIn(), FinalizeAddIn(), DoMenuAction() 세 개의 추가적인 인터페이스 메소드를 정의하고 있다.

IStarUMLAddIn 인터페이스 메소드

IStarUMLAddIn 인터페이스를 구현할 때 정의해야 하는 메소드는 다음과 같다.

메소드 설명
InitializeAddIn() InitializeAddIn() 메소드는 StarUMLApplication 개체가 각 Add-In COM Object를 생성한 후에 호출하는 초기화 메소드이다. 이것은 StarUML™의 이벤트 수신 등록과 같이 Add-In COM Object의 초기화에 필요한 동작을 정의할 때 사용한다.
FinalizeAddIn() FinalizeAddIn() 메소드는 StarUMLApplication 개체가 Add-In COM Object에 대한 참조를 끊기 바로 전에 호출하는 메소드이다. 이것은 StarUML™의 이벤트 수신 해제와 같이 Add-In COM Object의 소멸 전에 필요한 동작을 정의할 때 사용한다.
DoMenuAction(ActionID: Integer) DoMenuAction() 메소드는 8장 'Extending Menu'에서 보았듯이 각 Add-In이 정의한 확장 메뉴 항목이 사용자에 의해 선택되었을 때 호출되며, 메뉴 확장 파일에서 정의한 각 메뉴 항목의 'actionId' 값이 인자로 전달된다.

Add-In COM Object 예제

다음은 IStarUMLAddIn 인터페이스를 구현하는 StarUML™ Add-In COM Object의 간단한 예를 보이고 있다. 이것은 델파이 파스칼 문법으로 정의된 것이다.

type
    AddInExample = class(TComObject, IStarUMLAddIn)
    private
        StarUMLApp: IStarUMLApplication;
    protected
        function InitializeAddIn: HResult; stdcall;
        function FinalizeAddIn: HResult; stdcall;
        function DoMenuAction(ActionID: Integer): HResult; stdcall;
        ...
    public
        procedure Initialize; override;
        destructor Destroy; override;
        ...
    end;

...

implementation

procedure AddInExample.Initialize;
begin
    inherited;
    StarUMLApp := CreateOleObject('StarUML.StarUMLApplication') as IStarUMLApplication;
    ...
end;

destructor AddInExample.Destroy;
begin
    ...
    StarUMLApp := nil;
    inherited;
end;

function AddInExample.InitializeAddIn: HResult;
begin
    ...
    Result := S_OK;
end;

function AddInExample.FinalizeAddIn: HResult;
begin
    ...
    Result := S_OK;
end;

function AddInExample.DoMenuAction(ActionID: Integer): HResult; stdcall;
begin
    Result := S_OK;
    ...
end;

Add-In 설명 파일 작성하기

Add-In 설명 파일의 기본 개념

Add-In Description 파일(*.aid)은 XML 형식의 텍스트 파일로, StarUML에 플러그인(plug-in)되는 각 Add-In은 반드시 하나의 Add-In 파일을 제공해야 한다. StarUML은 Add-In Description 파일이 정의하는 내용을 바탕으로 Add-In을 레지스터리에 등록하고 초기화하며, Add-In과 연결된 메뉴 확장 파일을 초기화한다.

노트: Add-In Description 파일은 반드시 *.aid 확장자를 가져야 하며, StarUML™ 모듈 디렉토리(<install-dir>\modules) 하부 디렉토리에 존재해야 한다.

Add-In Description 파일의 전체 구조

Add-In Description 파일은 XML 문서의 규칙을 따르며, 사용자 정의 항목들은 'ADDIN' 요소 내에 기술된다.

<?xml version="1.0" encoding="..."?>

<ADDIN>
    <NAME>...</NAME>
    <DISPLAYNAME>...</DISPLAYNAME>
    <COMOBJ>...</COMOBJ>
    <FILENAME>...</FILENAME>
    <COMPANY>...</COMPANY>
    <COPYRIGHT>...</COPYRIGHT>
    <HELPFILE>...</HELPFILE>
    <ICONFILE>...</ICONFILE>
    <ISACTIVE>...</ISACTIVE>
    <MENUFILE>...</MENUFILE>
    <VERSION>...</VERSION>
    <MODULES>
        <MODULEFILENAME>...</MODULEFILENAME>
    </MODULES>
</ADDIN>
  • encoding 속성: XML 문서의 인코딩 속성 값을 지정한다 (e.g. UTF-8, EUC-KR). 이 속성의 값에 대해서는 XML 관련 자료를 참조하기 바란다.
  • NAME 요소: Add-In의 이름을 기술한다. (문자열 값)
  • DISPLAYNAME 요소 : StarUML UI상에서 보여질 Add-In의 이름 (문자열 값)
  • COMOBJ 요소: Add-In의 형태가 COM Add-In인 경우에만 사용되며, COM의 ProgID를 기술한다. (문자열 값)
  • FILENAME 요소 : Add-In 파일명을 기술한다. (문자열 값)
  • COMPANY 요소: Add-In을 개발한 회사/개인의 정보를 기술한다. (문자열 값)
  • COPYRIGHT 요소: 저작권에 대한 공지를 기술한다. (문자열 값)
  • HELPFILE 요소: Add-In의 Help가 기술되어진 URL 경로를 기술한다. (문자열 값)
  • ICONFILE 요소: StarUML 화면상에서 Add-In과 연결될 아이콘 파일명을 기술한다. (문자열 값)
  • ISACTIVE 요소: 이 요소의 값이 true이면 StarUML은 자동으로 Add-In을 로딩하고, false이면 로딩하지 않는다. (불린 값)
  • MENUFILE 요소: Add-In과 연결된 메뉴 확장 파일명을 기술한다. (문자열 값)
  • VERSION 요소: Add-In의 버전 정보를 기술한다. (문자열 값)
  • MODULES/MODULEFILENAME 요소: 하나의 Add-In이 여러개의 또 다른 COM을 사용할 경우에 Add-In이 최초로 실행 되기 전에 관련된 COM이 등록될수 있도록 사용하는 COM의 파일명을 MODULE 요소에 기술한다. (문자열 값)

Add-In 설명 파일 등록하기

작성된 Add-In Description 파일을 StarUML에서 자동으로 인식하려면 Add-In Description 파일이 StarUML™ 모듈 디렉토리(<install-dir>\modules) 하부 디렉토리로 옮겨야 한다. StarUML™은 프로그램 초기화 시에 모듈 디렉토리 하부를 검색하여 모든 Add-In Description 파일들을 읽어 들인 후 프로그램에 자동 등록한다. 만약 Add-In Description 파일이 문법에 맞지 않게 잘 못 작성되어 있거나, 확장자가 .aid가 아닌 경우에는 Add-In Description 파일을 정상적으로 읽어 들이지 않고 무시하게 될 것이다.
Add-In Description 파일은 가급적이면 모듈 디렉토리 하부에 새로운 디렉토리를 만들고 거기에 저장하기를 권장한다.

노트: Add-In Description 파일을 더 이상 사용하지 않으려면 StarUML™ 모듈 디렉토리(<install-dir>\modules) 하부에서 삭제하면 된다.

옵션 확장

옵션 확장의 기본 개념

StarUML에서는 사용자들이 StarUML의 환경과 세부적인 기능을 조절할 수 있도록 옵션 편집을 지원한다. 이런 옵션들은 StarUML 애플리케이션 자체 뿐만 아니라 써드파티 벤더들에 의해 제공되는 Add-in들에게도 필요하다. StarUML의 옵션 확장은 Add-in들에게 별도의 구현 과정 없이 옵션 설정 기능을 가능하게 해준다. 이를 위해서 Add-in 개발자는 텍스트 파일로 간단하게 옵션에 대한 정의만 기술하고 이 옵션 정의 파일을 레지스트리에 등록해 주기만 하면 된다. 등록된 옵션 정의는 프로그램 초기화 시에 로드 되며 사용자가 옵션 다이얼로그를 띄웠을 때 트리뷰와 인스펙터에 표시된다. 옵션 확장 기능을 통해서 개발자들은 Add-in 구현을 위한 시간과 노력을 절감할 수 있고, 사용자들에게 옵션 설정을 위한 일관된 유저 인터페이스를 제공할 수 있다.

Add-in에서 옵션 설정을 지원하기 위해서는 다음과 같은 절차가 필요하다.

  1. Add-in에 적용할 옵션 항목을 정의하기 위해 옵션 스키마 문서(.opt)를 작성한다.
  2. 옵션 스키마 파일를 Add-in이 설치된 디렉토리에 복사한다.

옵션의 계층 구조

StarUML은 애플리케이션과 각 Add-in에서 작성된 많은 옵션 항목들을 통합적으로 관리하기 위하여 다음과 같이 계층적으로 구성하였다.

  • Option Schema : Option Schema는 Option 구성의 최상위의 분류로 옵션 스키마 파일의 단위가 되고, 옵션 다이얼로그의 왼쪽 트리뷰에서 최상위 계층에 폴더 모양의 아이콘으로 나타난다. Option Schema는 StarUML 애플리케이션과 각 Add-in에 대응되는 옵션 구조의 가장 큰 단위이다.
  • Option Category : Option Category는 Option Schema를 기능별로 크게 분류한 것으로 옵션 다이얼로그의 왼쪽 트리뷰에서 하위 계층으로 표시된다.  Option Category는 옵션 다이얼로그에서 오른쪽의 옵션 인스펙터의 표시 단위가 된다.
  • Option Classification : Option Classification은 Option Category를 다시 세부적으로 구분한 것으로 옵션 다이얼로그의 옵션 인스펙터에서 분류 행에 해당된다. Option Classification은 실제 옵션 값을 편집할 수 있는 여러 개의 Option Item을 가진다.
  • Option Item : Option Item은 실제 옵션 값을 편집하는 단위이며, 옵션 다이얼로그의 옵션 인스펙터에서 하나의 행에 해당된다.

옵션 스키마 작성하기

옵션 스키마의 구조와 옵션 항목을 정의하기 위한  옵션 스키마 파일은 확장자가 .opt 인 XML 포맷의 텍스트 파일이다. 옵션 스키마에 대한 내용은 OPTIONSCHEMA 요소 내에 기술되며, 구문이나 내용에 오류가 없도록 해야 한다.

<?xml version=”1.0” encoding=”...” ?>
<OPTIONSCHEMA id="..."> 
    <HEADER>
    ...
    </HEADER>
    <BODY>
    ...
    </BODY>
</OPTIONSCHEMA>
  • encoding 속성 : XML 문서의 인코딩 속성 값을 지정한다 (e.g. UTF-8, EUC-KR). 이 속성의 값에 대해서는 XML 관련 자료를 참조하기 바란다.
  • id  속성 (OPTIONSCHEMA 요소) : 각 옵션스키마의 고유한 명칭을 기술한다. 이것은 다른 옵션 스키마과 구분될 수 있는 유일한 것이어야 한다.
  • HEADER 요소 : Header Contents 섹션 참조
  • BODY 요소 : Body Contents 섹션 참조

Header Contents

HEADER 부분에는 옵션 스키마의 제목과 상세설명 등 옵션 스키마에 대한 개괄적인 정보를 기술한다. HEADER 부분의 형식은 다음과 같다.

<HEADER>
    <CAPTION>...</CAPTION> 
    <DESCRIPTION>...</DESCRIPTION> 
</HEADER>
  • CAPTION 요소 : 옵션 스키마의 타이틀이고 옵션 다이얼로그의 트리뷰에서 노드에 캡션으로 표시된다.
  • DESCRIPTION 요소 : 옵션 스키마에 대한 간략한 설명으로 옵션 다이얼로그에서 항목 설명 텍스트 박스에 표시된다.

Body Contents

BODY 부분에는 실제로 옵션 스키마에 포함되는 모든 옵션 항목들을 계층적으로 구분하여 정의한다.

<BODY>
    <OPTIONCATEGORY>
        <CAPTION>...</CAPTION>
        <DESCRIPTION>...</DESCRIPTION>
        <OPTIONCLASSIFICATION>
            <CAPTION>...</CAPTION>
            <DESCRIPTION>...</DESCRIPTION>
            <OPTIONITEM>
               ...
            </OPTIONITEM>
            ...             
        </OPTIONCLASSIFICATION>
         ... 
    </OPTIONCATEGORY>
     ... 
</BODY>
  • OPTIONCATEGORY 요소 : 옵션 카테고리에 대한 구조를 정의한다.
    • CAPTION 요소 : 옵션 카테고리의 캡션으로 옵션 다이얼로그의 트리뷰에서 노드에 표시된다.
    • DESCRIPTION 요소 : 옵션 카테고리에 대한 간략한 설명으로 옵션 다이얼로그에서 해당 카테고리를 선택했을 때 항목 설명 텍스트 상자에 표시된다.
  • OPTIONCLASSIFICATION 요소 : 옵션 클래시피케이션에 대한 구조를 정의한다.
    • CAPTION 요소 : 옵션 클래시피케이션의 캡션으로 옵션 다이얼로그의 인스펙터에서 분류 행의 이름으로 표시된다
    • DESCRIPTION 요소 : 옵션 클래시피케이션의 대한 간략한 설명으로 옵션 다이얼로그에서 해당 클래시피케이션을 선택했을 때 항목 설명 텍스트 상자에 표시된다.
  • OPTIONITEM 요소 : 여러 개의 옵션 항목들을 정의한다. Option Item Definition 섹션 참조

옵션 항목 정의

OPTIONCLASSIFICATION 요소 하부에는 여러 개의 옵션 항목을 정의할 수 있다. 옵션 항목의 타입은 단순한 문자열만이 아니라 정수, 실수, 논리형, 열거형 등 몇 가지 형태로 명시화되어 있다. 옵션 다이얼로그에서는 옵션 항목의 타입에 따라 옵션 값 입력을 위한 정보를 제공하거나 입력할 수 있는 값을 제한한다.

StarUML에서 제공하는 옵션 항목의 타입은 다음과 같다.

옵션 항목 타입 XML 요소 이름 옵션 다이얼로그에서의 입력 형태
정수 (integer) OPTIONITEM-INTEGER 정수 범위의 숫자만 입력 할 수 있다.
실수 (real) OPTIONITEM-REAL 실수 범위의 숫자만 입력 할 수 있다.
문자열 (string) OPTIONITEM-STRING 문자열 값을 입력 받는다.
논리형 (boolean) OPTIONITEM-BOOLEAN 체크박스로 True / False를 입력 받는다.
텍스트 (text) OPTIONITEM-TEXT 입력 시 텍스트박스가 팝업 되어 거기에 여러 줄을 입력할 수 있다.
열거형 (enumeration) OPTIONITEM-ENUMERATION OPTION-ENUMERATIONITEM으로 정의된 여러 개의 열거항목을 콤보박스에서 선택할 수 있다.
글자체 (font name) OPTIONITEM-FONTNAME 시스템에 설치된 글자체 목록 중에서 하나를 선택할 수 있다.
파일명 (file name) OPTIONITEM-FILENAME 파일명을 직접 입력하거나 파일 열기 다이얼로그를 통해서 파일을 지정한다.
경로명 (path name) OPTIONITEM-PATHNAME 디렉토리(directory)를 직접 입력하거나 경로 지정 다이얼로그를 통해서 경로를 지정한다.
색상 (color) OPTIONITEM-COLOR 색상 콤보박스에서 색상을 선택하거나 색상 다이얼로그에서 색을 지정한다.
범위형 (range) OPTIONITEM-RANGE 지정된 범위 내의 정수 값을 입력 받는다. 스핀버튼으로 지정된 스텝만큼 값을 변경시킬 수 있다.

아래는 옵션 스키마 파일에서 OPTIONCLASSIFICATION 하부에 옵션 항목 정의 포맷을 보인 것이다.

<OPTIONCLASSIFICATION>
    <OPTIONITEM-INTEGER key="...">
        <CAPTION>...</CAPTION>
        <DESCRIPTION>...</DESCRIPTION>
        <DEFAULTVALUE>...</DEFAULTVALUE>
    </OPTIONITEM-INTEGER>
    <OPTIONITEM-REAL key="...">
        <CAPTION>...</CAPTION>
        <DESCRIPTION>...</DESCRIPTION>
        <DEFAULTVALUE>...</DEFAULTVALUE>
    </OPTIONITEM-REAL>
    <OPTIONITEM-STRING key="...">
        <CAPTION>...</CAPTION>
        <DESCRIPTION>...</DESCRIPTION>
        <DEFAULTVALUE>...</DEFAULTVALUE>
    </OPTIONITEM-STRING>
    <OPTIONITEM-BOOLEAN key="...">
        <CAPTION>...</CAPTION>
        <DESCRIPTION>...</DESCRIPTION>
        <DEFAULTVALUE>...</DEFAULTVALUE>
    </OPTIONITEM-BOOLEAN>
    <OPTIONITEM-TEXT key="...">
        <CAPTION>...</CAPTION>
        <DESCRIPTION>...</DESCRIPTION>
        <DEFAULTVALUE>...</DEFAULTVALUE>
    </OPTIONITEM-TEXT>
    <OPTIONITEM-ENUMERATION key="...">
        <CAPTION>...</CAPTION>
        <DESCRIPTION>...</DESCRIPTION>
        <DEFAULTVALUE>...</DEFAULTVALUE>
        <ENUMERATIONITEM>...</ENUMERATIONITEM>
        ...
    </OPTIONITEM-ENUMERATION>
    <OPTIONITEM-FONTNAME key="...">
        <CAPTION>...</CAPTION>
        <DESCRIPTION>...</DESCRIPTION>
        <DEFAULTVALUE>...</DEFAULTVALUE>
    </OPTIONITEM-FONTNAME>
    <OPTIONITEM-FILENAME key="...">
        <CAPTION>...</CAPTION>
        <DESCRIPTION>...</DESCRIPTION>
        <DEFAULTVALUE>...</DEFAULTVALUE>
    </OPTIONITEM-FILENAME>
    <OPTIONITEM-PATHNAME key="...">
        <CAPTION>...</CAPTION>
        <DESCRIPTION>...</DESCRIPTION>
        <DEFAULTVALUE>...</DEFAULTVALUE>
    </OPTIONITEM-PATHNAME>
    <OPTIONITEM-COLOR key="...">
        <CAPTION>...</CAPTION>
        <DESCRIPTION>...</DESCRIPTION>
        <DEFAULTVALUE>...</DEFAULTVALUE>
    </OPTIONITEM-COLOR>
    <OPTIONITEM-RANGE key="...">
        <CAPTION>...</CAPTION>
        <DESCRIPTION>...</DESCRIPTION>
        <DEFAULTVALUE>...</DEFAULTVALUE>
        <MINVALUE>...</MINVALUE>
        <MAXVALUE>...</MAXVALUE>
        <STEP>...</STEP>
    </OPTIONITEM-RANGE>
     ... 
</OPTIONITEMCLASSIFICATION>
  • key 속성 (모든 OPTIONITEM 요소들) : 옵션 항목의 고유한 키 값으로 옵션 스키마내에서 유일해야 한다. COM 인터페이스를 통해서 옵션 값을 읽어 올 때 파라미터로 사용된다.
  • CAPTION 요소 : 옵션 다이얼로그의 입력 행에서의 캡션이다.
  • DESCRIPTION 요소 : 옵션 항목에 대한 간략한 설명을 기술하는 것으로 옵션 다이얼로그에서 해당 옵션 항목이 선택되었을 때 항목설명 텍스트 상자에 표시된다.
  • DEFAULTVALUE 요소 : 옵션 항목의 기본값으로 각 타입별로 아래와 같이 유효한 범위내의 값으로 입력되어야 한다. DefaultValue가 해당 타입의 적합한 값이 아니면 옵션 다이얼로그에서 값을 편집할 수 없다.  

    옵션 항목 타입

    Default Value의 유효 범위

     
    OPTIONITEM-INTEGER -2147483648 ~ 2147483647 사이의 정수
    OPTIONITEM-REAL 정수 또는 소수점 형태의 실수
    OPTIONITEM-STRING 문자열
    OPTIONITEM-BOOLEAN True 또는 False
    OPTIONITEM-TEXT 문자열
    OPTIONITEM-ENUMERATION ENUMERATIONITEM 으로 정의된 문자열
    String value defined by ENUMERATIONITEM
    OPTIONITEM-FONTNAME 글자체  예)굴림
    OPTIONITEM-FILENAME 경로를 포함하는 파일명 형식 또는 빈 문자열
    예) C:\My Document\Default.xml
    OPTIONITEM-PATHNAME 적합한 경로명 또는 빈 문자열
    예) C:\My Document
    OPTIONITEM-COLOR 다음과 같은 형식의 문자열
    ${W}{B}{G}{R}
     
    {W} 예약된 부분 . 무조건 00
    {B} 색 구성 중 Blue 값의 비율 . 0 ~ 255 사이의 16 진수 값 (00 ~ FF)
    {G} 색 구성 중 Green 값의 비율 . 0 ~ 255 사이의 16 진수 값 (00 ~ FF)
    {R} 색 구성 중 Red 값의 비율 . 0 ~ 255 사이의 16 진수 값 (00 ~ FF)

    예) $00FF0000 , $00A0A0A0, $00FF00FF

    OPTIONITEM-RANGE MINVALUE와 MAXVALUE에 명시된 최소값과 최대값 사이의 정수
  • ENUMERATIONITEM 요소 : 열거형 타입의 옵션 항목(OPTION-ENUMERATION)에서 선택할 수 있는 열거 항목이다. OPTION-ENUMERATION에서 최소 한 개 이상의 EnumerationItem이 정의되어야 한다.
  • MINVALUE 요소 : 범위형 타입의 옵션 항목(OPTION-RANGE)에서 유효한 최소 정수 값이다.
  • MAXVALUE 요소 : 범위형 타입의 옵션 항목(OPTION-RANGE)에서 유효한 최대 정수 값이다.
  • STEP 요소 : 범위형 타입의 옵션 값 편집 시 스핀 버튼을 클릭했을 때의 증가치 정수 값이다.

다음은 StarUML의 기본 옵션 스키마의 일부분을 예제로 보인 것이다.

<?xml version="1.0" encoding="UTF-8" ?>
<OPTIONSCHEMA id="ENVIRONMENT">
    <HEADER>
        <CAPTION>Environment</CAPTION>
        <DESCRIPTION> </DESCRIPTION>
    </HEADER>
    <BODY>
        <OPTIONCATEGORY>
            <CAPTION>General</CAPTION>
            <DESCRIPTION>General Configuration is a group of the basic and general option items for the program. This category includes the [General], [Browser], [Collection Editor] and [Web] subcategories.</DESCRIPTION>
            <OPTIONCLASSIFICATION>
                <CAPTION>General</CAPTION>
                <DESCRIPTION></DESCRIPTION>
                <OPTIONITEM-RANGE key="UNDO_LEVEL">
                    <CAPTION>Max. number of undo actions</CAPTION>
                    <DESCRIPTION>Specifies the maximum number of actions for undo and redo.</DESCRIPTION>
                    <DEFAULTVALUE>30</DEFAULTVALUE>
                    <MINVALUE>1</MINVALUE>
                    <MAXVALUE>100</MAXVALUE>
                    <STEP>1</STEP>
                </OPTIONITEM-RANGE>
                <OPTIONITEM-BOOLEAN key="CREATE_BACKUP">
                    <CAPTION>Create backup files</CAPTION>
                    <DESCRIPTION>Specifies whether to create backup files when saving changes.</DESCRIPTION>
                    <DEFAULTVALUE>True</DEFAULTVALUE>
                </OPTIONITEM-BOOLEAN>
            </OPTIONCLASSIFICATION>
        </OPTIONCATEGORY>
    </BODY>
</OPTIONSCHEMA>

옵션 스키마 등록하기

작성된 옵션 스키마 파일을 프로그램에서 인식하려면 메뉴 확장 파일을 StarUML™ 모듈 디렉토리(<install-dir>\modules) 하부 디렉토리로 옮겨야 한다. StarUML™은 프로그램 초기화 시에 모듈 디렉토리 하부를 검색하여 모든 옵션 스키마 파일들을 읽어 들인 후 프로그램에 자동 등록한다. 만약 옵션 스키마 파일이 문법에 맞지 않게 잘 못 작성되어 있거나, 확장자가 .opt가 아닌 경우에는 옵션 스키마 파일을 정상적으로 읽어 들이지 않고 무시하게 될 것이다.
옵션 스키마 파일은 가급적이면 Add-In 실행모듈이 포함되어 있는 디렉토리와 동일한 디렉토리에 설치하는 것을 권고한다.

노트: 옵션 스키마를 더 이상 사용하지 않으려면 StarUML™ 모듈 디렉토리(<install-dir>\modules) 하부에서 삭제하면 된다.

옵션값 접근하기

COM 인터페이스를 사용하여 옵션값 접근하기

StarUML의 COM 인터페이스를 이용하면 사용자가 옵션다이얼로그를 통해 변경한 옵션 항목의 값을 참조 할 수 있다. IStarUMLApplicationGetOptionValue()는 입력 받은 SchemaID와 옵션의 Key로부터 옵션의 값을 Variant로 리턴해준다. GetOptionValue()의 호출 형식은 다음과 같다.

IStarUMLApplication.GetOptionValue(SchemaID: String, Key: String): Variant
  • SchemaID : 옵션 스키마 정의 파일에 명시되어 있는 스키마 아이디
  • Key : 옵션 스키마 파일에 기술된 옵션 항목의 키

GetOptionValue()의 Variant 타입의 리턴값은 각 옵션 항목의 타입에 따라서 캐스팅하여 사용하면 된다. 그러나, Jscript 나 VBscript처럼 타입 검사를 하지 않는 언어에서는 별도의 타입 캐스팅 절차 없이 바로 값을 읽어올 수 있다.

다음은 StarUML의 기본 옵션 스키마에 정의되어 있는 "UNDO_LEVEL" 옵션 항목의 값을 얻어와서 메세지 상자로 출력하는 JScript 예제이다.

var app = new ActiveXObject("StarUML.StarUMLApplication");
var undoLevel = app.GetOptionValue("ENVIRONMENT", "UNDO_LEVEL");

WScript.Echo("Max. number of undo actions : " + undoLevel);

옵션값의 이벤트 변경 처리하기

StarUMLIEventSubscriber를 구현한 Add-in들에게 프로그램의 조작 과정에서 발생하는 이벤트를 전파해준다. 사용자가 옵션 다이얼로그를 통해 옵션값을 변경하면 애플리케이션은 IEventSubscriber를 구현한 Add-in들의 이벤트 핸들러- NotifyEvent()-를 호출한다. 옵션값이 변경되었을 때 옵션 값을 즉시 Add-in에 반영하려면 IEventSubscriber을 구현하고 NotifiyEvent()메써드 내에서 EVK_OPTIONS_APPLIED 이벤트일때 IStarUMLApplication.GetOptionValue() 메써드를 사용하여 직접 옵션값을 읽어 오면 된다. VBScript나 JScript등 스크립트를 사용하는 Add-in들은 IEventSubscriber를 구현할 수 없으므로 사용자에 의한 옵션값 변경 시에 이를 Add-in에 바로 반영할 수 없다.

이벤트 핸들링에 관한 더 자세한 내용은 다음 섹션에서 다루어 질 것이다.

이벤트 수신의 기본 개념

IEventSubscriber 인터페이스를 구현하는 Add-In 개체는 StarUML 애플리케이션의 다양한 내부 이벤트(Event)들을 전파 받을 수 있다. StarUML 애플리케이션은 내부 이벤트가 발생할 때 마다 등록된 IEventSubscriber 타입 개체들의 NotifyEvent 메소드를 호출한다.

아래의 클래스 다이어그램은 이벤트 수신과 관련된 외부 API 인터페이스들의 구조를 보여주고 있다.

이벤트의 종류

위의 그림에서 EventKind 열거체(Enumeration)는 IEventSubscriber 인터페이스를 구현하는 Add-In 개체가 수신할 수 있는 StarUML 애플리케이션 내부 이벤트의 종류를 정의하고 있다. EventKind 열거체의 각 리터럴의 의미는 다음 표와 같다.

이벤트 종류 (리터럴) 정수 값 이벤트 설명
EVK_APPLICATION_ACTIVATE 0 StarUML 애플리케이션의 창(Window)이 활성화(activate)될 때 발생한다.
EVK_APPLICATION_DEACTIVATE 1 StarUML 애플리케이션의 창이 비활성화(deactivate)될 때 발생한다.
EVK_APPLICATION_MINIMIZE 2 StarUML애플리케이션의 창이 최소화될 때 발생한다.
EVK_APPLICATION_RESTORE 3 최소화된 StarUML애플리케이션의 창이 이전 크기로 복구될 때 발생한다.
EVK_OPTIONS_APPLIED 4 옵션 값이 변경되었을 때 발생한다.
EVK_PROJECT_OPENED 5 프로젝트 요소가 생성되었거나 프로젝트 파일을 열었을 때 발생한다.
EVK_PROJECT_SAVED 6 프로젝트가 저장되었을 때 마다 발생한다.
EVK_PROJECT_CLOSING 7 프로젝트 닫기를 선택했을 때 발생한다.
EVK_PROJECT_CLOSED 8 프로젝트가 닫혔을 때 발생한다.
EVK_DOCUMENT_MODIFIED 9 도큐먼트(프로젝트, 유닛)가 변경되었을 때 발생한다.
EVK_DOCUMENT_SAVED 10 도큐먼트(프로젝트, 유닛)가 저장되었을 때 발생한다.
EVK_UNIT_SEPARATED 11 유닛(Unit) 요소로 분리되었을 때 발생한다.
EVK_UNIT_MERGED 12 분리된 유닛 요소가 병합되었을 때 발생한다.
EVK_UNIT_OPENED 13 유닛이 불러오기 되었을 때 발생한다.
EVK_SELECTION_CHANGED 14 모델링 요소의 선택이 변경될 때 발생한다.
EVK_DIAGRAM_ACTIVATED 15 다이어그램이 열릴 때 발생한다.
EVK_ELEMENTS_ADDED 16 새로운 모델링 요소가 생성되었을 때 마다 발생한다.
EVK_ELEMENTS_DELETING 17 모델링 요소를 삭제할 때 발생한다.
EVK_ELEMENTS_DELETED 18 모델링 요소가 삭제되었을 때 발생한다.
EVK_MODELS_CHANGED 19 모델 요소의 속성 값이 변경되었을 때 발생한다.
EVK_VIEWS_CHANGED 20 뷰 요소의 속성 값이 변경되었을 때 발생한다.

이벤트 수신하기

StarUML 애플리케이션의 이벤트를 수신하려는 Add-In 개체는 모든 StarUML Add-In들의 공통사항인 IStarUMLAddIn 인터페이스 외에 추가로 IEventSubscriber 인터페이스를 구현해야 한다.

다음 예제는 IStarUMLAddIn 인터페이스와 IEventSubscriber 인터페이스를 구현하는 StarUML Add-In 개체의 클래스 정의를 보여준다. 예제는 델파이 파스칼(Delphi Pascal) 코드로 쓰여졌다.

type
    AddInExample = class(TComObject, IStarUMLAddIn, IEventSubscriber)
    private
        StarUMLApp: IStarUMLApplication;
        EventPub: IEventPublisher;
    protected
        function InitializeAddIn: HResult; stdcall;
        function FinalizeAddIn: HResult; stdcall;
        function DoMenuAction(ActionID: Integer): HResult; stdcall;
        function NotifyEvent(AEvent: EventKind): HResult; stdcall;
        ...
    public
        procedure Initialize; override;
        destructor Destroy; override;
        ...
    end;

이벤트 수신 등록 및 해지

IEventSubscriber 인터페이스를 구현한 Add-In 개체가 실제로 이벤트를 수신하기 위해서는 이벤트 수신을 등록하는 과정이 필요하다. 이벤트 수신 등록과 해지는 IEventPublisher 타입 개체를 통해 할 수 있는데, IEventPublisher 타입 개체는 IStarUMLApplication 요소를 통해 얻을 수 있다. 아래의 예제는 델파이 파스칼 코드에서 IStarUMLApplicationIEventPublisher 타입 개체의 참조를 얻는 것을 보여주고 있다.

implementation

procedure AddInExample.Initialize;
begin
    inherited;
    StarUMLApp := CreateOleObject('StarUML.StarUMLApplication') as IStarUMLApplication;
    EventPub := StarUMLApp.EventPublisher;
end;

destructor AddInExample.Destroy;
begin
    EventPub := nil;
    StarUMLApp := nil;
    inherited;
end;

그리고 IEventPublisher 인터페이스는 이벤트 수신 등록과 해지를 지원하는 다음과 같은 메소드들을 제공한다. 각 메소드에서 "ASubscriber" 인자는 IEventSubscriber 인터페이스를 구현한 Add-In 개체 자신이다.

메소드 설명
Subscribe(ASubscriber: IEventSubscriber; AEvent: EventKind) AEvent 인자가 지정하는 이벤트에 대한 수신을 등록한다.
SubscribeAll(ASubscriber: IEventSubscriber) 모든 이벤트에 대한 수신을 등록한다.
Unsubscribe(ASubscriber: IEventSubscriber; AEvent: EventKind) AEvent 인자가 지정하는 이벤트에 대한 수신을 해지한다.
UnsubscribeAll(ASubscriber: IEventSubscriber) 모든 이벤트에 대한 수신을 해지한다.

Add-In 개체가 특정 이벤트 만을 수신하고자 할 때는 Subscribe 메소드를 사용한다. 예를 들어 두 가지의 특정 이벤트에 대해서만 수신을 하고자 하는 경우, 각각의 이벤트에 대해 Subscribe 메소드를 호출해야 한다. 모든 이벤트들을 모두 수신 하기를 원한다면 SubscribeAll 메소드를 사용하면 된다. 일반적으로 Subscribe, SubscribeAll 메소드는 IStarUMLAddIn .InitializeAddIn 메소드 구현에서 호출한다.

Add-In 개체는 수신 등록한 이벤트를 더 이상 수신할 필요가 없을 때(개체가 소멸될 때 등) 자신이 등록한 모든 이벤트들에 대해 등록을 해지해야 한다. Subscribe 메소드를 사용하여 수신 등록을 한 경우에는 Unsubscribe 메소드를 사용하고, SubscribeAll 메소드를 사용한 경우에는 UnsubscribeAll 메소드를 사용하여 등록을 해지한다. 일반적으로 Unsubscribe, SubscribeAll 메소드는 IStarUMLAddIn.FinalizeAddIn 메소드 구현에서 호출한다.

다음은 EVK_ELEMENTS_ADDED, EVK_ELEMENTS_DELETED 두 이벤트에 대한 수신 등록과 해지를 하는 예이다.

implementation

function AddInExample.InitializeAddIn: HResult;
begin
    EventPub.Subscribe(Self, EVK_ELEMENTS_ADDED);
    EventPub.Subscribe(Self, EVK_ELEMENTS_DELETED);
    ...
    Result := S_OK;
end;

function AddInExample.FinalizeAddIn: HResult;
begin
    EventPub.Unsubscribe(Self, EVK_ELEMENTS_ADDED);
    EventPub.Unsubscribe(Self, EVK_ELEMENTS_DELETED);
    ...
    Result := S_OK;
end;

이벤트 인자 얻어오기

각 이벤트가 발생했을 때 해당 이벤트와 관련된 아규먼트(Argument)를 얻어야 할 필요성이 있다. 예를 들어 모델링 요소의 생성과 관련된(EVK_ELEMENTS_ADDED) 이벤트가 발생했을 때 어떤 모델링 요소가 생성되었는지를 알아야 하는 경우 등이다. IEventPublisher 인터페이스는 이벤트 아규먼트와 관련하여 다음과 같은 메소드들을 제공하고 있다.

메소드 설명
GetEventArgModelCount (): Integer 이벤트와 관련된 모델 요소들의 개수를 반환한다.
GetEventArgModelAt(Index: Integer): IModel 이벤트와 관련된 모델 요소들 중에서 Index 번째 요소에 대한 참조를 반환한다.
GetEventArgViewCount: Integer 이벤트와 관련된 뷰 요소들의 개수를 반환한다.
GetEventArgViewAt(Index: Integer): IView 이벤트와 관련된 뷰 요소들 중에서 Index 번째 요소에 대한 참조를 반환한다.
GetEventArgDocument: IDocument 이벤트와 관련된 도큐먼트(Document) 요소에 대한 참조를 반환한다.
GetEventArgUnit: IUMLUnitDocument 이벤트와 관련된 유닛(Unit) 요소에 대한 참조를 반환한다.

이벤트 처리하기

Add-In에서 이벤트 수신을 등록했다면 등록한 이벤트가 발생했을 때 필요한 처리를 해야 할 것이다. StarUML 애플리케이션은 등록된 이벤트가 발생할 때 마다 해당 Add-In의 NotifyEvent 메소드를 호출하며, 발생할 이벤트의 종류를 인자로 전달한다. NotifyEvent 메소드의 인자로 이벤트의 종류를 전달하는 이유는 Add-In이 하나 이상의 이벤트에 대한 수신 등록을 했을 가능성이 있기 때문이다. 각 Add-In은 NotifyEvent 메소드에서 이벤트의 종류별로 필요한 처리를 하는 로직(logic)을 구현하면 된다.

다음은 NotifyEvent 메소드를 구현한 예제이다. 이 예제에서는 StarUML 애플리케이션에 연관(UMLAssociation) 요소나 일반화(UMLGeneralization) 요소가 생성되었을 때, 각 요소의 연결이 의미적으로 유효한지를 검사하고 있다. (이 예제는 위의 예제들과 연결되므로 Add-In 개체의 정의부분은 위의 예제를 참고하기 바란다.)

implementation

function AddInExample.NotifyEvent(AEvent: EventKind): HResult;
var
    M: IModel;
    Assoc: IUMLAssociation;
    Gen: IUMLGeneralization;
    End1, End2: IUMLClassifier;
begin
    if AEvent = EVK_ELEMENTS_ADDED then 
    begin
        if EventPub.GetEventArgModelCount = 1 then 
        begin
            M := EventPub.GetEventArgModelAt(0);

            // Association
            if M.QueryInterface(IUMLAssociation, Assoc) = S_OK then 
            begin
                End1 := Assoc.GetConnectionAt(0).Participant;
                End2 := Assoc.GetConnectionAt(1).Participant
                if End1.IsKindOf('UMLPackage') or End2.IsKindOf('UMLPackage') then
                    ShowMessage('Packages cannot have associations.')
                ...
            end;

          // Generalization
          if M.QueryInterface(IUMLGeneralization, Gen) = S_OK then 
          begin
              if Gen.Child.IsRoot then
                  ShowMessage('Root elements cannot have parent elements.');
              if Gen.Parent.IsLeaf then
                  ShowMessage('Leaf elements cannot have child elements.');
           end;
        end;
    end;

    Result := S_OK;
end;

반응형

댓글