Методичка_лабораторные2 - Сибирский государственный

advertisement
Федеральное государственное образовательное
бюджетное учреждение высшего профессионального
образования «Сибирский государственный университет
телекоммуникаций и информатики»
Нечта И.В.
Ситняковская Е.И.
Объектно-ориентированное программирование
Методические указания
Новосибирск 2013
УДК 681.3.06(075.8)
Старший преподаватель Нечта И.В., к. т. н., доцент Ситняковская Е.И.
Объектно-ориентированное программирование: Методические указания /
ФГОБУ ВПО «СибГУТИ». – Новосибирск, 2013. – 36 стр.
Данные методические указания включают в себя 13 лабораторных
работ по предмету «Объектно-ориентированное программирование».
Методические указания предназначены для студентов инженернотехнических факультетов, изучающих программирование в 3 и 5 семестрах.
Кафедра прикладной математики и кибернетики.
Рецензент
Для специальности 230105
Утверждено редакционно-издательским
качестве методических указаний
советом
«СибГУТИ»
в
Сибирский государственный университет
телекоммуникаций и информатики, 2013г.
ОГЛАВЛЕНИЕ
Введение ………………………………………………………………………….. 4
Лабораторная работа №1. Создание и использование
динамических массивов ………………………………………………………..... 5
Лабораторная работа №2. Динамические структуры данных
(список, стек, очередь) …………………………………….................................. 7
Лабораторная работа №3. Классы и объекты.
Принцип инкапсуляции…..…………………………………………………….. 10
Лабораторная работа №4. Создание иерархии классов.
Принцип наследования. ………………………………………………………... 12
Лабораторная работа №5. Использование виртуальных методов.
Принцип полиморфизма……………... ………………………………………... 13
Лабораторная работа №6. Использование динамических объектов ………... 15
Лабораторная работа №7. Разработка программы «Магазин» ……………… 17
Среда Visual Studio C++
Лабораторная работа №8. Знакомство со средой Visual Studio C++ ……….. 19
Лабораторная работа №9. Работа с Формой ………………………………….. 22
Лабораторная работа №10. Работа с таймером ……..………………………... 23
Лабораторная работа №11. Разработка Меню……………………………….... 25
Лабораторная работа №12. Размещение и оформление компонентов ……… 30
Лабораторная работа №13. Создание заставки текстового редактора. …….. 34
Список литературы ……………………………………………………………...36
3
Введение
Объектно-ориентированное программирование (ООП) возникло
в результате естественного развития процедурного программирования. ООП
– парадигма программирования, в которой центральными понятиями
являются объект и класс. По определению одного из основоположников
ООП-технологий Гради Буча: ООП – это методология программирования,
которая основана на представлении программы, в виде совокупности
объектов, каждый из которых является реализацией определённого класса
(типа особого вида), а классы образуют иерархию на принципах
наследования.
Объектно-ориентированная методология преследует те же цели,
что и структурная - дисциплинировать процесс разработки больших
программных комплексов и тем самым снизить их сложность и стоимость.
Объектно-ориентированная модель – это описание, как самих объектов, так и
способа их взаимодействия. ООП основано на применении классов C++.
Класс описывает какой-либо объект реального мира. Созданный для какоголибо приложения класс можно затем повторно использовать в других
приложениях. Это значительно сокращает время разработки и увеличивает
производительность труда программистов. Можно сказать, что класс
представляет собой механизм (шаблон) создания объектов в памяти
компьютера. ООП используется при создании больших диалоговых
программных комплексов. При создании крупных проектов на практике
применяются, обычно, оба подхода: сначала ООП, затем структурный.
Класс – это обыкновенный тип, но более сложный, чем простые типы
данных. Класс объединяет данные разных типов и функции – реализующие
действия, которое выполняются с этими данными. Внутри класса данные –
это поля, а функции – это методы.
Основные принципы ООП:
Инкапсуляция – механизм, объединяющий данные и методы,
манипулирующие этими данными, и защищающий их от внешнего
вмешательства или неправильного использования.
Наследование – создание иерархии классов для того, чтобы поля данных
и методы предков автоматически становились полями данных и методами
потомков.
Полиморфизм – возможность объектов с одинаковой спецификацией иметь
различную реализацию.
4
Лабораторная работа №1
Создание и использование динамических массивов
ЦЕЛЬ РАБОТЫ: изучение принципов работы с динамической памятью.
ОСНОВНЫЕ СВЕДЕНИЯ
Любой алгоритм имеет два основных критерия оценки эффективности трудоемкость и объем необходимой памяти. Считается, что чем меньше
эти значения, тем эффективнее используются ресурсы компьютера.
Современные компьютеры обладают достаточным объемом оперативной
памяти, необходимым для выполнения большинства обычных программ.
Однако существуют такие программы, которые могут испытывать дефицит
памяти. В таком случае, может быть применена динамическая память.
Основное отличие динамической памяти от обычной (статической)
заключается в том, что существует возможность создания и удаления
объектов из оперативной памяти в ходе выполнения программы. Например,
если массив более не используется в программе, то его можно удалить
из памяти, а освобожденное таким образом место можно использовать
для повторного размещения новой структуры данных. Также динамическая
память используется под размещение структур данных с заранее
неизвестным размером. Организацией работы динамической памяти
занимается операционная система. Программисту достаточно использовать
две функции для работы с динамической памятью:
 malloc() - выделяет память в свободной области и возвращает указатель
типа void (возвращает адрес первого байта выделенной области
памяти). Если памяти не хватает, то возвращает нулевой указатель.
 free( ) - освобождает память.
