Оригинальный DVD-ROM: eXeL@B DVD !
eXeL@B ВИДЕОКУРС !

ВИДЕОКУРС ВЗЛОМ
выпущен 2 августа!


УЗНАТЬ БОЛЬШЕ >>
Домой | Статьи | RAR-cтатьи | FAQ | Форум | Скачать | Видеокурс
Новичку | Ссылки | Программирование | Интервью | Архив | Связь

ПРОГРАММИРОВАНИЕ НА C и С++



Возможности языков семейства Си по истине безграничны, однако, в этой свободе кроются и недостатки: всегда нужно программисту держать ухо востро и контроллировать "переполнение буфера", чтобы потом программа не вылетала в "синий экран" на массе разнообразных версий Windows и железа у пользователей. Те же крэкеры и реверсеры специально ищут в коде программ на Си уязвимости, куда можно подсадить любой вирусный код, об этом более подробно автор рассказывал в своём видеокурсе здесь. Я там многое узнал и теперь мой код стал значительно более безопасный.

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

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

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

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

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

  • 1) Сначала создадим проект tab_control типа диалог.
  • 2) В редакторе ресурсов добавить Tab Control в шаблон диалога и назначим ему ID = IDC_TAB.
  • 3) Используя ClassWizard, добавим переменную-член типа CTabCtrl со свойством Control.
  • 4) В OnInitDialog проинициализируем необходимые переменные для CTabCtrl.
  • 5) Используя ClassWizard, добавим обработку необходимых сообщений от Tab control 'я.
  • 6) Удалим за собой ненужные переменные.

Для начала сделайте первые три пункта, создайте переменную 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;
 
 		}
 
 	}
 
 

Ну вот и всё, приложение готово.

<< ВЕРНУТЬСЯ В ПОДРАЗДЕЛ

<< ВЕРНУТЬСЯ В ОГЛАВЛЕНИЕ




Материалы находятся на сайте https://exelab.ru/pro/



Оригинальный DVD-ROM: eXeL@B DVD !


Вы находитесь на EXELAB.rU
Проект ReactOS