아티클

접근성있는 Windows 데스크톱 앱 만들기 (Windows UIA를 중심으로) 1: 접근성있는 데스크톱 앱의 시작, Windows UIA란 무엇인가

엔비전스 접근성 2025-11-25 10:19:00

접근성있는 Windows 데스크톱 앱 만들기 (Windows UIA를 중심으로) 1: 접근성있는 데스크톱 앱의 시작, Windows UIA란 무엇인가?

연재를 시작하며

안녕하세요. 엔비전스 입니다.

모바일 애플리케이션의 급격한 성장과 웹 기술의 발전으로 많은 애플리케이션이 웹 기반으로 재탄생하고 있습니다. Slack, Notion, Discord와 같은 인기 애플리케이션들이 Electron이나 웹뷰를 활용해 크로스 플랫폼으로 개발되는 것을 쉽게 접할 수 있습니다. 이러한 변화 속에서 "전통적인 데스크톱 애플리케이션은 사라지는 것 아닌가?"라고 생각할 수 있습니다.

하지만 현실은 간단하지 않습니다. Visual Studio, Adobe Creative Suite, AutoCAD, 그리고 수많은 금융 및 기업용 애플리케이션들은 여전히 C++, C#과 같은 네이티브 언어로 개발되고 있습니다. 특히 금융권, 제조업, 의료 분야에서는 성능, 보안, 기존 시스템과의 통합성을 이유로 전통적인 데스크톱 애플리케이션이 핵심적인 역할을 하고 있는 경우가 많습니다. 이들 애플리케이션들은 단순히 유지보수만 되는 것이 아니라, 지속적으로 새로운 기능이 추가되고 현대화되고 있습니다.

그렇다면 전통적인 데스크톱 애플리케이션에도 접근성이 필요할까요? 답은 명백히 "그렇습니다"입니다. 업무 환경의 접근성과 다양성에 연결되는 문제이기 때문입니다. 접근성은 단순히 웹이나 모바일에만 국한된 이슈가 아니라, 모든 소프트웨어가 갖추어야 할 기본적인 요건입니다.

note: 실제 Electron으로 개발된 애플리케이션이 Windows 데스크톱에서 실행될 때 전혀 UIA와 무관하게 동작하지 않습니다. 웹앱 역시 이 환경에서는 뒤에서 살펴볼 UIA Provider 역할을 하기 때문입니다. 단순화라는 비판을 무릅쓰더라도 명확히 대비해 볼 수 있도록 Electron 기반의 웹앱과 전통적인 데스크톱 애플리케이션을 대비해 보았습니다.

그러나 안타깝게도 데스크톱 애플리케이션의 접근성 구현 방법은 웹이나 모바일 접근성만큼 널리 공유되지 않고 있습니다. WCAG(Web Content Accessibility Guidelines)나 WAI-ARIA에 대한 자료는 풍부하지만, Windows 데스크톱 앱에 접근성을 어떻게 구현하는지에 대한 자료는 마이크로소프트 공식 자료와 일부 개발 커뮤니티를 제외하면 찾아보기 어렵습니다. 특히, 국내에는 이런 자료가 더 부족한 편입니다. 이는 많은 개발자들이 "접근성을 구현하고 싶지만 어떻게 시작해야 할지 모르겠다"는 고민을 하게 만들 수 있습니다.

이 시리즈는 바로 그 간극을 메우기 위해 기획되었습니다. 총 다섯 개의 파트로 구성된 이 연재에서는 Windows 데스크톱 애플리케이션에 접근성을 구현하는 구체적인 방법을 다룹니다.

시리즈 구성:

  • 1부 (이번 글): Windows UIA의 개념과 접근성 원칙
  • 2부: C++와 WinUI 3를 이용한 접근성 구현
  • 3부: Win32를 이용한 접근성 구현
  • 4부: Python으로 접근성있는 앱 만들기
  • 5부: 접근성 검증 도구와 테스트 방법

