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

9. 접근성 도구 만들기 - 15. ProjectSelectForm

언제나휴일 2017. 12. 12. 13:39
반응형

9.3.3 ProjectSelectForm



 

 ProjectSelectForm은 메인 창이 있는 프로세스 목록을 보여주어 평가 대상을 선택하는 폼입니다. 그리고 선택한 평가 대상 프로세스로 평가 프로젝트를 생성하고 요소 정보를 수집하여 초기화 과정이 완료하는 것을 비동기적으로 처리하는 부분을 구현합시다.

 

[그림 9.12] ProcessSelectForm 배치

[그림 9.12] ProcessSelectForm 배치

 

번호

컨트롤 형식

컨트롤 이름

특이 사항

1

Button

btn_refresh

 

2

Button

btn_select

Enabled 속성을 False로 설정

3

ListBox

lbox_process

Dock 속성을 Fill로 설정

4

Label

lb_time_cnt

Visible 속성을 False로 설정

5

Label

lb_elem_cnt

Visible 속성을 False로 설정

6

Timer

tm_search

Interval 1000으로 설정

7

Label

lb_intro_msg

Visible 속성을 False로 설정

8

Label

lb_meta_msg

Visible 속성을 False로 설정

9

Label

lb_time_msg

Visible 속성을 False로 설정

10

Label

lb_doing_msg

Visible 속성을 False로 설정

[ 9.3] HighlightForm의 자식 컨트롤

 

 생성자 메서드는 프로젝트 제목을 입력인자로 전달받습니다. 그리고 폼 초기화 수행 후 폼의 타이틀을 입력인자로 받은 프로젝트 제목으로 설정합니다.

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();

}

 

 

 

 프로세스 항목을 얻어오는 메서드에서는 프로세스 항목을 보여줄 lbox_process 컨트롤의 아이템 항목을 지웁니다. 그리고 모든 프로세스 항목을 얻어와서 프로세스 ID가 자신과 다르고 메인 창의 핸들이 있을 때 EHProcess 개체로 래핑하여 리스트 박스 항목에 추가합니다.

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);

        }

    }

}

 

 lbox_process 컨트롤의 선택 항목 변경 이벤트 핸들러를 추가하여 선택 항목이 존재 여부에 따라 btn_select_process Enabled 속성을 변경합니다.

private void lbox_process_SelectedIndexChanged(object sender, EventArgs e)

{

    btn_select_process.Enabled = (lbox_process.SelectedIndex != -1);

}

  

 

 btn_select_process를 클릭 이벤트 핸들러를 추가합시다. 핸들러에서는 선택한 프로세스를 참조합니다. 그리고 프로젝트를 생성 요청하기 전에 비동기 작업을 기다리는 동안 수행 시간과 검색한 요소 개수를 보여주기 위한 레이블의 Visible 속성을 변경하고 타이머를 시작합니다. 그리고 선택한 프로세스로 평가 프로젝트를 생성합니다.

private void btn_select_process_Click(object sender, EventArgs e)

{

    EHProcess ehprocess = lbox_process.SelectedItem as EHProcess;

    SearchLabelsEnable();

    tm_search.Start();

    EvalManager EM = EvalManager.Manager;

    EM.MakeProjectAsync(Text, ehprocess, EndMakeProject,

              new AddFindElementDele(AddFindElement),null);

}

private void SearchLabelsEnable()

{

    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;

}

 요소 검색이 되었음을 통보받는 메서드에서는 lb_elem_cnt Text 속성을 변경합니다.

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();

    }

}

 

 타이머의 틱 이벤트 핸들러를 추가하고 이벤트 핸들러에서는 lb_time_cnt Text속성을 변경합니다.

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();

    }

}

 

 참고로 컨트롤의 속성을 변경하는 메서드에서 InvokeRequired 속성을 확인하는 이유는 컨트롤을 소유한 쓰레드에서만 속성을 변경하기 위해서입니다. Windows Form 에서는 컨트롤을 소유하지 않은 쓰레드에서 컨트롤의 속성을 변경하려고 하면 크로스 쓰레드 문제가 발생합니다.

반응형