VSPackage에서 사용자 인터페이스 요소를 추가하는 방법
VSPackage는 .vsct 파일을 통해 Visual Studio에 UI(사용자 인터페이스) 요소(예: 메뉴, 도구 모음 및 도구 창)를 추가할 수 있습니다.
Visual Studio 사용자 환경 지침에서 UI 요소에 대한 디자인 지침을 찾을 수 있습니다.
Visual Studio 명령 테이블 아키텍처
언급한 바와 같이 명령 테이블 아키텍처는 앞에서 설명한 아키텍처 원칙을 지원합니다. 명령 테이블 아키텍처의 추상화, 데이터 구조 및 도구 뒤에 있는 원칙은 다음과 같습니다.
메뉴, 명령 및 그룹의 세 가지 기본 종류의 항목이 있습니다. 메뉴는 UI에서 메뉴, 하위 메뉴, 도구 모음 또는 도구 창으로 노출될 수 있습니다. 명령은 사용자가 IDE에서 실행할 수 있는 프로시저이며 메뉴 항목, 단추, 목록 상자 또는 기타 컨트롤로 노출될 수 있습니다. 그룹은 메뉴와 명령 모두에 대한 컨테이너입니다.
각 항목은 항목을 설명하는 정의, 다른 항목에 상대적인 우선 순위 및 해당 동작을 수정하는 플래그에 의해 지정됩니다.
각 항목에는 항목의 부모를 설명하는 배치가 있습니다. 항목에는 여러 부모가 있을 수 있으므로 UI의 여러 위치에 표시할 수 있습니다.
모든 명령은 해당 그룹의 유일한 자식인 경우에도 그룹을 부모로 사용해야 합니다. 모든 표준 메뉴에는 부모 그룹도 있어야 합니다. 도구 모음 및 도구 창은 부모 역할을 합니다. 그룹에는 주 Visual Studio 메뉴 모음 또는 메뉴, 도구 모음 또는 도구 창을 부모로 가질 수 있습니다.
항목 정의 방법
.vsct 파일의 형식은 XML로 지정됩니다. 패키지에 대한 UI 요소를 정의하고 해당 요소가 IDE에 표시되는 위치를 결정합니다. 패키지의 모든 메뉴, 그룹 또는 명령에는 먼저 Symbols
섹션의 GUID 및 ID가 할당됩니다. .vsct 파일의 나머지 부분에서 각 메뉴, 명령 및 그룹은 GUID 및 ID 조합으로 식별됩니다. 다음 예제에서는 템플릿에서 메뉴 명령을 선택할 때 Visual Studio 패키지 템플릿에서 생성된 일반적인 Symbols
섹션을 보여줍니다.
<Symbols>
<!-- This is the package guid. -->
<GuidSymbol name="guidMenuTextPkg" value="{b1253bc6-d266-402b-89e7-5e3d3b22c746}" />
<!-- This is the guid used to group the menu commands together -->
<GuidSymbol name="guidMenuTextCmdSet" value="{a633d4e4-6c65-4436-a138-1abeba7c9a69}">
<IDSymbol name="MyMenuGroup" value="0x1020" />
<IDSymbol name="cmdidMyCommand" value="0x0100" />
</GuidSymbol>
<GuidSymbol name="guidImages" value="{53323d9a-972d-4671-bb5b-9e418480922f}">
<IDSymbol name="bmpPic1" value="1" />
<IDSymbol name="bmpPic2" value="2" />
<IDSymbol name="bmpPicSearch" value="3" />
<IDSymbol name="bmpPicX" value="4" />
<IDSymbol name="bmpPicArrows" value="5" />
</GuidSymbol>
</Symbols>
Symbols
섹션의 최상위 요소는 GuidSymbol 요소입니다. GuidSymbol
요소는 IDE에서 패키지 및 해당 구성 요소 부분을 식별하는 데 사용되는 GUID에 이름을 매핑합니다.
참고 항목
GUID는 Visual Studio 패키지 템플릿에 의해 자동으로 생성됩니다. 도구 메뉴에서 GUID 만들기를 클릭하여 고유한 GUID를 만들 수도 있습니다.
첫 번째 GuidSymbol
요소인 guid<PackageName>Pkg
은 패키지 자체의 GUID입니다. Visual Studio에서 패키지를 로드하는 데 사용하는 GUID입니다. 일반적으로 자식 요소가 없습니다.
규칙에 따라 메뉴와 명령은 두 번째 GuidSymbol
요소인 guid<PackageName>CmdSet
아래에 그룹화되고 비트맵은 세 번째 GuidSymbol
요소인 guidImages
아래에 그룹화됩니다. 이 규칙을 따를 필요는 없지만 각 메뉴, 그룹, 명령 및 비트맵은 GuidSymbol
요소의 자식이어야 합니다.
패키지 명령 집합을 나타내는 두 번째 GuidSymbol
요소에는 여러 IDSymbol
요소가 있습니다. 각 IDSymbol 요소는 이름을 숫자 값에 매핑하고 명령 집합의 일부인 메뉴, 그룹 또는 명령을 나타낼 수 있습니다. 세 번째 GuidSymbol
요소의 IDSymbol
요소는 명령의 아이콘으로 사용할 수 있는 비트맵을 나타냅니다. GUID/ID 쌍은 애플리케이션에서 고유해야 하므로 동일한 GuidSymbol
요소의 두 자식이 같은 값을 가질 수 없습니다.
메뉴, 그룹 및 명령
메뉴, 그룹 또는 명령에 GUID 및 ID가 있는 경우 IDE에 추가할 수 있습니다. 모든 UI 요소에는 다음과 같은 항목이 있어야 합니다.
UI 요소가 정의된
GuidSymbol
요소의 이름과 일치하는guid
특성입니다.연결된
IDSymbol
요소의 이름과 일치하는id
특성입니다.
guid
및 id
특성은 함께 UI 요소의 서명을 구성합니다.
부모 메뉴 또는 그룹에서 UI 요소의 배치를 결정하는
priority
특성입니다.부모 메뉴 또는 그룹의 서명을 지정하는
guid
및id
특성이 있는 Parent 요소입니다.
메뉴
각 메뉴는 Menus
섹션의 Menu 요소로 정의됩니다. 메뉴에는 guid
, id
및 priority
특성과 Parent
요소가 있어야 하며 다음과 같은 추가 특성과 자식도 있어야 합니다.
메뉴가 IDE에 일종의 메뉴 또는 도구 모음으로 표시되어야 하는지 여부를 지정하는
type
특성입니다.IDE에서 메뉴 제목을 지정하는 ButtonText 요소와 메뉴에 액세스하기 위해 명령 창에서 사용되는 이름을 지정하는 CommandName 요소를 포함하는 Strings 요소입니다.
선택적 플래그입니다. CommandFlag 요소는 메뉴 정의에 표시하여 IDE의 모양이나 동작을 변경할 수 있습니다.
도구 모음과 같은 도킹 가능한 요소가 아닌 한 모든 Menu
요소는 그룹을 부모로 사용해야 합니다. 도킹 가능한 메뉴는 자체 부모입니다. type
특성의 메뉴 및 값에 대한 자세한 내용은 Menu 요소 설명서를 참조하세요.
다음 예제에서는 도구 메뉴 옆에 있는 Visual Studio 메뉴 모음에 표시되는 메뉴를 보여 줍니다.
<Menu guid="guidTopLevelMenuCmdSet" id="TopLevelMenu" priority="0x700" type="Menu">
<Parent guid="guidSHLMainMenu" id="IDG_VS_MM_TOOLSADDINS" />
<Strings>
<ButtonText>TestMenu</ButtonText>
<CommandName>TestMenu</CommandName>
</Strings>
</Menu>
그룹
그룹은 .vsct 파일의 Groups
섹션에 정의된 항목입니다. 그룹은 컨테이너일 뿐입니다. 메뉴의 구분선으로 제외하면 IDE에 표시되지 않습니다. 따라서 Group 요소는 서명, 우선 순위 및 부모에 의해서만 정의됩니다.
그룹에는 메뉴, 다른 그룹 또는 부모 자체가 있을 수 있습니다. 그러나 부모는 일반적으로 메뉴 또는 도구 모음입니다. 이전 예제의 메뉴는 IDG_VS_MM_TOOLSADDINS
그룹의 자식이며 해당 그룹은 Visual Studio 메뉴 모음의 자식입니다. 다음 예제의 그룹은 이전 예제에 있는 메뉴의 자식입니다.
<Group guid="guidTopLevelMenuCmdSet" id="MyMenuGroup" priority="0x0600">
<Parent guid="guidTopLevelMenuCmdSet" id="TopLevelMenu"/>
</Group>
메뉴의 일부이므로 이 그룹에는 일반적으로 명령이 포함됩니다. 그러나 다른 메뉴도 포함할 수 있습니다. 다음 예제와 같이 하위 메뉴가 정의되는 방법입니다.
<Menu guid="guidTopLevelMenuCmdSet" id="SubMenu" priority="0x0100" type="Menu">
<Parent guid="guidTopLevelMenuCmdSet" id="MyMenuGroup"/>
<Strings>
<ButtonText>Sub Menu</ButtonText>
<CommandName>Sub Menu</CommandName>
</Strings>
</Menu>
명령
IDE에 제공되는 명령은 Button 요소 또는 Combo 요소로 정의됩니다. 메뉴 또는 도구 모음에 표시하려면 명령에 부모 그룹이 있어야 합니다.
단추
단추는 Buttons
섹션에 정의되어 있습니다. 사용자가 단일 명령을 실행하기 위해 클릭하는 메뉴 항목, 단추 또는 기타 요소는 단추로 간주됩니다. 일부 단추 유형에는 목록 기능도 포함될 수 있습니다. 단추는 메뉴에 있는 것과 동일한 필수 및 선택적 특성을 가지며, IDE의 단추를 나타내는 비트맵의 GUID 및 ID를 지정하는 Icon 요소를 가질 수도 있습니다. 단추 및 해당 특성에 대한 자세한 내용은 Buttons 요소 설명서를 참조하세요.
다음 예제의 단추는 이전 예제에서 그룹의 자식이며 해당 그룹의 부모 메뉴에 있는 메뉴 항목으로 IDE에 표시됩니다.
<Button guid="guidTopLevelMenuCmdSet" id="cmdidTestCommand" priority="0x0100" type="Button">
<Parent guid="guidTopLevelMenuCmdSet" id="MyMenuGroup" />
<Icon guid="guidImages" id="bmpPic1" />
<Strings>
<CommandName>cmdidTestCommand</CommandName>
<ButtonText>Test Command</ButtonText>
</Strings>
</Button>
콤보
콤보는 Combos
섹션에 정의되어 있습니다. 각 Combo
요소는 IDE의 드롭다운 목록 상자를 나타냅니다. 목록 상자는 콤보의 type
특성 값에 따라 사용자가 작성할 수 있거나 그렇지 않을 수도 있습니다. 콤보에는 단추와 동일한 요소 및 동작이 있으며 다음과 같은 추가 특성이 있을 수도 있습니다.
픽셀 너비를 지정하는
defaultWidth
특성입니다.목록 상자에 표시되는 항목이 포함된 목록을 지정하는
idCommandList
특성입니다. 명령 목록은 콤보를 포함하는 동일한GuidSymbol
노드에서 선언되어야 합니다.
다음 예제에서는 콤보 요소를 정의합니다.
<Combos>
<Combo guid="guidFirstToolWinCmdSet"
id="cmdidWindowsMediaFilename"
priority="0x0100" type="DynamicCombo"
idCommandList="cmdidWindowsMediaFilenameGetList"
defaultWidth="130">
<Parent guid="guidFirstToolWinCmdSet"
id="ToolbarGroupID" />
<CommandFlag>IconAndText</CommandFlag>
<CommandFlag>CommandWellOnly</CommandFlag>
<CommandFlag>StretchHorizontally</CommandFlag>
<Strings>
<CommandName>Filename</CommandName>
<ButtonText>Enter a Filename</ButtonText>
</Strings>
</Combo>
</Combos>
비트맵
아이콘과 함께 표시되는 명령에는 GUID 및 ID를 사용하여 비트맵을 참조하는 Icon
요소가 포함되어야 합니다. 각 비트맵은 Bitmaps
섹션의 Bitmap 요소로 정의됩니다. Bitmap
정의에 필요한 유일한 특성은 원본 파일을 가리키는 guid
및 href
입니다. 원본 파일이 리소스 스트립인 경우 사용 가능한 이미지를 스트립에 나열하려면 usedList 특성도 필요합니다. 자세한 내용은 Bitmap 요소 설명서를 참조하세요.
부모/자식 관리
다음 규칙은 항목이 다른 항목을 부모 항목으로 호출하는 방법을 제어합니다.
요소 | 명령 테이블의 이 섹션에 정의됨 | 포함될 수 있음(부모로서 또는 CommandPlacements 섹션의 배치 또는 둘 다) |
포함할 수 있음(부모라고 함) |
---|---|---|---|
그룹 | Groups 요소, IDE, 기타 VSPackages | 메뉴, 그룹, 항목 자체 | 메뉴, 그룹 및 명령 |
메뉴 | Menus 요소, IDE, 기타 VSPackages | 1~n개 그룹 | 0~n개 그룹 |
도구 모음 | Menus 요소, IDE, 기타 VSPackages | 항목 자체 | 0~n개 그룹 |
메뉴 항목 | Buttons 요소, IDE, 기타 VSPackages | 1~n개 그룹, 항목 자체 | -0~n개 그룹 |
단추 | Buttons 요소, IDE, 기타 VSPackages | 1~n개 그룹, 항목 자체 | |
콤보 | Combos 요소, IDE, 기타 VSPackages | 1~n개 그룹, 항목 자체 |
메뉴, 명령 및 그룹 배치
메뉴, 그룹 또는 명령은 IDE에서 둘 이상의 위치에 나타날 수 있습니다. 항목을 여러 위치에 표시하려면 CommandPlacements
섹션에 CommandPlacement 요소로 추가해야 합니다. 모든 메뉴, 그룹 또는 명령을 명령 배치로 추가할 수 있습니다. 그러나 여러 컨텍스트를 구분하는 위치에는 도구 모음을 표시할 수 없으므로 이러한 방식으로 배치할 수 없습니다.
명령 배치에는 guid
, id
및 priority
특성이 있습니다. GUID 및 ID는 배치된 항목의 GUID 및 ID와 일치해야 합니다. priority
특성은 다른 항목과 관련된 항목의 배치를 제어합니다. IDE가 동일한 우선 순위를 가진 두 개 이상의 항목을 병합하는 경우 IDE는 패키지가 빌드될 때마다 패키지 리소스를 동일한 순서로 읽도록 보장하지 않으므로 해당 배치가 정의되지 않습니다.
메뉴 또는 그룹이 여러 위치에 표시되면 해당 메뉴 또는 그룹의 모든 자식이 각 인스턴스에 표시됩니다.
명령 표시 유형 및 컨텍스트
여러 VSPackage가 설치되면 메뉴, 메뉴 항목 및 도구 모음이 많아져 IDE가 복잡해질 수 있습니다. 이 문제를 방지하려면 표시 유형 제약 조건 및 명령 플래그를 사용하여 개별 UI 요소의 표시 유형을 제어하면 됩니다.
표시 유형 제약 조건
표시 유형 제약 조건은 VisibilityConstraints
섹션에서 VisibilityItem 요소로 설정됩니다. 표시 유형 제약 조건은 대상 항목이 표시되는 특정 UI 컨텍스트를 정의합니다. 이 섹션에 포함된 메뉴 또는 명령은 정의된 컨텍스트 중 하나가 활성 상태인 경우에만 표시됩니다. 이 섹션에서 메뉴 또는 명령을 참조하지 않으면 항상 기본적으로 표시됩니다. 이 섹션은 그룹에 적용되지 않습니다.
VisibilityItem
요소에는 대상 UI 요소의 guid
및 id
, context
와 같은 세 가지 특성이 있어야 합니다. context
특성은 대상 항목이 표시되는 시기를 지정하고 유효한 UI 컨텍스트를 해당 값으로 사용합니다. Visual Studio의 UI 컨텍스트 상수는 VSConstants 클래스의 멤버입니다. 모든 VisibilityItem
요소는 하나의 컨텍스트 값만 사용할 수 있습니다. 두 번째 컨텍스트를 적용하려면 다음 예제와 같이 동일한 항목을 가리키는 두 번째 VisibilityItem
요소를 만듭니다.
<VisibilityConstraints>
<VisibilityItem guid="guidSolutionToolbarCmdSet"
id="cmdidTestCmd"
context="UICONTEXT_SolutionHasSingleProject" />
<VisibilityItem guid="guidSolutionToolbarCmdSet"
id="cmdidTestCmd"
context="UICONTEXT_SolutionHasMultipleProjects" />
</VisibilityConstraints>
명령 플래그
다음 명령 플래그는 적용되는 메뉴 및 명령의 표시 유형에 영향을 줄 수 있습니다.
AlwaysCreate
메뉴는 그룹 또는 단추가 없는 경우에도 만들어집니다.
유효 기간: Menu
CommandWellOnly
명령이 최상위 메뉴에 표시되지 않고 추가 셸 사용자 지정에 사용할 수 있도록 하려는 경우(예: 키에 바인딩하는 경우) 이 플래그를 적용합니다. VSPackage가 설치되면 사용자는 옵션 대화 상자를 연 다음, 키보드 환경 범주에서 명령 배치를 편집하여 이러한 명령을 사용자 지정할 수 있습니다. 바로 가기 메뉴, 도구 모음, 메뉴 컨트롤러 또는 하위 메뉴의 배치에는 영향을 주지 않습니다.
유효 기간: Button
, Combo
DefaultDisabled
명령을 구현하는 VSPackage가 로드되지 않았거나 QueryStatus 메서드가 호출되지 않은 경우 기본적으로 명령을 사용할 수 없습니다.
유효 기간: Button
, Combo
DefaultInvisible
명령을 구현하는 VSPackage가 로드되지 않았거나 QueryStatus 메서드가 호출되지 않은 경우 기본적으로 명령은 표시되지 않습니다.
DynamicVisibility
플래그와 결합해야 합니다.
유효 기간: Button
, Combo
, Menu
DynamicVisibility
QueryStatus
메서드 또는 VisibilityConstraints
섹션에 포함된 컨텍스트 GUID를 사용하여 명령의 표시 여부를 변경할 수 있습니다.
도구 모음이 아닌 메뉴에 표시되는 명령에 적용됩니다. QueryStatus
메서드에서 OLECMDF_INVISIBLE
플래그가 반환될 때 최상위 도구 모음 항목을 사용하지 않도록 설정할 수 있지만 숨길 수는 없습니다.
메뉴에서 이 플래그는 해당 멤버가 숨겨질 때 자동으로 숨겨져야 함을 나타냅니다. 최상위 메뉴에는 이미 이 동작이 있으므로 이 플래그는 일반적으로 하위 메뉴에 할당됩니다.
DefaultInvisible
플래그와 결합해야 합니다.
유효 기간: Button
, Combo
, Menu
NoShowOnMenuController
이 플래그가 있는 명령이 메뉴 컨트롤러에 배치된 경우 명령은 드롭다운 목록에 나타나지 않습니다.
유효 기간: Button
명령 플래그에 대한 자세한 내용은 CommandFlag 요소 설명서를 참조하세요.
일반 요구 사항
명령을 표시하고 사용하도록 설정하려면 먼저 다음과 같은 일련의 테스트를 통과해야 합니다.
명령이 올바르게 배치되었습니다.
DefaultInvisible
플래그가 설정되지 않았습니다.부모 메뉴 또는 도구 모음이 표시됩니다.
VisibilityConstraints 요소 섹션의 컨텍스트 항목으로 인해 명령이 표시되지 않습니다.
IOleCommandTarget 인터페이스를 구현하는 VSPackage 코드는 명령을 표시하고 사용하도록 설정합니다. 인터페이스 코드가 이를 가로채서 동작하지 않았습니다.
사용자가 명령을 클릭하면 라우팅 알고리즘에 설명된 절차가 적용됩니다.
미리 정의된 명령 호출
UsedCommands 요소를 사용하면 VSPackages가 다른 VSPackage 또는 IDE에서 제공하는 명령에 액세스할 수 있습니다. 이렇게 하려면 사용할 명령의 GUID 및 ID가 있는 UsedCommand 요소를 만듭니다. 이렇게 하면 현재 Visual Studio 구성의 일부가 아니더라도 Visual Studio에서 명령을 노드할 수 있습니다. 자세한 내용은 UsedCommand 요소를 참조하세요.
인터페이스 요소 모양
명령 요소 선택 및 위치 지정에 대한 고려 사항은 다음과 같습니다.
Visual Studio는 배치에 따라 다르게 표시되는 많은 UI 요소를 제공합니다.
DefaultInvisible
플래그를 사용하여 정의된 UI 요소는 QueryStatus 메서드의 VSPackage 구현에 의해 표시되거나VisibilityConstraints
섹션의 특정 UI 컨텍스트와 연결되지 않는 한 IDE에 표시되지 않습니다.성공적으로 배치된 명령도 표시되지 않을 수 있습니다. 이는 VSPackage가 구현했거나 구현하지 않은 인터페이스에 따라 IDE가 일부 명령을 자동으로 숨기거나 표시하기 때문입니다. 예를 들어 VSPackage의 일부 빌드 인터페이스 구현으로 인해 빌드 관련 메뉴 항목이 자동으로 표시됩니다.
UI 요소의 정의에
CommandWellOnly
플래그를 적용하면 사용자 지정을 통해서만 명령을 추가할 수 있습니다.명령은 특정 UI 컨텍스트에서만 사용할 수 있습니다. 예를 들어 IDE가 디자인 보기에 있을 때 대화 상자가 표시되는 경우에만 사용할 수 있습니다.
특정 UI 요소가 IDE에 표시되도록 하려면 하나 이상의 인터페이스를 구현하거나 일부 코드를 작성해야 합니다.