이번 1부에서는 데스크톱 애플리케이션의 접근성 원칙을 살펴보고, Windows 접근성의 핵심인 Windows UI Automation (UIA)의 개념을 상세히 알아보겠습니다. 이 글을 읽고 나면 "왜 UIA가 필요한가?"와 "UIA가 어떻게 작동하는가?"를 명확히 이해할 수 있으리라 기대합니다.

데스크톱 앱의 접근성 원칙

데스크톱 애플리케이션의 접근성은 웹이나 모바일 앱과 근본적으로 동일한 원칙을 공유합니다. W3C가 제시한 POUR 원칙(Perceivable, Operable, Understandable, Robust)은 플랫폼에 관계없이 적용되는 보편적인 접근성 원칙입니다. 다만 구현 방식이 플랫폼마다 다를 뿐입니다.

데스크톱 앱에서 Windows UI Automation으로 구현할 수 있는 주요 접근성 원칙들을 살펴보겠습니다.

1. 인식 가능한 UI 요소 레이블

스크린 리더 사용자는 화면을 시각으로 보기 어렵기 때문에 각 버튼, 입력 필드, 체크박스가 무엇을 하는 요소인지 음성으로 듣거나 점자로 읽어야 합니다. 단순히 "버튼"이라고만 읽히면 그 버튼이 무엇을 하는지 알 수 없습니다.

나쁜 예시:

[스크린 리더 읽기] "버튼" → 사용자는 이 버튼이 무엇을 하는지 전혀 알 수 없습니다.

좋은 예시:

[스크린 리더 읽기] "제출 버튼" → 사용자는 이것이 양식을 제출하는 버튼임을 명확히 알 수 있습니다.

UIA에서는 이를 Name 속성으로 구현합니다. 모든 대화형 요소(버튼, 입력 필드, 체크박스 등)는 반드시 의미 있는 Name을 가져야 합니다. 이는 접근성의 가장 기본적이면서도 가장 중요한 요소입니다.

2. 적절한 컨트롤 타입 제공

익히 아시듯 스크린 리더는 UI 요소가 어떤 "종류"인지도 알려줍니다. 같은 텍스트 입력이라도 "한 줄 텍스트 상자"인지 "여러 줄 편집 영역"인지에 따라 사용자가 다르게 조작해야 하기 때문입니다.

UIA는 Control Type이라는 개념으로 이를 구현합니다. Button, Edit, CheckBox, RadioButton, ComboBox 등 표준화된 컨트롤 타입을 제공하며, 각 타입은 고유한 동작과 키보드 조작 방식을 가집니다.

예시:

  • Button: Space 또는 Enter로 실행
  • CheckBox: Space로 체크/해제
  • ComboBox: 방향키로 항목 탐색, 때에 따라 Enter로 선택

올바른 Control Type을 설정하면 스크린 리더 사용자가 직관적으로 해당 요소를 조작할 수 있습니다.

3. 키보드 접근성 보장

마우스를 사용할 수 없는 사용자들은 키보드만으로 모든 기능에 접근할 수 있어야 합니다. 이는 운동장애 사용자뿐만 아니라 스크린 리더 사용자에게도 필수적입니다(스크린 리더 사용자는 대부분 키보드로 조작).

필수 요구사항:

  • Tab 키 탐색: Tab 키로 모든 대화형 요소 간 이동 가능
  • 논리적인 포커스 순서: 시각적 배치와 일치하는 Tab 순서
  • 포커스 표시: 현재 포커스된 요소가 시각적으로 명확히 표시됨
  • 키보드 단축키: Space, Enter, 방향키 등으로 모든 동작 수행 가능

UIA에서는 IsKeyboardFocusable 속성과 Tab Index 설정을 통해 키보드 접근성을 구현합니다.

4. 상태 정보 제공

체크박스가 선택되었는지, 버튼이 비활성화되었는지, 토글이 켜져있는지 등의 상태 정보도 스크린 리더에 전달되어야 합니다.

예시:

