. 자동개행열 지정

ApiEdit는 자동개행시 창의 오른쪽 끝에서만 자동개행되도록 되어 있는데 개행할 열을 직접 지정할 수 있도록 해보자. 통신망에 올리거나 일정한 형식을 갖추어야 하는 문서의 경우 창의 크기에 상관없이 80컬럼 정도에서 자동으로 개행되도록 하는 형식이 많이 사용된다. 이 옵션 구현을 위해 RightWrap이라는 변수가 추가되었으며 이 변수가 가리키는 열에서 자동으로 개행된다. 단 이 값이 0이면 창의 오른쪽 끝에서 자동개행되며 초기값은 0이다.

RightWrap 변수를 변경하는 것은 정렬 상태를 바꾸는 것과 효과가 동일하므로 SetWrap 함수에서 이 옵션을 처리하며 SetWrap 함수는 다음과 같이 수정된다.

 

void CApiEdit::SetWrap(int aWrap)

{

     DWORD dwStyle;

 

     nWrap=aWrap;

     dwStyle=GetWindowLong(hWnd,GWL_STYLE);

    if (nWrap && RightWrap==0) {

          dwStyle = dwStyle & ~WS_HSCROLL;

          xPos=0;

     } else {

          dwStyle = dwStyle | WS_HSCROLL;

     }

     SetWindowLong(hWnd,GWL_STYLE,dwStyle);

     SetWindowPos(hWnd,HWND_NOTOPMOST,0,0,0,0,

          SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);

     Invalidate(-1);

     UpdateLineInfo();

     UpdateScrollInfo();

     SetCaret();

}

 

자동개행 상태이고 자동개행열이 지정되어 있지 않을 때(RightWrap 0)만 수평 스크롤바를 숨길 수 있다. 자동개행 상태라도 RightWrap 0이 아닌 경우는 윈도우 폭과 상관없이 자동개행되므로 윈도우가 아주 작아질 때를 대비하여 수평 스크롤바를 보여주어야 한다. UpdateScrollInfo 함수도 마찬가지 이유로 수정되어야 한다.

 

void CApiEdit::UpdateScrollInfo()

{

     ....

     if (nWrap == 0 || RightWrap != 0) {

          ....

 

자동개행 상태가 아니거나 오른쪽 열이 지정되어 있으면 수평 스크롤바의 범위를 갱신해야 한다. 다음 함수도 수정한다.

 

void CApiEdit::SetNoFirstSpace(BOOL aNoFirstSpace)

{

     bNoFirstSpace=aNoFirstSpace;

    if (nWrap != 0 || RightWrap != 0) {

          ....

 

줄 처음 공백 허용 옵션이 변경되었을 때 자동개행 상태거나 자동개행열이 지정되어 있으면 정렬을 다시 해야 한다. 이외에 이 옵션이 영향을 미치는 곳으로 OnMouseMove에서 선택중에 수평으로 자동 스크롤하는 코드가 있으나 무시하기로 한다. 왜냐하면 보이지도 않는 열에서 자동개행되도록 하는 경우가 극히 드물기 때문이다. 이 값이 사용되는 곳은 정렬의 핵심 함수인 GetLine 함수이다.

 

void CApiEdit::GetLine(int Line, int &s, int &e)

{

     TCHAR *p;

     int len, acwidth;

     TCHAR *EndPos=NULL;

     TCHAR *EndPosNoSpace=NULL;

     BOOL IsPrevDBCS=FALSE;

    int Right;

 

    if (RightWrap == 0) {

        Right=frt.right-2;

    } else {

        Right=MarginWidth+RightWrap*FontWidth;

    }

     ....

    if (nWrap == 0 && RightWrap == 0) {

          while (*p != ‘\r’ && *p != 0)

              p++;

     } else {

          for (acwidth=MarginWidth;;) {

              ....

           if (acwidth > max(Right, MarginWidth+FontHeight*4)) {

                   break;

              }

              ....

 

frt.right-2에서 자동개행을 했었으나 이제 RightWrap이 지정되어 있으면 윈도우 폭에 상관없이 이 열에서 자동개행되어야 한다. 자동개행될 픽셀 좌표는 RightWrap과 평균 문자폭인 FontWidth를 곱한 값에 마진폭을 더한 값이 된다. 문자의 폭을 더해 나가다가 RightWrap이 지정한 열에 이르면 강제로 개행된다.

nWrap 설정보다는 RightWrap 설정이 더 우선이기 때문에 nWrap 0이더라도 RightWrap이 지정되어 있으면 이 열에서 강제로 개행된다. , 이 경우 글자단위로 정렬은 할 수 없으며 무조건 단어 단위로만 정렬된다.