Server-Side UI 자동화 공급자 구현

메모

이 설명서는 System.Windows.Automation 네임스페이스에 정의된 관리되는 UI 자동화 클래스를 사용하려는 .NET Framework 개발자를 위한 것입니다. UI 자동화에 대한 최신 정보는 Windows Automation API: UI 자동화를 참조하세요.

이 섹션에서는 사용자 지정 컨트롤에 대한 서버 쪽 UI 자동화 공급자를 구현하는 방법을 설명합니다.

WPF(Windows Presentation Foundation) 요소 및 비 WPF 요소(예: Windows Forms용으로 설계된 요소)에 대한 구현은 근본적으로 다릅니다. WPF 요소는 에서 파생된 AutomationPeer클래스를 통해 UI 자동화를 지원합니다. 비 WPF 요소는 공급자 인터페이스의 구현을 통해 지원을 제공합니다.

보안 고려사항

공급자는 부분 신뢰 환경에서 작업할 수 있도록 작성해야 합니다. UIAutomationClient.dll 부분 신뢰에서 실행되도록 구성되지 않았으므로 공급자 코드는 해당 어셈블리를 참조해서는 안 됩니다. 이 경우 코드는 완전 신뢰 환경에서 실행될 수 있지만 부분 신뢰 환경에서는 실패할 수 있습니다.

특히 AutomationElement 같은 UIAutomationClient.dll 클래스의 필드를 사용하지 마세요. 대신 UIAutomationTypes.dll클래스에서 해당하는 필드를 사용합니다(예: AutomationElementIdentifiers.).

Windows Presentation Foundation 요소별 공급자 구현

이 항목에 대한 자세한 내용은 WPF 사용자 지정 컨트롤의 UI 자동화를 참조하세요.

비 WPF 요소별 공급자 구현

WPF 프레임워크의 일부가 아니지만 관리 코드로 작성된 사용자 지정 컨트롤(대부분 Windows Forms 컨트롤)은 인터페이스를 구현하여 UI 자동화를 지원합니다. 모든 요소는 다음 섹션의 첫 번째 테이블에 나열된 인터페이스 중 하나 이상을 구현해야 합니다. 또한 요소가 하나 이상의 컨트롤 패턴을 지원하는 경우 각 컨트롤 패턴에 적절한 인터페이스를 구현해야 합니다.

UI 자동화 공급자 프로젝트는 다음 어셈블리를 참조해야 합니다.

  • UIAutomationProviders.dll

  • UIAutomationTypes.dll

  • WindowsBase.dll

공급자 인터페이스

모든 UI 자동화 공급자는 다음 인터페이스 중 하나를 구현해야 합니다.

인터페이스 설명
IRawElementProviderSimple 컨트롤 패턴 및 속성에 대한 지원을 포함하여 창에서 호스트되는 간단한 컨트롤에 대한 기능을 제공합니다.
IRawElementProviderFragment IRawElementProviderSimple에서 상속됩니다. 조각 내 탐색, 포커스 설정 및 요소의 경계 사각형 반환을 포함하여 복잡한 컨트롤의 요소에 대한 기능을 추가합니다.
IRawElementProviderFragmentRoot IRawElementProviderFragment에서 상속됩니다. 지정된 좌표에서 자식 요소를 찾고 전체 컨트롤의 포커스 상태를 설정하는 등 복잡한 컨트롤의 루트 요소에 대한 기능을 추가합니다.

다음 인터페이스는 추가된 기능을 제공하지만 구현할 필요는 없습니다.

인터페이스 설명
IRawElementProviderAdviseEvents 공급자가 이벤트에 대한 요청을 추적할 수 있도록 합니다.
IRawElementProviderHwndOverride 조각의 UI 자동화 트리 내에서 창 기반 요소의 위치를 변경할 수 있습니다.

네임스페이 System.Windows.Automation.Provider 스의 다른 모든 인터페이스는 컨트롤 패턴 지원을 위한 것입니다.

비 WPF 공급자에 대한 요구 사항

UI 자동화와 통신하려면 컨트롤이 다음과 같은 주요 기능 영역을 구현해야 합니다.

기능성 Implementation
공급자를 UI 자동화에 노출 제어 창으로 전송된 WM_GETOBJECT 메시지에 대한 응답으로 구현하는 개체(또는 파생 인터페이스)를 반환합니다 IRawElementProviderSimple . 조각의 경우 프래그먼트 루트의 프로바이더여야 합니다.
속성 값 제공 GetPropertyValue를 구현하여 값을 제공하거나 재정의합니다.
클라이언트가 컨트롤과 상호 작용할 수 있도록 설정 와 같은 IInvokeProvider컨트롤 패턴을 지원하는 인터페이스를 구현합니다. 당신의 구현에서 GetPatternProvider 패턴 공급자를 반환합니다.
이벤트 발생시키기 클라이언트가 수신 대기할 수 있는 이벤트를 발생시키는 정적 메서드 AutomationInteropProvider 중 하나를 호출합니다.
조각 내에서 탐색 및 포커스를 활성화 분할된 부분 내의 각 요소에 대해 IRawElementProviderFragment을 구현합니다. (조각의 일부가 아닌 요소에는 필요하지 않습니다.)
조각에서 자식 요소를 포커싱 및 위치 지정을 가능하게 함 IRawElementProviderFragmentRoot를 구현해야 합니다. 조각 루트가 아닌 요소에는 필요하지 않습니다.

