. 레코드 관리 함수 호출.

편집 동작을 기록하는 모든 함수를 완성했다. 이제 문서가 실제로 편집될 때 이 함수들을 호출하여 취소 레코드를 작성하도록 해야 한다. 문서를 편집하는 함수를 찾아 적당한 위치에서 이 함수들을 호출하면 된다. 먼저 문자열이 삽입되는 시점인 Insert 함수를 보자.

 

void CApiEdit::Insert(int nPos, TCHAR *str, BOOL bRec/*=TRUE*/)

{

     if (bReadOnly)

          return;

 

    if (bRec) {

        URInsert(nPos,str);

    }

     ....

 

함수 원형에 bRec 인수가 추가되어 있음을 유의하자. 이 인수가 TRUE인 경우만 취소 레코드를 작성해야 한다. bRec TRUE이면 URInsert 함수를 호출하여 문자열이 삽입된 위치와 삽입된 문자열을 전달한다. URInsert 함수는 Insert 함수가 제공한 정보를 참조하여 새로 레코드를 만들든지 아니면 기존 레코드에 병합을 하든지 하여 어쨌든 방금 삽입한 동작에 대한 기록을 작성해놓을 것이다. 다음은 삭제할 때인 Delete 함수를 수정한다.

 

void CApiEdit::Delete(int nPos, int nCount, BOOL bRec/*=TRUE*/)

{

    TCHAR *t;

 

     if (bReadOnly)

          return;

 

     if (nCount == 0) return;

     if (doclen < nPos+nCount) return;

 

    if (bRec) {

        t=(TCHAR *)malloc(nCount+1);

        lstrcpyn(t,p,nCount+1);

        URDelete(nPos,t);

        free(t);

    }

     ....

 

Delete 함수는 삭제할 문자열의 위치와 길이만 전달받기 때문에 삭제할 문자열에 대한 정보는 가지고 있지 않다. 그래서 임시버퍼 t에 삭제대상 문자열을 조사한 후 이 문자열을 URDelete 함수로 넘겨 주었다. 다음은 마우스로 문자열을 드래그할 때 이동 및 복사처리를 하는 CopyString 함수를 수정하자.

 

void CApiEdit::CopyString(BOOL bCopy, int from, int &to, int len, BOOL bRec/*=TRUE*/)

{

     ....

    if (bRec) {

        if (bCopy) {

           URInsert(to,t);

        } else {

           URMove(from,orito,t);

        }

    }

     free(t);

}

 

복사할 때는 새로 문자열이 삽입되는 것이므로 URInsert 함수를 대신 호출하며 이동할 때는 URMove 함수를 호출하여 이동동작을 기록하도록 하였다.

이 세 함수가 취소 레코드를 작성하는 URInsert, URDelete, URMove 함수와 직접적으로 대응되는 함수들이다. 이 함수들 외에 문서편집이 일어나는 곳이 한 군데가 더 있는데 바로 OnImeChar 함수이다.

 

LRESULT CApiEdit::OnImeChar(HWND hWnd, WPARAM wParam, LPARAM lParam)

{

     TCHAR szChar[3];

 

     if (IsDBCSLeadByte((BYTE)(wParam >> 8))) {

          szChar[0]=HIBYTE(LOWORD(wParam));

          szChar[1]=LOBYTE(LOWORD(wParam));

          szChar[2]=0;

     } else {

          szChar[0]=(BYTE)wParam;

          szChar[1]=0;

     }

 

     if (bComp) {

        URInsert(off-lstrlen(szChar),szChar);

          buf[off-2]=szChar[0];

          buf[off-1]=szChar[1];

     } else {

 

이 함수는 조립중인 문자가 완성될 때 Insert 함수를 호출하지 않고 버퍼를 직접 조작한다. 그래서 여기서도 URInsert 함수를 호출하여 새 문자가 삽입되었음을 기록해야 한다. 이 코드는 사실상 원칙적으로 꼭 필요하지는 않다. 그러나 한글조립중에 재정렬 생략을 위해 OnImeChar를 최적화했기 때문에 이 코드를 작성해야 할 필요가 있다. 만약 OnImeChar가 조립중에라도 Delete로 지우고 Insert로 삽입하도록 했다면 여기서 URInsert를 호출할 필요는 없다. 최적화에 의해 코드의 일관성이 깨진 좋은 예이다.