[스크린 리더 읽기]

  • "알림 받기 체크박스, 선택됨"
  • "제출 버튼, 비활성화됨"
  • "다크 모드 토글 버튼, 켜짐"

UIA는 IsEnabledIsCheckedToggleState 같은 속성들로 상태를 표현하며, 각 Control Pattern이 적절한 상태 정보를 제공합니다.

5. 동적 콘텐츠 알림 (Live Regions)

사용자의 직접적인 조작 없이 화면의 내용이 변경될 때(예: 채팅 메시지 도착, 다운로드 완료, 오류 발생), 스크린 리더 사용자는 이를 알 수 없습니다. 이런 동적 변화를 자동으로 알려주는 메커니즘이 필요합니다.

웹에서는 aria-live 속성으로 구현하는데, Windows UIA도 이 개념을 채택하여 Live Regions를 제공합니다. UIA의 LiveSetting 속성과 LiveRegionChanged 이벤트를 통해 구현합니다.

예시 시나리오:

  • 파일 업로드 진행률: "80% 완료"
  • 오류 메시지 출현: "올바른 이메일 주소를 입력하세요"
  • 알림 도착: "새 메시지 3개"

6. 구조와 관계 표현

복잡한 UI에서는 요소 간의 관계를 명확히 전달해야 합니다. 예를 들어, 입력 필드와 그 레이블의 연결, 에러 메시지와 해당 입력 필드의 연결 등입니다.

UIA는 LabeledBy 속성으로 레이블 관계를, DescribedBy 속성으로 설명 텍스트와의 관계를 표현합니다. 또한 AutomationId를 통해 요소 간 연결고리를 만들 수 있습니다.

7. 텍스트 대안 제공

아이콘만 있는 버튼이나 이미지 버튼의 경우, 시각적으로는 의미가 명확하지만 스크린 리더로는 그 의미를 알 수 없습니다.

나쁜 예시:

[아이콘: 플로피디스크] > 스크린 리더: "버튼"

좋은 예시:

[아이콘: 플로피디스크] + Name: "저장" > 스크린 리더: "저장 버튼"

모든 아이콘 버튼, 이미지 버튼, 그래픽 요소에는 반드시 텍스트 대안(Name 또는 HelpText)을 제공해야 합니다.

이러한 접근성 원칙들은 웹의 WAI-ARIA나 모바일의 접근성 API와 개념적으로 동일합니다. 중요한 것은 Windows 데스크톱 환경에서 이를 어떻게 구현하느냐인데, 바로 앞서 계속 언급했던 Windows UI Automation이 핵심 역할을 수행합니다.

Windows 데스크톱 앱 접근성의 중심: Windows UIA

위에서 설명한 접근성 원칙들을 실제로 구현하려면 애플리케이션과 스크린 리더(또는 다른 보조 기술) 사이에 표준화된 통신 방법이 필요합니다. 만약 각 애플리케이션이 제각기 다른 방식으로 접근성 정보를 제공한다면, 스크린 리더 제작사는 모든 앱에 대응하는 것이 불가능할 것입니다.

이 문제를 해결하는 것이 바로 Windows UI Automation (UIA)입니다.

UIA의 역할

UIA는 애플리케이션과 보조 기술 사이의 중간 다리 역할을 합니다. 마치 웹의 HTML이 브라우저와 스크린 리더 사이의 표준 언어 역할을 하듯, UIA는 Windows 애플리케이션과 보조 기술 사이의 공통 언어입니다.

보조 기술, UIA, 애플리케이션 작동 방식:

보조 기술 (Assistive Technology)

  • NVDA (스크린 리더)
  • JAWS (스크린 리더)
  • Narrator (Windows 내장)
  • 화면 확대기
  • 음성 인식 소프트웨어

↓UIA Client API

Windows UI Automation Core

  • (UIAutomationCore.dll)
  • 정보 중개 및 변환
  • 이벤트 라우팅
  • 트리 구조 관리

UIA Provider API

