다음을 통해 공유


동적 주석의 대안

UI 요소에 대해 사용자 지정된 IAccessible 지원을 제공하는 다른 방법이 있으며, 경우에 따라 올바른 솔루션입니다. 동적 주석 이전에는 이러한 대체 기술이 개발자가 사용할 수 있는 유일한 옵션이었습니다. 여기에는 모든 IAccessible 인터페이스 및 프로그래밍 기술 구현이 포함됩니다.

모든 IAccessible 인터페이스 구현

한 가지 다른 방법은 모든 IAccessible 인터페이스를 구현하는 것입니다. 이 방법은 사용자 지정 컨트롤 또는 근본적으로 다른 UI 요소에 필요한 경우가 많습니다. 그러나 개발 및 테스트 비용은 실제로 필요하지 않은 한 피해야 할 만큼 충분히 중요합니다. 단일 속성을 수정하는 것이 목표인 경우 비용을 정당화하기 어렵습니다.

프로그래밍 방식 기술

또 다른 옵션은 서브클래싱 및 래핑 기술을 사용하여 특정 속성에 대해 노출되는 정보를 수정하는 것입니다. 동적 주석이 대체하려는 기술입니다. 서브클래싱 및 래핑을 사용하여 단일 속성을 재정의하려면 개발자가 다음 단계를 수행해야 합니다.

  1. IAccessible 개체의 HWND를 서브클래스합니다.
  2. 올바른 IParam/OBJID 값에 대한 WM_GETOBJECT 메시지를 가로챌 수 있습니다.
  3. CallWndProc 콜백 함수를 사용하여 WM_GETOBJECT 메시지를 기본 클래스로 전달합니다. 0이 반환되면 CreateStdAccessibleObject를 호출합니다. 그렇지 않으면 반환된 값에서 LresultFromObject 를 호출하여 컨트롤의 네이티브 IAccessible 인터페이스 포인터를 가져옵니다.
  4. IAccessible을 구현하고 이전 단계에서 반환된 IAccessible 인터페이스 포인터를 래핑하는 래퍼 클래스를 만듭니다. 이 래퍼 클래스는 재정의할 메서드와 속성을 제외한 모든 메서드와 속성을 원래 IAccessible 인터페이스 포인터로 보냅니다. 여기에는 실제로 재정의된 수에 관계없이 모든 IAccessible 인터페이스의 21개 속성 및 메서드에 대한 전달 코드를 작성하는 작업이 포함됩니다.

또한 개발자는 다음 조건을 확인해야 합니다.

  • 재정의된 메서드 또는 속성은 필요한 자식 ID만 처리하고 다른 모든 ID를 원래 IAccessible 인터페이스 포인터로 전달해야 합니다.
  • 래핑은 원래 개체가 지원하는 경우에만 IEnumVARIANTIOleWindow 인터페이스를 전달해야 합니다.
  • 특히 다른 인터페이스가 지원되는 경우 참조 계산을 올바르게 처리해야 합니다.
  • IDispatch 반환 값은 특히 원래 IAccessible 인터페이스에 대한 포인터가 아니라 래퍼 인터페이스에 대한 인터페이스 포인터를 사용하여 호출되어야 하는 ITypeInfo::Invoke 메서드를 사용하여 올바르게 처리되어야 합니다.

이러한 기술은 하나 또는 두 개의 속성만 재정의해야 하는 경우에도 상당한 양의 작업이 필요합니다. 결과 코드의 대부분은 서브클래싱 및 래핑과 관련이 있으며, 실제로는 작은 부분만 재정의된 정보를 제공합니다.

그러나 이러한 기술이 필요한 시나리오가 있습니다. 예를 들어 자리 표시자 UI 요소를 만들기 위해 구조적으로 변경하는 경우 동적 주석 대신 이러한 기술을 사용해야 합니다.

레이블에서 파생된 이름 수정

편집 상자 컨트롤과 같은 일부 Microsoft Win32 일반 컨트롤은 거의 항상 레이블(리소스 파일의 LTEXT 항목) 또는 그룹 상자(리소스 파일의 GROUPBOX)와 함께 사용됩니다. Microsoft Active Accessibility는 해당 레이블에서 컨트롤의 이름 속성을 자동으로 파생합니다. 이러한 컨트롤의 경우 창 텍스트(이름 또는 ID 속성으로 Microsoft Visual Studio에 표시됨)는 무시됩니다. 일반적으로 자동 생성되고 설명이 거의 없으므로 이 텍스트는 무시됩니다. 예를 들면 "IDC_EDIT1"입니다.

