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

[소프트웨어 접근성] UI 자동화 요소 탐색기 만들기 실습 - 핵심 클래스 UISearcher 구현

언제나휴일 2016. 5. 5. 18:46
반응형

UI 자동화 요소 탐색기 만들기 실습 - 핵심 클래스 UISearcher 구현


[그림] 작성할 UI 자동화 요소 탐색기


 이번에는 메인 폼에서 사용자의 명령을 받았을 때 실제 작업을 처리하는 클래스를 정의합시다. 클래스 이름은 UISearcher로 할게요.

public class UISearcher

 

 멤버 필드로 래핑한 자동화 요소가 있고 생성자에서 입력 받은 값으로 기억하게 합시다. UI 자동화 요소 탐색기에서는 특정 프로세스를 선택하였을 때 메인 창의 UI 자동화 요소를 기준으로 탐색할 것입니다. 이를 위해서 선택한 프로세스의 메인 창의 UI 자동화 요소를 래핑한 자동화 요소를 생성자의 입력 인자로 전달받아 멤버 필드 wae를 설정합니다.

WrapAE wae;

public UISearcher(WrapAE wae)

{

    this.wae = wae;

}

 초기에 프로세스를 선택하면 선택한 프로세스의 활성화 컨트롤 목록을 트리 뷰에 표시합니다. 이를 위해 활성화 컨트롤을 탐색해 TreeNode에 추가하여 반환하는 기능을 제공합시다.

public TreeNode FindEnalbleControl()

{

 먼저 멤버 필드 wae의 문자열을 입력 인자로 TreeNode를 생성합니다. 이 노드는 탐색한 자동화 요소를 보관한 TreeNode들로 구성한 트리의 루트 노드입니다.

    TreeNode tn = new TreeNode(wae.ToString());

 트리 뷰에서 특정 TreeNode를 선택하였을 때 자동화 요소 속성을 레이블에 표시할 것입니다. 이를 위해 트리 노드의 Tag에 래핑한 자동화 요소를 설정합니다.

    tn.Tag = wae;

 

 활성화 요소를 탐색하여 트리 노드에 매다는 기능을 호출합니다.

    WalkEnabledElements(wae, tn);

    return tn;

}

 

private void WalkEnabledElements(WrapAE wae, TreeNode tn)

{

 컨트롤 여부를 판단하는 속성이 참인 속성 컨디션 개체를 생성합니다.

    Condition cond1 = new PropertyCondition(

               AutomationElement.IsControlElementProperty, true);

 활성화 상태가 참인 속성 컨디션 개체를 생성합니다.

    Condition cond2 = new PropertyCondition(

                AutomationElement.IsEnabledProperty, true);

  두 개의 컨디션을 인자로 AndCondition 개체를 생성하여 이를 입력 인자로 TreeWalker 개체를 생성합니다.

    TreeWalker walker = new TreeWalker(new AndCondition(cond1, cond2));

 이제 생성한 TreeWalker 개체와 래핑한 자동화 요소, 트리 노드를 입력 인자로 탐색합니다.

    WalkTree(walker, wae, tn);

}

 

private void WalkTree(TreeWalker walker, WrapAE wae, TreeNode tn)

{

 입력 인자로 전달받은 자동화 요소의 첫번째 자식 요소를 찾습니다.

    AutomationElement child = walker.GetFirstChild(wae.AE);

 자식 자동화 요소가 null이 아니면 다음을 반복합니다.

    while (child != null)

    {

 자식 자동화 요소를 래핑한 개체를 생성합니다.

        WrapAE cae = new WrapAE(child);

 래핑한 개체의 문자열을 입력 인자로 트리 노드를 생성합니다.

        TreeNode ctn = tn.Nodes.Add(cae.ToString());

 트리 노드의 Tag 속성에 래핑한 개체를 설정합니다.

        ctn.Tag = cae;

 재귀적으로 WalkTree를 호출합니다.

        WalkTree(walker,cae, ctn);

 자식 개체의 형제 자동화 요소를 찾습니다.

        child = walker.GetNextSibling(child);

    }

}

 

 전체 자동화 요소 트리를 TreeNode로 만들어주는 기능과 전체 컨트롤 자동화 요소 트리 및 전체 컨텐츠 자동화 요소를 TreeNode로 만들어 주는 기능을 제공합시다.

public TreeNode FindRawTree()

{

 MakeNodeWithWalkTree 메서드의 입력 인자를 RawViewWalker를 전달합니다.

    return MakeNodeWithWalkTree(TreeWalker.RawViewWalker);

}

 

public TreeNode FindControlTree()

{

 MakeNodeWithWalkTree 메서드의 입력 인자를 ControlViewWalker를 전달합니다.

    return MakeNodeWithWalkTree(TreeWalker.ControlViewWalker);

}

public TreeNode FindContentTree()

{

 MakeNodeWithWalkTree 메서드의 입력 인자를 ContentViewWalker를 전달합니다.

    return MakeNodeWithWalkTree(TreeWalker.ContentViewWalker);

}

 

 MakeNodeWithWalkTree 메서드를 구현합시다.

private TreeNode MakeNodeWithWalkTree(TreeWalker walker)

{

 멤버 필드 wae 개체의 문자열을 입력 인자로 TreeNode를 생성합니다. TreeNode는 폼에서 트리 뷰의 루트 노드로 등록할 것입니다.

    TreeNode tn = new TreeNode(wae.ToString());

 트리 노드의 Tag wae 개체를 등록합니다.

    tn.Tag = wae;

 WalkTree를 이용하여 자동화 트리를 트리 노드를 구성합니다.

    WalkTree(walker, wae, tn);

    return tn;

}

 

 래핑한 자동화 요소의 첫번재 자식을 찾는 기능도 필요합니다. 탐색 기능들은 모두 TreeWalker 의 정적 멤버인 RawViewWalker 개체를 사용할게요.

