. 문단 관리 함수 사용

문단 관리 함수들이 완성됨으로써 코드의 몇몇 부분을 좀 더 효율적으로 수정할 수 있다. 문단의 개념은 애초 ApiEdit7에서 북마크를 만들 때부터 필요했었으나 이 함수들의 구현이 다소 어려운 것 같아 지금까지 계속 미루어 왔었다. 다행히 문단 개념을 필요로 하는 부분이 많지 않아 지금까지 순차 검색으로 문단을 찾거나 드물게 발생하는 노운 버그를 그냥 남겨 두었었는데 이제 확실하게 수정해보자.

인수로 전달된 문단으로 이동하는 GotoLine 함수를 먼저 수정한다. 이 함수를 작성할 시점에는 문단번호로 오프셋을 찾아가는 함수가 없었기 때문에 pLine을 처음부터 끝까지 뒤지면서 문단을 찾는 순차 검색을 했었다. 이제 GetOffFromPara 함수로 문단의 시작점을 좀 더 간편하게 찾아갈 수 있으므로 비효율적인 순차 검색 코드를 삭제하고 다음과 같이 수정한다.

 

void CApiEdit::GotoLine(int Line, int Col/*=0*/, int Type/*=0*/)

{

     int tLine;

    int toff;

     ClearSelection();

 

     switch (Type) {

     case 0:

          tLine=min(Line,TotalLine-1);

          off=GetOffFromRC(Line,Col);

          break;

     case 1:

        toff=GetOffFromPara(Line,Col);

        if (toff!=-1) {

           off=toff;

        }

          break;

     }

     SetCaret();

}

 

GetOffFromPara 함수는 이동할 문단번호와 칸 번호를 인수로 전달하기만 하면 이 위치의 오프셋이 어디인지 조사한다. 조사된 오프셋으로 off 변수를 변경한 후 SetCaret만 호출하면 캐럿이 있는 위치로 즉시 이동할 것이다. 문단번호가 범위를 벗어날 경우 -1을 리턴하는데 이 때는 아무 것도 하지 않으면 된다. 북마크가 설정된 곳을 찾아가는 GotoBookmark 함수도 바로 문단을 찾아갈 수 있다. 순차 검색 코드를 삭제하고 다음과 같이 수정하도록 하자.

 

void CApiEdit::GotoBookmark(int Mark)

{

     ....

     GotoLine(Para,0,1);

}

 

다음으로 수정할 곳은 검색결과로부터 지정된 위치로 찾아가는 OpenFileFromOutput 함수이다. 이 함수는 검색결과창에 쓰여진 대로 검색된 위치를 찾아내는데, 일반적으로 정상 동작하지만 검색 후에 파일을 수정했으면 검색 위치를 제대로 찾지 못하는 문제가 있다. 제대로 찾지 못할 뿐만 아니라 이전 위치에 문자가 없어졌거나 한글의 경계에 걸치면 치명적인 에러를 유발시키기도 한다.

이 함수를 작성할 시점에 이미 문제를 알고 있었지만 파일이 수정되었는지의 여부를 확인할 방법이 없어 당분간 노운 버그로 남겨 두었었는데 이제 검색결과가 지정하는 오프셋을 정확하게 구할 수 있으므로 찾아가기 전에 에러 여부를 미리 알 수 있게 되었다. 이 함수를 다음과 같이 수정한다.

 

void OpenFileFromOutput(int idx)

{

     ....

     toff=pSi->Ae.GetOffFromPara(line,col);

     pSi->Ae.GetText(Text,MAX_PATH,toff,toff+lstrlen(LastFIF));

     if (stricmp(Text,LastFIF) != 0) {

          MessageBox(g_hFrameWnd,"검색 후에 파일이 수정되었습니다. "

              "검색된 줄의 첫 위치로 이동합니다.","알림",MB_OK);

          toff=pSi->Ae.GetOffFromPara(line,0);

          pSi->Ae.GotoLine(line,0,1);

     } else {

          pSi->Ae.GotoLine(line,col,1);

          pSi->Ae.SetSelect(toff,toff+lstrlen(LastFIF),TRUE);

     }

}

 

검색 결과에 기록된 문단번호와 문단 내의 칸 번호의 텍스트를 실제로 읽어 보고 만약 검색한 문자열(LastFIF)과 일치하지 않으면 검색 후에 파일이 수정된 것으로 판단한다. 이때는 파일이 수정되어 정확한 위치를 다시 찾을 수 없다는 에러 메시지를 출력하고 문단의 시작위치로만 캐럿을 옮겨주도록 했다. 문단번호와 칸 번호로 오프셋을 찾아주는 GetOffFromPara 함수가 작성되어 있기 때문에 검색결과로부터 문서내의 지정한 위치의 문자열을 구할 수 있게 되었다.

지금까지 작성한 코드 중에 문단 관리 함수가 꼭 필요한 부분은 이 정도뿐이다. 하지만 앞으로의 편집코드에서는 문단 관리 함수들이 아주 많이 사용될 것이다. ApiEdit를 더 깊이 이해해보고 싶다거나 직접 개선해보고 싶다면 이 함수들에 빨리 익숙해져야 한다.