Обращение к элементам динамической памяти осуществляется при помощи
указателей. Указатель – это переменная, которая содержит адрес другой
переменной (это ссылка на некоторый объект).
А переменная, расположенная в динамически распределенной области
памяти, на которую указывает указатель, называют динамической
переменной.
Рассмотрим работу с динамическими переменными на следующем
примере.
#include <stdlib.h>
//объявим указатель на динамическую переменную типа integer
int *p;
void main(){
//выделим память под размещение переменной
p=(int*)malloc(sizeof(int));
5
//теперь можно работать с переменной
*p=5;
printf(“%d”, *p);
…
Функция malloc выделяет участок памяти запрашиваемого размера
и возвращает адрес динамической переменной. Для обращения по адресу
используется символ “*”. Обращение по указателю без предварительного
выделения памяти (вызова функции malloc) ЗАПРЕЩАЕТСЯ.
Работа с массивами происходит аналогичным образом. Обратите внимание,
что при обращении к элементу массива символ “*” не ставится.
int *p;
void main(){
//выделим память под размещение 10 элементов типа int
p=(int*)malloc(10*sizeof(int));
//теперь можно работать с массивом
p[0]=5;
p[1]=2;
printf(“%d”, p[1]+p[0]);
Перед
завершением
работы
программы
все
переменные
из
динамической
памяти
следует
удалить
вызовом
функции
free(<указатель на переменную>). Обращение к динамической переменной
после ее удаления из памяти ЗАПРЕЩЕНО.
ЗАДАНИЕ
Задание 1. Создать динамический двумерный массив размером 200200
элементов, заполнить его случайными целыми числами (типа byte).
Переписать элементы матрицы во вновь созданный одномерный
динамический массив в следующем порядке
a) По правым диагоналям, начиная с правого верхнего элемента.
b) По левым диагоналям, начиная с левого верхнего элемента.
c) По спирали, начиная с центрального элемента.
d) По спирали, начиная с левого верхнего элемента.
Задание 2. Создать двумерный динамический массив с произвольным
количеством элементов в каждой сроке. Заполнить его и распечатать
построчно. Проверить объем доступной оперативной памяти до и после
выполнения программы.
6
КОНТРОЛЬНЫЕ ВОПРОСЫ
a) Каким образом происходит создание двумерного динамического
массива?
b) Как проверить была ли выделена память под переменную успешно?
Лабораторная работа №2
Использование динамических структур данных (список, стек,
очередь)
ЦЕЛЬ РАБОТЫ: Изучить принципы работы со сложными структурами
данных.
ОСНОВНЫЕ СВЕДЕНИЯ
Линейный список – последовательность однородных элементов
линейно связанных между собой указателями. Существуют частные случаи
списка:
 Стек – элементы добавляются и удаляются с вершины головы списка
LastInputFirstOutput.
 Очередь – элементы добавляются в конец, а удаляются с начала списка
