. 선택영역의 색상

HideSelType 옵션은 포커스를 잃었을 때 선택영역을 어떻게 처리할 것인가를 지정하는데 흐리게 표시하거나 아니면 아예 선택영역을 숨길 수 있다. 이 옵션은 보통의 경우라면 별 문제가 없지만 찾기 대화상자가 검색결과를 보여줄 때는 문제가 된다. 찾기 대화상자가 떠 있는 동안에는 ApiEdit가 포커스를 가진 것이 아니므로 이 옵션의 영향을 받아 검색결과가 흐리게 보일 것이다. 흐리게라도 보이면 다행인데 HideSelType 0이면 아예 검색결과가 보이지 않게 될 것이다.

이 문제를 해결하려면 찾기에 의해 선택된 블록은 HideSelType 설정상태와 포커스에 상관없이 항상 보이도록 해야 한다. 사용자가 직접 선택한 블록과 찾기 기능에 의해 선택된 블록이 구분되어야 한다는 얘기인데 ApiEdit는 단 하나의 선택영역만 허용하므로 블록 자체를 다르게 취급할 수는 없다. 다만 플래그를 두고 찾기에 의해 선택된 블록은 다르게 그리도록 할 수는 있다. 다음 플래그를 추가하고 생성자에서 FALSE로 초기화한다.

 

class CApiEdit

{

     ....

     BOOL bFindSelect;

 

CApiEdit::CApiEdit()

{

     bFindSelect=FALSE;

}

 

bFindSelect는 지금 선택된 블록이 찾기에 의해 선택된 것인지 사용자가 선택해놓은 것인지를 구분하는 플래그이다. 이 값이 TRUE이면 찾기에 의해 블록이 선택된 것이다. 블록을 선택하는 SetSelect 함수를 수정하여 선택영역이 찾기에 의한 선택인지를 인수로 전달받도록 한다.

 

void CApiEdit::SetSelect(int s, int e, BOOL bFind)

{

     if (s <= doclen && e <= doclen) {

          SelStart=s;

          if (e == -1)

              e=doclen;

          SelEnd=e;

     }

     off=SelEnd;

     SetCaret();

    if (bFind) {

        bFindSelect=TRUE;

    }

     Invalidate(-1);

}

 

이 함수는 한참 옛날에 GetSelect 함수를 만들 때 같이 만들어 두었던 것이며 FindText 함수에서 처음 사용했는데 벌써 원형이 바뀌었다. 이럴 줄 알았으면 아예 만들어 두지 말걸 약간 억울하다. 인수로 전달된 bFind bFindSelect 멤버변수에 저장할 뿐 별다른 일은 하지 않는다. FindText에서 찾기에 성공한 후 이 플래그를 TRUE로 변경하여 지금 선택한 블록은 찾기에 의해 선택된 것임을 표시해놓는다.

 

BOOL CApiEdit::FindText(int nPos, TCHAR *what, DWORD dwFlag)

{

     ....

     if (pFound) {

          SetSelect(pFound-buf,pFound-buf+lstrlen(what),TRUE);

          return TRUE;

     }

     return FALSE;

}

 

사용자가 직접 블록을 선택했으면 bFindSelect FALSE 값을 가질 것이며 FindText에 의해 선택된 블록이면 bFindSelect TRUE가 될 것이다. 이 플래그를 사용하는 곳은 선택영역을 직접 그리는 DrawLine 함수이다.

 

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

           if (bFindSelect) {

               fore=cSelFore;

               back=cSelBack;

           } else {

                   fore=SelFore;

                   back=SelBack;

           }

          } else {

              if (len==0) {

          ....

 

선택영역의 색상을 적용할 조건에 bFindSelect가 하나 더 추가되었다. 포커스를 가지고 있거나 선택영역 숨김 상태가 아니거나 검색에 의해 찾은 문자열이면 선택영역 색상으로 블록을 그린다. 즉 포커스가 없고 HideSelType 0이더라도 bFindSelect TRUE이기만 하면 선택영역을 제대로(흐리게 표시하지 않고) 그리도록 하였다. 따라서 찾기에 의해 선택된 블록은 항상 제대로 보이게 된다. 여러 개의 조건이 복합적으로 평가되기 때문에 조금 복잡해보이지만 조금만 생각해보면 당연한 조건들이다.

bFindSelect 플래그는 어디까지나 임시적인 상태이므로 사용자가 직접 선택을 할 때는 즉시 해제되어야 한다. 그래야만 사용자의 블록이 HideSelType 옵션값을 제대로 반영한다. 이 플래그를 해제하는 시기는 두 군데가 있다.

 

void CApiEdit::OnLButtonDown(HWND hWnd, BOOL fDoubleClick, int x, int y, UINT keyFlags)

{

     ....

    bFindSelect=FALSE;

     bShift=((GetKeyState(VK_SHIFT) & 0x8000) != 0);

     bControl=((GetKeyState(VK_CONTROL) & 0x8000) != 0);

 

void CApiEdit::OnKey(HWND hWnd, UINT vk, BOOL fDown, int cRepeat, UINT flags)

{

     ....

     if (fDown==FALSE)

          return;

 

    bFindSelect=FALSE;

     ....

 

마우스 버튼을 클릭하기만 하면 검색 문자열 상태가 해제된다. 키보드로 어떤 문자라도 입력하면 해제되는데 예를 들어 찾기를 한 상태에서 캐럿을 움직이거나 다른 문자를 입력하면 이 블록은 즉시 해제된다. 두 함수는 사용자의 직접적인 입력을 받아들이는 함수라는 점에서 공통적이다. 이후 선택되는 블록은 HideSelType 설정대로 표시될 것이다.