첨부 실행 코드는 나눔고딕코딩 폰트를 사용합니다.
728x90
반응형
728x170

▶ MouseHelper.cs

using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Threading;

namespace TestProject
{
    /// <summary>
    /// 마우스 헬퍼
    /// </summary>
    public static class MouseHelper
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Import
        ////////////////////////////////////////////////////////////////////////////////////////// Static
        //////////////////////////////////////////////////////////////////////////////// Private

        #region 마우스 이벤트 발생시키기 - mouse_event(flag, deltaX, deltaY, data, extraInformation)

        /// <summary>
        /// 마우스 이벤트 발생시키기
        /// </summary>
        /// <param name="flag">플래그</param>
        /// <param name="deltaX">델타 X</param>
        /// <param name="deltaY">델타 Y</param>
        /// <param name="data">데이터</param>
        /// <param name="extraInformation">부가 정보</param>
        [DllImport("user32")]
        private static extern void mouse_event(int flag, int deltaX, int deltaY, int data, int extraInformation);

        #endregion
        #region 키보드 이벤트 발생시키기 - keybd_event(virtualKey, scanCode, flag, extraInformation)

        /// <summary>
        /// 키보드 이벤트 발생시키기
        /// </summary>
        /// <param name="virtualKey">가상 키</param>
        /// <param name="scanCode">스캔 코드</param>
        /// <param name="flag">플래그</param>
        /// <param name="extraInfo">부가 정보</param>
        [DllImport("user32")]
        private static extern void keybd_event(byte virtualKey, byte scanCode, int flag, int extraInformation);

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Field
        ////////////////////////////////////////////////////////////////////////////////////////// Private

        #region Field

        /// <summary>
        /// MOUSE_EVENT_LEFT_DOWN
        /// </summary>
        private const int MOUSE_EVENT_LEFT_DOWN = 0x0002;

        /// <summary>
        /// MOUSE_EVENT_LEFT_UP
        /// </summary>
        private const int MOUSE_EVENT_LEFT_UP = 0x0004;

        /// <summary>
        /// MOUSE_EVENT_RIGHT_DOWN
        /// </summary>
        private const int MOUSE_EVENT_RIGHT_DOWN = 0x0008;

        /// <summary>
        /// MOUSE_EVENT_RIGHT_UP
        /// </summary>
        private const int MOUSE_EVENT_RIGHT_UP = 0x00010;

        /// <summary>
        /// VK_LCONTROL
        /// </summary>
        private const int VK_LCONTROL = 0xA2;

        /// <summary>
        /// KEY_DOWN
        /// </summary>
        private const int KEY_DOWN = 0x0;

        /// <summary>
        /// EXTENDED_KEY
        /// </summary>
        private const int EXTENDED_KEY = 0x01;

        /// <summary>
        /// KEY_UP
        /// </summary>
        private const int KEY_UP = 0x02;

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Static
        //////////////////////////////////////////////////////////////////////////////// Public

        #region 마우스 왼쪽 버튼 클릭하기 - ClickMouseLeftButton(point)

        /// <summary>
        /// 마우스 왼쪽 버튼 클릭하기
        /// </summary>
        /// <param name="point">포인트</param>
        public static void ClickMouseLeftButton(Point point)
        {
            System.Windows.Forms.Cursor.Position = point;

            mouse_event(MOUSE_EVENT_LEFT_DOWN, 0, 0, 0, 0);
            mouse_event(MOUSE_EVENT_LEFT_UP  , 0, 0, 0, 0);

            Thread.Sleep(100);
        }

        #endregion
        #region 마우스 오른쪽 버튼 클릭하기 - ClickMouseRightButton(point)

        /// <summary>
        /// 마우스 오른쪽 버튼 클릭하기
        /// </summary>
        /// <param name="point">포인트</param>
        public static void ClickMouseRightButton(Point point)
        {
            System.Windows.Forms.Cursor.Position = point;

            mouse_event(MOUSE_EVENT_RIGHT_DOWN, 0, 0, 0, 0);
            mouse_event(MOUSE_EVENT_RIGHT_UP  , 0, 0, 0, 0);

            Thread.Sleep(100);
        }

        #endregion

