프로그래밍 기술/소프트웨어 접근성, UI 자동화

9. 접근성 평가 도구 만들기 - 18. InvokePatternForm

언제나휴일 2017. 12. 12. 13:48
반응형

9.3.6 InvokePatternForm



 이번에는 자동화 요소 컨트롤 패턴을 사용하는 방법을 이용하여 InvokePattern을 사용하는 InvokePatternForm을 작성합시다. 실제 접근성 평가 도구를 만든다면 다른 컨트롤 패턴들도 같은 방법으로 사용하는 것을 작성해야 하는데 비슷한 방법을 사용하므로 이 책에서는 다루지 않겠습니다.

 

[그림 9.15] InvokePatternForm 배치

[그림 9.15] InvokePatternForm 배치

 

번호

컨트롤 형식

컨트롤 이름

특이 사항

1

ListBox

lbox_invokepattern

 

2

Button

btn_invoke

 

3

TextBox

tbox_inv_cnt

ReadOnly 속성을 True로 설정

[ 9.6] InvokePatternForm의 자식 컨트롤 

 

 InvokePatternForm은 멤버 필드로 자동화 이벤트 핸들러와 클릭 개수를 기억할 멤버, 루트 요소를 참조할 멤버를 선언합니다.

AutomationEventHandler handler;

int inv_cnt;

EHAutoElem root_eae;

 

 생성자 메서드에서는 루트 요소를 입력 인자로 받아 멤버 필드에 설정합니다.

public InvokePatternForm(EHAutoElem root_eae)

{

    InitializeComponent();

    this.root_eae = root_eae;

}

 

 폼의 Load 이벤트 핸들러를 추가하세요. 그리고 이벤트 핸들러에서는 자동화 이벤트 핸들러 개체를 생성하고 IsInvokePattern이 유효한 속성을 참으로 하는 Condition 개체를 생성하여 Invoke 가능한 요소를 검색합니다. 그리고 이들을 lbox_invokepattern 컨트롤 아이템 컬렉션에 추가합니다. 자동화 이벤트 핸들러 개체를 생성한 이유는 이후에 특정 요소를 선택하였을 때 프로그램 방식으로 클릭 이벤트를 감지하기 위해서입니다.

private void InvokePatternForm_Load(object sender, EventArgs e)

{

    handler = new AutomationEventHandler(OnInvoke);

    Condition condition = new PropertyCondition(

                 AutomationElement.IsInvokePatternAvailableProperty,true);

    AutomationElementCollection aec = root_eae.AE.FindAll(

                 TreeScope.Subtree, condition);

    foreach (AutomationElement ae in aec)

    {

        lbox_invokepattern.Items.Add(new EHAutoElem(ae));

    }

}

 

 OnInvoke 메서드에서는 Invoke 개수를 늘리는 메서드를 호출합니다.

private void OnInvoke(object src, AutomationEventArgs e)

{

    AutomationElement sourceElement;

    try

    {

        sourceElement = src as AutomationElement;

    }

    catch{      return;         }

    if (e.EventId == InvokePattern.InvokedEvent)

    {

        AddInvCnt();

    }

}

delegate void SetInvCntDele();

private void AddInvCnt()

{

    if (this.InvokeRequired)

    {

        SetInvCntDele d = new SetInvCntDele(AddInvCnt);

        this.Invoke(d,null);

    }

    else

    {

        inv_cnt++;

        tbox_inv_cnt.Text = inv_cnt.ToString();

    }

}

 

 btn_invoke 클릭 이벤트 핸들러를 추가합시다. 그리고 이벤트 핸들러에서는 선택한 요소를 참조한 후 InvokePattern을 얻어와서 Invoke 메서드를 호출합니다. 이렇게 하면 프로그램 방식으로 InvokePattern 컨트롤을 Invoke 하는 것입니다.

private void btn_invoke_Click(object sender, EventArgs e)

{

    EHAutoElem eae = SelectEHAutoElem();

    if(eae != null)

    {

        InvokePattern invoke_pattern= eae.GetPattern(ENUM_CONTROL.INVOKE)

                                                 as InvokePattern;

        if (invoke_pattern != null)

        {

            invoke_pattern.Invoke();

        }

    }

}

 

 선택한 요소를 반환하는 메서드는 lbox_invokepattern의 선택한 요소가 있는지 확인한 후에 이를 EHAutoElem 형식으로 참조 연산하여 반환합니다.

EHAutoElem SelectEHAutoElem()

{

    if (lbox_invokepattern.SelectedIndex == -1)

    {

        return null;

    }

    return lbox_invokepattern.SelectedItem as EHAutoElem;

} 

 

 lbox_invokepattern 컨트롤의 선택 인덱스 변경 이벤트 핸들러를 추가하여 선택한 요소를 참조한 후 선택한 InvokePattern 컨트롤의 선택했을 때 해야 하는 작업을 수행하는 메서드를 호출합니다.

private void lbox_invokepattern_SelectedIndexChanged(object sender, EventArgs e)

{

    if (lbox_invokepattern.SelectedIndex == -1)

    {

        return;

    }

    EHAutoElem eae = SelectEHAutoElem();

    SelectInvokePattern(eae);

}

 

 InvokePattern 요소를 선택하면 이전에 등록한 InvokeEvent 핸들러가 있으면 이를 해제합니다. 그리고 Invoke 개수를 0으로 설정하고 InvokeEvent 핸들러를 등록합니다.

void SelectInvokePattern(EHAutoElem eae)

{

    if (handler != null)

    {

        Automation.RemoveAutomationEventHandler(InvokePattern.InvokedEvent,

                                                                   eae.AE,handler);

    }

    inv_cnt = 0;

    Automation.AddAutomationEventHandler(InvokePattern.InvokedEvent,

                eae.AE, TreeScope.Element,handler);

    tbox_inv_cnt.Text = inv_cnt.ToString();

}

 

반응형