애플리케이션

  • 버튼, 입력 필드 등 UI 요소
  • UIA Provider 구현
  • 접근성 정보 제공

이 구조를 명확히 이해하는 것이 중요한데요. 개발자는 UIA Provider를 구현하여 자신의 앱 UI 정보를 UIA에 제공하고, 스크린 리더 같은 보조 기술은 UIA Client를 통해 그 정보를 받아갑니다. 중간의 UIA Core가 양쪽을 연결하고 조율하는 역할을 합니다. UIA Provider 드엥 관한 상세한 내용은 "UIA 상세히 알아보기" 섹션에서 더 자세히 알아보겠습니다.

실제 동작 예시

사용자가 스크린 리더(예: NVDA)를 실행하고 여러분이 만든 앱의 "제출" 버튼에 포커스를 이동했다고 가정합니다.

단계별 동작:

  1. 사용자: Tab 키를 눌러 버튼으로 포커스 이동
  2. 애플리케이션: 버튼에 포커스가 가면서 UIA에 FocusChanged 이벤트 발생
  3. UIA Core: 포커스 이벤트를 감지하고 해당 요소의 정보 수집
  4. UIA Provider (앱 내부): 버튼의 정보 제공
    • Name: "제출"
    • ControlType: Button
    • IsEnabled: true
    • HelpText: "작성한 양식을 서버에 전송합니다"
  5. UIA Core: 수집한 정보를 UIA Client에 전달
  6. NVDA (UIA Client): 정보를 받아서 음성으로 출력
  7. 사용자: "제출 버튼. 작성한 양식을 서버에 전송합니다" 라고 들음

이 모든 과정이 빠른 시간 안에 일어나며, 개발자가 UIA Provider를 올바르게 구현했다면 자동으로 작동합니다.

UIA가 제공하는 핵심 개념들

UIA를 이해하기 위해 알아야 할 핵심 개념들이 있습니다. 자세한 내용은 뒤에서 다루지만, 먼저 큰 그림을 그려보겠습니다.

1. Automation Properties (속성)

  • 각 UI 요소의 특성을 표현
  • 예: Name, ControlType, IsEnabled, BoundingRectangle 등

2. Control Patterns (컨트롤 패턴)

  • UI 요소가 할 수 있는 "동작"을 표준화
  • 예: InvokePattern(실행), ValuePattern(값 변경), TogglePattern(토글) 등

3. Automation Events (이벤트)

  • UI 상태 변화를 보조 기술에 알림
  • 예: FocusChanged, PropertyChanged, LiveRegionChanged 등

4. Tree Structure (트리 구조)

  • UI 요소들의 계층 관계를 트리로 표현
  • 부모-자식 관계, 형제 관계 탐색 가능

이 네 가지 개념을 조합하면 복잡한 접근성 요구사항도 구현할 수 있습니다.

UIA는 왜 만들어졌나?

Windows UIA가 어떻게 작동하는지 더 깊게 이해하기 전에, 왜 이것이 만들어졌는지 그 역사적 맥락을 잠깐 살펴보겠습니다. UIA는 갑자기 등장한 것이 아니라, 기존 기술의 한계를 극복하기 위해 탄생했습니다.

MSAA: Windows 접근성의 시작

Windows 접근성의 역사는 1997년으로 거슬러 올라갑니다. Microsoft는 Windows 95용 플랫폼 애드온으로 Microsoft Active Accessibility (MSAA)를 출시했습니다. 이는 Windows 애플리케이션에 접근성을 제공하는 최초의 표준 API였습니다.

MSAA의 핵심은 IAccessible 인터페이스입니다. 애플리케이션은 이 인터페이스를 구현하여 각 UI 요소의 다음 정보를 제공했습니다:

  • Role (역할): 버튼인지, 텍스트 상자인지, 메뉴인지
  • Name (이름): 요소의 레이블
  • Value (값): 현재 값 (예: 텍스트 상자 내용)
  • State (상태): 선택됨, 비활성화됨 등