        #region 가볍게 치기 - Flick(mouseDownPoint, mouseUpPoint, duration)

        /// <summary>
        /// 가볍게 치기
        /// </summary>
        /// <param name="mouseDownPoint">마우스 DOWN 포인트</param>
        /// <param name="mouseUpPoint">마우스 UP 포인트</param>
        /// <param name="duration">지속 시간</param>
        public static void Flick(Point mouseDownPoint, Point mouseUpPoint, TimeSpan duration)
        {
            System.Windows.Forms.Cursor.Position = mouseDownPoint;

            mouse_event(MOUSE_EVENT_LEFT_DOWN, 0, 0, 0, 0);

            Thread.Sleep(duration);

            System.Windows.Forms.Cursor.Position = mouseDownPoint;

            mouse_event(MOUSE_EVENT_LEFT_UP, 0, 0, 0, 0);

            Thread.Sleep(100);
        }

        #endregion

        #region 드래그 & 드롭하기 - DragDrop(dragStartPoint, dropPoint)

        /// <summary>
        /// 드래그 & 드롭하기
        /// </summary>
        /// <param name="dragStartPoint">드래그 시작 포인트</param>
        /// <param name="dropPoint">드래그 포인트</param>
        public static void DragDrop(Point dragStartPoint, Point dropPoint)
        {
            ClickMouseLeftButton(dragStartPoint);

            mouse_event(MOUSE_EVENT_LEFT_DOWN, 0, 0, 0, 0);

            System.Windows.Forms.Cursor.Position = dropPoint;

            mouse_event(MOUSE_EVENT_LEFT_UP, 0, 0, 0, 0);

            Thread.Sleep(100);
        }

        #endregion
        #region 드래그 & 컨트롤 드롭하기 - DragCtrlDrop(dragStartPoint, dropPoint)

        /// <summary>
        /// 드래그 & 컨트롤 드롭하기
        /// </summary>
        /// <param name="dragStartPoint">드래그 시작 포인트</param>
        /// <param name="dropPoint">드래그 포인트</param>
        public static void DragCtrlDrop(Point dragStartPoint, Point dropPoint)
        {
            ClickMouseLeftButton(dragStartPoint);

            mouse_event(MOUSE_EVENT_LEFT_DOWN, 0, 0, 0, 0);

            System.Windows.Forms.Cursor.Position = dropPoint;

            Thread.Sleep(100);

            keybd_event(VK_LCONTROL, 0, EXTENDED_KEY | KEY_DOWN, 0);

            Thread.Sleep(100);

            mouse_event(MOUSE_EVENT_LEFT_UP, 0, 0, 0, 0);

            Thread.Sleep(100);

            keybd_event(VK_LCONTROL, 0, EXTENDED_KEY | KEY_UP, 0);

            Thread.Sleep(100);
        }

        #endregion
    }
}

 

728x90

 

▶ UIAutomationHelper.cs

using System;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Threading;
using System.Windows.Automation;

namespace TestProject
{
    /// <summary>
    /// UI 자동화 헬퍼
    /// </summary>
    public static class UIAutomationHelper
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Field
        ////////////////////////////////////////////////////////////////////////////////////////// Private

        #region Field

        /// <summary>
        /// 엘리먼트 탐색 타임아웃 초 카운트
        /// </summary>
        private const int ELEMENT_SEARCH_TIMEOUT_SECOND_COUNT = 10;

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Static
        //////////////////////////////////////////////////////////////////////////////// Public

        #region 애플리케이션 실행하기 - ExecuteApplication(filePath, argumentList)

        /// <summary>
        /// 애플리케이션 실행하기
        /// </summary>
        /// <param name="filePath">파일 경로</param>
        /// <param name="argumentList">인자 리스트</param>
        /// <returns>자동화 엘리먼트</returns>
        public static AutomationElement ExecuteApplication(string filePath, string argumentList)
        {
            Process process = new Process();

            process.StartInfo.FileName  = filePath;
            process.StartInfo.Arguments = argumentList;

            process.Start();

            Thread.Sleep(2000);

            return (AutomationElement.FromHandle(process.MainWindowHandle));
        }

        #endregion
        #region 애플리케이션 실행하기 - ExecuteApplication(filePath)