FirstInputFirstOutput.
Рассмотрим подробнее процесс работы со стеком и очередью. Введём
описание переменных используемых ниже в примере. Переменная pHead –
указатель «головы» стека\очереди. Указатель Next содержит адрес
следующего элемента стека. Переменная pTail – конец очереди.
Структура данных pLE объявлена ниже:
struct pLE{
struct pLE * Next;
int Data;
// указатель на следующий элемент (в очереди, стеке)
// данные
}
Стек.
1) Добавление
а) добавление в пустую очередь:
pHead = New pLE;
pHead →Next = Null;
7
Next
Head
Data
3
2
Next
Head
Data
1
б) добавление в заполненную очередь:
1) p = New pLE;
2) p→Next = pHead;
3) pHead = p;
2) Удаление
1) x = pHead→Data;
2) p = pHead;
3) pHead = pHead→Next;
4) delete ( p );
3
pHead
Next
Data
2
4
p
1
x
8
3) Просмотр
p = pHead
while (p! = Null){
…;
p = p→Next;
}
Очередь
1) Добавление
pTail →Next = p;
pTail = p;
pHead
pTail
1
2
p
2) Удаление
Удаление элемента очереди происходит аналогично со стеком.
ЗАДАНИЕ
Задание 1 написать процедуры и функции для работы со списком:
a) Добавление элемента после к-ого элемента списка
b) Удаление из списка к-ого элемента
c) Подсчет числа элементов в списке
d) Перемещение р-ого элемента списка после к-ого элемента
С помощью этих процедур и функций создать список следующим образом.
Включать в список полные квадраты из одномерного массива целых чисел
(типа byte). Удалить повторяющиеся элементы списка. Определить длину
полученного списка.
Задание 2 написать программу, которая визуально демонстрирует работу
стека и очереди. Длину стека и очереди ограничить 10-ю элементами.
КОНТРОЛЬНЫЕ ВОПРОСЫ
a) Привести примеры программ, когда рационально использовать стек
и очередь.
9
b) Что уступает по скорости поиска элемента: массив или список?
Лабораторная работа №3
Классы и объекты. Принцип инкапсуляции.
ЦЕЛЬ РАБОТЫ: Изучить принципы работы со сложными структурами
данных.
ОСНОВНЫЕ СВЕДЕНИЯ
Одним из важнейших механизмов объектно-ориентированного
программирования является инкапсуляция - механизм, способствующий
объединению данных с методами класса (или другими функциями),
обрабатывающими эти данные. Также к инкапсуляции относится механизм
ограничения доступа к определённым компонентам объекта. Рассмотрим
следующий пример.
class Animal {
public:
// данные и методы этого раздела будут открыты для всех
int coords[2];
void run();
private:
// данные и методы этого раздела будут открыты только для
// методов данного класса.
int color;
void Kill();
};
В рассмотренном примере класс Animal инкапсулирует свойство color
и метод Kill, предоставляя внешний интерфейс run и coords.
Модификаторы доступа используются для ограничения области
видимости элементов класса. Существуют следующие модификаторы.
Модификатор
доступа
public
protected
private
Область видимости элементов раздела
Из внешних
Из методов
Из методов
функций
наследуемых классов
самого класса
Да
Да
Да
Нет
Да
Да
Нет
Нет
Да
ЗАДАНИЕ
Задание 1.описать класс tpoint, инкапсулирующий основные свойства
и методы точки на плоскости. Создать массив из 100 точек. Нарисовать точки
10
случайным образом случайным цветом на экране. Добавить методы
движения точек:
a) Прямолинейное движение с отражением от стенок экрана.
b) Случайное движение с отражением.
Задание 2. Описание класса оформить в отдельном модуле. Сделать защиту
полей класса (т.е. использование полей через методы).
КОНТРОЛЬНЫЕ ВОПРОСЫ
a) Привести примеры ситуаций, когда необходимо
ограничение области видимости элементов класса.
b) Какой режим доступа устанавливается по умолчанию?
применять
Лабораторная работа №4
Создание иерархии классов. Принцип наследования.
ЦЕЛЬ РАБОТЫ: Изучить принципы работы со сложными структурами
данных.
ОСНОВНЫЕ СВЕДЕНИЯ
Основным достоинством объектно-ориентированного программирования
является возможность повторного использования ранее созданных классов
через наследование. Наследование – создание иерархии классов для того,
чтобы поля данных и методы предков автоматически становились полями
данных и методами потомков. Наследование реализуется возможностью
объединять класс с другим, во время объявления второго класса. Рассмотрим
следующую иерархию объектов.
Животное
Млекопитающее
Мышь
Птица
Голубь
Собака
11
Птеродактиль
Класс, лежащий на вершине иерархии, содержит поля характерные для всех
классов иерархии, например, вес. По мере углубления вниз иерархии
производится добавление отдельных полей, характерных только для данного
вида существ (например, поле Размах крыла для класса Птица), причем
остальные поля автоматически наследуются из родительского класса.
Такой механизм очень удобен в использовании и позволяет быстро
разрабатывать большое количество разных типов объектов. Пример:
class Animal{
protected:
int weight;
};
class Bird : public Animal{
protected:
int wingspan;
};
Таким образом, класс Bird имеет не только свое поле wingspan,
но и унаследованное weight.
ЗАДАНИЕ
Добавить к программе, разработанной на занятии 3:
Создать иерархию графических классов. Описания классов оформить
в отдельном модуле.
Графическая фигура
точка
отрезок
прямоугольник
ромб
окружность
треугольник
эллипс
КОНТРОЛЬНЫЕ ВОПРОСЫ
a) Объясните, что такое наследование и каковы основные правила
наследования.
b) Можно ли унаследовать элементы сразу же от двух классов?
12
Лабораторная работа №5
Использование виртуальных методов. Принцип полиморфизма.
ЦЕЛЬ РАБОТЫ: Изучение принципов полиморфизма и возможностей
его применения.
ОСНОВНЫЕ СВЕДЕНИЯ
Полиморфизм – возможность объектов иметь разную реализацию при
одинаковых интерфейсах. Когда наследуются классы, то часть
идентификаторов
(например,
имен
методов)
оказывается
уже использованными, что заставляет программиста придумывать другие
имена для схожих по «смыслу» методов. Например:
class technic{
public:
int move(){
printf(“Передвигаемся”);
}
};
class tank: public technic{
public:
int move(){
printf(“Едем в танке”);
}
};
class plane: public technic{
public:
int move(){
printf(“Летим на самолете”);
}
};
void main(){
technic a;
tank
b;
plane c;
a.move();
b.move();
c.move();
// Передвигаемся
// Едем в танке
// Летим на самолете
}
Как видно из примера полиморфизм дает возможность использовать
один и тот же идентификатор move для различных реализаций, не прибегая к
созданию дополнительных имен move1, move2, …
13
Также существует понятие виртуальных методов. Виртуальный метод –
функция класса, которая может быть переопределена в наследниках так,
что конкретная реализация метода для вызова будет определяться во время
выполнения программы. Рассмотрим следующий пример.
void main(){
technic a[2];
a[0]= new (technic);
a[1]= new (tank);
a[2]= new (plane);
for (int i=0;i<=2;i++)
a[i].move();
Результат:
Передвигаемся
Едем в танке
Летим на самолете
Для того, чтобы вызов метода a[i].move() был обработан правильно и
для каждого объекта в массиве a[] был вызван свой метод move()
(соответствующий типу объекта) необходимо объявить метод move как
виртуальный.
class technic{
public:
virtual int move(){
printf(“Передвигаемся”);
}
};
Спецификатор virtual наследуется для всех потомков класса.
ЗАДАНИЕ
Создать массивы фигур из иерархии (см. Занятие 4). Нарисовать
фигуры. Добавить методы движения фигур:
a) Прямолинейное движение с отражением от стенок экрана.
b) Вращение вокруг центра фигуры.
Создать массив динамических объектов (из ранее созданной иерархии
графических классов). Нарисовать движущиеся фигуры. Массив должен быть
один, а фигуры - различные. При описании методов движения и рисования
фигур использовать виртуальные методы.
14
КОНТРОЛЬНЫЕ ВОПРОСЫ
a) Объясните что такое полиморфизм.
b) Когда используются виртуальные функции?
Лабораторная работа №6
Использование динамических объектов.
ЦЕЛЬ РАБОТЫ: Изучить стандарт оформления кода.
ОСНОВНЫЕ СВЕДЕНИЯ
Большинство программистов работают группами и очень часто
программный код, разработанный одним человеком, дорабатывается
или используется другим. Поэтому необходимо создавать удобочитаемый
текст программы. Существуют стандарты оформления кода программы.
Рассмотрим следующие пункты стандарта:
Идентификаторы должны быть содержательными (по имени можно сказать
о назначении объекта):
Имена переменных должны быть существительными. Если они состоят
из нескольких слов, то такие слова должны разделяться символом
подчеркивания (num_students), либо каждое слово должно начинаться
с заглавной буквы (FileSize).
Имена функций должны быть глаголами. (OpenFile). Следует избегать
аббревиатур.
Имена типов следует писать слитно, не разделяя слова. Каждое слово
необходимо начинать с большой буквы(StrongTank). Для разделения классов,
объединений
и
констант
часто
используются
префиксы.
const kPi=3.14;
Описание классов следует форматировать следующим образом.
class p{
public:
char name[9];
int age;
p() {
age=0;
}
}
15
Методы класса не должны содержать большое количество строк кода, так как
это затрудняет понимание алгоритма работы. Следует также активно
использовать комментарии, чтобы описать логику программы. В начале
модуля ставится многострочный комментарий, в котором указывается
назначение модуля.
Рефакторинг кода – процесс изменения кода программы с целью увеличения
его удобочитаемости и облегчения дальнейшей его модификации.
Рефакторинг применяется при наличии избыточного числа временных
переменных, «длинной» реализации метода класса, «длинного» списка
параметров функции, «длинного» класса и т.д. Кроме этого для повышения
удобочитаемости применяется форматирование кода программы.
ЗАДАНИЕ
Описать класс tlist, инкапсулирующий основные свойства линейного
списка. В качестве методов класса должны быть описаны необходимые
операции со списками (стеком и очередью). Создать иерархию список – стек
– очередь. Продемонстрировать возможности классов иерархии в основной
программе. Текст программы должен быть оформлен по вышеописанным
правилам.
Лабораторная работа №7
Разработка программы «Магазин».
ЦЕЛЬ РАБОТЫ: Научиться
исключительных ситуаций.
пользоваться
механизмом
обработки
ОСНОВНЫЕ СВЕДЕНИЯ
Во время работы программы могут возникнуть различные
исключительные
ситуации,
которые
необходимо
обрабатывать.
Существующие механизмы отслеживания исключений могут быть
задействованы следующим образом.
try{
//блок возбуждения исключительных ситуаций
trow 10; // возбуждение исключения
}
catch (type1 arg){
// блок перехвата исключительных ситуаций
}
После возбуждения исключительной ситуации, она перехватывается
соответствующей указанному типу инструкцией catch. Рассмотрим пример:
int test(int i){
16
if (test) trow i;
}
void main(){
try{
cout <<”начало”;
test(1);
test(0);
test(2);
}
catch (int i){
cout << “перехват ”;
cout << i;
}
}
Результат:
перехват 1
перехват 2
Для обработки всех остальных исключительных ситуаций используется
инструкция catch(…). Блоки обработки исключительных ситуаций помогают
предотвратить аварийное завершение вашей программы.
В целях уменьшения вероятности возникновения ошибки в программе
предусмотрен механизм ограничения доступа к полям класса через свойства.
Например :
class ttt{
private:
int a;
public:
void set_a(int a){
if (a>0){
this->a=a;
}
}
int get_a(){
return a;
}
};
Свойство set_a() устанавливает значение переменной, а get_a(),
соответственно, считывает. Рассмотренный механизм доступа позволяет
отслеживать правильность присваиваемых значений. Также в момент
присваивания можно выполнять ряд действий, например для активации окна
приложения (form->active=true;) следует выполнить ряд дополнительных
процедур связанных с процессом активации.
17
ЗАДАНИЕ
Написать приложение «Магазин». Программа должна давать
возможность пользователю просматривать перечень продуктов, доступный
объем и их стоимость. Необходимо предусмотреть функцию добавления,
удаления товара или изменения его стоимости. Любой продукт
в магазине должен иметь срок годности. При наличии просроченного товара
система должна уведомлять об этом пользователя, указывая список
испорченных продуктов. Здесь рекомендуется использовать шаблоны
функций для обработки данных о товарах разного типа.
КОНТРОЛЬНЫЕ ВОПРОСЫ
a) В каких случаях используется исключение?
b) Что такое шаблон и для чего он используется?
18
Среда Visual Studio C++
Лабораторная работа №1
ТЕМА: Знакомство со средой Visual Studio C++. Создание простейшего
приложения. Работа с визуальными компонентами: Button, Label, TextBox.
Работа с невизуальным компонентом MenuStrip.
ЗАДАНИЕ
1.
2.
3.
4.
5.
6.
Запустите Visual Studio C++.
Выберите в палитре компонентов закладку All Windows Forms.
Перенесите с палитры компонентов на форму компоненты Label
и Button. Для этого поочередно подводите курсор мыши к компонентам,
читая подсказки, до тех пор, пока не появится Label. Выберете
его, нажав левую кнопку мыши, а затем переместите указатель на форму
и нажмите еще раз на кнопку мыши. Помещенный на форму компонент
будет иметь имя Label1 .
Проделайте то же самое, только с компонентом Button .
Напишите обработчик события Button1Click. Для этого выберите
на форме Button1 и щелкните на него дважды. Вы окажетесь в окне
редактирования.
Приведите обработчик события нажатия кнопки к следующему виду:
this->label1->Text=L"Hello";
Сохраните Приложение, выбрав пункт в главном меню File -> Save All.
Название проекта и название программного модуля не должно
совпадать!
8. Запустите на выполнение ваше Приложение. Для этого выберете
в главном меню пункт Debug->StartDebugging, или нажмите клавишу F5.
9. Нажмите на кнопку в запущенном Приложении и посмотрите,
что из этого получилось. Закройте Приложение.( При нажатии на кнопку
вызывается обработчик события System::Void button1_Click; , в котором
мы меняем свойство TextBox у объекта Label1).
10. Поместите на форму компонент TextBox.(см. п.3).
11. Приведите обработчик события нажатия кнопки к следующему виду
(вызов обработчика см. в п.5):
7.
this->textbox1->Text=L"Hello";
19
12. Измените свойство textbox1.Text на “Привет, студент!!!”. Для этого
выберете на форме объект textbox1. Перейдите в Object Inspector,
в закладке Properties найдите свойство Text и замените его.
13. Запустите на выполнение ваше Приложение. Попробуйте нажимать
кнопку, вводя разное значение в строку редактирования. Закройте
приложение.
14. Поменяйте свойство объекта Label1.Text на “1” (см. п.3).
15. Приведите обработчик события нажатия кнопки к следующему виду:
(см. п.5)
int i;
i = Convert::ToInt32(this->label1->Text);
this->label1->Text= Convert::ToString(i+1);
{ToString, ToInt32, – функции, преобразующие целый тип в строковый
и строковый в целый соответственно}
16. Запустите Приложение.
17. Закройте Приложение.
Задание 2
1.
2.
3.
4.
Для выполнения Задания 2 откройте новое Приложение.
Поместите на форму визуальные компоненты Label, TextBox и два
компонента Button. При наборе текста в окне TextBox изменяется
надпись на компоненте Label, при нажатии кнопки Сброс окно TextBox
очищается и изменяется надпись на компоненте Label , при нажатии
кнопки Выход приложение завершает свою работу (метод формы Close).
Для выравнивания положения визуальных компонент на форме,
выделите нужные компоненты и примените команду TextBox->Align.
Добавьте еще несколько компонентов на форму и поработайте с группой
компонентов: измените расположение, размер, какое-либо свойство
компонентов, исключите компонент из группы, добавьте в группу.
Для составления программного кода обработчиков событий необходимо
выбрать нужное событие на закладке Events в Инспекторе Объектов
и дважды щелкнуть на поле справа от события или выбрать нужный
20
5.
6.
обработчик из выпадающего списка, если он уже был
запрограммирован. Для компонент Button запрограммируйте нужным
образом обработчики событий Click, а для компонента TextBox обработчик TextChanged.
Для того, чтобы при запуске приложения активным был компонент
TextBox, воспользуйтесь командой TextBox->TabIndex. Измените
порядок обхода компонентов. Запустите Приложение. Воспользуйтесь
клавишей Tab.
Закройте Приложение. Закройте Visual C++.
Задание 3
1.
2.
Запустите Visual Studio C++. Откройте Приложение с Заданием 2.
Разместите на форме компонент MenuStrip. Структура меню должна
быть следующей.
File
Help
Save F2
About F1
Exit Alt+X
3.
4.
Двойной щелчок мышью по размещенному на форме компоненту
откроет окно [Design]. Используя свойства Text пунктов меню, создайте
нужную структуру меню. Для использования клавиш мнемонического
доступа к пунктам меню (Alt+подчеркнутая буква пункта) в свойстве
Text, букву подчеркивать не надо, но перед ней следует набрать символ
& (например, &File). Для определения клавиш быстрого доступа
к пунктам меню используйте свойство ShortcutKeys.
Запрограммируйте работу пунктов Exit и About. Для этого,
в обработчик события Click пункта Exit вставьте закрытие приложения,
а в обработчик события Click пункта About вставьте вызов диалогового
окна (MessageBox) вида:
Посмотрите, из чего состоит Ваше приложение, с помощью менеджера
Solution Explorer. Попробуйте исключить модуль из проекта, добавить
модуль в проект.
21
Лабораторная работа №2
ТЕМА: Работа с формой (сохранение положения и размера формы
при повторном запуске Приложения). Компоненты TextBox, Label, Button.
Обработчики событий формы, кнопок. Стандартные окна запросов,
сообщений.
ЗАДАНИЕ
Задание 1
Написать программу, восстанавливающую при открытии формы следующие
свойства: координаты формы (левый верхний угол), размер формы (высота,
ширина), текст TextBox1. Сохранять параметры необходимо в той же папке ,
в файле с таким же именем, как у файла .EXE, но с расширением .INI.
Задание 2
Добавить к предыдущей программе запрос на закрытие формы.
Рекомендации
1. Используя типизированный файл, при описании переменной типа String
необходимо задать ее размер.
2. Используя свойство ProcessName, можно получить название .EXEфайла.
(Например,
this->label1->Text=System::Diagnostics::
Process::GetCurrentProcess()->ProcessName+".exe";)
3. Для запроса на закрытие формы используйте событие FormClosing.
4. Перед считыванием данных из файла необходимо проверить
существование такого файла (при первом запуске Приложения его
не существует). Если файл не найден – выход из процедуры.
HANDLE hFind = FindFirstFile(“filename.ini”, &wfd);
if (hFind!=INVALID_HANDLE_VALUE){
//Найден
}
В раздел объявления переменных добавить: WIN32_FIND_DATA wfd;
Задание 3
Дополнить приложение, разработанное по заданиям 1 ,2, следующим
образом:
1. Создать кнопку c надписью Builder. Изменить имя кнопки
на ButtonBuilder. По нажатию на эту кнопку должно происходить
следующее:
22
System::Windows::Forms::DialogResult res;
res=MessageBox::Show("A", "Form Closing",
MessageBoxButtons::YesNo,MessageBoxIcon::Question);
if (res==IDNO){
label1->Text=L"You chose NO";
}else{
label1->Text=L"You chose Yes";
}
2.
В момент, когда кнопка Builder активна (в фокусе), по нажатию
на клавишу Escape должна очиститься метка label1:
if (e->KeyCode==Keys::Escape)
3.
4.
5.
6.
Создать кнопку c надписью Color. Изменить имя кнопки на ButtonColor.
По нажатию на эту кнопку должно происходить следующее: появляться
запрос об изменении цвета формы на зеленый. Нажатие на кнопку
(в окне с запросом) Yes изменяет цвет формы на зеленый,
на NO – восстанавливает первоначальный цвет формы. Для создания
запроса использовать MessageBox. Окно с запросом должно появляться
приблизительно посередине формы.
Создать кнопку Button (Свойство DialogResult = Close). По нажатия
на кнопку должно закрываться Приложение.
Создать кнопку Button вида Help. По нажатия на кнопку должно
появляться сообщение: Ничего не знаю! . Используйте MessageBox.
Создать обработчики, изменяющие текст заголовка Формы
в зависимости от нажатия левой клавиши мыши:
1 нажатие - Еще раз
2 нажатия - Слушаю Вас
Лабораторная работа №3
ТЕМА: Работа с таймером
ОСНОВНЫЕ СВЕДЕНИЯ
Компонент Timer (таймер) служит для отсчета интервалов реального
времени. У компонента Timer одно событие – Tick. Оно возникает через
равный
промежуток
времени,
заданный
в
свойстве
Interval
(в миллисекундах), только если Enabled=True.
23
ЗАДАНИЕ
Приложение включает 2 формы:
1-я форма – табло
2-я форма – собственная (созданная в Paint) картинка (без заголовка)
на весь экран.
По нажатию на кнопку Пуск должно происходить следующее:
Начинается отсчет времени, т.е. на Form1 поочередно с интервалом
в 1 секунду появляются цифры:
5 4 3 2 1,
а через 1 сек. После появления цифры 1 появляется Form2.
Через 5 секунд появляется сообщение:
24
Нажимаем Ok: Form2 закрывается, и мы снова видим Form1
следующего вида:
По нажатию на кнопку Пуск все повторяется.
Добавьте на Form1 в правый нижний угол часы, показывающие
текущее время следующим образом:
Сначала
17:05
Через 1 сек.
17 05
Т.е. через каждую секунду «:» будет то появляться, то исчезать.
Лабораторная работа №4
ТЕМА:
Компоненты
MenuStrip,
ContextMenuStrip,
RichTextBox,
OpenFileDialog, SaveFileDialog. Создание вложенного динамического меню.
ЗАДАНИЕ
Создание простейшего редактора, который работает с файлом
memos.txt, находящемся в текущей папке.
Задание 1
1.
Создайте главное меню – компонент MainStrip - с пунктами:
25
File
Help
New
About…
Open…
F1
F3
Close
Save
F2
Save As…
Exit
2.
3.
Alt+X
Создайте обработчики событий, поступающих от объектов:
Exit1 – закрытие формы; About1 – информация об авторах
в стандартном окне (MessageBox).
Запустите приложение
Задание 2
1.
1.1.
1.2.
1.3.
2.
3.
4.
5.
6.
Создать всплывающее меню – компонент ContextMenuStrip,
содержащее пункты: Save, About, Exit.
Меню должно появляться во время работы Приложения при нажатии
на правую кнопку мыши. Для того, чтобы форма могла использовать
ContextMenuStrip, определите значение свойства ContextMenuStrip для
формы.
Для обработки событий Click объектов About2 и Exit2 установите
обработчики событий Click объектов About1 и Exit1.
Запустите Приложение и проверьте работу объекта ContextMenuStrip.
Поместите на форму объект Label. Присвойте свойству Text значение
FileName.
Поместите на форму объект TextBox под объектом Label. Измените
значение свойства Text объекта TextBox1 на memos.txt .
Поместите на форму объект RichTextBox. Измените его размер
и выровняйте компоненты, расположенные на форме, используя
в главном меню TextBox | Align. (Для выделения группы компонентов
используйте ‘захват’ компонентов левой кнопкой мыши)
Уберите у свойства Text объекта RichTextBox1 его значение.
Установите вертикальную и горизонтальную полосы прокрутки,
используя свойство ScrollBars объекта RichTextBox1.
Для создания обработчика события, заключающегося в выборе пункта
Save в главном меню, в процедуру обработки события Click объекта
Save1 главного меню запишите код:
26
this->richTextBox1->SaveFile("c:\\Temp\\memos.txt");
7.
8.
Для обработки события Click объекта Save2 всплывающего меню
подключите ту же процедуру Save1Click.
В процедуру обработки события Activated формы запишите следующий
код:
if (System::IO::File::Exists("c:\\Temp\\memos.txt ")){
this->richTextBox1->LoadFile("c:\\Temp\\memos.txt ");
}else{
this->richTextBox1->SaveFile("c:\\Temp\\memos.txt");
}
9.
Тогда, если при запуске Приложения файл memos.txt существует
в текущей папке, то он загружается в окно richTextBox1. В случае
отсутствия файла memos.txt в текущей папке создается новый пустой
файл memos.txt (в файл записывается пустое значение свойства Lines
объекта richTextBox1).
Запустите Приложение и проверьте его работу.
Задание 2: Создание простейшего редактора, который работает с
диалоговыми окнами открытия и сохранения файлов.
1.
2.
3.
Модифицируйте ранее созданный редактор:
 Удалите с формы объекты TextBox1, Label1;
 Очистите событие Activated формы;
 Свойство ContextMenuStrip формы сделайте пустым;
 Размер объекта richTextBox1 сделайте во всю клиентскую область
