6) InvokePatternForm

프로젝트에 InvokePatternForm을 추가하고 자식 컨트롤을 배치합니다. InvokePatternForm에는 선택한 평가 대상 프로젝트의 메인 창에 있는 Invoke 가능한 컨트롤들의 목록을 표시할 리스트 박스 컨트롤과 프로그램 방식으로 Invoke 할 수 있게 버튼 컨트롤과 Invoke 횟수를 표시할 텍스트 박스 컨트롤을 배치합니다.

[그림 10.14] InvokePatternForm의 자식 컨트롤 배치
[그림 10.14] InvokePatternForm의 자식 컨트롤 배치
번호컨트롤 형식컨트롤 이름특이 사항
1ListBoxlbox_invokepattern 
2Buttonbtn_invoke 
3TextBoxtbox_inv_cntReadOnly 속성을 True로 설정

[표 10.6] InvokePatternForm의 자식 컨트롤

InvokePattern의 Invoke 이벤트를 구독하여 Invoke 이벤트 횟수를 표시할 것입니다. 이를 위해 자동화 이벤트 핸들러 멤버를 선언합니다.

AutomationEventHandler handler;

Invoke  횟수를 기억할 멤버와 루트 요소와 매핑한 EHAutoElem 개체를 위한 멤버도 선언합니다.

int inv_cnt;
EHAutoElem root_eae;

생성자에서는 루트 요소와 매핑한 EHAutoElem 개체를 받게 수정하고 멤버 필드에 대입합니다.

public InvokePatternForm(EHAutoElem root_eae)
{
    InitializeComponent();
    this.root_eae = root_eae;
}

폼의 Load 이벤트 핸들러를 등록합니다.

private void InvokePatternForm_Load(object sender, EventArgs e)
{

자동화 이벤트 핸들러를 생성합니다.

    handler = new AutomationEventHandler(OnInvoke);

InvokePattern 중에 사용 가능한 자동화 요소를 탐색합니다.

   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));
    }
}
private void OnInvoke(object src, AutomationEventArgs e)
{
    try
    {

src를 AutomationElement 형식으로 참조합니다.

         AutomationElement se = src as AutomationElement;
    }
    catch (ElementNotAvailableException){    return;    }

이벤트 ID가 InvokedEvent일 때 Invoke 카운터를 증가하여 표시하는 메서드를 호출합니다.

    if (e.EventId == InvokePattern.InvokedEvent)
    {
        AddInvCnt();
    }
}

크로스 스레드 문제를 해결하기 위한 대리자를 정의합시다.

delegate void SetInvCntDele();
private void AddInvCnt()
{

크로스 문제를 해결합니다.

    if (this.InvokeRequired)
    {
        SetInvCntDele d = new SetInvCntDele(AddInvCnt);
        this.Invoke(d,null);
    }

Invoke 횟수를 1 증가한 후에 화면에 표시합니다.

    else
    {
        inv_cnt++;
        tbox_inv_cnt.Text = inv_cnt.ToString();
    }
}

Invoke 버튼 클릭 이벤트 핸들러를 등록하세요.

private void btn_invoke_Click(object sender, EventArgs e)
{

선택한 요소를 구합니다. 이 부분은 별도의 메서드로 정의합시다.

    EHAutoElem eae = SelectEHAutoElem();
    if(eae != null)
    {

InvokePattern 개체를 구하여 Invoke 메서드를 호출합니다.

        InvokePattern invoke_pattern=eae.GetPattern(ENUM_CONTROL.INVOKE) as InvokePattern;
        if (invoke_pattern != null){    invoke_pattern.Invoke();    }
    }
}
EHAutoElem SelectEHAutoElem()
{

리스트 박스에 선택 항목이 없으면 null을 반환하고 있으면 EHAutoElem 형식을 참조하여 반환합니다.

    if (lbox_invokepattern.SelectedIndex == -1){    return null;    }
    return lbox_invokepattern.SelectedItem as EHAutoElem;
}

리스트 박스의 SelectedIndexChanged 이벤트 핸들러를 등록하세요.

private void lbox_invokepattern_SelectedIndexChanged(object sender, EventArgs e)
{

선택 항목이 없으면 이벤트 핸들러를 종료합니다.

    if (lbox_invokepattern.SelectedIndex == -1){    return;    }

선택한 자동화 요소를 래핑한 EHAutoElem 개체를 구하여 선택 개체로 설정합니다. 선택 개체로 설장하는 부분은 SelectInvokePattern 메서드를 만들어 사용합니다.

    EHAutoElem eae = SelectEHAutoElem();
    SelectInvokePattern(eae);
}
void SelectInvokePattern(EHAutoElem eae)
{

핸들러가 있으면 자동화 이벤트 핸들러를 해제합니다.

    if (handler != null)
    {
        Automation.RemoveAutomationEventHandler(InvokePattern.InvokedEvent,eae.AE, handler);
    }

Invoke 횟수를 0으로 리셋합니다.

    inv_cnt = 0;

선택한 자동화 요소의 InvokedEvent 발생을 구독할 자동화 이벤트 핸들러를 등록합니다.

    Automation.AddAutomationEventHandler(InvokePattern.InvokedEvent,
            eae.AE, TreeScope.Element, handler);

리셋한 Invoke 횟수를 화면에 표시합니다.

    tbox_inv_cnt.Text = inv_cnt.ToString();
}
using System;
using System.Windows.Automation;
using System.Windows.Forms;
namespace 접근성_평가_도우미
{
    public partial class InvokePatternForm : Form
    {
        AutomationEventHandler handler;
        int inv_cnt;
        EHAutoElem root_eae;
        public InvokePatternForm(EHAutoElem root_eae)
        {
            InitializeComponent();
            this.root_eae = root_eae;
        }
        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));
            }
        }
        private void OnInvoke(object src, AutomationEventArgs e)
        {   
            try
            {
                AutomationElement se = src as AutomationElement;
            }
            catch (ElementNotAvailableException){    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();
            } 
        }
        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();    }
            }
        }
        EHAutoElem SelectEHAutoElem()
        {
            if (lbox_invokepattern.SelectedIndex == -1){    return null;    }
            return lbox_invokepattern.SelectedItem as EHAutoElem;
        }
        private void lbox_invokepattern_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (lbox_invokepattern.SelectedIndex == -1){    return;    }
            EHAutoElem eae = SelectEHAutoElem();
            SelectInvokePattern(eae);
        }
        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();
        }
    }
}

[소스 10.14] InvokePatternForm.cs