1) HighlightForm

HighlightForm은 선택한 자동화 요소의 사각 영역에 프로그램 방식의 하이라이트를 표시하는 폼입니다. 내부에서 수행하는 작업은 없고 사각 영역의 상, 하, 좌, 우를 네 개의 HightlightForm을 배치하여 시각적으로 감싸는 사각형 형태로 보이게 할 것입니다. 이를 위해 HighlightForm 속성을 먼저 지정하세요.

속성명속성값속성명속성값
AutoScaleModeNoneBackColorRed
EnabledFalseFormBorderStyleNone
MaximizeBoxFalseMinimizeBoxFalse
ShowIconFalseShowInTaskbarFalse
Size0,0SizeGripStyleHide
StartPositionManualTopMostTrue

[표 10.1] HighlightForm 속성

이렇게 HighlightForm은 단순히 원하는 사각 영역을 감싸는 폼입니다. 하지만 누군가는 자동화 요소의 사각 영역에 HighlightForm을 위치시키고 크기를 변경하는 엔진이 필요합니다. 프로젝트에 EHHighlight 클래스를 추가하여 이러한 역할을 표현합니다.

public class EHHighlight
{

사각 영역을 기억하는 멤버와 4 개의 HightlightForm 개체가 필요합니다.

    Rectangle rect;
    HightlightForm leftform = null;
    HightlightForm topform = null;
    HightlightForm rightform = null;
    HightlightForm bottomform = null;

테두리 두께는 4로 설정합니다.

    int bordersize = 4;

사각 영역을 가져오기 및 설정하기 속성을 제공합시다.

    public Rectangle Rect
    {
        get{    return rect;    }
        set
        {
            rect = value;

변경한 사각 영역에 맞게 상, 하, 좌, 우 폼의 속성을 변경하는 메서드를 호출합니다.

            ChangeRect();
        }
    }

보이게 하거나 숨길 때 사용할 속성을 제공합시다.

    public bool Visible
    {
        get{    return leftform.Visible;    }
        set{    ChangeVisible(value);    }
    }

생성자에서는 4개의 HighlightForm 개체를 생성합니다.

    public EHHighlight()
    {
        leftform = new HightlightForm();
        topform = new HightlightForm();
        rightform = new HightlightForm();
        bottomform = new HightlightForm();
        Rect = new Rectangle(-100, -100, bordersize, bordersize);
    }

보이게 하거나 숨기는 작업을 HighlightForm을 소유한 스레드가 아닌 스레드에서 요청할 때 크로스 스레드 문제가 발생합니다. 이를 해결하기 위해 대리자를 정의합니다.

    private delegate void ChangeVisibleDele(bool visible);
    private void ChangeVisible(bool visible)
    {

현재 수행 스레드가 HighlightForm을 소유한 스레드가 아니면 대리자를 생성하여 .NET 프레임워크에게 소유 스레드가 대리자에 위임한 메서드를 수행하게 폼의 Invoke 메서드를 호출합니다.

        if (leftform.InvokeRequired)
        {
            leftform.Invoke(new ChangeVisibleDele(ChangeVisible), new object[] { visible });
        }

폼의 Visible 속성을 설정합니다.

        else
        {
            leftform.Visible = visible;
            bottomform.Visible = visible;
            rightform.Visible = visible;
            topform.Visible = visible;
        }
    }

모든 폼을 닫을 수 있게 Close 메서드를 제공합시다.

    public void Close()
    {
        leftform.Close();
        rightform.Close();
        topform.Close();
        bottomform.Close();
    }

사각 영역을 변경하는 부분에서도 HighlightForm 개체를 소유하지 않은 스레드에서 요청하면 크로스 스레드 문제가 발생합니다. 이를 해결하기 위해 대리자를 정의합시다.

    delegate void ChangeRectDele();
    private void ChangeRect()
    {
        if (leftform.InvokeRequired)
        {

수행 스레드가 leftform을 소유한 스레드가 아니면 대리자를 생성하여 .NET 프레임워크에게 소유한 스레드에서 대리자에 위임한 메서드를 수행할 수 있게 Invoke 메서드를 호출합니다.

            leftform.Invoke(new ChangeRectDele(ChangeRect), null);
        }

사각 영역의 상, 하, 좌, 우에 네 개의 HighlightForm 개체가 위치할 수 있게 조정합니다.

        else
        {
            leftform.Left = rect.Left - bordersize;
            leftform.Top = rect.Top - bordersize;
            leftform.Width = bordersize;
            leftform.Height = rect.Height + 2 * bordersize;
            rightform.Left = rect.Right;
            rightform.Top = leftform.Top;
            rightform.Width = leftform.Width;
            rightform.Height = leftform.Height;
            ...중략...
        }
    }
}
using System.Drawing;
using System;
namespace 접근성_평가_도우미
{
    public class EHHighlight
    {
        Rectangle rect;
        HightlightForm leftform = null;
        HightlightForm topform = null;
        HightlightForm rightform = null;
        HightlightForm bottomform = null;
        int bordersize = 4;
        public Rectangle Rect
        {
            get{    return rect;    }
            set
            {
                rect = value;
                ChangeRect();
            }
        }
        public bool Visible
        {
            get{    return leftform.Visible;    }
            set{    ChangeVisible(value);    }
        }
        public EHHighlight()
        {
            leftform = new HightlightForm();   topform = new HightlightForm();
            rightform = new HightlightForm();  bottomform = new HightlightForm();
            Rect = new Rectangle(-100, -100, bordersize, bordersize);
        }
        private delegate void ChangeVisibleDele(bool visible);
        private void ChangeVisible(bool visible)
        {
            if (leftform.InvokeRequired)
            {
                leftform.Invoke(new ChangeVisibleDele(ChangeVisible), new object[] { visible });
            }
            else
            {
                leftform.Visible = visible;    bottomform.Visible = visible;
                rightform.Visible = visible;    topform.Visible = visible;
            }
        }
        public void Close()
        {
            leftform.Close();    rightform.Close();
            topform.Close();    bottomform.Close();
        }
        delegate void ChangeRectDele();
        private void ChangeRect()
        {
            if (leftform.InvokeRequired)
            {
                leftform.Invoke(new ChangeRectDele(ChangeRect), null);
            }
            else
            {
                leftform.Left = rect.Left - bordersize;
                leftform.Top = rect.Top - bordersize;
                leftform.Width = bordersize;
                leftform.Height = rect.Height + 2 * bordersize;
                rightform.Left = rect.Right;         rightform.Top = leftform.Top;
                rightform.Width = leftform.Width;   rightform.Height = leftform.Height;
                topform.Left = rect.Left;            topform.Top = leftform.Top;
                topform.Width = rect.Width;        topform.Height = bordersize;
                bottomform.Left = topform.Left;     bottomform.Top = rect.Bottom;
                bottomform.Width = topform.Width; bottomform.Height = topform.Height;
            }
        }
    }
}

[소스 10.10] EHHighlight.cs