        /// <summary>
        /// 애플리케이션 실행하기
        /// </summary>
        /// <param name="filePath">파일 경로</param>
        /// <returns>자동화 엘리먼트</returns>
        public static AutomationElement ExecuteApplication(string filePath)
        {
            return ExecuteApplication(filePath, string.Empty);
        }

        #endregion

        #region 명칭으로 엘리먼트 컬렉션 구하기 - GetElementCollectionByName(windowElement, elementName)

        /// <summary>
        /// 명칭으로 엘리먼트 컬렉션 구하기
        /// </summary>
        /// <param name="windowElement">윈도우 엘리먼트</param>
        /// <param name="elementName">엘리먼트명</param>
        /// <returns>자동화 엘리먼트 컬렉션</returns>
        public static AutomationElementCollection GetElementCollectionByName(AutomationElement windowElement, string elementName)
        {
            if(windowElement == null)
            {
                return null;
            }

            return GetElementCollection
            (
                windowElement,
                new PropertyCondition(AutomationElement.NameProperty, elementName)
            );
        }

        #endregion
        #region 명칭으로 엘리먼트 구하기 - GetElementByName(windowElement, elementName)

        /// <summary>
        /// 명칭으로 엘리먼트 구하기
        /// </summary>
        /// <param name="windowElement">윈도우 엘리먼트</param>
        /// <param name="elementName">엘리먼트명</param>
        /// <returns>자동화 엘리먼트</returns>
        public static AutomationElement GetElementByName(AutomationElement windowElement, string elementName)
        {
            if(windowElement == null)
            {
                return null;
            }

            return GetElement
            (
                windowElement,
                new PropertyCondition(AutomationElement.NameProperty, elementName)
            );
        }

        #endregion
        #region ID로 엘리먼트 구하기 - GetElementByID(windowElement, elementID)

        /// <summary>
        /// ID로 엘리먼트 구하기
        /// </summary>
        /// <param name="windowElement">윈도우 엘리먼트</param>
        /// <param name="elementID">엘리먼트 ID</param>
        /// <returns>자동화 엘리먼트</returns>
        public static AutomationElement GetElementByID(AutomationElement windowElement, string elementID)
        {
            if(windowElement == null)
            {
                return null;
            }

            return GetElement
            (
                windowElement,
                new PropertyCondition(AutomationElement.AutomationIdProperty, elementID)
            );
        }

        #endregion

        #region 엘리먼트명 구하기 - GetElementName(windowElement, elementID)

        /// <summary>
        /// 엘리먼트명 구하기
        /// </summary>
        /// <param name="windowElement">윈도우 엘리먼트</param>
        /// <param name="elementID">엘리먼트 ID</param>
        /// <returns>엘리먼트명</returns>
        public static string GetElementName(AutomationElement windowElement, string elementID)
        {
            return GetElementByID(windowElement, elementID).Current.Name;
        }

        #endregion

        #region 엘리먼트 호출하기 - InvokeElement(windowElement, condition)

        /// <summary>
        /// 엘리먼트 호출하기
        /// </summary>
        /// <param name="windowElement">윈도우 엘리먼트</param>
        /// <param name="condition">조건</param>
        /// <returns>처리 결과</returns>
        public static bool InvokeElement(AutomationElement windowElement, Condition condition)
        {
            if(windowElement == null)
            {
                return false;
            }

            AutomationElement element = GetElement(windowElement, condition);

            if(element != null)
            {
                InvokePattern pattern = element.GetCurrentPattern(InvokePattern.Pattern) as InvokePattern;

                pattern.Invoke();

                return true;
            }

            return false;
        }

        #endregion
        #region 명칭으로 엘리먼트 호출하기 - InvokeElementByName(windowElement, elementName)

        /// <summary>
        /// 명칭으로 엘리먼트 호출하기
        /// </summary>
        /// <param name="windowElement">윈도우 엘리먼트</param>
        /// <param name="elementName">엘리먼트명</param>
        /// <returns>처리 결과</returns>
        public static bool InvokeElementByName(AutomationElement windowElement, string elementName)
        {
            return InvokeElement
            (
                windowElement,
                new PropertyCondition(AutomationElement.NameProperty, elementName)
            );
        }