MSAA의 공헌:

  • Windows 접근성의 기반 마련
  • Internet Explorer, Microsoft Office 등 주요 애플리케이션 지원
  • 스크린 리더 개발 가속화 (JAWS, Window-Eyes 등)

MSAA의 한계

하지만 시간이 지나면서 MSAA의 근본적인 한계들이 드러났습니다.

1. 확장 불가능한 역할 모델

MSAA의 Role은 고정된 목록입니다. 1990년대 후반의 UI 요소들(버튼, 텍스트박스, 체크박스 등)에 최적화되어 있었기 때문에, 새로운 종류의 컨트롤이 등장하면 표현할 방법이 없었습니다.

문제 사례:

  • 리치 텍스트 에디터: 복잡한 서식과 이미지를 포함한 문서를 어떻게 표현할 것인가?
  • 트리 그리드: 트리뷰와 그리드를 결합한 컨트롤은?
  • 커스텀 슬라이더: 범위 선택, 다중 핸들을 가진 슬라이더는?

MSAA는 이런 새로운 UI 패턴을 표현할 수단이 없었습니다. IAccessible 인터페이스 자체를 수정할 수도 없었습니다(COM 인터페이스는 변경 불가).

2. 복잡한 탐색 모델

MSAA는 UI 요소들을 계층 구조로 표현하지만, 탐색 방법이 일관되지 않았습니다. 어떤 요소는 자식 요소를 IAccessible로 반환하고, 어떤 요소는 IEnumVARIANT 인터페이스로 반환하는 등 개발자와 보조 기술 모두에게 혼란을 주었습니다.

3. 텍스트 객체 모델 부재

MSAA의 Value 속성은 단순 문자열만 담을 수 있습니다. 서식이 있는 텍스트(굵기, 색상, 하이퍼링크 등)를 표현할 방법이 없었습니다. 이는 워드 프로세서 등의 복잡한 애플리케이션에서 까다로운 문제였습니다.

IAccessible2: IBM의 도전

MSAA의 한계를 인식한 IBM은 2006년 IAccessible2라는 대안을 제시했습니다. 이는 MSAA를 확장하는 방식으로, IAccessible 인터페이스를 상속받아 추가 기능을 제공했습니다.

IAccessible2의 특징:

  • 테이블, 하이퍼링크, 리치 텍스트 지원
  • 관계(relations) 표현 가능
  • Linux의 AT-SPI와 호환성 고려 (크로스 플랫폼)

채택 현황:

  • Firefox, Chrome이 채택
  • 현재 NVDA, JAWS가 웹 브라우저에서 사용
  • 오픈 표준으로 자리잡음

하지만 IAccessible2는 여전히 MSAA의 기본 구조 위에 세워진 것이기에 근본적인 설계 한계를 완전히 극복하지는 못했습니다.

Note : 오해를 방지하기 위해 첨언하자면 Chrome과 Firefox, Microsoft Edge 역시 현재 UIA를 가장 우선하여 지원합니다. IAccessible2는 보조 수단에 가깝습니다.

UIA의 탄생: 새로운 시작

이러한 배경 속에서 Microsoft는 2005년경 새로운 접근성 API를 설계하기 시작했고, 2006년 Windows Vista와 함께 UI Automation을 공식 출시했습니다.

UIA는 MSAA를 개선하는 것이 아니라 처음부터 다시 설계한 것입니다. 10년간 축적된 접근성 경험과 새로운 UI 패러다임을 반영하여 만들어졌습니다.

UIA가 MSAA의 한계를 극복한 방법

1. 확장 가능한 Control Patterns

UIA는 고정된 Role 대신 Control Patterns라는 개념을 도입했습니다. 이는 "이 요소가 무엇인가"보다 "이 요소가 무엇을 할 수 있는가"에 초점을 맞춥니다.

예시:

  • InvokePattern: 실행할 수 있음 (버튼, 링크 등)
  • ValuePattern: 값을 읽고 쓸 수 있음 (텍스트박스)
  • RangeValuePattern: 범위 내 값 조정 (슬라이더, 진행 바)
  • SelectionPattern: 항목 선택 (리스트박스, 콤보박스)
  • GridPattern: 테이블 탐색
  • TextPattern: 리치 텍스트 접근

