기본 콘텐츠로 건너뛰기

[VSIX] IntelliCommand 패키지 분석 및 교정(?) - Non-EN Visual Studio 에 적용하기.

Visual Studio Extension 들 중에 쓸만한 것들이 많이 있다. 그리고 Visual Studio에는 다양한 기능을 제공하는 Shortcut 들이 존재하지만 일일이 기억하지 못하기 때문에 좋은 기능이 있어서 노가다(?)를 줄여줄 수 있음에도 몰라서 못 쓰는 경우가 많다.

IntelliCommand 라는 Visual Studio Extension은 Ctrl, Alt, Shift 등의 기능키를 누르고 있으면 (대략 2초 - 설정에서 변경 가능) 해당 기능키에 배정되어 있는 Shortcut 들을 보여주는 기능을 가지고 있다.

제작자도 언급한 것과 같이 영문 Visual Studio 에서만 동작을 하고 그외 언어로 설치된 Visual Studio에서는 (한글에 영문 Language Pack 설치 포함) 동작하지 않는다. 이왕 패키지를 구성하는 것을 테스트하고 있기 때문에 IntelliCommand를 한글버전에서도 동작할 수 있도록 분석과 교정을 해 보도록 한다.

Initialize Settings

패키지가 시작되면 다음과 같은 흐름을 가지고 처리가 진행된다.

  1. Get Shell Service (IVsShell)
  2. Shell의 속성이 변경되면 처리할 수 있도록 AdviseShellPropertyChanges 를 설정한다.
  3. 속성이 변경되면 InitializeCommandServices 를 수행한다.
    1. DTE2 서비스를 얻고, Command 출력을 위한 OutputWindowService를 생성한다. (디버그용으로 Visual Studio의 "출력 창"을 열고 정보를 출력하는 기능)
    2. DTE 개체에 대해서 다음과 같은 처리 서비스를 등록한다.
      1. CommandScopeService
      2. Dispatcher.CurrentDispatcher
      3. KeyboardListenerService
      4. IntelliCommandOptionsDialogPage
    3. Main Window 인 CommandsInfoWindow 를 등록하고 Show 한다.
      1. CommandsPresenter를 설정한다.
        1. CommandInfosLoader를 구성하고 Command 정보를 Load 한다.
          1. CommandContainer를 구성하고 DTE에 설정되어 있는 Commands 들을 OutputWindow 에 설정한다.
          2. Scope 과 Modifier에 따라서 Commands 를 구성한다.
        2. Keyboard Listener 서비스에서 KeyDown / KeyUp 에 대한 핸들러를 설정한다.
      2. Theme 를 갱신한다.
      3. Window 의 Open 상태를 false 로 설정하여 숨김 처리한다.

위의 처리가 수행되면 아래의 그림과 같이 ShellService 의 CommandContainer에는 DTE 에서 제공하는 각 Modifier / Scope 별로 Command 들의 정보가 설정되게 된다.


위의 결과로 봐서는 DTE 에 설정된 모든 Command 가 제대로 올라와서 관리되는 것으로 보인다. 그렇다면 Non-En Visual Studio에서 동작이 되지 않는다는 것은 결국 Ctrl, Alt, Shift 와 같은 Modifier Key를 제대로 처리하지 못하는 것으로 보이기 때문에 Key 처리 부분을 확인해 보도록 한다.

위의 Initialize Settings 에서 3.1.2 에 보면 KeyDown / KeyUp 처리 핸들러를 설정해 놓은 부분이 있다. 이 핸들러는 패키지가 구동된 후에 Visual Studio 에서 KeyDown / KeyUp 이 발생하면 처리되는 부분이다.

역시나 여기서 몇 가지 문제점이 발생하는 것을 확인할 수 있었다.

Problem #1 - WPF Keyboard.Modifiers == None

첫 번째는 Ctrl 키가 눌려졌을 때 제대로 ModifierKeys.Control 이 반환되지만, 그 이후에 다시 Ctrl 키를 누르면 ModifierKeys.None 이 반환된다.

이 부분은 좀 더 많은 것을 찾아보아야 하겠지만, 현재로서는 2초 이상 키를 누르고 있는 상태가 유지되는 것이므로 동작에 큰 문제는 주지 않는 상태라고 볼 수 있다.

Problem #2 - Resource Characters

Ctrl, Alt, Shift 에 대해서 ModifierKeys 를 조정해서라도 로직을 흐르게 하면 Modifier에 설정된 Command 정보를 필터링하는 부분이 존재한다. (위의 Initialize Settings 의 3.1.1.2)
그런데 여기서 Resource 문제가 발생한다. DTE 에서 올린 Command 의 Scope 은 "전역" 인데 실제 키 처리 상에서 검증하는 Scope (CurrentScopes) 에서는 "Global" 로 처리되고 있기 때문에 필터링이 제대로 되지 않는 상황이 발생한다.

따라서 Resource 를 한글 Resource 로 처리하거나 아니면 Command Load 시점에 한글 Resource를 영문으로 처리하면 제대로 동작하게 된다.

이번 테스트에서는 CommandContainer 클래스에서 눌려진 Modifier Key 조합에 따른 필터링 메서드에서 한글 Resource를 변경하여 처리되도록 수정하였다.


다음의 그림은 동작하고 있는 것을 보여주는 화면을 캡쳐한 것이다.


위의 그림은 Modifier로 Control 을 누르고 있는 상태에서 관련된 Command 들을 보여주고 있다.

간단하게 원인이 뭔지, 어떻게 하면 수정을 할 수 있을지에 대해서 알아본 것이기 때문에 코드를 전반적으로 조정하거 수정한 것은 아니다. 단지, Resource 처리 부분을 변경해서 실행이 가능하도록 하는 방법이 적용될 수 있다는 것을 확인한 것으로 이번 도전(?)은 완료~~ ^^

댓글