. 이동 및 표시

관련 함수를 다 만들었으니 이제 북마크 기능을 구현하는 것은 아주 쉽다. OnCreate에서 ClearBookmark 함수를 호출하여 배열을 초기화한다. 최초 실행시 북마크는 하나도 설정되어 있지 않은 상태이다. MarkColor 변수는 북마크 표식에 사용할 색상값인데 눈에 잘 띄는 노란색으로 초기화하였다.

 

BOOL OnCreate(HWND hWnd, LPCREATESTRUCT lpCreateStruct)

{

     ....

    ClearBookmark();

    MarkColor=RGB(255,255,0);

 

북마크는 문서의 이동을 빠르게 하기 위해 사용하는 기능이므로 메뉴나 컨트롤 같은 장치보다는 단축키로 사용하는 것이 효율적이다. ApiEdit가 제공하는 북마크 관련 단축키는 다음과 같은데 보편적으로 많이 사용하는 키를 할당하였다.

 

단축키

설명

Ctrl+Shift+0~9

이름있는 북마크 토글

Ctrl+0~9

이름있는 북마크로 이동

Ctrl+F2

이름없는 북마크 토글

F2

이름없는 다음 북마크로 이동

Shift+F2

이름없는 이전 북마크로 이동

 

이 단축키들도 액셀러레이터로 정의하면 좋겠지만 ApiEdit는 아직 리소스를 사용하지 않으므로 코드에서 직접 처리하도록 하자. OnKey에서 단축키를 입력받아 북마크 관련 함수를 호출하였다.

 

void OnKey(HWND hWnd, UINT vk, BOOL fDown, int cRepeat, UINT flags)

{

     ....

     if (fDown==FALSE)

          return;

 

    if (vk>=‘0’ && vk<=‘9’ && bControl) {

        if (bShift) {

           ToggleBookmark(-1,vk-’0’);

        } else {

           GotoBookmark(vk-’0’);

        }

    }

 

     switch (vk)

     {

     ....

    case VK_F2:

        if (bControl) {

           ToggleBookmark(-1,100);

        } else {

           if (bShift) {

               GotoBookmark(11);

           } else {

               GotoBookmark(10);

           }

        }

        return;

 

<Ctrl>키와 <Shift>키의 상태 등을 잘 조합하여 ToggleBookmark, GotoBookmark 함수를 적절히 호출하였다. 여기까지 작성하면 북마크는 이미 동작한다. 하지만 어디가 북마크로 설정되어 있는지 보여주는 장치가 아직까지 없는데 북마크가 설정된 줄에 북마크 표시를 달아보자. 북마크 표시를 출력하는 일은 한 줄을 출력하는 DrawLine에서 담당한다.

 

int DrawLine(HDC hdc, int Line)

{

     ....

     int Mark;

     HBRUSH hMark, OldBrush;

 

     if (MarginWidth != 0) {

          ....

          if (bShowLineNum && pLine[Line].nLine==0) {

              ....

          }

 

          if (pLine[Line].nLine == 0) {

              Mark=FindBookmark(pLine[Line].nPara);

              if (Mark != -1) {

                   hMark=CreateSolidBrush(MarkColor);

                   OldBrush=(HBRUSH)SelectObject(hdc,hMark);

                   RoundRect(hdc,0,0,10,FontHeight,2,2);

                   DeleteObject(SelectObject(hdc,OldBrush));

                   if (Mark >= 0 && Mark <= 9) {

                        wsprintf(szLine,"%d",Mark);

                        OldAlign=SetTextAlign(hdc,TA_LEFT);

                        OldBkMode=SetBkMode(hdc,TRANSPARENT);

                        SetTextColor(hdc,RGB(0,0,0));

                        OldFont=(HFONT)SelectObject(hdc,hLineNumFont);

 

                        TextOut(hdc,2,0+2,szLine,lstrlen(szLine));

 

                        SelectObject(hdc,OldFont);

                        SetTextAlign(hdc,OldAlign);

                        SetBkMode(hdc,OldBkMode);

                   }

              }

          }

     }

     return 1;

}

 

줄번호 기능과 마찬가지로 북마크를 보여주려면 일단 마진이 있어야 한다. 그리고 각 문단의 선두에 대해서만 이 줄이 북마크를 가지고 있는지 조사한다. FindBookmark로 조사한 결과 이 문단에 북마크가 설정되어 있다면 마진영역에 사각형을 그려 북마크 표시를 한다. 이름없는 북마크는 사각형만 그리고 이름있는 북마크는 사각형 안에 북마크 번호까지 출력했다.

북마크 출력문과 줄번호 출력문이 같은 블록 안에 있는데 두 출력문은 순서가 없으므로 서로 자리를 바꿀 수도 있다. , 줄번호를 먼저 출력한 후 북마크를 출력할 수도 있고 그 반대도 가능하다. 이때 출력문의 순서에 따라 두 표식이 겹쳤을 때의 수직위치가 결정되는데 뒤에 있는 출력문이 더 위에 오게 된다. 아무래도 줄마다 있는 줄번호보다는 가끔씩 나타나는 북마크 표시가 더 중요하므로 북마크가 더 위에 있도록 하였다.

마진 영역에 앙증맞은 노란색으로 북마크 표시가 되어 있으며 <F2>, <Ctrl+숫자키>로 북마크 위치로 빠르게 이동한다. 줄번호가 4자리 이상이 되면 북마크 표시와 줄번호가 약간 겹치는 아쉬움이 있기는 하지만 어차피 마진영역이 좁아 두 정보를 충돌없이 보여주기는 어렵다.