Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

ООП_Лабораторный практикум

.pdf
Скачиваний:
79
Добавлен:
11.05.2015
Размер:
1.5 Mб
Скачать

Рис 2.3. Закладка Member Variables

Project - название вашего проекта.

Class Name - название класса, элементы которого вы будете связывать с переменными. Убедитесь в том, чтобы был выбран класс CTestDlg, потому что именно он отвечает за диалоговую панель, которую вы проектировали.

Control IDs - названия элементов управления, с которыми можно связать переменные.

Type - тип переменной, которую вы связываете с элементом диалога.

Memberназвание переменной, которую вы связываете с элементом диалога.

Рис 2.4. Окно Add Member Variable

Member Varible Name - название переменной, с которой связsdftncz элемент управления.

Category - здесь выбирается категория переменной. К примеру, Value - это категория переменной, предназначенная для передачи значения переменной, Control - категория предназначена для управления элементами. К примеру, с помощью переменной такой категории можно менять названия кнопок, добавлять строки в ListBox и многое др.

Varible Typeтип переменной.

21

4. Код, инициализирующий окно редактирования

При запуске программы, основанной на диалоге, необходимо установить определенные значения некоторых элементов управления: необходимо, чтобы флажки Visible и Enable были отмечены, иначе окна редактирования не будет видно. Для этого выполните следующие действия:

1)Зайдите в View->ClassWizard, откройте закладку Message Maps.

2)В Message IDs выберите CTestDlg, в Messages появится список событий, с которыми может быть связано диалоговое окно. Выберите там событие WM_INITDIALOG. Оно происходит, когда запускается программа и инициализируется диалоговое окно.

3)Щелкните на кнопку Add Function, а затем нажмите на кнопку Edit Code, для редактирования исходного кода.

4)Функция OnInitDialog() уже содержит часть кода написанного VC++ . Найдите в нем комментарий // TODO: Add extra initialization here, который сообщает нам, что после него мы можем добавить свой код.

5)Напишите следующий код в функции OnInitDialog(): BOOL CTestDlg::OnInitDialog()

{

CDialog::OnInitDialog();

...

// TODO: Add extra initialization here ////////Мой код начинается здесь///////////

//Устаноить переменную флажка VisibleCheck и EnabledCheck в состояние

//TRUE m_VisibleCheck=TRUE; m_EnableCheck=TRUE; //Обновить экран

UpdateData(FALSE);

////////Мой код заканчивается здесь///////////

return TRUE; // Вернуть TRUE, если только вы не установили фокус на //элемент управления

}

Рассмотрим код:

Первый и второй операторы присваивают переменным m_VisibleCheck и m_EnableCheck значение TRUE. Это означает, что при запуске программы флажки будут отмечены.

Последний оператор UpdateData(FALSE) обновляет экран, т.е. он обновляет значения переменных элементов управления на текущие. В нашем случае, при выполнении этого оператора текущее содержимое переменных связанных с флажками будет передано к ним.

5.Связывание кода с событием BN_CLICKED кнопки Exit

При нажатии на кнопку Exit программа Test.Exe завершится. Чтобы связать код с событием BN_CLICKED кнопки EXIT, выполните следующие действия:

1)Выберите ClassWizard в меню View

2)Выберите закладку Message Maps в панели ClassWizard

3)Используйте диалоговую панель ClassWizard для выбора следующего события: Class Name: CTestDlg

Object ID: IDC_EXIT_BUTTON Messages: BN_CLICKED

4)Щелкните на кнопку Add Fucntion и в раскрывшемся окне нажмите кнопку OK.

5)Сейчас панель MFC ClassWizard должна будет выглядеть как на рисунке 2.5:

22

Рис 2.5. Окно MFC ClassWizard, закладка Message Maps

6)Нажмите кнопку Edit Code и напишите следующий код в функции OnExitButton(): void CTestDlg::OnExitButton()

{

// TODO: Add your control notification handler code here

////////Мой код начинается здесь///////////

OnOK();

////////Мой код заканчивается здесь///////////

}

Функция OnOK(), которую вы ввели завершает программу, при нажатии на кнопку Exit.

6. Связывание кода с событием BN_CLICKED кнопки Test

