. 선택영역 관리

문서의 일부분이 선택되면 파란색으로 반전되어 블록의 범위를 확실하게 보여준다. 사용자는 이 선택영역에 대해 복사, 삭제, 이동 등의 편집을 하게 되는데 단 편집기가 포커스를 잃었을 때는 당장 편집을 하지 않으므로 굳이 선택영역을 보여주지 않아도 된다. 오히려 선택영역을 숨기는 것이 다른 프로그램의 입장에서는 더 보기 좋을 수도 있다.

메모장을 열어 일부를 선택해놓고 다른 프로그램으로 포커스를 옮겨보자. 사용자가 당장 메모장을 사용하지 않는데도 여전히 선택영역을 표시하고 있는데 이는 바탕화면을 무척 지저분하게 보이도록 만든다. 타이틀바는 흐리게 바뀌었는데 선택영역만 짙은 색으로 계속 남아 있는 모습이 별로 보기 좋지 않다. 워드프로세서나 웹브라우저 같은 제대로 만든 프로그램은 포커스를 잃었을 때, 즉 현재 사용자가 자기에게 관심을 보이지 않을 때는 선택영역을 숨겨 눈에 거슬리지 않도록 배려한다.

물론 이 기능은 상황에 따라 필요할 수도 있고 아닐 수도 있다. 포커스를 잃어도 여전히 선택영역을 보여 줘야 하는 경우도 있고 좀 다른 방식으로 선택영역을 표시하는 것이 더 좋은 경우도 있는 것이다. 그래서 에디트나 리스트 뷰 같은 컨트롤은 포커스가 없을 때 선택영역을 어떻게 표시할 것인가를 지정하는 스타일을 가지고 있고 이 스타일로 선택영역 숨김 여부를 사용자가 선택하도록 해놓았다.

ApiEdit도 이 기능을 넣어 보도록 하자. 단순히 숨김, 표시뿐만 아니라 흐리게 표시할 수 있는 기능도 넣어 볼 것이다. 블록 숨김 옵션은 앞에서 이미 선언해놓은 HideSelType이라는 전역변수로 지정하며 이 변수의 값은 다음과 같이 정의하였다.

 

설명

0

선택영역을 숨긴다.

1

흐리게 표시한다.

2

포커스를 잃어도 선택영역을 보여준다.

 

더 많은 옵션을 만들 수도 있지만 일단 이 정도면 사용자의 취향을 맞추기에 부족하지 않을 것이다. 이 옵션들 중 가장 합리적인 값은 흐리게 표시하는 1번 값이며 그래서 OnCreate에서 HideSelType의 값을 1로 초기화하였다. 선택영역을 숨기는 방법은 간단하다. DrawLine에서 HideSelType 0이고 포커스를 잃은 상태이면 선택영역을 무시하면 된다. 다음 조건문 하나면 선택영역을 간단하게 숨길 수 있다.

 

int DrawLine(HDC hdc, int Line)

{

     ....

          if (bInSel && (GetFocus()==hWndMain || HideSelType!=0)) {

               fore=SelFore;

               back=SelBack;

          } else {

               fore=RGB(0,0,0);

               back=GetSysColor(COLOR_WINDOW);

          }

 

선택 상태로 출력하려면 일단 이 조각이 선택되어 있어야 하고(bInSel == TRUE) 포커스를 가지고 있거나 HideSelType 0이 아니어야 한다. 즉 조각이 선택되어 있는 상태라도 포커스가 없고 HideSelType 0이면 조각이 선택되지 않은 것으로 간주함으로써 선택영역을 숨긴다. 1 2의 차이는 선택영역을 표시하기는 하되 색상을 어떻게 출력할 것인가만 다르다. 이 처리는 포커스 변동시에 SelFore, SelBack을 바꾸면 된다.

 

void OnSetFocus(HWND hWnd, HWND hwndOldFocus)

{

     SetCaret(FALSE,FALSE);

 

     SelFore=GetSysColor(COLOR_HIGHLIGHTTEXT);

     SelBack=GetSysColor(COLOR_HIGHLIGHT);

 

    if (HideSelType != 2 && SelStart != SelEnd) {

        InvalidateRect(hWnd,NULL,TRUE);

    }

}

 

void OnKillFocus(HWND hWnd, HWND hwndNewFocus)

{

     DestroyCaret();

 

    if (HideSelType != 2) {

        SelFore=RGB(0,0,0);

        SelBack=RGB(192,192,192);

    }

    if (HideSelType != 2 && SelStart != SelEnd) {

        InvalidateRect(hWnd,NULL,TRUE);

    }

}

 

포커스를 받았을 때 SelFore, SelBack을 시스템 하이라이트 색상으로 바꿔 주고 포커스를 잃으면 회색 바탕에 검정색으로 바꾸어 준다. 선택영역의 색상이 바뀌면 작업영역을 무효화하여 다시 그리도록 해야 한다. , 선택영역이 없거나 HideSelType 2인 경우, 즉 항상 표시일 때는 굳이 다시 그릴 필요가 없다.

 

HideSelType을 바꿔 가며 숨김, 흐리게 표시가 제대로 되는지 테스트해보자. 여러 번 테스트해보면 알겠지만 선택영역은 숨기는 것보다 흐리게 표시하는 것이 가장 보기에 좋은 것 같다. , 이 처리는 선택영역 표시를 잠시 숨기는 것이지 선택 자체를 해제하는 것은 아니다.