프로젝트에 InvokePatternForm을 추가하고 자식 컨트롤을 배치합니다. InvokePatternForm에는 선택한 평가 대상 프로젝트의 메인 창에 있는 Invoke 가능한 컨트롤들의 목록을 표시할 리스트 박스 컨트롤과 프로그램 방식으로 Invoke 할 수 있게 버튼 컨트롤과 Invoke 횟수를 표시할 텍스트 박스 컨트롤을 배치합니다.
번호 | 컨트롤 형식 | 컨트롤 이름 | 특이 사항 |
1 | ListBox | lbox_invokepattern | |
2 | Button | btn_invoke | |
3 | TextBox | tbox_inv_cnt | ReadOnly 속성을 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