При нажатии на кнопку Test программа Test.Exe в окне редактирования напишет текст: This is a Test. Чтобы связать код с событием BN_CLICKED кнопки Test, выполните следующие действия:

1)Выберите ClassWizard в меню View

2)Выберите закладку Message Maps в панели ClassWizard

3)Используйте диалоговую панель ClassWizard для выбора следующего события: Class Name: CTestDlg

Object ID: IDC_TEST_BUTTON Messages: BN_CLICKED

4)Нажмите кнопку Add Fucntion и в раскрывшемся окне нажмите кнопку OK.

5)Нажмите кнопку Edit Code и напишите следующий код в функции OnTestButton(): void CTestDlg::OnTestButton()

{

//TODO: Add your control notification handler code here

////////Мой код начинается здесь///////////

///Присвоить переменной окна редактирования IDC_TEST_EDIT значение

//This is a Test.

23

m_TestEdit="This is a Test";

//// Обновить экран

UpdateData(FALSE);

////////Мой код заканчивается здесь///////////

}

Этот код содержит два оператора: первый присваивает переменной m_TestEdit типа

CString значение This is a Test, а второй оператор UpdateData(FALSE) – обновляет экран, т.е.

сообщает переменным диалогового окна текущие их значения.

7. Связывание кода с событием BN_CLICKED кнопки Clear

При нажатии на кнопку Clear программа Test.Exe должна стирать текст из окна редактирования. Чтобы связать код с событием BN_CLICKED кнопки Clear, выполните следующие действия:

1)Выберите ClassWizard в меню View

2)Выберите закладку Message Maps в панели ClassWizard

3)Используйте диалоговую панель ClassWizard для выбора следующего события: Class Name: CTestDlg

Object ID: IDC_CLEAR_BUTTON Messages: BN_CLICKED

4)Нажмите кнопку Add Fucntion и в раскрывшемся окне нажмите кнопку OK.

5)Нажмите кнопку Edit Code и напишите следующий код в функции OnClearButton(): void CTestDlg::OnClearButton()

{

// TODO: Add your control notification handler code here

////////Мой код начинается здесь///////////

///Присвоить переменной окна редактирования IDC_TEST_EDIT значение

//NULL. m_TestEdit=" ";

//// Обновить экран

UpdateData(FALSE);

////////Мой код заканчивается здесь///////////

}

8. Связывание кода с событием BN_CLICKED флажка Visible

При включении флажка Visible программа Test.Exe должна сделать окно редактирования невидимым, а при выключении - наоборот. Чтобы связать код с событием BN_CLICKED флажка Visible, выполните действия, аналогичные действиям на предыдущих этапах

В функции OnVisibleButton() напиште следующий код: void CTestDlg::OnVsibleCheck()

{

// TODO: Add your control notification handler code here

////////Мой код начинается здесь///////////

////Обновить значения переменных элементов управления,

////(содержимое эрана передается переменным элементов управления) UpdateData(TRUE);

///Если отметка флажка Visible зделать окно редактирования видимым

///А если нет - то невидимым if (m_VisibleCheck==TRUE)

GetDlgItem(IDC_TEST_EDIT)->ShowWindow(SW_SHOW); else GetDlgItem(IDC_TEST_EDIT)->ShowWindow(SW_HIDE);

////////Мой код заканчивается здесь///////////

}

24

Код, который вы ввели, содержит следующие операторы:

UpdateData(TRUE); - этот оператор обновляет значения переменных элементов управления текущими значениями, которые содержаться на экране. Т.е. при нажатии на флажок переменная может принимать два значения TRUE или FALSE, TRUE - это когда флажок включен, а FALSE - наоборот. Значит, при выполнении этого оператора переменная флажка управления принимает текущее положение флажка и все остальные переменные обновляются значениями, которые отображаются на экране.

Следующий оператор проверяет: включен или выключен флажок. Если он включен,

то выполняется оператор GetDlgItem(IDC_TEST_EDIT)->ShowWindow(SW_SHOW);,