public static WrapAE FindFirstChild(WrapAE wae)

{

    TreeWalker tw = TreeWalker.RawViewWalker;

 TreeWalker GetFirstChild 메서드로 첫번째 자식 요소를 찾습니다.

    AutomationElement ae = tw.GetFirstChild(wae.AE);

 찾지 못하면 입력 인자로 받은 개체를 반환합시다.

    if (ae == null){    return wae;    }

 찾았으면 찾은 자동화 요소를 래핑한 개체를 생성하여 반환합니다.

    return new WrapAE(ae);

}

 

 같은 원리로 나머지 탐색 기능을 구현합니다.

public static WrapAE FindNext(WrapAE wae)

{

    TreeWalker tw = TreeWalker.RawViewWalker;

    AutomationElement ae = tw.GetNextSibling(wae.AE);

    if (ae == null){    return wae;    }

    return new WrapAE(ae);

}

 

public static WrapAE FindPrev(WrapAE wae)

{

    TreeWalker tw = TreeWalker.RawViewWalker;

    AutomationElement ae = tw.GetPreviousSibling(wae.AE);

    if (ae == null){    return wae;    }

    return new WrapAE(ae);

}

 

public static WrapAE FindLastChild(WrapAE wae)

{

    TreeWalker tw = TreeWalker.RawViewWalker;

    AutomationElement ae = tw.GetLastChild(wae.AE);

    if (ae == null){    return wae;    }

    return new WrapAE(ae);

}

 

public static WrapAE FindParent(WrapAE wae)

{

    TreeWalker tw = TreeWalker.RawViewWalker;

    AutomationElement ae = tw.GetParent(wae.AE);

    if (ae == null){    return wae;    }

    return new WrapAE(ae);

}

 

using System.Windows.Automation;

using System.Windows.Forms;

namespace UsingTreeWalker

{

    public class UISearcher

    {

        WrapAE wae;

        public UISearcher(WrapAE wae)

        {

            this.wae = wae;

        }

        public TreeNode FindEnalbleControl()

        {

            TreeNode tn = new TreeNode(wae.ToString());

            tn.Tag = wae;

            WalkEnabledElements(wae, tn);

            return tn;

        }

        public TreeNode FindRawTree()

        {

            return MakeNodeWithWalkTree(TreeWalker.RawViewWalker);

        }

        public TreeNode FindControlTree()

        {

            return MakeNodeWithWalkTree(TreeWalker.ControlViewWalker);

        }

 

        public TreeNode FindContentTree()

        {

            return MakeNodeWithWalkTree(TreeWalker.ContentViewWalker);           

        }

        private TreeNode MakeNodeWithWalkTree(TreeWalker walker)

        {

            TreeNode tn = new TreeNode(wae.ToString());

            tn.Tag = wae;

            WalkTree(walker, wae, tn);

            return tn;

        }

        private void WalkTree(TreeWalker walker, WrapAE wae, TreeNode tn)

        {

            AutomationElement child = walker.GetFirstChild(wae.AE);

            while (child != null)

            {

                WrapAE cae = new WrapAE(child);

                TreeNode ctn = tn.Nodes.Add(cae.ToString());

                ctn.Tag = cae;

                WalkTree(walker,cae, ctn);

                child = walker.GetNextSibling(child);

            }

        }

        private void WalkEnabledElements(WrapAE wae, TreeNode tn)

        {

            Condition cond1 = new PropertyCondition(

                                  AutomationElement.IsControlElementProperty, true);

            Condition cond2 = new PropertyCondition(

                                  AutomationElement.IsEnabledProperty, true);

            TreeWalker walker = new TreeWalker(new AndCondition(cond1, cond2));

            WalkTree(walker, wae, tn);

        }

        public static WrapAE FindFirstChild(WrapAE wae)

        {

            TreeWalker tw = TreeWalker.RawViewWalker;

            AutomationElement ae = tw.GetFirstChild(wae.AE);

            if (ae == null){    return wae;    }

            return new WrapAE(ae);

        }

        public static WrapAE FindNext(WrapAE wae)

        {

            TreeWalker tw = TreeWalker.RawViewWalker;

            AutomationElement ae = tw.GetNextSibling(wae.AE);

            if (ae == null)

            {

                return wae;

            }

            return new WrapAE(ae);

        }

        public static WrapAE FindPrev(WrapAE wae)

        {

            TreeWalker tw = TreeWalker.RawViewWalker;

            AutomationElement ae = tw.GetPreviousSibling(wae.AE);

            if (ae == null)

            {

                return wae;

            }

            return new WrapAE(ae);

        }

        public static WrapAE FindLastChild(WrapAE wae)

        {

            TreeWalker tw = TreeWalker.RawViewWalker;

            AutomationElement ae = tw.GetLastChild(wae.AE);

            if (ae == null)

            {

                return wae;

            }

            return new WrapAE(ae);

        }

        public static WrapAE FindParent(WrapAE wae)

        {

            TreeWalker tw = TreeWalker.RawViewWalker;

            AutomationElement ae = tw.GetParent(wae.AE);

            if (ae == null)

            {

                return wae;

            }

            return new WrapAE(ae);

        }

    }

}

[소스] UISearcher.cs



[소프트웨어 접근성] UI 자동화 요소 탐색기 만들기 실습 - 컨트롤 배치


[소프트웨어 접근성] UI 자동화 요소 탐색기 만들기 실습- 프로세스, 자동화 요소 래퍼


[소프트웨어 접근성] UI 자동화 요소 탐색기 만들기 실습 - 메인 폼 구현


반응형