. 덮어쓰기와 캐럿 위치

덮어쓰기 모드일 때는 삽입 상태가 아니라는 것을 확실하게 보여주기 위해 캐럿이 문자폭만큼 차지하도록 되어 있다. 그러다 보니 한 가지 문제가 생겼는데 자동개행된 줄 끝에서 캐럿이 이동할 때 움직임이 매끄럽지 못하다는 점이다. 다음과 같이 문장을 입력해놓고 자동개행된 줄의 끝으로 캐럿을 가져가 보자.

다음에서 오른쪽으로 이동하면 자로 가는데 다음에서 오른쪽으로 이동하면 자로 가는 것이 아니라 줄 끝으로 이동한다. 한 번 더 오른쪽으로 이동해야만 캐럿이 비로소 다음 줄 처음으로 가게 된다. 왼쪽으로 이동할 때도 마찬가지 증상이 있다. 이렇게 이동하다 보니 캐럿이 자동개행된 줄의 끝에 있을 때는 다 보이지도 않고 일부만 보이게 된다.

ApiEdit는 줄 끝과 다음 줄의 처음이 같은 오프셋이라도 bLineEnd 플래그에 따라 캐럿 위치를 다르게 인식하기 때문에 이런 문제가 발생하였다. bLineEnd는 꼭 필요한 플래그이지만 덮어쓰기 모드에서는 오히려 문제를 일으키고 있는 것이다. 삽입 모드에서는 캐럿이 문자들의 사이에 위치하여 다음 삽입 위치를 표시하지만 덮어쓰기 모드에서는 문자 자체에 캐럿이 위치한다. 그래서 bLineEnd가 의미가 없다.

문제가 있다는 것을 알았으면 수정해야 하는데 정확한 원인을 파악했으므로 수정하기는 어렵지 않다. 덮어쓰기 모드일 때는 bLineEnd와 관련된 모든 코드를 무시하면 된다. 그렇게 수정하기만 하면 이 문제가 없어지므로 독자분들이 직접 수정하도록 하자. 나는 너무 귀찮아서 그렇게 하지 않을 작정이다. bLineEnd는 프로그램 전반을 통제하는 중요한 변수이고 참조하는 곳도 많은데 이 부분을 건드리는 것은 보통 피곤한 일이 아니다.

이 문제로 인해 ApiEdit는 덮어쓰기 모드일 때 캐럿이동이 조금 불편해졌다. 그러나 그뿐이다. 이 버그로 인해 프로그램이 다운된다거나 문서가 파괴되는 치명적인 문제는 없다. 그러나 약간 이상 동작을 하는 부분은 솔직히 있었다. SetCaret 함수를 보면 캐럿이 화면에 다 보이지 않을 때 캐럿이 보이도록 스크롤하는 코드가 있는데 캐럿이 줄 끝에 있는 상태에서 캐럿의 일부만 보이면 수평으로 강제 스크롤되는 것이다. 그래서 이 문제를 다음과 같이 이미 해결해놓았다.

 

void SetCaret(BOOL bUpdatePrevX/*=TRUE*/, BOOL bScrollToCaret/*=TRUE*/)

{

     ....

     if (bScrollToCaret) {

          if (nWrap==0) {

              if ((x+caretwidth > xPos+frt.right) || (x < xPos+MarginWidth)) {

                   xPos=max(0,x-frt.right/2);

                   bScroll=TRUE;

              }

          }

 

자동개행 상태에서만 문제가 되므로 nWrap 0일 때만 수평으로 캐럿을 따라 스크롤되도록 하였다. 사실 덮어쓰기 모드에서 캐럿이 숨지만 않는다면 굳이 if (nWrap==0)조건이 있어야 할 이유는 없다. 이 처리를 추가함에 따라 덮어쓰기 모드에서 캐럿이동은 약간 불편한 것 외에는 일체의 다른 문제가 없으며 따라서 수정하지 않는다. 수정하지 않겠다고 하면 여러분들은 분명히 이상하게 생각할 것이다.

모르고 들어가는 버그는 어쩔 수 없지만 알고 있으면서도 고치지 않는다고? , 조금이라도 사용자가 불편하면 고쳐야지 책임감이 없군 이렇게 책망하겠지만 그래도 이 버그는 고치지 않는다. 개발자는 변명에도 능숙해야 하는데 잠시 쉬었다가 계속해서 변명을 들어 보도록 하자.