(свойство Align);
 Добавьте на форму компоненты OpenFileDialog и SaveFileDialog;
 Определите свойства DefaultExt, Filter, FilterIndex, Title этих
компонентов;
По событию Click меню Open должны выполняться следующие
действия:
 Открываться диалоговое окно открытия файла;
 При закрытии окна по кнопке Open:
o В richTextBox1 загрузить выбранный файл;
o В заголовок формы - полное имя файла;
o richTextBox1 сделать видимым;
o Save, SaveAs – включить (т.е. сделать доступными);
По событию Click меню Save должны выполняться следующие
действия:
27

4.
5.
6.
7.
8.
Сохраняться текст richTextBox1 в том же файле без запроса (Имя
текущего файла является значением свойства Text формы – см.
обработчик события Click меню Open)
(Запустите Приложение и проверьте работу Open и Save, используя
файл memos.txt)
По событию Click меню SaveAs должны выполняться следующие
действия:
 В диалоговом окне сохранения файла должно предлагаться имя,
заданное в заголовке формы;
 Текст из окна объекта richTextBox1 сохраняется в файле
с выбранным пользователем именем;
(Запустите Приложение и проверьте работу SaveAs1)
По событию OnClick объекта New1 должны выполняться следующие
действия:
 Очистить поле Lines объекта RichTextBox1;
 RichTextBox1 сделать видимым;
 SaveAs1 – включить (т.е. сделать доступным);
 Save1 – выключить (т.е. сделать недоступным);
