. 툴바에 에디트 넣기

툴바에 들어가는 컨트롤은 통상 버튼이며 툴바는 버튼 이외의 컨트롤은 직접 지원하지 않는다. 하지만 툴바에 다른 컨트롤을 꼭 넣고 싶다면 약간의 편법을 사용할 수도 있다. 툴바는 높이가 제한되어 있기 때문에 리스트 박스나 트리뷰 같은 큰 컨트롤은 넣을 수가 없으며 푸쉬 버튼이나 체크, 라디오 버튼 등은 이미 툴 바가 지원하고 있으므로 넣을 필요가 없다. 결국 현실적으로 툴바에 넣을 수 있는 컨트롤은 에디트 아니면 콤보 박스 정도의 높이가 낮은 컨트롤에 국한된다.

여기서는 에디트를 툴바에 넣는 예제를 만들어 보되 다른 컨트롤들도 방법은 동일하다. 방법은 의외로 간단한데 툴바도 윈도우이므로 이 윈도우의 차일드로 에디트를 생성하기만 하면 된다. 이때 두 가지 문제점이 있는데 첫째는 에디트가 보내는 통지 메시지를 메인 윈도우가 받는 것이 아니라 툴바가 받는다는 점이다. 왜냐하면 에디트를 툴바의 차일드로 생성했기 때문이다.

통지 메시지를 메인 윈도우가 받으려면 공통 컨트롤 라이브러리에 있는 툴바의 윈도우 프로시저를 서브 클래싱하여 툴바가 통지 메시지를 먼저 받아서 다시 부모 윈도우에게 전달해 주면 된다. 그러나 이 방법은 너무 귀찮고 어렵다. 좀 더 간단한 방법은 에디트를 메인 윈도우의 차일드로 만든 후 SetParent 함수로 부모만 툴 바로 바꿔 주는 것이다. 이렇게 되면 에디트는 툴바의 작업 영역에 나타나면서도 오너인 메인 윈도우에게 통지 메시지를 보내게 된다.

두번째 문제는 툴바에 에디트가 들어갈 공간을 확보하는 것이다. 툴바에 이미 들어가 있는 버튼들과 위치가 겹쳐서는 안되며 마치 원래 그 자리가 자기 자리인 것 처럼 에디트가 배치되어야 한다. 여기도 약간의 편법이 필요한데 필요한만큼 구분 여백을 만들고 이 구분 여백 자리에 에디트를 배치하면 된다. 버튼의 폭은 TB_GETITEMRECT 메시지로 쉽게 구할 수 있으므로 구분 여백의 좌표를 구하고 그 자리에 에디트를 깜쪽같이 끼워 넣으면 된다.

다음은 완성된 예제이다. 에디트 컨트롤을 툴 버튼 사이에 배치하며 텍스트가 편집되면 메인 윈도우가 EN_CHANGE 통지 메시지를 받아 타이틀 바에 텍스트를 출력한다.

 

#include <commctrl.h>

#define ID_TOOLBAR 100

HWND hToolBar;

HWND hEdit;

LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM lParam)

{

   TBBUTTON ToolBtn[7]={

      {STD_FILENEW,10,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0,0,0},

      {STD_FILEOPEN,11,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0,0,0},

      {STD_FILESAVE,12,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0,0,0},

      {200,0,0,TBSTYLE_SEP,0,0,0,0},

      {STD_CUT,13,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0,0,0},

      {STD_COPY,14,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0,0,0},

      {STD_PASTE,15,TBSTATE_ENABLED,TBSTYLE_BUTTON,0,0,0,0}

   };

   TCHAR szBuf[256];

   RECT srt;

 

   switch(iMessage) {

   case WM_CREATE:

      InitCommonControls();

      hToolBar=CreateToolbarEx(hWnd, WS_CHILD | WS_VISIBLE | WS_BORDER,

          ID_TOOLBAR, 15, HINST_COMMCTRL, IDB_STD_SMALL_COLOR, ToolBtn, 7,

          16,16,16,16,sizeof(TBBUTTON));

      SendMessage(hToolBar,TB_GETITEMRECT,3,(LPARAM)&srt);

      hEdit=CreateWindow("edit",NULL,WS_CHILD | WS_VISIBLE | WS_BORDER

          |ES_AUTOHSCROLL,

          srt.left+2,srt.top+1,(srt.right-srt.left-4),(srt.bottom-srt.top-2)

          ,hWnd,(HMENU)20,g_hInst,NULL);

      SetParent(hEdit,hToolBar);

      return 0;

   case WM_COMMAND:

      switch (LOWORD(wParam)) {

      case 20:

          switch (HIWORD(wParam)) {

          case EN_CHANGE:

             GetWindowText(hEdit,szBuf,256);

             SetWindowText(hWnd,szBuf);

             return 0;

          }

          break;

      }

      return 0;

   case WM_SIZE:

      SendMessage(hToolBar,TB_AUTOSIZE,0,0);

      return 0;

   case WM_DESTROY:

      PostQuitMessage(0);

      return 0;

   }

   return(DefWindowProc(hWnd,iMessage,wParam,lParam));

}

 

ToolBtn 배열에 구분 여백을 200픽셀 폭으로 미리 만들어 두었다. 이 폭이 바로 에디트 컨트롤의 폭이 되며 에디트의 폭을 바꾸고 싶으면 이 값을 바꾸면 된다. 툴바를 만든 후 구분 여백의 위치를 조사하고 이 위치에 에디트 컨트롤을 생성시켰다. 이때 부모 윈도우는 메인 윈도우인 상태로 생성하고 생성 후 SetParent 함수로 부모를 툴바로 변경한다. 그러면 에디트는 메인 윈도우에게 통지 메시지를 보내게 된다.

에디트가 삽입된 자리는 구분 여백에 의해 확보되어 있는 공간이므로 이 상태에서 다른 버튼을 삽입하거나 삭제하더라도 에디트의 위치를 재조정해줄 필요는 없다. 콤보 박스나 기타 다른 컨트롤도 동일한 방법으로 툴 바에 넣을 수 있다.