. 줄 정보 조사

pLine에 줄의 정보를 조사하는 함수를 다음과 같이 작성한다. 문서 전체를 딱 한 번만 정렬하므로 함수 내용은 아주 간단하다.

 

void UpdateLineInfo()

{

     int l,s,e;

 

     for (l=0;;l++) {

          GetLine(l,s,e);

 

          pLine[l].Start=s;

          pLine[l].End=e;

          if (s==-1) {

               TotalLine=l;

               break;

          }

     }

}

 

0번째 줄부터 GetLine을 호출하여 줄 정보를 조사하되 GetLine s -1을 리턴할 때까지, 즉 문서의 끝까지 반복한다. 그래서 이 함수가 호출되면 문서의 처음부터 끝까지 스캔하면서 줄 정보를 배열에 다시 작성하게 된다. 루프가 종료될 때 TotalLine 변수는 문서의 총 줄 수를 가지게 될 것이다.

줄 정보는 문서가 조금이라도 변경되면 다시 작성해야 하므로 버퍼를 조작하는 모든 함수에서 UpdateLineInfo 함수를 호출해야 하는데 다섯 군데가 있다. 먼저 버퍼를 초기화하는 OnCreate에서부터 줄 정보를 초기화한다.

 

BOOL OnCreate(HWND hWnd, LPCREATESTRUCT lpCreateStruct)

{

     ....

    UpdateLineInfo();

     UpdateScrollInfo();

     ....

 

최초 빈 문서로 시작하므로 이때의 호출은 pLine[0]만 초기화하게 될 것이다. 변경된 줄 정보는 스크롤 범위 설정에 곧바로 사용되므로 UpdateScrollInfo보다 먼저 호출되어야 한다. 윈도우의 크기가 변경될 때도 줄 정보를 다시 작성한다.

 

void OnSize(HWND hWnd, UINT state, int cx, int cy)

{

     if (state != SIZE_MINIMIZED) {

        if (nWrap) {

            UpdateLineInfo();

        }

          UpdateScrollInfo();

          if (GetFocus()==hWnd) {

               SetCaret();

          }

     }

}

 

, 자동개행 상태가 아닐 때는 윈도우 크기 변경 자체가 정렬에 영향을 주지 않으므로 nWrap 0일 때는 굳이 이 함수를 호출하지 않아도 된다. 그 외의 경우는 폭이 바뀔 때마다 각 줄의 끝이 바뀌므로 재정렬해야 한다. 버퍼에 문자열을 삽입, 삭제하는 Insert, Delete도 당연히 이 함수를 호출해야 한다. 한 글자라도 삽입되거나 삭제되면 문서 전체의 정렬 상태가 바뀔 수 있다.

 

void Insert(int nPos, TCHAR *str)

{

     ....

     bLineEnd=FALSE;

    UpdateLineInfo();

     UpdateScrollInfo();

}

 

void Delete(int nPos, int nCount)

{

     ....

    UpdateLineInfo();

     UpdateScrollInfo();

}

 

보다시피 항상 스크롤 정보를 갱신하기 전에 정렬정보를 먼저 갱신해야 한다. 재정렬을 해야 하는 마지막 시점은 자동개행 상태를 변경하는 SetWrap 함수에서이다. 정렬방식이 바뀌면 줄의 시작과 끝도 따라서 바뀌게 된다.

 

int SetWrap(int aWrap)

{

     ....

    UpdateLineInfo();

     UpdateScrollInfo();

     SetCaret();

 

     return Old;

}

 

문서나 정렬 상태에 변화가 생기는 모든 부분에서 UpdateLineInfo 함수를 호출하여 줄 정보를 다시 만들도록 했으므로 pLine 배열은 항상 제대로 된 줄 정보를 가지고 있을 것이다.