비-WPF 공급자의 속성 값

사용자 지정 컨트롤에 대한 UI 자동화 공급자는 자동화 시스템뿐만 아니라 클라이언트 애플리케이션에서 사용할 수 있는 특정 속성을 지원해야 합니다. Windows(HWND)에서 호스트되는 요소의 경우 UI 자동화는 기본 창 공급자에서 일부 속성을 검색할 수 있지만 사용자 지정 공급자에서 다른 속성을 가져와야 합니다.

HWND 기반 컨트롤 공급자는 일반적으로 다음 속성을 제공할 필요가 없습니다(필드 값으로 식별됨).

메모

RuntimeIdProperty 창에서 호스트되는 간단한 요소 또는 조각 루트의 값은 창에서 가져옵니다. 그러나 루트 아래의 조각 요소(예: 목록 상자의 목록 항목)는 자체 식별자를 제공해야 합니다. 자세한 내용은 GetRuntimeId를 참조하세요.

IsKeyboardFocusableProperty Windows Forms 컨트롤에서 호스트되는 공급자에 대해 반환되어야 합니다. 이 경우 기본 창 공급자가 올바른 값을 검색할 수 없습니다.

NameProperty 일반적으로 호스트 공급자가 제공합니다. 예를 들어 사용자 지정 컨트롤에서 Control파생된 경우 이름은 컨트롤의 Text 속성에서 파생됩니다.

예제 코드는 UI 자동화 공급자의 반환 속성을 참조하세요.

비 WPF 공급자 내의 이벤트

UI 자동화 공급자는 클라이언트 애플리케이션에 UI 상태의 변경 내용을 알리는 이벤트를 발생시켜야 합니다. 이벤트를 발생시키는 데 사용되는 메서드는 다음과 같습니다.

메서드 설명
RaiseAutomationEvent 다양한 이벤트를 발생시키며, 여기에는 컨트롤 패턴에 의해 트리거되는 이벤트도 포함됩니다.
RaiseAutomationPropertyChangedEvent UI 자동화 속성이 변경되면 이벤트를 발생합니다.
RaiseStructureChangedEvent UI 자동화 트리의 구조가 변경되면 이벤트를 발생합니다. 예를 들어 요소를 제거하거나 추가합니다.

이벤트의 목적은 UI 자동화 시스템 자체에 의해 활동이 트리거되는지 여부에 관계없이 UI(사용자 인터페이스)에서 발생한 작업을 클라이언트에 알리는 것입니다. 컨트롤이 직접 사용자 입력이나 클라이언트 애플리케이션이 Invoke을 호출하여 실행될 때마다 InvokedEvent에 의해 식별되는 이벤트가 발생해야 합니다.

성능을 최적화하기 위해, 공급자는 수신하도록 등록된 클라이언트 애플리케이션이 없는 경우 이벤트를 선택적으로 발생시키거나 전혀 발생시키지 않을 수 있습니다. 다음 메서드는 최적화에 사용됩니다.

메서드 설명
ClientsAreListening 이 정적 속성은 클라이언트 애플리케이션이 UI 자동화 이벤트를 구독했는지 여부를 지정합니다.
IRawElementProviderAdviseEvents 공급자가 조각 루트에서 이 인터페이스를 구현하면 클라이언트가 조각의 이벤트에 대한 이벤트 처리기를 등록 및 등록 취소할 때 이를 알 수 있습니다.

비 WPF 공급자 탐색

창에서 호스트되는 사용자 지정 단추(HWND)와 같은 간단한 컨트롤에 대한 공급자는 UI 자동화 트리 내에서 탐색을 지원할 필요가 없습니다. 요소에 대한 탐색은 호스트 창의 기본 공급자에 의해 처리되며, 이 창은 구현 HostRawElementProvider에 지정됩니다. 그러나 복잡한 사용자 지정 컨트롤에 대한 공급자를 구현하는 경우 조각의 루트 노드와 해당 하위 노드 간 및 형제 노드 간 탐색을 지원해야 합니다.

메모

루트가 아닌 조각의 요소는 HostRawElementProvider에서 null 참조를 반환해야 합니다. 이는 이들 요소가 창에 직접 호스트되지 않으며, 기본 공급자가 이들 요소로의 탐색을 지원할 수 없기 때문입니다.