        #endregion
        #region ID로 엘리먼트 호출하기 - InvokeElementByID(windowElement, elementID)

        /// <summary>
        /// ID로 엘리먼트 호출하기
        /// </summary>
        /// <param name="windowElement">윈도우 엘리먼트</param>
        /// <param name="elementID">엘리먼트 ID</param>
        /// <returns>처리 결과</returns>
        public static bool InvokeElementByID(AutomationElement windowElement, string elementID)
        {
            return InvokeElement
            (
                windowElement,
                new PropertyCondition(AutomationElement.AutomationIdProperty, elementID)
            );
        }

        #endregion

        #region 엘리먼트 확장하기 - ExpandElement(element)

        /// <summary>
        /// 엘리먼트 확장하기
        /// </summary>
        /// <param name="element">엘리먼트</param>
        /// <returns>처리 결과</returns>
        public static bool ExpandElement(AutomationElement element)
        {
            if(element == null)
            {
                return false;
            }

            ExpandCollapsePattern pattern = element.GetCurrentPattern(ExpandCollapsePattern.Pattern) as ExpandCollapsePattern;

            pattern.Expand();

            return true;
        }

        #endregion
        #region 엘리먼트 확장하기 - ExpandElement(windowElement, condition)

        /// <summary>
        /// 엘리먼트 확장하기
        /// </summary>
        /// <param name="windowElement">윈도우 엘리먼트</param>
        /// <param name="condition">조건</param>
        /// <returns>처리 결과</returns>
        private static bool ExpandElement(AutomationElement windowElement, Condition condition)
        {
            AutomationElement element = GetElement(windowElement, condition);

            return ExpandElement(element);
        }

        #endregion
        #region 명칭으로 엘리먼트 확장하기 - ExpandElementByName(windowElement, elementName)

        /// <summary>
        /// 명칭으로 엘리먼트 확장하기
        /// </summary>
        /// <param name="windowElement">윈도우 엘리먼트</param>
        /// <param name="elementName">엘리먼트명</param>
        /// <returns>처리 결과</returns>
        public static bool ExpandElementByName(AutomationElement windowElement, string elementName)
        {
            return ExpandElement
            (
                windowElement,
                new PropertyCondition(AutomationElement.NameProperty, elementName)
            );
        }

        #endregion
        #region ID로 엘리먼트 확장하기 - ExpandElementByID(windowElement, elementID)

        /// <summary>
        /// ID로 엘리먼트 확장하기
        /// </summary>
        /// <param name="windowElement">윈도우 엘리먼트</param>
        /// <param name="elementID">엘리먼트 ID</param>
        /// <returns>처리 결과</returns>
        public static bool ExpandElementByID(AutomationElement windowElement, string elementID)
        {
            return ExpandElement
            (
                windowElement,
                new PropertyCondition(AutomationElement.AutomationIdProperty, elementID)
            );
        }

        #endregion

        #region ID로 엘리먼트 토글하기 - ToggleElementByID(windowElement, elementID)

        /// <summary>
        /// ID로 엘리먼트 토글하기
        /// </summary>
        /// <param name="windowElement">윈도우 엘리먼트</param>
        /// <param name="elementID">엘리먼트 ID</param>
        public static void ToggleElementByID(AutomationElement windowElement, string elementID)
        {
            AutomationElement element = GetElement(windowElement, new PropertyCondition(AutomationElement.AutomationIdProperty, elementID));

            TogglePattern pattern = element.GetCurrentPattern(TogglePattern.Pattern) as TogglePattern;

            pattern.Toggle();
        }

        #endregion

        #region 항목 선택하기 - SelectItem(windowElement, elementID, itemIndex)

        /// <summary>
        /// 항목 선택하기
        /// </summary>
        /// <param name="windowElement">윈도우 엘리먼트</param>
        /// <param name="elementID">엘리먼트 ID</param>
        /// <param name="itemIndex">항목 인덱스</param>
        public static void SelectItem(AutomationElement windowElement, string elementID, int itemIndex)
        {
            AutomationElement element = GetElementByID(windowElement, elementID);
            
            AutomationElementCollection itemCollection = element.FindAll
            (
                TreeScope.Children,
                new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.ListItem)
            );