(Запустите Приложение и проверьте работу New1)
По событию OnClick объекта Close1 должны выполняться следующие
действия:
 RichTextBox1 сделать невидимым;
 SaveAs1, Save1 – выключить (т.е. сделать недоступными);
 В заголовок формы – Form1;
Запустите Приложение и проверьте его работу.
Сразу после запуска Приложения RichTextBox1 должно быть
невидимым; При выборе пункта меню New, объект RichTextBox1
должен становиться активным.
Установите свойство WindowState формы на значение Maximized.
(Запустите готовое приложение и проверьте его работу)
Задание 3
Создание пункта File главного меню текстового редактора
с возможностью добавлять имена файлов во вложенное динамическое меню
пункта Reopen, максимальный размер которого ограничен 4 пунктами.
1.
Создайте главное меню следующего вида:
File
New …
Open …
0 Name0
►
Reopen
Save
Save As …
Ctrl+S
1 Name1
2 Name2
3 Name3
28
Доступность пункта меню определяет значение свойства Enabled, для
пунктов Reopen, Save, Save As, Close установите это свойство равным
False. Эти пункты становятся доступными после выполнения команды
New или Open. Все пункты вложенного меню для Reopen невидимы
(установите свойства Visible равным False) и заполнены фиктивными
именами файлов.
Добавить пункты меню можно следующим образом:
this->toolStripMenuItem2->DropDownItems->Add(this->
toolStripMenuItem3);
2.
3.
4.
5.
Команды Save, Save As не имеют обработчиков событий.
В обработчике события Click
пункта меню New должно быть
реализовано следующее:
 Пункты меню Save, Save As, Close становятся доступны.
 Если пункт Reopen доступен (т.е. содержит список конкретных
файлов), то убирается пометка с имени файла (свойство Checked
пункта меню) в подменю Reopen.
В обработчике события OnClick пункта меню Close должно быть
реализовано следующее:
 Пункты меню Save, Save As, Close становятся недоступны.
 Убирается пометка в списке имен ранее открывавшихся файлов.