где GetDlgItem(IDC_TEST_EDIT) извлекает указатель на элемент управления, а функция ShowWindow(SW_SHOW); с параметром SW_SHOW, делает окно редактирования видимым. А если флажок не отмечен, то выполняется та же самая функция ShowWindow(); с параметром SW_HIDE (спрятать окно редактирования).

9.Связывание кода с событием BN_CLICKED флажка Visible

При включении флажка Enable программа Test.exe должна сделать окно редактирования доступным, а при выключении - недоступным. Чтобы связать код с событием BN_CLICKED флажка Enable, выполните действия аналогичные предыдущему этапу:

Код функции OnEnableButton() следующий: void CTestDlg::OnEnableCheck()

{

// TODO: Add your control notification handler code here

////////Мой код начинается здесь///////////

////Обновить значения переменных элементов управления,

////(содержимое эрана передается переменным элементов управления) UpdateData(TRUE);

///Если отметка флажка Enable зделать окно редактирования видимым

///А если нет - то невидимым if(m_EnableCheck==TRUE)

GetDlgItem(IDC_TEST_EDIT)->EnableWindow(SW_SHOW);

else GetDlgItem(IDC_TEST_EDIT)->EnableWindow(SW_HIDE);

////////Мой код заканчивается здесь///////////

}

10.Связывание кода с событием EN_CHANGE окна редактирования

При вводе текста и его изменении в окне редактирования, возникает событие EN_CHANGE. В нашей программе при вводе слова CALCULATOR запускается калькулятор, а при вводе Paint - графический редактор Paint. Чтобы связать код с событием EN_CHANGE окна редактирования, выполните следующие действия:

1)Выберите ClassWizard в меню View

2)Выберите закладку Message Maps в панели ClassWizard

3)Используйте диалоговую панель ClassWizard для выбора следующего события: Class Name: CTestDlg

Object ID: IDC_TEST_EDIT Messages: EN_CHANGE

4)Нажмите на кнопку Add Fucntion и в раскрывшемся окне нажмите кнопку OK.

5)Нажмите кнопку Edit Code и напишите следующий код в функции OnChangeTestEdit():

void CTestDlg::OnChangeTestEdit()

{

// TODO: Add your control notification handler code here

////////Мой код начинается здесь///////////

///Обновить переменные

25

UpdateData(TRUE);

///Содать переменную типа CString, присвоить ей значение

///переменной m_TestEdit и выполнить перевод символов в верхний

///регистр.

CString UpperValue; UpperValue=m_TestEdit; UpperValue.MakeUpper();

///Если в окне редактирования напечатано PAINT

///запускается редактор PAINT и окно редактирования становится пустым. if(UpperValue=="PAINT")

{

system("mspaint.exe"); m_TestEdit=" "; UpdateData(FALSE);

}

///Если в окне редактирования напечатано CALCULATOR

///запускается калькулятор и окно редактирования становится пустым. if(UpperValue=="CALCULATOR")

{

system("calc.exe"); m_TestEdit=" "; UpdateData(FALSE);

}

////////Мой код заканчивается здесь///////////

}

Код который вы ввели содержит следующие операторы:

UpdateData(TRUE); - обновляет переменную m_TestEdit значением содержимого окна редактирования, при каждом его изменении, так как окно редактирования связано с событием EN_CHANGE.

Следующий оператор CString UpperValue; содает новую переменную типа CString.

Затем переменная UpperValue приравнивается к переменной m_TestEdit, это можно сделать, так как они имеют одинаковый тип.

Оператор UpperValue.MakeUpper(); переводит все символы переменной UpperValue в верхний регистр.

Оператор if(UpperValue=="PAINT"); проверяет, если введено ли слово PAINT, то выполняются следующие три оператора: system("pbrush.exe"); - запускает графический редактор, так как не указан явный путь к файлу, то программа будет искать его в каталоге C:\WINDOWS; m_TestEdit=""; - присваивает переменной окна редактирования значение NULL; UpadteData(FALSE) - обновляет экран.

Разработка программы завершена. Теперь отладьте и выполните программу.

Упражнение 1. Необходимо включить в свою программу еще код, чтобы при вводе слова Beep в окне редактирования, компьютер подавал звуковой сигнал.

