. 선택영역 삭제

선택영역을 지정한 후 여러 가지 작업을 할 수 있는데 그 중 가장 빈도가 높은 작업이 바로 삭제하는 것이다. 문서의 일부분을 선택한 후 <Del>키를 누르면 선택한 부분만 삭제해야 한다. 또한 이 기능은 꼭 <Del>키나 <BS>키를 누를 때뿐만 아니라 선택이 있는 상태에서 새로운 문자를 입력할 때도 필요하다. 문장을 선택해놓고 다른 문장을 입력한다는 것은 선택영역을 새로운 문장으로 대체한다는 뜻이다. 이 동작을 하기 위해서는 선택영역만 삭제하는 함수가 필요하다. 다음 함수를 추가하도록 하자.

 

BOOL DeleteSelection()

{

     int SelFirst, SelSecond;

 

     if (SelStart != SelEnd) {

          SelFirst=min(SelStart,SelEnd);

          SelSecond=max(SelStart,SelEnd);

          Delete(SelFirst,SelSecond-SelFirst);

          SelStart=SelEnd=0;

          off=SelFirst;

          return TRUE;

     }

     return FALSE;

}

 

선택영역이 있으면 정규화한 후 Delete 함수를 호출하여 이 영역을 삭제한다. 그리고 선택영역은 해제하고 캐럿은 선택영역의 처음 위치로 보낸다. 선택영역을 삭제했으면 TRUE를 리턴하고 아예 선택영역이 없었다면 FALSE를 리턴하였다. 선택영역이 삭제되면 화면을 다시 그려야 하고 캐럿도 옮겨야 하는데 이 작업은 DeleteSelection에서 하지 않고 호출원에서 직접 하도록 하였다. 그다지 어려운 내용이 없는 간단한 함수다.

문자열이 입력되는 곳마다 이 함수를 호출해야 하는데 많지는 않고 세 군데뿐이다. 먼저 명시적으로 문장을 삭제하는 VK_DELETE에서 이 함수를 불러준다.

 

     case VK_DELETE:

        if (DeleteSelection()==FALSE) {

               if (IsDBCS(off)) {

                   Delete(off, 2);

               } else {

                   Delete(off, 1);

               }

        }

          InvalidateRect(hWnd,NULL,TRUE);

          SetCaret();

          return;

 

DeleteSelection을 먼저 부르고 이 함수가 TRUE를 리턴했으면, 즉 선택영역이 있었으면 캐럿만 옮긴다. 선택영역이 없었다면 한 문자를 삭제하면 된다. <BS>키도 선택영역을 삭제하는 기능을 가져야 하는데 현재 BS <Del>키의 기능을 빌려서 쓰고 있기 때문에 별도의 코드를 추가하지 않아도 된다.

다음은 선택 상태에서 문자열이 입력될 때 선택을 삭제하도록 하자. 영문자는 OnChar에서 입력되므로 이 함수에서 문자열을 삽입하기 전에 DeleteSelection 함수만 부르면 된다. , 선택영역이 있으면 무조건 지워버리고 문자를 입력받는다.

 

void OnChar(HWND hWnd, TCHAR ch, int cRepeat)

{

     ....

    DeleteSelection();

     for (i=0;i<cRepeat;i++) {

          Insert(off,szChar);

          off+=lstrlen(szChar);

     }

     bComp=FALSE;

     InvalidateRect(hWnd,NULL,TRUE);

     SetCaret();

}

 

한글은 조립이 시작될 때 선택영역을 삭제해야 하므로 OnImeComposition에서 이 함수를 부르면 된다.

 

LRESULT OnImeComposition(HWND hWnd, WPARAM wParam, LPARAM lParam)

{

     HIMC hImc;

     TCHAR *szComp;

     int len;

 

    DeleteSelection();

     hImc=ImmGetContext(hWnd);

     ...

 

언뜻 생각하기에 글자가 완성되는 OnImeChar에서 선택영역을 삭제해야 할 것 같지만 조립이 시작되는 시점에서 삭제해야 한다. 조립을 시작할 때 선택영역을 삭제하면  OnImeChar가 호출될 때는 선택이 남아 있을 수가 없다.