Поместите на форму компонент OpenFileDialog.
Команда Open открывает диалоговое окно открытия файла и, в случае
выбора файла, добавляет его в подменю Reopen в качестве нулевого
пункта и помечает этот пункт. При добавлении нового имени весь
список имён смещается вниз. В обработчике события Click пункта
меню Open должно быть реализовано следующее:
 Открывается диалоговое окно открытия файла. Если пользователь
выбрал файл для открытия, то выполняется следующее:
 Пункты меню Save, Save As, Close становятся доступны.
 Для пункта Reopen необходимо:
o Установить доступность.
Выполнить смещение в имеющемся списке имен файлов
на одну позицию вниз с сохранением свойства Visible
от предыдущего элемента. При смещении списка изменяется
нумерация в названии пунктов меню. Для удаления элементов
меню используйте следующую команду:
this->toolStripMenuItem2->DropDownItems->Remove(this->
toolStripMenuItem3);
o
В качестве нулевой строки вложенного меню установить
подчеркнутую цифру 0, а за ней полное имя файла, полученное
29
6.
7.
из диалогового окна. Свойство Visible этой строки установить
равным True.
o Убрать старую пометку в списке имен файлов и установить
пометку в нулевой строке.
 Добавьте в процедуру обработку ситуации, когда открываемый