새로운 UI 패턴이 등장하면 새로운 Control Pattern을 추가하면 됩니다. 기존 인터페이스를 수정할 필요가 없습니다.

2. 일관된 트리 구조와 탐색

앞선 서술로 짐작하신 분도 계시겟지만, UIA는 모든 UI를 일관된 트리 구조로 표현합니다. 데스크톱이 루트이고, 각 창이 자식이며, 창 내부의 요소들이 그 하위 자식입니다.

탐색 방향:

  • Parent: 부모 요소로
  • FirstChild / LastChild: 첫 번째/마지막 자식으로
  • NextSibling / PreviousSibling: 다음/이전 형제로

이 일관된 구조 덕분에 보조 기술은 어떤 앱이든 동일한 방식으로 탐색할 수 있습니다.

3. 강력한 텍스트 모델 (Text Pattern)

UIA의 TextPattern은 복잡한 서식 정보를 모두 제공합니다:

  • 폰트, 크기, 색상
  • 굵기, 기울임, 밑줄
  • 하이퍼링크
  • 이미지 삽입
  • 문단 정렬

이를 통해 워드 프로세서나 리치 텍스트 에디터도 완벽히 접근 가능하게 만들 수 있습니다.

4. Live Regions과 이벤트 시스템

UIA는 동적 콘텐츠를 위한 Live Regions 개념을 도입했습니다(웹의 aria-live와 동일한 개념). LiveRegionChanged 이벤트를 통해 실시간 업데이트를 스크린 리더에 알릴 수 있습니다.

설정 옵션:

  • Off: 알림 없음
  • Polite: 현재 읽기 완료 후 알림
  • Assertive: 즉시 알림 (중단)

5. 향상된 성능과 아키텍처

UIA는 클라이언트와 프로바이더 사이에 코어 서비스를 두어 다음을 제공합니다:

  • 고유한 Runtime ID 생성
  • 이벤트 라우팅 최적화
  • 캐싱 메커니즘
  • 프로세스 간 통신(IPC) 효율화

UIA와 MSAA의 공존

중요한 점은 UIA가 MSAA를 완전히 대체하지 않았다는 것입니다. Windows는 여전히 MSAA를 지원하며, UIA와 MSAA 사이에 브리지(Bridge)를 제공합니다.

브리지 동작:

  • MSAA-to-UIA Proxy: MSAA 앱을 UIA 클라이언트가 접근
  • UIA-to-MSAA Bridge: MSAA 클라이언트가 UIA 앱에 접근

이를 통해 오래된 앱과 새 보조 기술, 또는 새 앱과 오래된 보조 기술이 함께 작동할 수 있습니다.

UIA 상세히 알아보기

이제 UIA의 배경을 이해했으니, 본격적으로 UIA의 구성 요소를 자세히 살펴보겠습니다. 2부에서 실제 코드를 작성하기 전에 이 개념들을 확실히 이해해두면 구현이 훨씬 수월합니다.

UIA Provider와 Client

UIA는 크게 두 가지 역할로 나뉩니다.

UIA Provider (공급자):

  • 역할: 애플리케이션이 자신의 UI 정보를 제공
  • 구현 주체: 애플리케이션 개발자 (바로 여러분!)
  • 주요 작업:
    • UI 요소의 속성 제공 (Name, ControlType 등)
    • Control Patterns 구현
    • 이벤트 발생 (포커스 변경, 값 변경 등)

UIA Client (소비자):

  • 역할: 제공된 UI 정보를 받아서 활용
  • 구현 주체: 보조 기술 개발자 (NVDA, JAWS, Narrator 등)
  • 주요 작업:
    • UI 트리 탐색
    • 요소 속성 읽기
    • Control Pattern 메서드 호출
    • 이벤트 수신