애플리케이션의 사용자 인터페이스가 올바르게 설계되지 않은 경우 Microsoft Active Accessibility에서 이름을 올바르게 설정하지 못할 수 있습니다. 컨트롤과 연결하려면 레이블 또는 그룹 상자를 탭 순서의 동적 컨트롤 바로 앞에 배치해야 합니다.

Visual Studio에서 도구를 사용하거나(리소스 편집기가 열려 있을 때 서식 메뉴에서) 리소스 파일을 직접 편집하여 탭 순서를 변경할 수 있습니다.

다음 예제에서는 두 개의 레이블이 지정된 편집 상자가 포함된 대화 상자에 대한 리소스 파일의 설명을 보여 줍니다.

IDD_INPUTNAME DIALOGEX 22, 17, 312, 118
STYLE DS_SETFONT | DS_MODALFRAME | WS_CAPTION | WS_SYSMENU
CAPTION "Enter your name"
FONT 8, "System", 0, 0, 0x0
BEGIN
    DEFPUSHBUTTON   "OK",IDOK,179,35,30,11,WS_GROUP
    LTEXT           "First Name:",IDC_STATIC,8,16,43,8
    LTEXT           "Last Name:",IDC_STATIC,8,33,43,8
    EDITTEXT        IDC_EDITFIRSTNAME,53,15,120,12,ES_AUTOHSCROLL
    EDITTEXT        IDC_EDITLASTNAME,53,34,120,12,ES_AUTOHSCROLL
END

이 예제에서는 레이블 및 컨트롤이 올바른 탭 순서로 나열되지 않습니다. 따라서 Microsoft Active Accessibility는 이름 편집 상자에 이름 "성"을 할당하고 성 편집 상자에 이름은 전혀 할당하지 않습니다.

다음 예제에서는 올바른 리소스 목록을 보여 줍니다. 또한 바로 가기 키가 레이블에 지정되었습니다.

IDD_INPUTNAME DIALOGEX 22, 17, 312, 118
STYLE DS_SETFONT | DS_MODALFRAME | WS_CAPTION | WS_SYSMENU
CAPTION "Enter your name"
FONT 8, "System", 0, 0, 0x0
BEGIN
    LTEXT           "&First Name:",IDC_STATIC,8,16,43,8
    EDITTEXT        IDC_EDITFIRSTNAME,53,15,120,12,ES_AUTOHSCROLL
    LTEXT           "&Last Name:",IDC_STATIC,8,33,43,8
    EDITTEXT        IDC_EDITLASTNAME,53,34,120,12,ES_AUTOHSCROLL
    DEFPUSHBUTTON   "OK",IDOK,179,35,30,11,WS_GROUP
END

컨트롤에 트랙바의 최소값 및 최대값과 같은 보조 레이블이 있는 경우 이러한 레이블은 탭 순서로 컨트롤 다음에 배치되어야 합니다. 컨트롤의 기본 레이블은 컨트롤 자체 바로 앞에 나타나야 합니다.

레이블이 없는 컨트롤 명명

모든 컨트롤에 대해 표시되는 레이블이 항상 가능하거나 바람직하지는 않습니다. 그러나 보이지 않는 레이블을 추가하여 컨트롤의 이름을 계속 제공할 수 있습니다. 언제나처럼 보이지 않는 레이블은 탭 순서에서 컨트롤 바로 앞에 와야 합니다.

Microsoft Visual Studio .NET에서 리소스 편집기를 사용하는 경우 Visible 속성을 False로 설정할 수 있습니다. 리소스 파일(.rc)을 편집할 때 레이블을 보이지 않게 하려면 다음 예제와 같이 NOT WS_VISIBLE 또는 레이블 컨트롤의 스타일 부분에 추가합니다.

    LTEXT           "&FullName:",IDC_STATIC,111,23,44,8,NOT WS_VISIBLE

레이블이 보이지 않더라도 지정된 바로 가기 키가 작동합니다.