Упражнение 2. Необходимо добавить в свою программу код, чтобы при вводе слова Message в окне редактирования, выдавалось сообщение:

а)

б)

26

в)

г)

д)

е)

ж)

з)

Часть 2. Использование конструктора и деструктора. Работа с динамической памятью.

Для создания и инициализации объекта используется функция, получившая название Конструктор, которая определяет (контролирует), как создается и инициализируется объект.

После использования объектов их необходимо уничтожить. Для этого предназначена функция - Деструктор, которая определяет, как и когда уничтожить объект.

Если этих методов явно в программе нет, компилятор при создании экземпляра класса вызовет стандартный конструктор, который и создаст объект после его декларации. После выхода из функции (из блока), в которой был создан объект, компилятор вызовет деструктор «по умолчанию», который его уничтожит. Если же объект создавался как глобальный, деструктор будет вызван по завершении работы программы.

Некоторые особенности конструктора и деструктора

1)Эти функции не имеют возвращаемого значения (даже void).

2)Они не наследуются производными классами, хотя и вызываются из них.

3)Нельзяработатьсадресамиэтихфункций.

4)Кконструктору нельзяобратитьсянапрямуюкаккобычномуметоду.

5)Деструктор можно вызывать, используя его полное квалификационное Рассмотримэтидваметодаболееподробно.

Конструктор

Конструктор - функция-член класса, определяющая способ создания объекта. Имя конструктора должносовпадать сименем класса.

Существует несколько форм конструктора. Наиболее часто используется конструктор с параметрами. Эти параметры используются для одновременной инициализации создаваемых объектов. Например:

27

class X

{

int m; // Будущие объекты – целочисленные переменные

public:

//Конструкторспараметром, черезкоторыйбудущимобъектамбудут присваиваться //конкретные значения

X (int i) { m = i; }

//Методпереустановкизначенийсуществующихобъектов

void Set (int i) { m = i; }

// Методпросмотратекущегосостояниясуществующихобъектов void Print (void) { cout « " m = " « m « endl; }

};

main()

 

{

 

X al(5);

// Явныйвызовконструктора: объектсозданиинициализированзначением5

al. Print();

// Просмотртекущегозначения

al. Set(8);

// Изменениетекущегозначениеобъектана8

al. Print();

// Просмотрновоготекущегозначения

}

 

Конструктор - это специальная функция класса, поэтому допускается вторая форма его декларации: в виде прототипа и его определения вне пространства класса. Конструктор как функция может иметь умалчиваемые значения параметров. В программе может быть несколько конструкторов. Такие конструкторы часто называют конструкторы с перекрытием. Здесь работает механизм перегрузкифункций.

Деструктор - специальная функция класса, которая отвечает за уничтожение объекта. Имя деструкторасовпадаетсименемкласса, передкоторымставитсясимвол«тильда» — ~.

Еслидекларирован

 

class X { . . . } ;

 

тодеструктордлянего

~Х(){}

То есть если элементы-данные класса имеют известный размер в байтах, например: int т; (2 байта), double x; (4 байта) и т.д. Компилятор при создании объектов выделит соответствующие участкипамяти, ивэтомслучаедеструкторненужен, т.к. онбудетиметьпустоеопределение.

Если же объект создается в динамической области памяти, например, с помощью операции захвата памяти new, то деструктор необходимо задавать явно, т.к. он должен уничтожить объект послеегоиспользованияспомощьюоперацииdelete. Рассмотримкраткоэтидвеоперации.

Операции new иdelete (C++)

Управление программным размещением объектов в памяти, т.е. выделение памяти в процессе работы программы под переменные и массивы в языке C++, осуществляется с помощью операцийnew иdelete.

Операция new автоматически определяет размер выделяемой памяти для указанного типа, а такжепозволяетинициализироватьвновьсоздаваемыйобъект.

Форматопераций:

ID_указателя = new тип (значение); // Захват памяти

(работасдинамическимобъектомчерезкосвеннуюадресациюоперация«*») delete ID_указателя; // Освобождениепамятипослеработысобъектом гдеID_указателя - идентификатор переменной-указателяна заданный тип;

тип- типзначений, длякоторыхвыделяетсяпамять; значение - константа (необязательный атрибут), определяющая начальное значение