애플리케이션 개발자의 경우 주로 Provider 측에 집중해야 합니다. 다행히 WinUI 3나 WPF 같은 현대적인 프레임워크는 대부분의 Provider 구현을 자동으로 해주므로, 우리는 속성만 설정하면 됩니다. 하지만 커스텀 컨트롤을 만들거나 Win32를 사용할 때는 직접 Provider를 구현해야 합니다.

Automation Properties: UI 요소의 특성

Automation Properties는 각 UI 요소의 "특성"을 표현합니다. 웹 개발자라면 HTML 요소의 attribute를 떠올리면 됩니다.

필수 속성:

속성 설명 예시
Name 요소의 레이블 "제출", "이름 입력", "약관 동의"
ControlType 요소의 종류 Button, Edit, CheckBox 등
IsKeyboardFocusable 키보드 포커스 가능 여부 true / false
IsEnabled 활성화 상태 true / false

권장 속성:

속성 설명 예시
AutomationId 고유 식별자 "submit_button", "name_input"
HelpText 추가 설명 "양식을 서버에 전송합니다"
BoundingRectangle 화면상 위치 {x, y, width, height}
LabeledBy 연결된 레이블 다른 요소 참조
LiveSetting 동적 콘텐츠 알림 수준 Off, Polite, Assertive

2부 예고: WinUI 3에서는 AutomationProperties.SetName(element, "제출")처럼 간단히 설정할 수 있습니다.

Control Patterns: 동작의 표준화

Control Patterns는 UIA의 가장 강력한 기능 중 하나입니다. "이 요소가 무엇을 할 수 있는가"를 표준화된 인터페이스로 표현합니다.

주요 Control Patterns:

InvokePattern (실행)

  • 용도: 클릭/실행 가능한 요소
  • 지원 컨트롤: Button, MenuItem, Hyperlink
  • 메서드Invoke() - 요소를 실행
  • 사용 예: 스크린 리더가 "제출 버튼에서 Enter를 누르면" Invoke() 호출

ValuePattern (값)

  • 용도: 값을 읽고 쓸 수 있는 요소
  • 지원 컨트롤: TextBox, PasswordBox
  • 속성Value (현재 값), IsReadOnly (읽기 전용 여부)
  • 사용 예: 스크린 리더가 입력 필드의 현재 값을 읽거나 새 값을 입력

TogglePattern (토글)

  • 용도: 켜기/끄기 상태를 가진 요소
  • 지원 컨트롤: CheckBox, ToggleButton
  • 속성ToggleState (Off, On, Indeterminate)
  • 메서드Toggle() - 상태 전환
  • 사용 예: 체크박스를 "선택됨" ↔ "선택 안 됨"으로 전환

RangeValuePattern (범위 값)

  • 용도: 특정 범위 내에서 값 조정
  • 지원 컨트롤: Slider, ProgressBar, Spinner
  • 속성ValueMinimumMaximumSmallChangeLargeChange
  • 사용 예: 슬라이더를 방향키로 조정

SelectionPattern (선택)

  • 용도: 항목 선택 컨테이너
  • 지원 컨트롤: ListBox, ComboBox, Menu
  • 속성CanSelectMultipleIsSelectionRequired
  • 메서드GetSelection() - 선택된 항목 가져오기

GridPattern (그리드)

  • 용도: 테이블 형태 데이터
  • 지원 컨트롤: DataGrid, Table
  • 속성RowCountColumnCount
  • 메서드GetItem(row, column) - 특정 셀 가져오기

하나의 요소가 여러 Pattern을 동시에 지원할 수 있습니다. 예를 들어, 편집 가능한 콤보박스는 ValuePattern, SelectionPattern, ExpandCollapsePattern을 모두 지원합니다.

Automation Events: 변화를 알리는 메커니즘

보조 기술은 UI의 변화를 실시간으로 알아야 합니다. 매 순간 모든 요소를 폴링(polling)하는 것은 비효율적이므로, UIA는 이벤트 기반 시스템을 제공합니다.

