위 그림과 같이 탭 컨트롤을 이용하여 각각의 다른 다이얼로그를 컨트롤 하고자 해봤다.
이와 비슷한 방법으로는 프로퍼티 시트를 사용하면 되지만,
뷰와 다이얼로그에서 별도로 동작하기보다는 여러 컨트롤을 함께 사용하고 싶었기에 구현해봤다.
먼저 탭 컨트롤을 리소스에서 만들어주고, 컨트롤 변수를 설정한다. 이미지도 함께 올릴수 있다.
// 헤더
CTabCtrl m_ctrl_tab;
CImageList m_cImageList ;
// cpp
OnInitDialog()에서 탭 컨트롤을 먼저 구현해 준다.
// Image list 등록
m_cImageList.Create( 24, 24, ILC_COLOR24, 2, 0 ) ;
// Load the large icons
CBitmap cBmp0, cBmp1, cBmp2, cBmp3 ;
cBmp0.LoadBitmap( IDB_BITMAP_LIVE ) ;
m_cImageList.Add( &cBmp0, RGB( 0, 0, 0 ) ) ;
cBmp0.DeleteObject();
cBmp1.LoadBitmap( IDB_BITMAP_FILE ) ;
m_cImageList.Add( &cBmp1, RGB( 0, 0, 0 ) ) ;
cBmp1.DeleteObject();
m_ctrl_tab.SetImageList( &m_cImageList ) ;
m_cImageList.Create( 24, 24, ILC_COLOR24, 2, 0 ) ;
// Load the large icons
CBitmap cBmp0, cBmp1, cBmp2, cBmp3 ;
cBmp0.LoadBitmap( IDB_BITMAP_LIVE ) ;
m_cImageList.Add( &cBmp0, RGB( 0, 0, 0 ) ) ;
cBmp0.DeleteObject();
cBmp1.LoadBitmap( IDB_BITMAP_FILE ) ;
m_cImageList.Add( &cBmp1, RGB( 0, 0, 0 ) ) ;
cBmp1.DeleteObject();
m_ctrl_tab.SetImageList( &m_cImageList ) ;
TC_ITEM item ;
item.mask = TCIF_TEXT | TCIF_IMAGE ;
item.pszText = _T("Live") ;
item.iImage = 0 ;
m_ctrl_tab.InsertItem( 0, &item ) ;
item.mask = TCIF_TEXT | TCIF_IMAGE ;
item.pszText = _T("File") ;
item.iImage = 1 ;
item.pszText = _T("File") ;
item.iImage = 1 ;
m_ctrl_tab.InsertItem( 1, &item ) ;
이제 탭컨트롤의 탭이 변할때마다 다이얼로그를 바꾸도록 한다.
탭 컨트롤의 TCN_SELCHANGE 메시지를 정의한다.
void CUpconvDlg::OnTcnSelchangeTab1(NMHDR *pNMHDR, LRESULT *pResult)
{
// TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.
{
// TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.
..
..
}
이렇게 하면 탭 컨트롤은 준비가 된다.
이제는 탭 안에 들어갈 다이얼로그를 모달리스로 띄워보자.
새클래스를 다이얼로그로 상속받아서 2개 만든다.
그리고 그 클래스들을 인클루드 하고, 동적으로 생성시켜 모달리스 다이얼로그로 만든다.
// 헤더
CTestDlg* m_pDlg1 ;
CTestDlg2* m_pDlg2 ;
CTestDlg2* m_pDlg2 ;
// cpp
생성자
m_pDlg1 = new CTestDlg ;
m_pDlg2 = new CTestDlg2 ;
소멸자
if ( m_pDlg1 )
delete m_pDlg1 ;
delete m_pDlg1 ;
if ( m_pDlg2 )
delete m_pDlg2 ;
delete m_pDlg2 ;
그리고 OnInitDialog()에서 다이얼로그를 만든다.
if ( m_pDlg1 != NULL )
m_pDlg1->Create( IDD_TESTDLG ) ;
if ( m_pDlg2 != NULL )
m_pDlg2->Create( IDD_TESTDLG2 ) ;
m_pDlg2->Create( IDD_TESTDLG2 ) ;
이렇게 하면 일단 모달리스 다이얼로그는 만들어졌다.
따라서 만들어둔 탭 컨트롤의 TCN_SELCHANGE에서 다음과 같이 구현 할수 있다.
void CUpconvDlg::OnTcnSelchangeTab1(NMHDR *pNMHDR, LRESULT *pResult)
{
// TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.
{
// TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.
int nIndex = m_ctrl_tab.GetCurSel() ;
if ( nIndex == 0 )
{
{
// 다이얼로그가 탭 컨트롤의 베이스에 맞게 사이즈와 위치를 잡아서 뿌려준다.
// 이때, 탭의 인덱스를 얻어와서 뿌려줄 윈도우는 Show하고, 다른 윈도우는 Hide로 감춘다.
int nPixel = 2 ;
if ( m_pDlg1 != NULL )
{
CRect TabRt, DlgRt ;
m_ctrl_tab.GetItemRect( nIndex, &TabRt ) ;
::GetWindowRect( m_ctrl_tab.m_hWnd, &DlgRt ) ;
{
CRect TabRt, DlgRt ;
m_ctrl_tab.GetItemRect( nIndex, &TabRt ) ;
::GetWindowRect( m_ctrl_tab.m_hWnd, &DlgRt ) ;
int x, y, nWidth, nHeight;
DWORD dwStyle = m_ctrl_tab.GetStyle() ;
DWORD dwStyle = m_ctrl_tab.GetStyle() ;
if ( dwStyle & TCS_VERTICAL )
{ // Vertical tabs
}
else
{ // Horizontal tabs
x = DlgRt.left + nPixel ;
y = DlgRt.top + TabRt.Height() + nPixel*2 ;
nWidth = DlgRt.Width() - nPixel*2 ;
nHeight = DlgRt.Height() - TabRt.Height() - nPixel*2 ;
}
m_pDlg1->SetWindowPos( NULL, x, y, nWidth, nHeight, SWP_NOZORDER ) ;
}
m_pDlg1->ShowWindow( SW_SHOW ) ;
m_pDlg2->ShowWindow( SW_HIDE ) ;
{ // Vertical tabs
}
else
{ // Horizontal tabs
x = DlgRt.left + nPixel ;
y = DlgRt.top + TabRt.Height() + nPixel*2 ;
nWidth = DlgRt.Width() - nPixel*2 ;
nHeight = DlgRt.Height() - TabRt.Height() - nPixel*2 ;
}
m_pDlg1->SetWindowPos( NULL, x, y, nWidth, nHeight, SWP_NOZORDER ) ;
}
m_pDlg1->ShowWindow( SW_SHOW ) ;
m_pDlg2->ShowWindow( SW_HIDE ) ;
}
else if ( nIndex == 1 )
{
int nPixel = 2 ;
else if ( nIndex == 1 )
{
int nPixel = 2 ;
if ( m_pDlg2 != NULL )
{
CRect TabRt, DlgRt ;
m_ctrl_tab.GetItemRect( nIndex, &TabRt ) ;
::GetWindowRect( m_ctrl_tab.m_hWnd, &DlgRt ) ;
{
CRect TabRt, DlgRt ;
m_ctrl_tab.GetItemRect( nIndex, &TabRt ) ;
::GetWindowRect( m_ctrl_tab.m_hWnd, &DlgRt ) ;
int x, y, nWidth, nHeight;
DWORD dwStyle = m_ctrl_tab.GetStyle() ;
DWORD dwStyle = m_ctrl_tab.GetStyle() ;
if ( dwStyle & TCS_VERTICAL )
{ // Vertical tabs
{ // Vertical tabs
}
else
{ // Horizontal tabs
x = DlgRt.left + nPixel ;
y = DlgRt.top + TabRt.Height() + nPixel*2 ;
nWidth = DlgRt.Width() - nPixel*2 ;
nHeight = DlgRt.Height() - TabRt.Height() - nPixel*2 ;
}
m_pDlg2->SetWindowPos( NULL, x, y, nWidth, nHeight, SWP_NOZORDER ) ;
}
m_pDlg2->ShowWindow( SW_SHOW ) ;
m_pDlg1->ShowWindow( SW_HIDE ) ;
}
else
{ // Horizontal tabs
x = DlgRt.left + nPixel ;
y = DlgRt.top + TabRt.Height() + nPixel*2 ;
nWidth = DlgRt.Width() - nPixel*2 ;
nHeight = DlgRt.Height() - TabRt.Height() - nPixel*2 ;
}
m_pDlg2->SetWindowPos( NULL, x, y, nWidth, nHeight, SWP_NOZORDER ) ;
}
m_pDlg2->ShowWindow( SW_SHOW ) ;
m_pDlg1->ShowWindow( SW_HIDE ) ;
}
// result의 리턴을 없앤다.
//*pResult = 0;
}
//*pResult = 0;
}
다소 중복되는 소스 코드이므로 나중에 잘 정리하면 되고,
다음 문제는 윈도우를 이동할때 다이얼로그의 위치는 그대로 존재하기 때문에,
WM_MOVING 메시지에서 위의 소스를 그대로 다시 사용하면
메인 다이얼로그나 뷰를 이동시키더라도 탭 컨트롤의 다이얼로그의 위치가 따로 놀지는 않을것이다.
이제 마지막으로 문제는 처음부터 첫번째 인덱스의 탭에 해당하는 다이얼로그를 띄워줘야 하므로
OnInitDialog()의 호출이 끝나고 다음에 발생하는 메시지인 WM_SHOWWINDOW 메시지를 정의해서
첫번째 탭의 인덱스의 다이얼로그가 활성화 되도록 호출해준다.
void CUpconvDlg::OnMoving(UINT fwSide, LPRECT pRect)
{
CDialog::OnMoving(fwSide, pRect);
{
CDialog::OnMoving(fwSide, pRect);
// TODO: 여기에 메시지 처리기 코드를 추가합니다.
OnTcnSelchangeTab1( NULL, NULL ) ;
}
void CUpconvDlg::OnShowWindow(BOOL bShow, UINT nStatus)
{
CDialog::OnShowWindow(bShow, nStatus);
// TODO: 여기에 메시지 처리기 코드를 추가합니다.
OnTcnSelchangeTab1( NULL, NULL ) ;
}
{
CDialog::OnShowWindow(bShow, nStatus);
// TODO: 여기에 메시지 처리기 코드를 추가합니다.
OnTcnSelchangeTab1( NULL, NULL ) ;
}
'Programming > MFC' 카테고리의 다른 글
실행 파일이 존재하는 곳의 파일 경로 (0) | 2006.11.15 |
---|---|
SDI 메뉴 없애기 (0) | 2006.11.14 |
Multi Line List (0) | 2006.11.03 |
ExplorerView (0) | 2006.11.01 |
Thread 강제 종료 (0) | 2006.09.27 |