. 팝업 메뉴

선택영역을 만들었으면 이제 사용할 때다. 클립보드를 통해 선택한 문자열을 복사하여 다른 프로그램에게 줄 수도 있고 문서의 다른 부분으로 붙여넣기를 할 수도 있다. 이런 동작을 하려면 먼저 명령을 내릴 수 있는 방법이 필요하므로 팝업메뉴를 붙여 보도록 하자. 어차피 ApiEdit가 컨트롤이 되려면 자체 팝업메뉴를 가지고 있어야 한다. 팝업메뉴에는 다음 4개의 명령이 들어갈 것이다.

 

#define IDM_AE_CUT 40001

#define IDM_AE_COPY 40002

#define IDM_AE_PASTE 40003

#define IDM_AE_SELALL 40004

 

소스의 선두 부분에 적당히 메뉴의 ID를 선언하도록 하자. ID의 값은 다른 프로젝트와 충돌되지 않도록 충분히 뒤쪽의 값을 사용했는데 명령 ID는 윈도우에 대해 지역적이기 때문에 사실 충돌하더라도 별 상관은 없다. 팝업메뉴는 WM_CONTEXTMENU 메시지를 받았을 때 출력하면 된다.

 

void OnContextMenu(HWND hWnd, HWND hwndContext, UINT xPos, UINT yPos)

{

     HMENU hPopup;

     POINT pt;

 

     hPopup=CreatePopupMenu();

     AppendMenu(hPopup,MF_STRING,IDM_AE_CUT,"잘라내기(&T)");

     AppendMenu(hPopup,MF_STRING,IDM_AE_COPY,"복사(&C)");

     AppendMenu(hPopup,MF_STRING,IDM_AE_PASTE,"붙여넣기(&P)");

     AppendMenu(hPopup,MF_STRING,IDM_AE_SELALL,"모두선택(&A)");

 

     if (IsClipboardFormatAvailable(CF_TEXT)==FALSE) {

          EnableMenuItem(hPopup, IDM_AE_PASTE, MF_BYCOMMAND | MF_GRAYED);

     }

 

     if (SelStart == SelEnd) {

          EnableMenuItem(hPopup, IDM_AE_CUT, MF_BYCOMMAND | MF_GRAYED);

          EnableMenuItem(hPopup, IDM_AE_COPY, MF_BYCOMMAND | MF_GRAYED);

     }

 

     if (xPos==65535) {

          GetCaretPos(&pt);

          ClientToScreen(hWnd,&pt);

          xPos=pt.x;

          yPos=pt.y;

     }

     TrackPopupMenu(hPopup,TPM_LEFTALIGN,xPos,yPos,0,hWnd,NULL);

     DestroyMenu(hPopup);

}

 

팝업메뉴를 만들고 커서 위치에 출력하되 오른쪽 클릭이 아닌 <Shift+F10>으로 팝업메뉴를 호출했을 때는 캐럿 위치에 출력하였다. <Shift+F10>으로 팝업메뉴를 호출하면 xPos, yPos 좌표는 모두 -1(65535)로 전달된다. 클립보드의 상태에 따라 메뉴항목의 상태를 적당히 조정했다. 클립보드에 CF_TEXT 포맷이 있으면 붙여넣기 메뉴항목을 사용할 수 있고 잘라내기, 복사는 선택영역이 있을 때만 사용할 수 있다.

팝업메뉴를 만드는 일반적인 방법은 리소스에 메뉴를 정의하고 리소스로부터 팝업메뉴를 읽어와 출력하는 것인데 여기서는 코드로 메뉴를 직접 생성하였다. 왜 리소스를 사용하지 않고 귀찮게 코드를 직접 쓰는가 하면 ApiEdit는 최종적으로 컨트롤이 되어야 하기 때문이다. 벌써 컨트롤에 관한 내용을 논할 필요는 없겠지만 일단 컨트롤은 리소스를 가질 수 없다(또는 대단히 번거롭다)고 알아 두도록 하자.