메인 폼에서 프로젝트 생성버튼을 눌렀을 때 뜨는 폼으로 현재 프로세스 목록을 보여주어 평가 대상 프로젝트를 선택할 수 있는 폼입니다. 프로젝트에 ProjectSelectForm을 추가하세요.
그리고 대상 프로젝트를 선택하였을 때 자동화 요소를 검색하는데 시간이 오래 걸릴 수 있다는 메시지와 함께 대기 시간을 카운터하고 검출한 UI 요소 개수를 표시하여 평가자에게 프로세스가 정상적으로 동작 중인 상태임을 알려줍니다.
모든 Label 컨트롤의 Visable속성과 btn_select 버튼 컨트롤의 Enabled 속성을 false로 설정하세요. 그리고 ListBox 컨트롤의 Dock 속성을 Fill로 하고 Timer의 Interval 속성을 1000으로 설정합니다.
번호 | 컨트롤 형식 | 컨트롤 이름 | 번호 | 컨트롤 형식 | 컨트롤 이름 |
1 | Button | btn_refresh | 6 | Label | lb_time_msg |
2 | Button | btn_select | 7 | Label | lb_time_cnt |
3 | ListBox | lbox_process | 8 | Label | lb_doing_msg |
4 | Label | lb_intro_msg | 9 | Label | lb_elem_cnt |
5 | Label | lb_meta_msg | 10 | Timer | tm_search |
[표 10.3] ProjectSelectForm 의 자식 컨트롤
먼저 생성자에 프로젝트 제목을 입력 인자로 설정하여 폼의 Text 속성을 설정합니다.
public ProcessSelectForm(string title) { InitializeComponent(); this.Text = title; }
폼의 Load 이벤트 핸들러를 등록하여 프로세스 목록을 조사하여 표시합니다. 프로세스 목록을 조사하여 표시하는 부분은 ProcessList 메서드를 만들어서 사용할게요.
private void ProcessSelectForm_Load(object sender, EventArgs e) { ProcessList(); }
새로 고침 버튼의 클릭 이벤트 핸들러를 조사하여 ProcessList 메서드를 호출합니다.
private void btn_refresh_Click(object sender, EventArgs e) { ProcessList(); }
void ProcessList() {
먼저 리스트 박스의 모든 항목을 지웁니다.
lbox_process.Items.Clear();
모든 프로세스를 구합니다.
Process[] processes = Process.GetProcesses(); foreach (Process process in processes) {
프로세스 목록 중에 프로세스 ID가 자기 자신인 것은 필터링합니다.
if (process.Id == Process.GetCurrentProcess().Id){ continue; }
메인 윈도우 창이 있을 때 래핑한 EHProcess 개체를 생성하여 리스트 박스 목록에 추가합니다.
if (process.MainWindowHandle != IntPtr.Zero) { EHProcess ep = new EHProcess(process); lbox_process.Items.Add(ep); } } }
리스트 박스의 SelectedIndexChanged 이벤트 핸들러를 등록합니다.
private void lbox_process_SelectedIndexChanged(object sender, EventArgs e) {
선택 버튼의 Enabled 속성을 선택 항목이 있는지 여부로 설정합니다.
btn_select_process.Enabled = (lbox_process.SelectedIndex != -1); }
선택 버튼의 클릭 이벤트 핸들러를 등록합니다.
private void btn_select_process_Click(object sender, EventArgs e) {
선택 항목을 EHProcess 형식으로 참조합니다.
EHProcess ehprocess = lbox_process.SelectedItem as EHProcess;
정보 표시 레이블 컨트롤을 시각화합니다. 이 부분은 SearchLablesShow 메서드를 만들어서 사용합시다.
SearchLabelsShow();
타이머를 가동합니다.
tm_search.Start();
평가 관리자 단일체를 구하여 정적 메서드 MakeProject를 호출하여 비동기적으로 평가 프로젝트를 생성합니다.
EvalManager EM = EvalManager.Manager; EM.MakeProjectAsync(Text, ehprocess, EndMakeProject, new AddFindElementDele(AddFindElement),null); }
정보 표시 레이블들의 Visiblae 속성을 true로 설정합니다.
private void SearchLabelsShow() { lb_intro_msg.Visible = true; lb_meta_msg.Visible = true; lb_time_msg.Visible = true; lb_time_cnt.Visible = true; lb_doing_msg.Visible = true; lb_elem_cnt.Visible = true; }
void AddFindElement(int n) {
크로스 스레드 문제를 해결하기 위해 컨트롤의 InvokeRequired 속성의 참인지 확인합니다.
if (this.InvokeRequired) {
수행 스레드가 폼을 소유한 스레드가 아니면 폼의 Invoke 메서드를 호출하여 .NET 플렛폼에게 소유 스레드가 대리자에 위임한 작업을 수행할 수 있게 합니다.
this.Invoke(new AddFindElementDele(AddFindElement), new object[]{n}); }
이전까지 발견한 요소 개수와 새로 발견한 개수를 더한 값을 화면에 표시합니다.
else { int cnt = int.Parse(lb_elem_cnt.Text); lb_elem_cnt.Text = (cnt + n).ToString(); } }
타이머의 Tick 이벤트 핸들러를 등록합니다.
private void tm_search_Tick(object sender, EventArgs e) {
수행 시간을 1 증가한 값을 화면에 표시합니다.
int tcnt = int.Parse(lb_time_cnt.Text); lb_time_cnt.Text = (tcnt + 1).ToString(); }
void EndMakeProject(IAsyncResult iar) {
대리자의 위임한 행위가 끝날 때 수행하는 콜백 메서드인 EndMakeProject도 클로스 스레드 문제가 발생할 수 있습니다. 크로스 스레드 문제를 해결합니다.
if (this.InvokeRequired) { this.Invoke(new AsyncCallback(EndMakeProject), new object[] { iar }); }
폼을 닫습니다.
else { Close(); } }
using System; using System.Windows.Forms; using System.Diagnostics; namespace 접근성_평가_도우미 { public partial class ProcessSelectForm : Form { public ProcessSelectForm(string title) { InitializeComponent(); this.Text = title; } private void ProcessSelectForm_Load(object sender, EventArgs e) { ProcessList(); } private void btn_refresh_Click(object sender, EventArgs e) { ProcessList(); } void ProcessList() { lbox_process.Items.Clear(); Process[] processes = Process.GetProcesses(); foreach (Process process in processes) { if (process.Id == Process.GetCurrentProcess().Id) { continue; } if (process.MainWindowHandle != IntPtr.Zero) { EHProcess ep = new EHProcess(process); lbox_process.Items.Add(ep); } } } private void lbox_process_SelectedIndexChanged(object sender, EventArgs e) { btn_select_process.Enabled = (lbox_process.SelectedIndex != -1); } private void btn_select_process_Click(object sender, EventArgs e) { EHProcess ehprocess = lbox_process.SelectedItem as EHProcess; SearchLabelsShow(); tm_search.Start(); EvalManager EM = EvalManager.Manager; EM.MakeProjectAsync(Text, ehprocess, EndMakeProject, new AddFindElementDele(AddFindElement),null); } private void SearchLabelsShow() { lb_intro_msg.Visible = true; lb_meta_msg.Visible = true; lb_time_msg.Visible = true; lb_time_cnt.Visible = true; lb_doing_msg.Visible = true; lb_elem_cnt.Visible = true; } void AddFindElement(int n) { if (this.InvokeRequired) { this.Invoke(new AddFindElementDele(AddFindElement), new object[]{n}); } else { int cnt = int.Parse(lb_elem_cnt.Text); lb_elem_cnt.Text = (cnt + n).ToString(); } } private void tm_search_Tick(object sender, EventArgs e) { int tcnt = int.Parse(lb_time_cnt.Text); lb_time_cnt.Text = (tcnt + 1).ToString(); } void EndMakeProject(IAsyncResult iar) { if (this.InvokeRequired) { this.Invoke(new AsyncCallback(EndMakeProject), new object[] { iar }); } else { Close(); } } } }
[소스 10.10] ProjectSelectForm.cs