주요 이벤트:

AutomationFocusChanged

  • 발생 시점: 키보드 포커스가 다른 요소로 이동
  • 활용: 스크린 리더가 새로 포커스된 요소 정보를 읽음

PropertyChanged

  • 발생 시점: 요소의 속성이 변경됨
  • 예시: Name 변경, IsEnabled 변경, Value 변경
  • 활용: 동적으로 레이블이 바뀌거나 버튼이 활성화될 때 알림

StructureChanged

  • 발생 시점: UI 구조가 변경됨 (요소 추가/제거)
  • 예시: 리스트에 항목 추가, 다이얼로그 출현
  • 활용: 스크린 리더가 UI 트리 재구성

LiveRegionChanged

  • 발생 시점: Live Region의 내용이 변경됨
  • 활용: "다운로드 완료", "새 메시지 3개" 같은 알림 전달

Pattern-specific Events

  • InvokePattern.Invoked: 요소가 실행됨
  • Selection.Invalidated: 선택 항목이 무효화됨
  • Text.TextChanged: 텍스트 내용이 변경됨

UI Automation Tree: 계층 구조

UIA의 트리 구조는 다음과 같은데요. 이는 HTML DOM, Accessibility tree와 유사합니다.

트리 예시:

  • Desktop (루트)
    • Application Window (Visual Studio)
      • Menu Bar
        • File Menu
        • Edit Menu
        • View Menu
      • Tool Bar
        • Save Button
        • Build Button
        • Run Button
      • Code Editor
        • Line 1 (Text)
        • Line 2 (Text)
        • Line 3 (Text)
    • Application Window (Chrome)
      • ...

트리 뷰 종류:

  • Raw View: 모든 요소 포함 (개발/디버깅용)
  • Control View: 사용자가 상호작용하는 요소만 (일반 탐색)
  • Content View: 정보를 담은 요소만 (빠른 탐색)

보조 기술은 상황에 따라 적절한 뷰를 선택해 효율적으로 탐색합니다.

Automation Peer: 프레임워크의 중간 계층

WinUI 3, WPF 같은 XAML 프레임워크에서는 Automation Peer라는 중간 계층이 있습니다. 이는 XAML 컨트롤과 UIA Provider 사이의 어댑터 역할을 합니다.

장점:

  • 개발자는 Automation Peer만 구현하면 됨
  • 프레임워크가 UIA Provider의 복잡한 부분 처리
  • 더 높은 수준의 추상화 제공

2부에서 자세히: 커스텀 컨트롤을 만들 때 Automation Peer를 어떻게 구현하는지 코드로 보여드리겠습니다.

글을 맺으며

이번 1부에서는 Windows 데스크톱 애플리케이션의 접근성이 여전히 중요한 이유와, 이를 구현하기 위한 핵심 기술인 Windows UI Automation의 개념을 살펴보았습니다. MSAA라는 레거시 API의 한계를 극복하고자 탄생한 UIA는 확장 가능한 Control Patterns, 일관된 트리 구조, 강력한 이벤트 시스템을 통해 현대적인 UI의 접근성을 완벽히 구현할 수 있게 해줍니다.

지금까지 살펴본 내용—Automation Properties, Control Patterns, Events—은 모두 다음 파트들에서 실제 코드로 구현하게 될 기초 지식입니다. 개념이 복잡해 보일 수 있지만, 실제로 WinUI 3 같은 프레임워크를 사용하면 대부분 자동으로 처리되므로 걱정하지 않으셔도 됩니다.

그럼 다음 2부에서 C++와 WinUI 3를 사용하여 실제로 접근성있는 애플리케이션을 만들어보겠습니다. XAML에서 AutomationProperties를 설정하는 방법, 커스텀 컨트롤을 위한 Automation Peer 구현, Live Regions 활용, 그리고 NVDA로 직접 테스트하는 과정까지 단계별로 안내해드리겠습니다.

댓글 0
댓글을 작성하려면 해주세요.