файл уже имеется в списке (запомните его номер и при смещение
вниз в списке имен не изменяйте пункты полменю Reopen,
следующие за этим номером).
В обработчике события Click пункта вложенного меню должно быть
реализовано следующее (для пункта Reopen):
 Убрать старую пометку в списке имен файлов.
 Поставить пометку на том имени файла, по которому щелкнули
мышкой.
Дополните написанные обработчики событий, таким образом,
чтобы на месте заголовка формы, кроме самого заголовка формы,
отображалось ещё и имя выбранного файла.
Лабораторная работа №5
ТЕМА: Размещение и оформление компонентов. Работа с компонентами
Label, Button, Panel, PictureBox, OpenFileDialog, Timer. Работа с клавиатурой:
определение нажатой клавиши, включая функциональные и специальные
(Ctrl, Alt, Shift), её кода. Создание событий, учитывающих состояние нажатой
клавиши. Работа с приложением, содержащим более одной формы.
ОСНОВНЫЕ СВЕДЕНИЯ
Обработка клавиатуры осуществляется путем создания обработчиков
событий:
– KeyDown. Вызывается при нажатии любой клавиши, включая
функциональные и специальные (Shift, Alt, Ctrl). Данное событие
используется
для
интерпретации
нажатия
нескольких
клавиш.
– KeyPress. Вызывается при нажатии клавиши, генерирующей символы
ASCII. Событие применяется для определения символа нажатой клавиши.
Событие
генерируется
после
KeyDown,
но
перед
KeyUp.
– KeyUp. Вызывается при отпускании любой клавиши. Для каждого события
OnKeyUp
всегда
имеется
парное
ему
событие
KeyDown.
Каждый из обработчиков этих событий получает, по крайней мере, один
параметр Key, который представляет нажатую клавишу. В процедурах
KeyDown, KeyUp параметр Key принадлежит типу Word, а в процедуре
KeyPress – типу Char (символ ASCII).
Для того, чтобы события клавиатуры принимал не компонент формы,
обладающий в данный момент фокусом ввода, а сама форма, используйте
свойство формы KeyPreview. Windows представляет нажатие клавиши
30
с помощью кодовых символов виртуальных клавиш, которые обозначаются
так, например, System::Windows::Forms::Keys::Alt.
ЗАДАНИЕ
Задание 1:
Создание визуальной части приложения.
1.
Разместите на форме 7 объектов типа Label. При создании одинаковых
по размеру объектов пользуйтесь TextBoxSize. Для выравнивания
Keypress character
F12
Key down value
123
Press any key and hold
down Shift, Alt, and Ctrl
keys to see their ASCII
and virtual key values.
Special key:
Alt, Shift, Ctrl
Close
2.
3.
4.
положения объектов на форме используйте TextBoxAlign. ( Size
и Align есть в меню по правой кнопке.). Эти команды применяются
для группы выделенных объектов. Для выделения нескольких объектов
на форме: нажать левую кнопку мыши и выделить объекты с помощью
указателя мыши.
Для изменения одинаковых свойств каких-либо объектов также удобно
работать с группой. Например, при необходимости у меток и кнопки
установить жирный шрифт какого-либо заданного значения надо:
выделить нужные объекты и в инспекторе объектов изменить (один
раз!) свойство Font.
Для всех объектов типа Label установите: свойство Font, свойство
AutoSize равным False, свойство Aligment – Center, свойство Layout –
Center, свойство Text.
Поместите на форму кнопку с растровым изображением, которая будет
закрывать приложение.
Для всех объектов типа Label оформите границы, используя такие
декоративные элементы, как Panel.
31
5.
6.
7.
8.
Опишите массив, элементами которого являются названия
функциональных клавиш от F1 до F12, а индексы элементов
представляют виртуальные коды этих клавиш, в виде типизированной
константы.
В процедуре обработки события формы KeyDown выполните
следующие действия:
 Показать значение переменной Key (код виртуальной клавиши).
