. 편집 메뉴

파일 입출력과 직접적인 상관은 없지만 편집 메뉴에 대한 처리도 여기서 작성하도록 하자. 클립보드 처리코드가 ApiEdit에 이미 작성되어 있으므로 대응되는 메시지만 보내주면 나머지 처리는 ApiEdit가 알아서 한다. OnCommand에 다음 코드를 작성한다.

 

void OnCommand(HWND hWnd,WPARAM wParam,LPARAM lParam)

{

     switch(LOWORD(wParam)) {

     ....

     case IDM_EDIT_COPY:

          SendMessage(pSi->Ae.hWnd,WM_COMMAND,MAKEWPARAM(IDM_AE_COPY,0),0);

          break;

     case IDM_EDIT_CUT:

          SendMessage(pSi->Ae.hWnd,WM_COMMAND,MAKEWPARAM(IDM_AE_CUT,0),0);

          break;

     case IDM_EDIT_PASTE:

          SendMessage(pSi->Ae.hWnd,WM_COMMAND,MAKEWPARAM(IDM_AE_PASTE,0),0);

          break;

     case IDM_EDIT_SELALL:

          SendMessage(pSi->Ae.hWnd,WM_COMMAND,MAKEWPARAM(IDM_AE_SELALL,0),0);

          break;

     ....

 

액셀러레이터 리소스가 정의되어 있으므로 <Ctrl+C>, <Ctrl+V> 등의 단축키도 이제 사용할 수 있다. 클립보드 처리는 ApiEdit가 다 하므로 간단한데 오히려 메뉴항목을 관리하는 작업이 더 번거롭다. 붙여넣기는 클립보드에 텍스트 데이터가 있으면 가능하며 복사, 잘라내기는 선택영역이 있어야 사용할 수 있다. 그런데 호스트는 선택영역이 있는지 없는지 SelStart SelEnd를 조사할 수 없으므로 ApiEdit가 선택영역에 대한 조사 및 설정을 할 수 있도록 해야 한다. 다음 두 함수를 ApiEdit에 추가한다.

 

class CApiEdit

{

     ....

     void GetSelect(int &s, int &e);

     void SetSelect(int s, int e);

 

선택영역을 조사하는 함수와 설정하는 함수이다. 코드는 다음과 같이 간단하다.

 

void CApiEdit::GetSelect(int &s, int &e)

{

     s=min(SelStart,SelEnd);

     e=max(SelStart,SelEnd);

}

 

void CApiEdit::SetSelect(int s, int e)

{

     if (s >= 0 && e >= -1 && s <= doclen && e <= doclen) {

          SelStart=s;

          if (e == -1)

              e=doclen;

          SelEnd=e;

          off=SelEnd;

          SetCaret();

          Invalidate(-1);

     }

}

 

SelStart SelEnd를 정규화하여 대입하고 변경하기만 하면 된다. 단 선택영역을 설정할 때는 선택의 처음과 끝이 모두 문서 범위안에 있는지 반드시 체크해야 한다. 특별한 경우로 e -1이면 문서 끝까지 선택하도록 하였으므로 SetSelect(0,-1)명령으로 문서 전체를 선택할 수 있다. SetSelect는 당장 사용되지 않는다. GetSelect 함수를 호출해보면 선택영역이 있는지 없는지 알 수 있으며 그 결과에 따라 잘라내기, 복사 메뉴항목의 상태를 결정한다.

 

void OnInitMenu(HWND hWnd,WPARAM wParam,LPARAM lParam)

{

     HMENU hMenu;

     HWND hActive;

     SInfo *pSi;

    int s,e;

 

     hMenu=(HMENU)wParam;

     hActive=(HWND)SendMessage(g_hMDIClient,WM_MDIGETACTIVE,0,NULL);

     if (hActive) {

          ....

        pSi->Ae.GetSelect(s,e);

        if (s == e) {

           EnableMenuItem(hMenu, IDM_EDIT_CUT, MF_BYCOMMAND | MF_GRAYED);

           EnableMenuItem(hMenu, IDM_EDIT_COPY, MF_BYCOMMAND | MF_GRAYED);

        } else {

           EnableMenuItem(hMenu, IDM_EDIT_CUT, MF_BYCOMMAND | MF_ENABLED);

           EnableMenuItem(hMenu, IDM_EDIT_COPY, MF_BYCOMMAND | MF_ENABLED);

        }

 

        if (IsClipboardFormatAvailable(CF_TEXT)==FALSE) {

           EnableMenuItem(hMenu, IDM_EDIT_PASTE, MF_BYCOMMAND | MF_GRAYED);

        } else {

           EnableMenuItem(hMenu, IDM_EDIT_PASTE, MF_BYCOMMAND | MF_ENABLED);

        }

     }

}

 

ApiEdit에도 팝업메뉴 항목을 관리하기 위한 동일한 코드가 있다. 일종의 중복된 코드인 셈인데 ApiEdit가 컨트롤인 관계로 이 코드들은 합치기가 어려우며 호스트와 컨트롤이 각각 가질 수밖에 없다.