. 새 문서

파일 입출력 기능이 들어가면 문서를 만들던 중에 편집을 취소할 수도 있고 다른 문서를 불러 올 수도 있다. 이때마다 ApiEdit는 새 문서를 만들기 위해 초기화되어야 한다. 지금까지는 모든 초기화를 OnCreate에서 했었는데 컨트롤 생성 후 문서를 새로 만들거나 기존 문서를 읽어올 수 없었기 때문에 별 문제가 없었다. 하지만 이제는 편집중에 새 문서를 만들 수 있기 때문에 OnCreate에 있는 초기화 코드 중 일부는 실행중에도 호출되어야 한다.

, 컨트롤 전역적인 초기화와 문서편집을 위한 초기화 코드가 나누어져야 한다. 문서와 관련된 초기화 코드를 별도의 함수에 작성하고 새 문서를 만들 때마다 이 함수를 호출하도록 바꾸어 보자. InitDoc이라는 멤버함수를 추가하고 OnCreate에 있는 초기화 코드 중 문서와 관련된 코드를 모두 가져 온다. ApiEdit.h에 함수의 원형을 선언하고 ApiEdit.cpp에 함수의 코드를 작성하면 된다. 멤버함수가 추가될 때 헤더 파일에 원형 선언을 빼먹지 말도록 하자.

 

void CApiEdit::InitDoc()

{

     int i;

 

    if (buf) {

        free(buf);

    }

     buflen=1024;

     buf=(TCHAR *)malloc(buflen);

     memset(buf,0,buflen);

     doclen=0;

     Linelen=100;

    if (pLine) {

        free(pLine);

    }

     pLine=(tagLine *)malloc(sizeof(tagLine)*Linelen);

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

          pLine[i].Start=-1;

     }

     bReadOnly=FALSE;

     bOvr=FALSE;

     off=0;

     PrevX=0;

     bLineEnd=FALSE;

     xMax=1024;

     xPos=0;

     yPos=0;

     SelStart=SelEnd=0;

     bModified=FALSE;

     ClearBookmark();

     UpdateLineInfo();

     UpdateScrollInfo();

    if (GetFocus()==hWnd) {

        SetCaret();

    }

    Invalidate(-1);

}

 

새로 만들어지는 문서이므로 off는 당연히 문서 처음인 0으로 변경되어야 하며 북마크는 모두 해제하고 스크롤 위치도 문서 좌상단으로 변경해야 한다. 보다시피 OnCreate에 있는 코드 중 문서 초기화와 관련된 코드들이 이 함수로 모두 옮겨졌다. 옮겨진 코드 외에 추가된 코드도 있는데 굵게 표시된 코드는 새로 추가된 코드이다.

전에는 버퍼를 한 번 할당해놓고 계속 사용했었는데 이제는 문서가 만들어질 때마다 할당을 해제하고 다시 할당해야 할 필요가 생겼다. 이전 문서가 10MB 크기라고 해서 새로 만드는 문서도 이만큼의 메모리가 필요한 것은 아니기 때문이다. 그래서 buf가 할당되어 있으면 먼저 해제하고 작은 크기로 다시 할당하도록 했다. 문서가 새로 만들어지므로 캐럿도 당연히 좌상단으로 이동해야 한다. 제일 끝에 있는 Invalidate문은 화면을 완전히 지우고 다시 그리도록 하는데 OnCreate에서는 이 처리가 필요없었지만 문서편집중에 초기화를 하는 것이므로 이전 문서 내용을 화면에서 지워야 한다.

OnCreate는 많은 양의 코드를 InitDoc에게 뺏기고 자신은 InitDoc을 호출함으로써 생성시의 초기화를 대신한다.

 

BOOL CApiEdit::OnCreate(HWND hWnd, LPCREATESTRUCT lpCreateStruct)

{

     HDC hdc;

     TEXTMETRIC tm;

 

     MySetImeMode(hWnd,TRUE);

     bComp=FALSE;

     hdc=GetDC(hWnd);

     GetTextMetrics(hdc,&tm);

     FontHeight=tm.tmHeight;

     LineRatio=120;

     LineHeight=int(FontHeight*LineRatio/100);

     FontWidth=tm.tmAveCharWidth;

     PrepareCharWidth(hdc);

     ReleaseDC(hWnd,hdc);

     nWrap=2;

     bNoFirstSpace=FALSE;

     TabWidth=4;

     TabSize=FontWidth*TabWidth;

     bCapture=FALSE;

     HideSelType=1;

     MarginWidth=25;

     MarColor1=RGB(192,192,192);

     MarColor2=RGB(160,160,160);

     bShowLineNum=FALSE;

     NumColor=RGB(0,0,0);

     MarkColor=RGB(255,255,0);

     bShowTab=FALSE;

     bShowEnter=FALSE;

     bShowSpace=FALSE;

     ShowTabType=1;

     ShowEnterType=1;

     ShowSpaceType=0;

     CodeColor=RGB(128,128,128);

     nShowCurLine=0;

     CurColor=RGB(255,255,0);

     bSelLine=FALSE;

     SelStartLine=0;

     bDragSel=FALSE;

     bWantTab=TRUE;

     SumDelta=0;

     bHideCaret=FALSE;

    InitDoc();

 

     return TRUE;

}

 

남은 코드는 줄간, 탭크기 등의 변수 초기화와 폰트 생성, 문자폭 계산 등과 같이 문서와 직접적인 상관이 없는 코드들뿐이다. 이 코드들도 잠시 후면 다른 설정 변경 함수에게 골고루 나누어주게 될 것이다. 호스트에서 InitDoc만 호출하면 언제든지 새 문서를 편집할 수 있다.