. 조립중의 재정렬 생략

글자가 실제로 입력되었을 때는 이 글자가 들어갈 수 있도록 메모리를 뒤로 이동시켜야 하고 정렬도 다시 해야 한다. 글자가 삭제될 때도 물론 마찬가지다. 메모리 이동과 재정렬은 시간을 많이 소모하는 동작이지만 삽입, 삭제될 때는 문서에 변화가 생겼으므로 불가피하게 정렬을 하지 않을 수가 없다. 그러나 한글조립중일 때는 임시적인 글자 대체이므로 굳이 메모리 이동 및 재정렬할 필요가 없다. 다음 그림을 보자.

대한민국을 입력하고 있는 중인데 두 번째 음절에 자까지 입력된 상황에서 ㄴ을 입력하였다. 자를 자로 대체하기 위해 먼저 조립중에 있는 임시 문자인 자를 삭제하며 이 과정에서 Delete 함수가 메모리 이동 및 재정렬을 수행한다. 그리고 새로 입력된 음소를 합쳐 자가 그 자리에 삽입되는데 Insert 함수도 메모리 이동을 하면서 정렬을 다시 하게 된다.

결과적으로 볼 때 자가 자로 바뀌기만 했을 뿐 전후의 메모리 상태는 전혀 변화가 없으며 따라서 정렬도 바뀔 필요가 없다. Insert, Delete 함수를 호출하지 않고 곧바로 버퍼에 있는 글자를 바꾸고 화면을 다시 그리기만 하면 된다. 두 번의 불필요한 재정렬을 하지 않아도 되는 것이다. OnImeComposition을 다음과 같이 수정해보자.

 

LRESULT OnImeComposition(HWND hWnd, WPARAM wParam, LPARAM lParam)

{

     ....

          szComp[len]=0;

        if (bComp && len!=0) {

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

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

        } else {

              if (bComp) {

                   ....

              off+=len;

        }

 

          ImmReleaseContext(hWnd,hImc);

          ....

 

조립중일 때(bComp)는 버퍼의 현재 위치에 곧바로 조립중인 문자를 대체하였으며 재정렬을 하지 않도록 하였다. , 조립중이라도 len 0인 경우는 BS에 의해 문자가 삭제된 경우이므로 대체할 문자가 없으며 조립중인 글자가 삭제되므로 메모리 이동도 필요하고 재정렬도 필요하다. 조립중은 글자가 완성될 때인 OnImeChar 함수도 수정한다.

 

LRESULT 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) {

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

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

    } else {

        if (bOvr) {

              if (IsDBCS(off)) {

                   if (buf[off] != ‘\r’) {

                        Delete(off,2);

                   }

              } else {

                   Delete(off,1);

              }

          }

          Insert(off,szChar);

          off+=lstrlen(szChar);

    }

 

     bComp=FALSE;

     Invalidate(FindParaStart(off-lstrlen(szChar)));

     SetCaret();

     return 0;

}

 

bComp TRUE일 때, 즉 조립중인 한글이 완성될 때도 글자를 대체만 할 뿐 재정렬할 필요가 없다. 덮어쓰기 모드일 때도 마찬가지 방식으로 동작하면 된다. 아래쪽의 if (bOvr && bCmop==FALSE) 조건에서 bComp==FALSE 조건은 필요없어졌다.

글자 조립중에는 메모리 삽입, 삭제를 하지 않으며 재정렬도 하지 않으므로 한글조립은 실시간으로 수행되며 시간이 거의 들지 않는다. 그러나 조립이 시작될 때나 영문자입력중일 때는 아직도 여전히 느리다.