Для преобразования кода в строковую переменную используйте
функцию Convert::ToInt32().
 Проверить были ли нажаты клавиши Shift, Alt, Ctrl. Создать строку
из комбинации нажатых клавиш (например, Shift+Alt+Ctrl, если
были нажаты все три клавиши) и поместить её на форму
в соответствующее место.
 Если была нажата функциональная клавиша, то вывести
её символьное представление в соответствующее место.
Процедура обработки события KeyPress получает значение параметра
Key, равное символу ASCII. Поскольку управляющие коды от 1 до 26
(соответствуют от Ctrl+A до Ctrl+Z) не имеют соответствующего
визуального символа, то в соответствующем месте формы будем
отображать просто символы от ‘A’ до ‘Z’ (ASCII коды от 65 до 90).
Для отображения кода в объекте Label функцию Convert::ToString().
В процедуру обработки события формы KeyUp добавьте операторы
очистки заголовков объектов типа Label из среднего столбца.
32
Задание 2
Создание визуальной части приложения.
ОСНОВНЫЕ СВЕДЕНИЯ
Свойства компонента PictureBox:
 Image - Центральное свойство класса. Служит контейнером
изображения;
 SizeMode - Управляет размером изображения так, чтобы в них
полностью загрузилось картинка.
 ErrorImage – Изображение, отображаемое в случае ошибки загрузки
картинки, указанной в свойстве Image.
1.
Добавьте к проекту новую форму. На форму поместите компоненты:
Panel, Button, Image, Label, OpenFileDialog. Загрузите в Image
картинку. Картинка должна автоматически принимать размер
компонента Image.
2.
Разместите компоненты как показано на рисунке. У Label установите
следующие свойства: Text, Font.
3.
Создание невизуальной части приложения.
Для кнопки Button1 напишите следующий код в обработчике события
Click:
if (this->openFileDialog1->ShowDialog()==
System::Windows::Forms::DialogResult::OK){
this->pictureBox1->Image->FromFile(this-> openFileDialog1->FileName);
this->pictureBox1->SizeMode=
System::Windows::Forms::PictureBoxSizeMode::StretchImage;
4.
Добавьте на Form1 кнопку Picture, при нажатии на которую будет
появляться Form2.
33
Задание 3
1.
2.
Добавьте к проекту новую форму.
Создайте приложение, работающее следующим образом: при нажатии
и
удержании
клавиш

(System::Windows::Forms::Keys::Up)
и

(System::Windows::Forms::Keys::Down)
увеличивается
или уменьшается целое число в центре экрана, при отпускании
клавиши на экране остается текущее число.
3.
Добавьте на Form1 кнопку Число, при нажатии на которую будет
появляться Form3.
Лабораторная работа №6
ТЕМА: Создание заставки текстового редактора.
ЗАДАНИЕ
Задание 1
1.
2.
3.
4.
Откройте с помощью FileAddnew Class новую форму Form2.
Удалите значение свойства Text. Свойству FormBorderStyle присвойте
значение None (результат увидите только при запуске программы).
Для удаления кнопок минимизации, максимизации формы
и системного меню установите у свойств MinimizeBox, MaximizeBox,
ControlBox равными False(результат увидите только при запуске
программы).
Свойство Enabled установите равным False для того, чтобы
заблокировать обработку событий и лишить возможности пользователя
управлять окном с помощью клавиатуры или мыши.
Сохраните проект, определив имя второго программного модуля
проекта.
Сделаем заставку, которая будет активна при запуске программы 4 сек.,
и, затем, исчезает.
 Подключите модуль Form2.h
 Добавьте в конструктор класса Form1 следующее:
Form1(void){
Form2^ f2 = gcnew Form2;
34
f2->Show();
f2->Update();
System::Threading::Thread::Sleep(4000);
f2->Hide();
InitializeComponent();
}
5.
6.
Поместите на форму 2 заставки компонент PictureBox. Выберите файл
с картинкой для загрузки изображения. Для того чтобы растровое
изображение внутри объекта Image1 занимало всю клиентную область,
требуется изменить значение свойства SizeMode на StretchImage.
Поместите на форму заставки справа и снизу от рисунка
два компонента Label. Отобразите на них информацию об авторе
приложения и название приложения, используя различный размер, цвет
и начертание шрифта.
Задание 2
Создание таймера.
1.
2.
3.
4.
Добавьте к проекту новую форму Form3. Указанная форма должна
отображаться вместе с основной (после заставки)
Измените границы окна у Form3, сделайте их невидимыми, уберите
значки максимизации, минимизации, закрытия формы.
Поместите на форму Form3 компонент Label, свойству Text этого
компонента присвойте значение 00:00:00. Выберите для своих часов
шрифт, размер и стиль.
Поместите на форму Form3 компонент Timer. В обработчик события
Tick объекта Тimer1 добавьте следующую строку:
System::DateTime now = System::DateTime::Now;
this->label1->Text=Convert::ToString(now);
5.
6.
Для события Create формы Form3 выберите обработчик Tick, который
был создан для компонента Timer1. Тогда текущее время будет
записано в метку до появления окна.
Для формы Form3 установите свойство TopMost равным true для того,
чтобы часы были расположены всё время поверх других окон. Кроме
того, установите свойство Enabled в True.
35
СПИСОК ЛИТЕРАТУРЫ
1.
2.
3.
4.
Г. Шилдт Самоучитель С++: Пер. с англ. – 3-е изд: - СПб.:
БХВ-Петербург, 2001. – 688 с.
Иванова Г.С., Ничушкина Т.Н., Пугачев Е.К. Объектноориентированное программирование: Учеб. для вузов / Под. Ред. Г.С.
Ивановой. — М.: Изд-во МГТУ им. Н.Э.Баумана, 2001. — 320 с.
Буч Г. Объектно-ориентированный анализ и проектирование
с примерами приложений на С++: пер. с англ. М.: Бином, СПб.: Невский
диалект, 1998.
Скляров
В.А.
Язык
С++
и
объектно-ориентированное
программирование. М.: Высш. шк., 1997. — 478 с.
36
Download