|
컨트롤 패턴 클래스 |
공급자 인터페이스 |
설명 |
DockPattern |
IDockProvider |
도킹 컨테이너에 도킹할 수 있는 컨트롤에 사용된다. 예: 도구 모음 또는 도구 팔레트 |
ExpandCollapsePattern |
IExpandCollapseProvider |
확장하거나 축소할 수 있는 컨트롤에 사용된다. 예: 파일 메뉴와 같은 응용 프로그램의 메뉴 항목 |
GridPattern |
IGridProvider |
특정 셀로 이동 및 크기 조정 같은 표 기능을 지원하는 컨트롤에 사용된다. 예: Windows 탐색기의 큰 아이콘 보기 또는 Microsoft Word의 머리글 없는 간단한 표 |
GridItemPattern |
IGridItemProvider |
표 안에 셀이 있는 컨트롤에 사용된다. 개별 셀이 GridItem 패턴을 지원해야 한다. 예: Microsoft Windows Explorer 자세히 보기의 각 셀 |
InvokePattern |
IInvokeProvider |
호출할 수 있는 컨트롤에 사용된다. 예: 단추 |
MultipleViewPattern |
IMultipleViewProvider |
같은 정보, 데이터 또는 자식 집합의 여러 표현 간에 전환할 수 있는 컨트롤에 사용된다. 예: 데이터를 축소판 이미지, 바둑판식, 아이콘, 목록 또는 자세히 보기로 표현할 수 있는 목록 뷰 컨트롤 |
RangeValuePattern |
IRangeValueProvider |
컨트롤에 적용할 수 있는 값의 범위가 있는 컨트롤에 사용된다. 예: 1900부터 2010까지의 연도를 포함하거나 1부터 12까지의 달을 표현하는 회전자 컨트롤 |
ScrollPattern |
IScrollProvider |
스크롤할 수 있는 컨트롤에 사용된다. 예: 컨트롤의 표시 가능한 영역에 나타낼 수 있는 것보다 정보가 많을 경우 활성화되는 스크롤 막대가 포함된 컨트롤 |
ScrollItemPattern |
IScrollItemProvider |
스크롤되는 목록에 개별 항목이 있는 컨트롤에 사용된다. 예: 콤보 상자 컨트롤처럼 스크롤 목록에 개별 항목이 있는 목록 컨트롤 |
SelectionPattern |
ISelectionProvider |
선택 컨테이너 컨트롤에 사용된다. 예: 목록 상자와 콤보 상자 |
SelectionItemPattern |
ISelectionItemProvider |
목록 상자 및 콤보 상자와 같은 선택 컨테이너 컨트롤에 있는 개별 항목에 사용된다. |
TablePattern |
ITableProvider |
표와 머리말 정보가 있는 컨트롤에 사용된다. 예: Microsoft Excel 워크시트 |
TableItemPattern |
ITableItemProvider |
테이블의 항목에 사용된다. |
TextPattern |
ITextProvider |
텍스트 정보를 노출하는 문서 및 편집 컨트롤에 사용된다. |
TogglePattern |
IToggleProvider |
상태를 전환할 수 있는 컨트롤에 사용된다. 예: 확인란 및 선택 가능한 메뉴 항목 |
TransformPattern |
ITransformProvider |
크기를 조정하고, 이동하고, 회전할 수 있는 컨트롤에 사용된다. Transform 컨트롤 패턴은 일반적으로 디자이너, 폼, 그래픽 편집기 및 그리기 응용 프로그램에 사용된다. |
ValuePattern |
IValueProvider |
값 범위를 지원하지 않는 컨트롤에서 클라이언트가 값을 가져오거나 설정할 수 있습니다. 예: 날짜 시간 선택 컨트롤 |
WindowPattern |
IWindowProvider |
Microsoft Windows 운영 체제에 대한 기본 개념인 창에 관련된 정보를 노출합니다. 예: 최상위 응용 프로그램 창(Microsoft Word, Microsoft Windows Explorer 등), multiple-document interface (MDI) 자식 창 및 대화 상자 |
5. 예제 프로그램
간단하게 UI Automation을 사용하여 데스크 탑에 있는 다른 응용프로그래밍의 컨트롤들을 제어 해보는 프로그램이다.
버튼 이라던지 호출 가능한 컨트롤들과 텍스트 박스등 값 형태를 가지고 있는 컨트롤들을 나눠 콤보 박스에 추가하고 콤보박스의 해당 아이템들을 선택하여 대상 응용프로그램의 컨트롤들을 사용할 수 있는 프로그램이다.
초기 화면은 이러하다. 프로그램 파일 선택을 눌러 대상 프로그램의 exe 파일을 불러와 실행 시킨다.
따로 더미 응용프로그램을 만들어 불러온다. 5개의 버튼요소와 4개의 텍스트 박스 요소를 얻어 온다.
왼쪽 콤보박스의 경우 아이템을 클릭시 더미 응용프로그램의 해당 컨트롤의 이벤트가 실행되고 오른쪽 콤보박스의 경우 아이템 클릭후 텍스트박스에 값을 넣고 변경을 누르게 되면 더미 프로그램의 해당되는 텍스트박스에 값이 바뀌게 된다.
처음으로 참조 추가를 해야 한다.
( xaml 코드는 특별히 없으니 기술하지 않음 )
Main.xaml.cs |
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; using Microsoft.Win32; using System.Data;
namespace ControlProcess { /// <summary> /// Window1.xaml에 대한 상호 작용 논리 /// </summary> public partial class Window1 : Window { ComboBoxItem item2 = null; public Window1() { InitializeComponent(); } private void Button_Click(object sender, RoutedEventArgs e) { AEButtonList.Items.Clear(); OpenFileDialog ofd = new OpenFileDialog(); ofd.FileName = "실행파일"; ofd.DefaultExt = ".exe"; ofd.Filter = "실행파일 (*.exe)|*.exe";
Nullable<bool> re = ofd.ShowDialog(); if (re == true) { AECollection ae = new AECollection(ofd.FileName); DataTable dt = ae.DataTable;
DataTable dt2 = ae.DataTable2; ComboBoxItem item;
foreach (DataRow dr in dt.Rows) { item = new ComboBoxItem(); item.Content = dr["name"]; item.Tag = ae; item.ToolTip = dr["aeid"]; AEButtonList.Items.Add(item); } foreach (DataRow dr in dt2.Rows) { item = new ComboBoxItem(); item.Content = dr["name"]; item.Tag = ae; item.ToolTip = dr["aeid"]; AETextList.Items.Add(item); } Result.Content = string.Format("{0}개의 실행 가능한 자동화 요소 발견", dt.Rows.Count); Result2.Content = string.Format("{0}개의 실행 가능한 자동화 요소 발견", dt2.Rows.Count); } }
private void AEList_SelectChanged(object sender, Selecti[안내]태그제한으로등록되지않습니다-xxonChangedEventArgs e) { ComboBoxItem item = AEButtonList.SelectedItem as ComboBoxItem; if (item == null) { return; }
AECollection ae = item.Tag as AECollection;
ae.InvokeAE(item.ToolTip.ToString());
}
private void button1_Click(object sender, RoutedEventArgs e) { AECollection ae = item2.Tag as AECollection;
ae.SetValue(item2.ToolTip.ToString(),textBox1.Text); }
private void AETextList_Selecti[안내]태그제한으로등록되지않습니다-xxonChanged(object sender, Selecti[안내]태그제한으로등록되지않습니다-xxonChangedEventArgs e) { item2 = AETextList.SelectedItem as ComboBoxItem; if (item2 == null) { return; }
} } }
|
프로그램 구조는 생각 간단 하다. 열고자 하는 프로그램(exe파일) 을 열어 AECollection 개체를 통해 DataTable을 받아와 콤보 박스에 추가 한다. 콤보박스에 추가시 아이템의 Tag 값에 AECollection 을 넣어줘 콤보 박스의 아이템 클릭 시 해당 아이템의 Tag 값을 얻어와 버튼일 경우 Invoke 를 TextBox일 경우 SetValue 메서드를 호출 해준다. |
AECollection.cs |
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Diagnostics; using System.Threading; using System.Windows.Automation; using System.Data;
namespace ControlProcess { public class AECollection {
AutomationElementCollection collection; AutomationElementCollection textboxcollection; DataTable dataTable; DataTable dataTable2; public DataTable DataTable2 { get { if (dataTable2 == null) { dataTable2 = MakeDataTable2(); } return dataTable2; } }
public DataTable DataTable { get { if (dataTable == null) { dataTable = MakeDataTable(); } return dataTable; } } private DataTable MakeDataTable2() { dataTable2 = new DataTable("AETable");
dataTable2.Columns.Add(new DataColumn("name", typeof(string))); dataTable2.Columns.Add(new DataColumn("ae", typeof(AutomationElement))); dataTable2.Columns.Add(new DataColumn("aeValuePattern", typeof(object)));
DataColumn[] pk = new DataColumn[1]; pk[0] = new DataColumn("aeid", typeof(string)); dataTable2.Columns.Add(pk[0]); dataTable2.PrimaryKey = pk;
DataRow dr; object obj;
foreach (AutomationElement ae in textboxcollection) { dr = dataTable2.NewRow();
dr["name"] = ae.Current.AutomationId; dr["aeid"] = ae.Current.GetHashCode(); if (ae.TryGetCurrentPattern( ValuePattern.Pattern, out obj)) { dr["aeValuePattern"] = obj; dr["ae"] = ae; dataTable2.Rows.Add(dr); }
}
return dataTable2;
} private DataTable MakeDataTable() { dataTable = new DataTable("AETable");
dataTable.Columns.Add(new DataColumn("name", typeof(string))); dataTable.Columns.Add(new DataColumn("ae", typeof(AutomationElement))); dataTable.Columns.Add(new DataColumn("aeInvokePattern", typeof(object)));
DataColumn[] pk = new DataColumn[1]; pk[0] = new DataColumn("aeid", typeof(string)); dataTable.Columns.Add(pk[0]); dataTable.PrimaryKey = pk;
DataRow dr; object obj;
foreach (AutomationElement ae in collection) { dr = dataTable.NewRow();
dr["name"] = ae.Current.AutomationId; dr["aeid"] = ae.Current.GetHashCode(); if (ae.TryGetCurrentPattern(InvokePattern.Pattern, out obj)) { dr["aeInvokePattern"] = obj; dr["ae"] = ae; dataTable.Rows.Add(dr);
}
}
return dataTable;
} public AECollection(string proname) { Process process = Process.Start(proname); Thread.Sleep(3000);
IntPtr MainHWnd = process.MainWindowHandle;
AutomationElement ae = AutomationElement.FromHandle(MainHWnd); Condition conditon = new AndCondition( new PropertyCondition(AutomationElement.IsInvokePatternAvailableProperty, true), new PropertyCondition(AutomationElement.IsEnabledProperty, true)); collection = ae.FindAll(TreeScope.Subtree, conditon);
AutomationElement ae2 = AutomationElement.FromHandle(MainHWnd); Condition condition = new AndCondition(new PropertyCondition(AutomationElement.IsTextPatternAvailableProperty, true), new PropertyCondition(AutomationElement.IsValuePatternAvailableProperty, true), new PropertyCondition(AutomationElement.IsEnabledProperty, true));
textboxcollection = ae2.FindAll(TreeScope.Subtree, condition); }
public bool InvokeAE(string aeid) { DataRow dr = dataTable.Rows.Find(aeid);
if (dr == null) { return false; }
object obj = dr["aeInvokePattern"]; InvokePattern invokePattern = obj as InvokePattern;
invokePattern.Invoke(); return true; }
internal bool SetValue(string aeid , string textboxtext) { DataRow dr = dataTable2.Rows.Find(aeid);
if (dr == null) { return false; }
object obj = dr["aeValuePattern"]; ValuePattern vp = obj as ValuePattern;
vp.SetValue(textboxtext); return true; } } }
|
초기 생성자에서 파일(Main에서 OpenFileDialog 로 열기한 exe파일) 이름을 받아와 프로그램을 실행 시키고 해당 프로세스의 핸들 값을 받아온다. AutomationElement.IsInvokePatternAvailableProperty, AutomationElement.IsEnabledProperty, 이러한 패턴을 가지고 있는 컨트롤을 뽑아내서 AutomationElementCollection 개체에 보관을 하고 마찬가지로 텍스트 박스를 뽑아 내기 위해서는 AutomationElement.IsTextPatternAvailableProperty, AutomationElement.IsValuePatternAvailableProperty, 이러한 패턴을 가지고 있는 컨트롤들을 뽑아내서 컬렉션에 보관한다. 보관후 DataTable(싱글톤으로 되어 있다.) 에 추가하고 TryGetCurrentPattern를 이용해 해당 패턴을 검색후 참일경우 DataTable에 추가된다. |