Программирование на Visual C++

Google
  Главная   Новости   Статьи   Книги   Ссылки  

20. Использование класса CTabCtrl

Tab control - это мощное средство для решению многих проблем в интерфейсе приложений. Оно позволят существенно увеличить скорость работы вашего приложения, разбить на "части" диалог в удобной для пользователя форме.

В MFC есть встроенный класс по работе с Tab control - класс CTabCtrl.

Для практики напишем программу, которая будет использовать класс CTabCtrl и в которой будет три "закладки" - диалога.

Шаги создания проекта:

Для начала сделайте первые три пункта, создайте переменную m_ctrTab класса CTabCtrl. После этого в функцие BOOL CTab_controlDlg::OnInitDialog() добавте следующее:

...  	
TC_ITEM TabItem;
TabItem.mask = TCIF_TEXT;
TabItem.pszText = "Закладка1";
m_ctrTab.InsertItem( 0, &TabItem );
TabItem.pszText = "Закладка2"; 
m_ctrTab.InsertItem( 1, &TabItem );
TabItem.pszText = "Закладка3"; 
m_ctrTab.InsertItem( 2, &TabItem );
... 

Это код инициализации Tab Control, мы создаём три закладки. Теперь нам надо, чтобы при нажатие на любую закладку, на экране появлялось то, что нам нужно. Самый простой вариант - это использовать на каждую закладку по диалогу - и потом просто в области Tab Control'а - выводить нужный диалог, в зависимости от текущей закладки.

Сделаем это. Добавим три диалога в редакторе ресурсов и создадим каждому из них по классу - наследнику от CDialog. Назовем эти классы CPage1, CPage2 и CPage3( файлы Page1.cpp(h), Page2.cpp(h), Page3.cpp(h) ) .

В свойствах этих трёх диалогов поставте Style как "Child" и Border как "none" - это очень важно, а в самих диалогах создайте какие либо элементы ( например, типа Static Text ), чтобы было видно отличие.

Напишите эти три строчки в начале файла tab_controlDlg.cpp

#include "Page1.h"
#include "Page2.h"
#include "Page3.h"

Продолжим в OnInitDialog:
Надо последовательно создать все страницы, причём указатели на них хранятся в самом m_ctrTab !!! В этом примере мы ипользовали lParam структуры TCITEM как хранилище указателя. Теперь переменные pPage1, pPage2 и pPage3 больше не нужны - указатели хранятся в надежном месте! Для каждой страницы вызывается метод ShowWindow() - для отображения первой, и скрытия остальных страниц.

...  	
CPage1* pPage1;
pPage1 = new CPage1;
TabItem.mask = TCIF_PARAM; 
TabItem.lParam = (LPARAM)pPage1; 
m_ctrTab.SetItem(0, &TabItem);
VERIFY(pPage1->Create(CPage1::IDD, &m_ctrTab)); 
pPage1->SetWindowPos(NULL, 10, 30, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
pPage1->ShowWindow(SW_SHOW); 

CPage2* pPage2;
pPage2 = new CPage2; 
TabItem.mask = TCIF_PARAM;  	
TabItem.lParam = (LPARAM)pPage2; 	
m_ctrTab.SetItem(1, &TabItem);
VERIFY(pPage1->Create(CPage2::IDD, &m_ctrTab)); 
pPage2->SetWindowPos(NULL, 10, 30, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
pPage2->ShowWindow(SW_HIDE); 

CPage3* pPage3;  	
pPage3 = new CPage3; 
TabItem.mask = TCIF_PARAM; 
TabItem.lParam = (LPARAM)pPage3; 
m_ctrTab.SetItem(2, &TabItem); 
VERIFY(pPage1->Create(CPage3::IDD, &m_ctrTab));
pPage3->SetWindowPos(NULL, 10, 30, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
pPage3->ShowWindow(SW_HIDE);
... 

Теперь добавим код по отображению текущей страницы и сокрытию предыдущей. Для этого добавим обработчики сообщений TCN_SELCHANGE и TCN_SELCHANGING :

void CTab_controlDlg::OnSelchangingTab(NMHDR* pNMHDR,LRESULT* pResult)  { 
// TODO: Add your control notification handler code here
int nTab = m_ctrTab.GetCurSel(); 
TC_ITEM tci;  	
tci.mask = TCIF_PARAM; 
m_ctrTab.GetItem(nTab, &tci); 
ASSERT(tci.lParam); 
CWnd* pWnd = (CWnd *)tci.lParam;
pWnd->ShowWindow(SW_HIDE);   *pResult = 0; }
void CTab_controlDlg::OnSelchangingTab(NMHDR* pNMHDR, LRESULT* pResult)  {  
	int nTab = m_ctrTab.GetCurSel();
	TC_ITEM tci;
	tci.mask = TCIF_PARAM;
	m_ctrTab.GetItem(nTab, &tci);
	ASSERT(tci.lParam);
	CWnd* pWnd = (CWnd *)tci.lParam; 
	pWnd->ShowWindow(SW_HIDE);
	*pResult = 0;
} 

Здесь используются те самые указатели, которые мы спрятали в OnInitDialog

Теперь освободим память и разрушим диалоговые окна при выходе из приложения.
Добавим функцию OnDestroy:

void CTab_controlDlg::OnDestroy() { 
	CDialog::OnDestroy();
	CWnd* pWnd; 
	TC_ITEM tci;
	tci.mask = TCIF_PARAM;
	for (int i = 2; i>=0; i--) {
		m_ctrTab.GetItem(i, &tci);
		ASSERT(tci.lParam);
		pWnd = (CWnd *)tci.lParam;
		pWnd->DestroyWindow(); 
		delete pWnd;
	}
}

Ну вот и всё, приложение готово.
Отсюда можно взять рабочую программу под MFC, с использованием CTabCtrl.

Содержание

Используются технологии uCoz