탭 컨트롤은 위의 저 부분을 뜻하지요.
MFC 탭 컨트롤에 대해서 알아보겠습니다.
MFC에서 탭은 "탭 컨트롤 + 탭 페이지" 로 구분됩니다.
여기서 탭 컨트롤은 도구 상자에서 끌어와서 탭이 위치할 자리를 잡아주고
탭 페이지는 다이얼로그를 만들어서 탭 위에 올려주게됩니다.
탭 컨트롤 생성
도구 상자에서 "Tab Control"을 끌어와서 하나 생성합니다.
생성함과 동시에 5개의 탭이 생성된 것처럼 보이지만
실은 아무것도 없습니다.
여기에 탭을 추가하여 넣어주어야합니다.
Visual Studio 2022로 넘어오면서 속성까지 한글로 변해버렸다........
일단 속성에서는 세로(Vertical), 여러 줄(MultiLine)이 가장 많이 쓰입니다.
세로는 탭을 세로줄에 추가할지 유무이며, 여러줄은 탭이 많아졌을 때 여러줄로 탭을 표현할 지 유무입니다.
탭을 만들었으면 새로운 다이얼로그를 준비합니다.
탭 페이지가 될 다이얼로그 생성
Dialog 삽입을 이용하여 다이얼로그를 생성합니다.
저는 총 2개의 다이얼로그(IDD_DLG_TAB1, IDD_DLG_TAB2)를 만들었습니다.
이제 각 다이얼로그의 클래스를 만들어줍니다.
저는 각 다이얼로그에 맞게 "CTabDlg1, CTabDlg2"를 각각 만들어주었습니다.
이제 탭의 페이지가 될 각 다이얼로그에 기본 설정을 합니다.
(이 부분은 소스코드로 직접 설정해도 되지만 편집기의 속성을 이용합니다.)
항목 | 값 |
스타일 (Style) | Child |
시스템 메뉴 (System Menu) | False |
테두리 (Border) | None |
(Visual Studio 2022 한글 속성......)
설정을 하고 나면 이렇게 맨들맨들(???) 해집니다.
(마치 내 미래의 머리처럼)
각 페이지별로 구분할 수 있게 간단하게 Static 하나씩만 추가하였습니다.
이제 메인 화면의 메인 클래스로 돌아와서 위의 탭 페이지를 추가합니다.
생성된 다이얼로그 | 다이얼로그의 클래스명 |
IDD_CPPUTILTEST_DIALOG (메인) | CCppUtilTestDlg (탭 컨트롤의 ID는 IDC_TAB) |
IDD_DLG_TAB1 | CTabDlg1 |
IDD_DLG_TAB2 | CTabDlg2 |
탭 페이지를 탭에 추가하기
Tab Control을 사용하기 위해서는 2가지 방법을 사용합니다.
- 해당 컨트롤을 "변수 추가 기능(위자드)"을 이용하여 DDX_Control으로 연결하여 사용
- 직접 컨트롤을 변수를 추가하여 SubclassDlgItem 함수를 사용하여 연결하여 사용
저는 후자를 선호하기 때문에 후자를 이용하겠습니다.
#pragma once
#include "TabDlg1.h" // 탭 페이지 1
#include "TabDlg2.h" // 탭 페이지 2
class CCppUtilTestDlg : public CDialogEx
{
// ... 생략 ...
private:
CTabCtrl m_ctlTab; // 탭 컨트롤
CTabDlg1 m_ctlTabPage1; // 탭 페이지1
CTabDlg1 m_ctlTabPage2; // 탭 페이지2
void InitControls(); // 컨트롤을 초기화하는 함수
// ... 생략 ...
};
먼저 메인 다이얼로그의 헤더에 위와 같이 선언해주고
메인 클래스로 넘어옵니다.
// ... 생략 ...
BOOL CCppUtilTestDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
SetIcon(m_hIcon, TRUE);
SetIcon(m_hIcon, FALSE);
InitControls(); // <-- 여기서 컨트롤을 초기화 한다.
return TRUE;
}
void CCppUtilTestDlg::InitControls()
{
CRect rcCtrl;
// 메인 Tab Control
if (m_ctlTab.m_hWnd == NULL)
{
m_ctlTab.SubclassDlgItem(IDC_TAB, this); // 컨트롤 연결
m_ctlTab.GetWindowRect(rcCtrl); // 컨트롤 크기 확인
ScreenToClient(rcCtrl); // 컨트롤 크기를 상대 좌표로 변환 (다이얼로그 위의 크기)
m_ctlTab.InsertItem(0, _T("1번 탭")); // 탭 생성
m_ctlTab.InsertItem(1, _T("2번 탭")); // 탭 생성
}
// Tab Page 1번
{
m_ctlTabPage1.Create(IDD_DLG_TAB1, &m_ctlTab); // 다이얼로그 생성 (탭에 종속되게 생성)
m_ctlTabPage1.MoveWindow(2, 26, rcCtrl.Width() - 6, rcCtrl.Height() - 28); // 위치 이동
m_ctlTabPage1.ShowWindow(SW_HIDE); // 초기 값은 HIDE
}
// Tab Page 2번
{
m_ctlTabPage2.Create(IDD_DLG_TAB2, &m_ctlTab); // 다이얼로그 생성 (탭에 종속되게 생성)
m_ctlTabPage2.MoveWindow(2, 26, rcCtrl.Width() - 6, rcCtrl.Height() - 28); // 위치 이동
m_ctlTabPage2.ShowWindow(SW_HIDE); // 초기 값은 HIDE
}
// 초기 선택 탭 설정
m_ctlTab.SetCurSel(0);
m_ctlTabPage1.ShowWindow(SW_SHOW); // 첫 페이지는 SHOW
}
위와 같이 작성합니다.
여기서 MoveWindow 할 때 위치를 (0, 0, Width, Height)로 안하고 뭔가 조금 조정하는 이유는 직접 한번 알아내보길 바랍니다.
(왜 Y위치를 저렇게 아래로 내리는지, 너비와 높이를 저렇게 줄이는지 바로 알게 될 것입니다.)
이제 이벤트를 추가합니다.
탭 컨트롤에서 "TCN_SELCHANGE" 이벤트를 추가합니다.
이 이벤트는 탭의 선택 상태가 바뀌었을 때 이벤트가 발생합니다.
(주의 : 동일 탭을 눌렀을 때는 발생하지 않습니다.)
void CCppUtilTestDlg::OnTcnSelchangeTab(NMHDR* pNMHDR, LRESULT* pResult)
{
int nCurSel = m_ctlTab.GetCurSel(); // 현재 선택된 탭의 인덱스
switch (nCurSel)
{
case 0: // 첫번째 탭을 눌렀으면
m_ctlTabPage1.ShowWindow(SW_SHOW);
m_ctlTabPage2.ShowWindow(SW_HIDE);
break;
case 1: // 두번째 탭을 눌렀으면
m_ctlTabPage1.ShowWindow(SW_HIDE);
m_ctlTabPage2.ShowWindow(SW_SHOW);
break;
}
*pResult = 0;
}
현재 선택된 탭의 인덱스에 맞게 페이지를 Show 또는 Hide 합니다.
프로그램 실행
'Study > MFC' 카테고리의 다른 글
[MFC] Combo Box 컨트롤 (콤보 박스) (0) | 2022.03.05 |
---|---|
[MFC] Button 컨트롤 - 색상 변경 (0) | 2022.02.17 |
[MFC] Button 컨트롤 (버튼 컨트롤) (0) | 2022.02.17 |
[MFC, ATL]레지스트리 읽기, 쓰기 (CRegKey) (0) | 2021.07.23 |
[MFC Active X] 글자를 출력하는 컨트롤 만들기 (0) | 2021.07.22 |