. 탭의 스타일

탭 컨트롤은 고정된 한 영역에 여러 개의 페이지를 겹쳐서 출력할 수 있도록 해 주는 컨트롤이다. 바탕화면의 등록 정보 윈도우나 제어판의 애플릿들을 보면 탭 컨트롤을 볼 수 있는데 여러 가지 복잡한 설정을 각 탭에 나누어서 지정할 수 있으므로 입력받아야 할 정보가 많을 때 주로 사용한다.

 

프로퍼티 시트의 차일드로 포함되는 것이 보통이지만 독립된 컨트롤로도 사용할 수 있다. MDI 프로그램의 열려진 문서 목록을 표시한다든가 긴 문서의 섹션을 나눌 때도 탭 컨트롤이 사용된다. 탭 컨트롤을 생성할 때는 WC_TABCONTROL 윈도우 스타일을 지정하여 CreateWindow 함수를 호출한다. 다음 TabCtrl 예제는 세 개의 페이지를 가지는 탭 컨트롤 예제이다.

 

#include <commctrl.h>

HWND hTab;

HWND hStatic;

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

{

   TCITEM tie;

   TCHAR *arNum[3]={"첫번째 페이지입니다. 컨트롤로 페이지를 전환합니다.",

      "여기는 두번째 페이지입니다.",

      "마지막 페이지입니다."};

 

   switch(iMessage) {

   case WM_CREATE:

      InitCommonControls();

      hTab=CreateWindow(WC_TABCONTROL,"",WS_CHILD | WS_VISIBLE

          | WS_CLIPSIBLINGS,

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

      hStatic=CreateWindow("static",arNum[0],WS_CHILD | WS_VISIBLE,

          0,0,0,0,hWnd,(HMENU)1,g_hInst,NULL);

      tie.mask=TCIF_TEXT;

      tie.pszText="one";

      TabCtrl_InsertItem(hTab,0,&tie);

      tie.pszText="two";

      TabCtrl_InsertItem(hTab,1,&tie);

      tie.pszText="three";

      TabCtrl_InsertItem(hTab,2,&tie);

      return 0;

   case WM_NOTIFY:

      switch (((LPNMHDR)lParam)->code) {

      case TCN_SELCHANGE:

          SetWindowText(hStatic,arNum[TabCtrl_GetCurSel(hTab)]);

          break;

      }

      return 0;

   case WM_SIZE:

      MoveWindow(hTab,0,0,LOWORD(lParam),HIWORD(lParam),TRUE);

      MoveWindow(hStatic,LOWORD(lParam)/2-250,HIWORD(lParam)/2,500,25,TRUE);

      return 0;

   case WM_DESTROY:

      PostQuitMessage(0);

      return 0;

   }

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

}

 

WM_CREATE에서 탭 컨트롤을 생성했으며 세 개의 탭 항목을 추가하였다. WM_SIZE에서는 탭 컨트롤이 작업 영역 전체를 가득 채우도록 했다. 탭의 중앙 영역, 즉 페이지의 내용이 출력되는 영역을 표시 영역(Display Area)이라고 하는데 이 영역에 탭이 표시하는 페이지가 나타난다. 예제에서는 스태틱을 하나 배치하고 탭이 변경될 때마다 스태틱의 텍스트를 변경하였다. 실행중의 모습은 다음과 같다.

탭 컨트롤의 위쪽에는 세 개의 탭이 표시되어 있고 표시 영역에는 스태틱 컨트톨이 배치되어 있다. 이때 스태틱 컨트롤은 탭의 차일드가 아니라 메인 윈도우의 차일드임을 주의해야 한다. 탭은 표시 영역을 제공할 뿐이지 페이지의 내용 자체를 제공해 주지는 않으며 탭이 변경될 때 대응되는 페이지를 표시하고 관리하는 것은 메인 윈도우가 직접 해야 한다.

콤보 박스가 항목이 변경될 때 CBN_SELCHNGE 통지 메시지를 보내 주듯이 탭 컨트롤은 탭이 변경될 때 TCN_SELCHANGE 통지 메시지를 부모 윈도우로 보내 준다. 이때 부모 윈도우는 변경된 탭 번호에 맞게 페이지를 변경하거나 기타 필요한 처리를 해야 한다. 에제에서는 스태틱 컨트롤의 텍스트만 변경하고 있다.

탭 컨트롤은 보통 메인 윈도우 또는 대화상자의 차일드로 생성되므로 WS_CHILD 스타일은 선택의 여지없이 주어야 하며 WS_VISIBLE도 마찬가지다. 또한 탭이 페이지의 내용을 표시하는 컨트롤(위 예제의 경우 스태틱) 영역을 덮어쓰지 말아야 하므로 WS_CLIPSIBLINGS 스타일은 반드시 주어야 한다. 이외에 TCS_로 시작되는 탭 컨트롤 스타일을 추가로 지정할 수 있다.

 

스타일

설명

TCS_BOTTOM

TCS_RIGHT

탭이 컨트롤의 바닥(또는 오른쪽)에 나타난다.

TCS_BUTTONS

탭이 버튼으로 나타나며 표시 영역에는 경계선이 그려지지 않는다.

TCS_FIXEDWIDTH

탭이 모두 같은 폭을 가지도록 고정된다. 이 스타일은 TCS_RIGHTJUSTIFY 스타일과 함께 쓸 수는 없다. 이 스타일을 지정하지 않으면 텍스트와 아이콘의 폭에 따라 탭의 폭이 결정된다.

TCS_FLATBUTTONS

TCS_BUTTONS 스타일과 함께 사용되며 평평한 모양의 버튼을 만든다.

TCS_FOCUSNEVER

마우스로 탭을 클릭해도 포커스를 가질 수 없도록 한다.

TCS_FOCUSBUTTONDOWN

포커스를 가지며 커서 이동키로 탭 간을 전환할 수 있다.

TCS_FORCEICONLEFT

아이콘이 탭의 왼쪽으로 정렬된다. TCS_FIXEDWIDTH 스타일과 함께 사용된다.

TCS_FORCELABELLEFT

탭의 텍스트를 왼쪽으로 정렬한다. 이 스타일을 주지 않으면 텍스트를 중앙으로 정렬한다. TCS_FIXEDWIDTH, TCS_FORCEICONLEFT 스타일과 함께 사용되며 이 경우 아이콘, 텍스트 순으로 왼쪽 정렬된다.

TCS_HOTTRACK

마우스 커서가 탭 위에 있을 때 탭이 강조된다.

TCS_MULTILINE

탭을 여러 줄로 배치한다. 이 스타일을 주지 않으면 탭이 한줄로만 배치되며 업다운 컨트롤로 스크롤해야 한다.

TCS_MULTISELECT

Ctrl키를 누른 상태에서 탭을 여러 개 선택할 수 있다. TCS_BUTTONS 스타일과 함께 사용해야 한다.

TCS_OWNERDRAWFIXED

부모 윈도우가 탭을 직접 그리는 오너 드로우 탭을 생성한다.

TCS_RAGGEDRIGHT

탭이 탭 컨트롤의 폭을 가득 채우지 않도록 한다. 이 스타일이 디폴트이다.

TCS_RIGHTJUSTIFY

탭이 탭 컨트롤 전체를 가득 채우도록 폭을 확장한다. TCS_MULTILINE 스타일과 함께 사용해야 한다.

TCS_SCROLLOPPOSITE

불필요한 탭이 컨트롤의 반대쪽으로 스크롤된다.

TCS_SINGLELINE

탭을 한줄로만 출력한다. 이 스타일이 디폴트이다.

TCS_TABS

탭이 (버튼이 아닌)탭으로 표시되며 표시 영역에 경계선이 그려진다. 이 스타일이 디폴트이다.

TCS_TOOLTIPS

툴팁 컨트롤을 가진다.

TCS_VERTICAL

탭을 위쪽에 배치하지 않고 왼쪽에 배치한다. TCS_MULTILINE 스타일과 함께 사용해야 하며 TCS_RIGHT 스타일을 같이 주면 오른쪽에 탭이 배치된다.

 

스타일 자체가 어렵지는 않지만 상호 배치되거나 종속적인 스타일이 많아 실제로 원하는 모양을 만들려면 다소 많은 테스트가 필요하다. 다음은 버튼 형태로, 탭을 바닥에 정렬한 예를 보인 것이다.

 

탭의 수가 많을 때는 여러 줄로 표시할 수도 있고 텍스트 외에 아이콘을 같이 출력하거나 여러 가지 정렬 방식을 적용할 수도 있다. TabCtrl 예제로 탭의 다양한 스타일을 적용해 보아라.