            ExpandCollapsePattern pattern = (ExpandCollapsePattern)element.GetCurrentPattern(ExpandCollapsePattern.Pattern);

            pattern.Expand();

            AutomationElement itemElement = itemCollection[itemIndex];

            object selectPattern = null;

            if(itemElement.TryGetCurrentPattern(SelectionItemPattern.Pattern, out selectPattern))
            {
                ((SelectionItemPattern)selectPattern).Select();
            }
        }

        #endregion

        #region 선택 여부 구하기 - IsSelected(windowElement, elementID)

        /// <summary>
        /// 선택 여부 구하기
        /// </summary>
        /// <param name="windowElement">윈도우 엘리먼트</param>
        /// <param name="elementID">엘리먼트 ID</param>
        /// <returns>선택 여부</returns>
        public static bool IsSelected(AutomationElement windowElement, string elementID)
        {
            AutomationElement element = GetElementByID(windowElement, elementID);

            SelectionItemPattern pattern = element.GetCurrentPattern(SelectionItemPattern.Pattern) as SelectionItemPattern;

            return pattern.Current.IsSelected;
        }

        #endregion
        #region 이용 가능 여부 구하기 - IsEnabled(windowElement, elementID)

        /// <summary>
        /// 이용 가능 여부 구하기
        /// </summary>
        /// <param name="windowElement">윈도우 엘리먼트</param>
        /// <param name="elementID">엘리먼트 ID</param>
        /// <returns>이용 가능 여부</returns>
        public static bool IsEnabled(AutomationElement windowElement, string elementID)
        {
            AutomationElement element = GetElementByID(windowElement, elementID);

            return (bool)element.GetCurrentPropertyValue(AutomationElement.IsEnabledProperty);
        }

        #endregion

        #region 엘리먼트 선택하기 - SelectElement(element)

        /// <summary>
        /// 엘리먼트 선택하기
        /// </summary>
        /// <param name="element">엘리먼트</param>
        public static void SelectElement(AutomationElement element)
        {
            SelectionItemPattern pattern = element.GetCurrentPattern(SelectionItemPattern.Pattern) as SelectionItemPattern;

            pattern.Select();
        }

        #endregion
        #region 엘리먼트 선택하기 - SelectElement(windowElement, elementID)

        /// <summary>
        /// 엘리먼트 선택하기
        /// </summary>
        /// <param name="windowElement">윈도우 엘리먼트</param>
        /// <param name="elementID">엘리먼트 ID</param>
        public static void SelectElement(AutomationElement windowElement, string elementID)
        {
            AutomationElement element = GetElementByID(windowElement, elementID);

            SelectionItemPattern pattern = element.GetCurrentPattern(SelectionItemPattern.Pattern) as SelectionItemPattern;

            pattern.Select();
        }

        #endregion

        #region 값 설정하기 - SetValue(windowElement, elementID, value)

        /// <summary>
        /// 값 설정하기
        /// </summary>
        /// <param name="windowElement">윈도우 엘리먼트</param>
        /// <param name="elementID">엘리먼트 ID</param>
        /// <param name="value">값</param>
        public static void SetValue(AutomationElement windowElement, string elementID, string value)
        {
            AutomationElement element = GetElementByID(windowElement, elementID);

            ValuePattern pattern = element.GetCurrentPattern(ValuePattern.Pattern) as ValuePattern;

            pattern.SetValue(value);
        }

        #endregion

        #region 자식 카운트 구하기 - GetChildCount(windowElement, elementID)

        /// <summary>
        /// 자식 카운트 구하기
        /// </summary>
        /// <param name="windowElement">윈도우 엘리먼트</param>
        /// <param name="elementID">엘리먼트 ID</param>
        /// <returns>자식 카운트</returns>
        public static int GetChildCount(AutomationElement windowElement, string elementID)
        {
            AutomationElement element = GetElementByID(windowElement, elementID);

            return element.FindAll(TreeScope.Children, PropertyCondition.TrueCondition).Count;
        }

        #endregion

        #region 엘리먼트 텍스트 구하기 - GetElementText(element)

        /// <summary>
        /// 엘리먼트 텍스트 구하기
        /// </summary>
        /// <param name="element">엘리먼트</param>
        /// <returns>엘리먼트 텍스트</returns>
        public static string GetElementText(AutomationElement element)
        {
            TextPattern pattern = (TextPattern)element.GetCurrentPattern(TextPattern.Pattern);

            return pattern.DocumentRange.GetText(-1);
        }

        #endregion
        #region 엘리먼트 텍스트 구하기 - GetElementText(windowElement, elementID)

        /// <summary>
        /// 엘리먼트 텍스트 구하기
        /// </summary>
        /// <param name="windowElement">윈도우 엘리먼트</param>
        /// <param name="elementID">엘리먼트 ID</param>
        /// <returns>엘리먼트 텍스트</returns>
        public static string GetElementText(AutomationElement windowElement, string elementID)
        {
            TextPattern pattern = (TextPattern)GetElementByID(windowElement, elementID).GetCurrentPattern(TextPattern.Pattern);

            return pattern.DocumentRange.GetText(-1);
        }

        #endregion

        #region 엘리먼트 호출하기 - InvokeElement(element)

        /// <summary>
        /// 엘리먼트 호출하기
        /// </summary>
        /// <param name="element">엘리먼트</param>
        public static void InvokeElement(AutomationElement element)
        {
            InvokePattern pattern = (InvokePattern)element.GetCurrentPattern(InvokePattern.Pattern);

            pattern.Invoke();

            Thread.Sleep(500);
        }

        #endregion

        #region 첫번째 자식 구하기 - GetFirstChild(windowElement)

        /// <summary>
        /// 첫번째 자식 구하기
        /// </summary>
        /// <param name="windowElement">윈도우 엘리먼트</param>
        /// <returns>첫번째 자식</returns>
        public static AutomationElement GetFirstChild(AutomationElement windowElement)
        {
            return GetElement(windowElement, Condition.TrueCondition);
        }

        #endregion
        #region 첫번째 자식 구하기 - GetFirstChild(parentElement, childName)

        /// <summary>
        /// 첫번째 자식 구하기
        /// </summary>
        /// <param name="parentElement">부모 엘리먼트</param>
        /// <param name="childName">자식 명칭</param>
        /// <returns>첫번째 자식</returns>
        public static AutomationElement GetFirstChild(AutomationElement parentElement, string childName)
        {
            return GetElement(parentElement, new PropertyCondition(AutomationElement.NameProperty, childName));
        }

        #endregion

        #region 테이블 셀 엘리먼트 호출하기 - InvokeTableCellElement(windowElement, elementID, row, column)

        /// <summary>
        /// 테이블 셀 엘리먼트 호출하기
        /// </summary>
        /// <param name="windowElement">윈도우 엘리먼트</param>
        /// <param name="elementID">엘리먼트 ID</param>
        /// <param name="row">행</param>
        /// <param name="column">컬럼</param>
        public static void InvokeTableCellElement(AutomationElement windowElement, string elementID, int row, int column)
        {
            AutomationElement tableElement = GetElementByID(windowElement, elementID);

            GridPattern pattern = tableElement.GetCurrentPattern(GridPattern.Pattern) as GridPattern;

            AutomationElement cellElement = pattern.GetItem(row, column);

            AutomationElement hyperLinkElement = GetFirstChild(cellElement);

            InvokeElement(hyperLinkElement);
        }

        #endregion

        #region 선택 엘리먼트 구하기 - GetSelectedElement(parentElement)

        /// <summary>
        /// 선택 엘리먼트 구하기
        /// </summary>
        /// <param name="parentElement">부모 엘리먼트</param>
        /// <returns>선택 엘리먼트</returns>
        public static AutomationElement GetSelectedElement(AutomationElement parentElement)
        {
            return GetElement(parentElement, new PropertyCondition(SelectionItemPattern.IsSelectedProperty, true));
        }

        #endregion

        #region 리스트 뷰에서 데이터 테이블 구하기 - GetDataTableFromListView(windowElement, elementID)

        /// <summary>
        /// 리스트 뷰에서 데이터 테이블 구하기
        /// </summary>
        /// <param name="windowElement">윈도우 엘리먼트</param>
        /// <param name="elementID">엘리먼트 ID</param>
        /// <returns>데이터 테이블</returns>
        public static DataTable GetDataTableFromListView(AutomationElement windowElement, string elementID)
        {
            AutomationElement element = GetElementByID(windowElement, elementID);

            GridPattern pattern = element.GetCurrentPattern(GridPattern.Pattern) as GridPattern;

            DataTable dataTable = new DataTable();

            for(int i = 0; i < pattern.Current.ColumnCount; i++)
            {
                dataTable.Columns.Add(GetColumnHeaderID(pattern.GetItem(0, i)));
            }

            for(int i = 0; i < pattern.Current.RowCount; i++)
            {
                dataTable.Rows.Add();

                for(int j = 0; j < pattern.Current.ColumnCount; j++)
                {
                    AutomationElement cellElement = pattern.GetItem(i, j);

                    string columnName = GetColumnHeaderID(cellElement);

                    dataTable.Rows[i][columnName] = cellElement.GetCurrentPropertyValue(AutomationElement.NameProperty);
                }
            }

            return dataTable;
        }

        #endregion

        #region 선택에 엘리먼트 추가하기 - AddElementToSelection(element)

        /// <summary>
        /// 선택에 엘리먼트 추가하기
        /// </summary>
        /// <param name="element">엘리먼트</param>
        public static void AddElementToSelection(AutomationElement element)
        {
            SelectionItemPattern pattern = element.GetCurrentPattern(SelectionItemPattern.Pattern) as SelectionItemPattern;

            pattern.AddToSelection();
        }

        #endregion

        #region 마우스 클릭 실행하기 - PerformMouseClick(windowElement, elementID)

        /// <summary>
        /// 마우스 클릭 실행하기
        /// </summary>
        /// <param name="windowElement">윈도우 엘리먼트</param>
        /// <param name="elementID">엘리먼트 ID</param>
        public static void PerformMouseClick(AutomationElement windowElement, string elementID)
        {
            try
            {
                AutomationElement element = GetElementByID(windowElement, elementID);

                MouseHelper.ClickMouseLeftButton(GetPointToClick(element));
            }
            catch(NoClickablePointException)
            {
                AutomationElement element = GetElementByID(windowElement, elementID);

                int x = (int)element.GetClickablePoint().X;
                int y = (int)element.GetClickablePoint().Y;

                Point point = new Point(x, y);

                MouseHelper.ClickMouseLeftButton(point);
            }
        }

        #endregion
        #region 마우스 오른쪽 버튼 클릭 실행하기 - PerformMouseRightButtonClick(windowElement, elementID)

        /// <summary>
        /// 마우스 오른쪽 버튼 클릭 실행하기
        /// </summary>
        /// <param name="windowElement">윈도우 엘리먼트</param>
        /// <param name="elementID">엘리먼트 ID</param>
        public static void PerformMouseRightButtonClick(AutomationElement windowElement, string elementID)
        {
            AutomationElement element = null;

            try
            {
                element = GetElementByID(windowElement, elementID);

                MouseHelper.ClickMouseRightButton(GetPointToClick(element));
            }
            catch(NoClickablePointException)
            {
                element = GetElementByID(windowElement, elementID);

                MouseHelper.ClickMouseRightButton(GetPointToClick(element));
            }
        }

        #endregion

        #region 존재 여부 구하기 - Exists(windowElement, elementID)

        /// <summary>
        /// 존재 여부 구하기
        /// </summary>
        /// <param name="windowElement">윈도우 엘리먼트</param>
        /// <param name="elementID">엘리먼트 ID</param>
        /// <returns>존재 여부</returns>
        public static bool Exists(AutomationElement windowElement, string elementID)
        {
            try
            {
                AutomationElement element = GetElement(windowElement, new PropertyCondition(AutomationElement.AutomationIdProperty, elementID));

                return element != null;
            }
            catch
            {
                return false;
            }
        }

        #endregion
        #region 미존재 여부 구하기 - NotExists(windowElement, elementName)

        /// <summary>
        /// 미존재 여부 구하기
        /// </summary>
        /// <param name="windowElement">윈도우 엘리먼트</param>
        /// <param name="elementName">엘리먼트명</param>
        /// <returns>미존재 여부</returns>
        public static bool NotExists(AutomationElement windowElement, string elementName)
        {
            try
            {
                AutomationElement element = windowElement.FindFirst(TreeScope.Descendants, new PropertyCondition(AutomationElement.NameProperty, elementName));

                return element == null;
            }
            catch
            {
                return false;
            }
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////// Private

        #region WinForm 포인트 구하기 - GetWinFormPoint(wpfPoint)

        /// <summary>
        /// WinForm 포인트 구하기
        /// </summary>
        /// <param name="wpfPoint">WPF 포인트</param>
        /// <returns>WinForm 포인트</returns>
        private static System.Drawing.Point GetWinFormPoint(System.Windows.Point wpfPoint)
        {
            return new System.Drawing.Point
            {
                X = Convert.ToInt32(wpfPoint.X),
                Y = Convert.ToInt32(wpfPoint.Y)
            };
        }

        #endregion

        #region 엘리먼트 컬렉션 구하기 - GetElementCollection(windowElement, condition)

        /// <summary>
        /// 엘리먼트 컬렉션 구하기
        /// </summary>
        /// <param name="windowElement">윈도우 엘리먼트</param>
        /// <param name="condition">조건</param>
        /// <returns>자동화 엘리먼트 컬렉션</returns>
        private static AutomationElementCollection GetElementCollection(AutomationElement windowElement, Condition condition)
        {
            return windowElement.FindAll(TreeScope.Descendants, condition);
        }

        #endregion
        #region 엘리먼트 구하기 - GetElement(windowElement, condition)

        /// <summary>
        /// 엘리먼트 구하기
        /// </summary>
        /// <param name="windowElement">윈도우 엘리먼트</param>
        /// <param name="condition">조건</param>
        /// <returns>자동화 엘리먼트</returns>
        private static AutomationElement GetElement(AutomationElement windowElement, Condition condition)
        {
            DateTime startTime = DateTime.Now;

            AutomationElement element = null;

            do
            {
                element = windowElement.FindFirst(TreeScope.Descendants, condition);

                if(element == null)
                {
                    Thread.Sleep(500);
                }

                if((DateTime.Now - startTime).TotalSeconds > ELEMENT_SEARCH_TIMEOUT_SECOND_COUNT)
                {
                    throw new TimeoutException
                    (
                        $"Searching for an element took longer than specified timeout of {ELEMENT_SEARCH_TIMEOUT_SECOND_COUNT} seconds"
                    );
                }
            }
            while(element == null);

            return element;
        }

        #endregion

        #region 컬럼 헤더 ID 구하기 - GetColumnHeaderID(cellElement)

        /// <summary>
        /// 컬럼 헤더 ID 구하기
        /// </summary>
        /// <param name="cellElement">셀 엘리먼트</param>
        /// <returns>컬럼 헤더 ID</returns>
        private static string GetColumnHeaderID(AutomationElement cellElement)
        {
            AutomationElement gridElement = cellElement.GetCurrentPropertyValue(GridItemPatternIdentifiers.ContainingGridProperty) as AutomationElement;

            TablePattern pattern = gridElement.GetCurrentPattern(TablePattern.Pattern) as TablePattern;

            int column = (int)cellElement.GetCurrentPropertyValue(GridItemPatternIdentifiers.ColumnProperty);

            AutomationElement headerElement = pattern.Current.GetColumnHeaders()[column];

            return (string)headerElement.GetCurrentPropertyValue(AutomationElement.NameProperty);
        }

        #endregion

        #region 클릭 포인트 구하기 - GetPointToClick(element)

        /// <summary>
        /// 클릭 포인트 구하기
        /// </summary>
        /// <param name="element">엘리먼트</param>
        /// <returns>WinForm 포인트</returns>
        private static System.Drawing.Point GetPointToClick(AutomationElement element)
        {
            return GetWinFormPoint
            (
                new System.Windows.Point
                (
                     element.Current.BoundingRectangle.Left + 10,
                     element.Current.BoundingRectangle.Top  + 10
                )
            );
        }

        #endregion
    }
}

※ 테스트를 하지는 않은 참고용 코드이다.

※ 아래 네임스페이스를 추가한다.

  • UIAutomationClient
  • UIAutomationTypes
728x90
반응형
그리드형(광고전용)
Posted by icodebroker

댓글을 달아 주세요