динамическойпеременной.

Таким образом, операция new устанавливает указатель на участок свободной динамической оперативной памяти размером sizeof(num). Если выделить память не удается, то возвращается

28

нулевой указатель, что дает возможность проконтролировать процесс захвата участка динамической памяти.

Объект существует до тех пор, пока память не будет освобождена при помощи операции delete (илидоокончанияработыпрограммы).

Следующий участок программы демонстрирует работу с целочисленной динамической переменной.

int *p;

if (! (p= new int(5))){ printf ("Ошибка\n"); getchQ;

exit (1);

}

*р= 66;

printf ("\n Динамическая переменная = %d ", *р); getch();

delete p;

Теперь можно видоизменить рассмотренный ранее пример, включив в него работу с динамической памятью, применяя косвенную адресацию, а также добавив метод увеличения текущего состояния объекта в два раза:

class X {

int *m; // Будущие объекты - целочисленные динамические переменные

public:

//Конструктор с параметром, через который будущим объектам будут

//присваиваться конкретные значения

X (int i) { m = new int(i); }

//Деструктор

~X(){ delete m; }

//Метод переустановки значений существующих объектов void Set (int i) { *m=i;}

//Метод просмотра текущего состояния существующих объектов void Print (void) { cout « " m = " « *m « endl;}

void run(void) { *m *= 2; }

};

X al (5);

// Явный вызов конструктора: объект создан и инициализирован значением 5

al. Print();

// Просмотр текущего значения

al. Set(8);

// Изменение текущего значения объекта на 8

al. Print();

// Просмотр нового текущего значения

al.run();

// Решение поставленной задачи

al. Print();

// Просмотр нового значения

Упражнение 3. Разработать программу, иллюстрирующую прямой и косвенный способы обращения к методам. Пользовательский класс X должен содержать необходимые элементыданные, которые создаются в динамической области памяти, конструктор с параметрами (исходные значения по умолчанию) для создания объектов (new) и установки начального состояния:

Конструктор:

X(…);

Деструктор:

~X( );

Метод печати текущего состояния массива:

void Print(…);,

Метод переустановки текущего состояния массива:

void Set(...);

Функция, решающая поставленную задачу:

void Run(...);

29

Код методов и функциидруга — вне пространства определения класса.

Варианты: Метод Run() вычисляет:

а) разность трех целых чисел; б) произведение трех целых чисел; в) сумму трех целых чисел;

г) сумму трех чисел с плавающей запятой; д) разность трех чисел с плавающей запятой;

е) произведение трех чисел с плавающей запятой; ж) результат деления двух целых чисел с проверкой деления на ноль;

з) результат деления двух чисел с плавающей запятой с проверкой деления на ноль.

Контрольные вопросы.

1)Синтаксис, параметры и назначение функции UpdateData(…);

2)Опишите способ связи переменной с элементом управления.

3)Опишите способ создания переменной с помощью MFC ClassWizard.

4)Назначение и параметры функций ShowWindow( ) и EnableWindow( ).

5)Что такое событие (на примере EN_CHANGE)?

6)Что такое “конструктор”, какие его основные особенности?

7)Что такое “деструктор”, какие его основные особенности?

8)Когда наличие деструктора обязательно?

9)Назначение операций new и delete.

10)Сколько существуют динамические объекты?

Лабораторная работа №3.

Работа с мышью. Работа с динамической памятью. Одномерный динамический массив.

Цель работы: изучить способы работы с мышью в среде Microsoft Visual C++ 6.0. Изучить создание одномерных массивов при помощи конструктора с захватом динамической памяти и деструктора для их уничтожения..

Часть 1. Среда разработки Microsoft Visual C++ 6.0. Работа с мышью.

1. Создание нового проекта.

Для изучения способов работы с мышью в среде Microsoft Visual C++ 6.0 создадим лабораторную программу, выполняющую следующие действия:

Программа рисует с помощью мыши линии установленного цвета и размера, программа будет рисовать линию в соответствии с движениями мыши.

При нажатии на кнопки Exit программа завершается.

При запуске вашей программы, главное окно будет выглядеть так (рис 3.1):

30