조각의 구조는 구현에 따라 결정됩니다 Navigate. 각 조각에서 가능한 각 방향에 대해 이 메서드는 해당 방향으로 요소에 대한 공급자 개체를 반환합니다. 해당 방향에 요소가 없으면 메서드는 참조를 반환합니다 null .

조각 루트는 자식 요소에 대한 탐색만 지원합니다. 예를 들어, 리스트 상자는 방향이 FirstChild일 때 목록의 첫 번째 항목을 반환하고, 방향이 LastChild일 때 마지막 항목을 반환합니다. 조각 루트는 부모 또는 형제에 대한 탐색을 지원하지 않습니다. 호스트 창 공급자가 처리합니다.

루트가 아닌 프래그먼트의 요소는 부모, 형제 및 자식에 대한 탐색을 지원해야 합니다.

WPF가 아닌 공급자 재구성

팝업 창은 실제로 최상위 창이므로 기본적으로 데스크톱의 자식으로 UI 자동화 트리에 표시됩니다. 그러나 대부분의 경우 팝업 창은 논리적으로 다른 컨트롤의 자식입니다. 예를 들어 콤보 상자의 드롭다운 리스트는 논리적으로 콤보 상자의 자식입니다. 마찬가지로 메뉴 팝업 창은 논리적으로 메뉴의 자식입니다. UI 자동화는 연결된 컨트롤의 자식으로 표시되도록 팝업 창을 재지정할 수 있도록 지원합니다.

팝업 창을 재분석하려면:

  1. 팝업 창에 대한 공급자를 만듭니다. 이렇게 하려면 팝업 창의 클래스를 미리 알려야 합니다.

  2. 해당 팝업에 대해 평소와 같이 모든 속성과 패턴을 구현합니다( 마치 자체적으로 컨트롤인 것처럼).

  3. 속성을 구현하여 HostRawElementProvider이 팝업 창의 창 핸들인 매개 변수를 받아 HostProviderFromHandle에서 가져온 값을 반환하도록 합니다.

  4. 팝업 창과 그 부모에 대해 Navigate를 구현하여 논리적 부모에서 논리적 자식 및 형제 노드 간에 내비게이션이 제대로 처리되도록 합니다.

UI 자동화가 팝업 창을 탐지하면 탐색이 기본 설정을 재정의하고 있음을 인식하여, 데스크톱의 하위 요소로 발견될 때 팝업 창을 무시합니다. 대신 노드는 조각을 통해서만 연결할 수 있습니다.

클래스에 상관없이 창을 호스트할 수 있는 경우에 재구성은 적합하지 않습니다. 예를 들어, rebar는 해당 밴드에서 모든 유형의 HWND를 호스트할 수 있습니다. 이러한 경우를 처리하기 위해 UI 자동화는 다음 섹션에 설명된 대로 대체 형태의 HWND 재배치를 지원합니다.

비 WPF 공급자 위치 변경

UI 자동화 조각에는 각각 창(HWND)에 포함된 두 개 이상의 요소가 포함될 수 있습니다. 각 HWND에는 HWND를 포함하는 HWND의 자식으로 간주하는 자체 기본 공급자가 있으므로 UI 자동화 트리는 기본적으로 조각의 HWND를 부모 창의 자식으로 표시합니다. 대부분의 경우 이 동작은 바람직한 동작이지만 UI의 논리적 구조와 일치하지 않으므로 혼동이 발생할 수 있습니다.

좋은 예는 강철막대 제어입니다. 리바에는 밴드가 포함되며, 각 밴드에는 도구 모음, 편집 상자 또는 콤보 상자와 같은 HWND 기반 컨트롤이 포함될 수 있습니다. Rebar HWND의 기본 윈도우 제공자는 밴드 컨트롤 HWND를 자식으로 인식하고, 리바 제공자는 밴드를 자식으로 봅니다. HWND 공급자와 리바 공급자가 함께 작업하고 자식을 결합하기 때문에 밴드와 HWND 기반 컨트롤은 모두 리바의 자식으로 표시됩니다. 그러나 논리적으로는 밴드만 rebar의 자식으로 표시되어야 하며 각 밴드 공급자는 포함된 컨트롤에 대한 기본 HWND 공급자와 결합되어야 합니다.

이를 수행하기 위해 리바에 대한 프래그먼트 루트 제공자는 밴드를 나타내는 자식 컴포넌트 집합을 노출합니다. 각 밴드에는 속성 및 패턴을 노출할 수 있는 단일 공급자가 있습니다. 해당 구현에서, 밴드 공급자는 HostRawElementProvider를 구현할 때, 컨트롤의 창 핸들을 HostProviderFromHandle 호출에 전달하여 가져오는 컨트롤 HWND에 대한 기본 창 공급자를 반환합니다. 마지막으로, rebar에 대한 프래그먼트 루트 공급자는 인터페이스 IRawElementProviderHwndOverride를 구현하며, GetOverrideProviderForHwnd에서는 지정된 HWND에 포함된 컨트롤에 대한 적절한 밴드 공급자를 반환합니다.

참고하십시오