Файл: Отчёт по лабораторной работе 2 По объектноориентированному программированию.docx
Добавлен: 01.12.2023
Просмотров: 22
Скачиваний: 1
ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
Министерство науки и высшего образования РФ
ФГБОУ ВО
Московский авиационный институт
(Национальный исследовательский университет)
МАИ
Кафедра 304.
Отчёт по лабораторной работе №2
По объектно-ориентированному программированию
Вариант №6
Выполнил студент группы М3О-225Бк-21
Королёв М.А.________
Принял доцент кафедры 304 к.т.н. Новиков П.В.
Ст. преподаватель кафедры 304 Ивашенцев И.В.
Москва 2023 г.
Постановка задачи 4
Тема работы 4
Цель работы 4
Индивидуальное задание на выполнение 4
Описание классов. 5
Класс Location 6
Поля данных(приватные): 6
Методы(открытые): 6
Методы-акцессоры: 6
Класс Point 6
Поля данных(приватные): 6
Методы(открытые): 6
Методы-акцессоры: 6
Класс BareTree 7
Поля данных(приватные): 7
Поля данных(защищенные): 7
Методы(защищенные): 7
Методы(открытые): 7
Методы-акцессоры: 8
Класс Tree 8
Поля данных(приватные): 8
Методы(открытые): 8
Класс AppleTree 8
Поля данных(приватные): 8
Методы(открытые): 8
Класс Fir 9
Поля данных(приватные): 9
Методы(открытые): 9
Класс Stump 9
Поля данных(приватные): 9
Методы(открытые): 9
Класс Axe 9
Поля данных(приватные): 10
Методы(открытые): 10
Класс RepairKit 10
Поля данных(приватные): 10
Методы(открытые): 10
Текст программы 11
Файл Location.hpp 11
Файл Location.cpp 11
Файл Point.hpp 11
Файл Point.cpp 12
Файл BareTree.hpp 12
Файл BareTree.cpp 13
Файл Tree.hpp 15
Файл Tree.cpp 15
Файл AppleTree.hpp 15
Файл AppleTree.cpp 16
Файл Fir.hpp 16
Файл Fir.cpp 17
Файл Stump.hpp 18
Файл Stump.cpp 18
Файл Axe.hpp 19
Файл Axe.cpp 19
Файл RepairKit.hpp 20
Файл RepairKit.cpp 20
Файл main.cpp 21
Результаты 25
Вывод 28
Список литературы 29
Тема работы
Наследование.
Цель работы
Изучение понятий «наследование», «вертикальная иерархия», «веерная иерархия».
Изучение способа расширения иерархии классов путем наследования.
Индивидуальное задание на выполнение
Построить вертикальную иерархию потомков класса Figure, добавив 2 прямых потомка.
Построить веерную иерархию потомков класса Figure, добавив 2 прямых потомка.
Построить иерархию дополнительных объектов, с которыми будут взаимодействовать потомки класса Figure.
Реализовать простейшее взаимодействие объектов.
Описание классов.
Класс Location
Поля данных(приватные):
Целочисленные поля m_x и m_y содержат координаты объекта.
Методы(открытые):
Конструктор Location(int x, int y) – аргументами являются начальные координаты.
Метод move(int x, int y) – сдвигает объект относительно текущих координат на x и y соответственно.
Методы-акцессоры:
Методы get_x() и get_y() возвращают текущие координаты объекта.
Класс Point
Класс Point является наследником класса Location, поэтому содержит информацию родительского класса.
Поля данных(приватные):
Поле m_is_visible содержит логическое значение, отвечающее за видимость объекта.
Поле m_color содержит закодированный цвет.
Методы(открытые):
Конструктор Point(int x, int y, COLORREF color) – устанавливает начальные координаты путем вызова родительского конструктора, а также сохраняет значение цвета точки в поле m_color.
Виртуальный метод draw(HDC &hdc) отвечает за отрисовку объекта точки в окне. Аргумент hdc – контекст устройства отрисовки.
Виртуальный метод process_key_down(WPARAM key) отвечает за обработку нажатой кнопки на клавиатуре. Аргумент key – код нажатой кнопки. В данном классе содержит пустую реализацию.
Виртуальный метод process_left_mouse_down(POINT& p) отвечает за обработку нажатой левой кнопки мыши. Аргумент p – точка с координатами x и y, в которой было произведено нажатие. В данном классе содержит пустую реализацию.
Виртуальный деструктор
Point() не выполняет каких-либо действий, но используется для правильного освобождения ресурсов в класса-потомках.
Методы-акцессоры:
Метод is_visible() – возвращает текущее состояние видимости объекта.
Метод hide() – скрывает объект, устанавливает полю m_is_visible значение false.
Метод show() – показывает объект, устанавливает полю m_is_visible значение true.
Метод get_color() – возвращает установленный в конструкторе цвет.
Класс BareTree
Класс BareTree является наследником класса Point, поэтому содержит информацию родительского класса.
Поля данных(приватные):
Поле m_brush содержит объект Windows – кисть. Необходимо для отрисовки объекта с заданным цветом.
Поле m_pen содержит объект Windows – перо. Необходимо для задания цвета контура рисуемого объекта или цвета линии.
Поля данных(защищенные):
Поле m_is_dragging содержит логическое значение, показывающее, находится ли объект в состоянии изменения координат.
Поле m_width содержит целочисленное значение ширины дерева.
Поле m_height содержит целочисленное значение высоты дерева.
Методы(защищенные):
Виртуальный метод draw_dragging_rectangle(HDC &hdc) отвечает за отрисовку признака режима перемещения, а именно прямоугольного контура вокруг объекта.
Методы(открытые):
Конструктор BareTree(int x, int y, COLORREF color) устанавливает начальные координаты и цвет путем вызова родительского конструктора, создает кисть и перо для рисования дерева, устанавливает ширину и высоту объекта в поля m_width и m_height.
Виртуальный метод draw(HDC &hdc) переопределен, он отображает дерево без листьев в окне с заданным цветом и координатами. Также отображает прямоугольную границу, когда активен режим перетаскивания.
Виртуальный метод process_left_mouse_down(POINT &p) переопределен, он отвечает за перевод объекта в режим перемещения. Если в момент нажатия левой кнопки мыши курсор находился в прямоугольной области, описанной вокруг дерева, то поле m_is_dragging будет переключено в противоположное значение.
Виртуальный метод process_key_down(WPARAM key) переопределен, он отвечает за обработку нажатия кнопок перемещения, скрытия, показа объекта. Если режим перемещения не активен, обработка нажатий не осуществляется.
Деструктор
BareTree() освобождает ресурсы Windows, полученные в конструкторе и записанные в поля m_brush, m_pen.
Методы-акцессоры:
Метод get_width() возвращает целочисленное значение m_width – ширина дерева.
Метод get_height() возвращает целочисленное значение m_height – высота дерева.
Класс Tree
Класс Tree является наследником класса BareTree, поэтому содержит информацию родительского класса.
Поля данных(приватные):
Поле m_color_leaf содержит цвет листвы.
Поле m_brush_leaf содержит объект Windows – кисть. Необходимо для отрисовки листвы заданным цветом.
Методы(открытые):
Конструктор Tree(int x, int y, COLORREF color, COLORREF color_leaf) устанавливает начальные координаты и цвет путем вызова родительского конструктора, создает кисть для рисования листвы дерева.
Виртуальный метод draw(HDC &hdc) переопределен, он отображает дерево с листвой в окне с заданным цветом и координатами. Также отображает прямоугольную границу, когда активен режим перетаскивания.
Деструктор
Tree() освобождает ресурсы Windows, полученные в конструкторе и записанные в поле m_brush_leaf.
Класс AppleTree
Класс AppleTree является наследником класса Tree, поэтому содержит информацию родительского класса.
Поля данных(приватные):
Поле m_color_apple содержит цвет яблок.
Поле m_brush_apple содержит объект Windows – кисть. Необходимо для отрисовки яблок заданным цветом.
Методы(открытые):
Конструктор AppleTree(int x, int y, COLORREF color, COLORREF color_leaf, COLORREF color_apple) устанавливает начальные координаты и цвет путем вызова родительского конструктора, создает кисть для рисования яблок дерева.
Виртуальный метод draw(HDC &hdc) переопределен, он отображает дерево с яблоками в окне с заданным цветом и координатами. Также отображает прямоугольную границу, когда активен режим перетаскивания.
Деструктор
AppleTree() освобождает ресурсы Windows, полученные в конструкторе и записанные в поле m_brush_apple.
Класс Fir
Класс Fir является наследником класса BareTree, поэтому содержит информацию родительского класса.
Поля данных(приватные):
Поле m_brush содержит объект Windows – кисть. Необходимо для отрисовки ели.
Методы(открытые):
Конструктор Fir(int x, int y, COLORREF color) устанавливает начальные координаты и цвет путем вызова родительского конструктора, создает кисть для рисования ели. Устанавливает ширину и высоту рисуемого объекта.
Виртуальный метод draw(HDC &hdc) переопределен, он отображает ель в окне с заданным цветом и координатами. Также отображает прямоугольную границу, когда активен режим перетаскивания.
Деструктор
Fir() освобождает ресурсы Windows, полученные в конструкторе и записанные в поле m_brush.
Класс Stump
Класс Stump является наследником класса BareTree, поэтому содержит информацию родительского класса.
Поля данных(приватные):
Поле m_brush содержит объект Windows – кисть. Необходимо для отрисовки пня.
Методы(открытые):
Конструктор Stump(int x, int y, COLORREF color) устанавливает начальные координаты и цвет путем вызова родительского конструктора, создает кисть для рисования пня. Устанавливает ширину и высоту рисуемого объекта.
Виртуальный метод draw(HDC &hdc) переопределен, он отображает пень в окне с заданным цветом и координатами. Также отображает прямоугольную границу, когда активен режим перетаскивания.
Деструктор
Stump() освобождает ресурсы Windows, полученные в конструкторе и записанные в поле m_brush.
Класс Axe
Класс Axe является наследником класса Point, поэтому содержит информацию родительского класса.
Поля данных(приватные):
Поле m_brush_axe содержит объект Windows – кисть. Необходимо для отрисовки топора.
Поле m_brush_stick содержит объект Windows – кисть. Необходимо для отрисовки ручки топора.
Поле m_pen_string содержит объект Windows – перо. Необходимо для отрисовки крепящих веревок топора.
Методы(открытые):
Конструктор Axe(int x, int y, COLORREF color) устанавливает начальные координаты и цвет путем вызова родительского конструктора, создает кисти и перья для рисования топора.
Виртуальный метод draw(HDC &hdc) переопределен, он отображает топор в окне с заданным цветом и координатами.
Деструктор
Axe() освобождает ресурсы Windows, полученные в конструкторе и записанные в поле m_brush_axe, m_brush_stick, m_pen_string.
Класс RepairKit
Класс RepairKit является наследником класса Point, поэтому содержит информацию родительского класса.
Поля данных(приватные):
Поле m_brush_plus содержит объект Windows – кисть. Необходимо для отрисовки медицинского креста аптечки.
Поле m_brush_box содержит объект Windows – кисть. Необходимо для отрисовки чемодана аптечки.
Методы(открытые):
Конструктор RepairKit(int x, int y, COLORREF color) устанавливает начальные координаты и цвет путем вызова родительского конструктора, создает кисти и перья для рисования аптечки.
Виртуальный метод draw(HDC &hdc) переопределен, он отображает аптечку в окне с заданным цветом и координатами.
Деструктор
RepairKit() освобождает ресурсы Windows, полученные в конструкторе и записанные в поле m_brush_plus, m_brush_box.
Текст программы
Файл Location.hpp
#pragma once
class Location {
private:
int m_x;
int m_y;
public:
Location(int x, int y);
void move(int x, int y);
int get_x();
int get_y();
};
Файл Location.cpp
#include "Location.hpp"
Location::Location(int x, int y) {
m_x = x;
m_y = y;
}
void Location::move(int x, int y) {
m_x += x;
m_y += y;
}
int Location::get_x() {
return m_x;
}
int Location::get_y() {
return m_y;
}
Файл Point.hpp
#pragma once
#include
#include "Location.hpp"
class Point : public Location {
private:
bool m_is_visible;
COLORREF m_color;
public:
Point(int x, int y, COLORREF color);
virtual void draw(HDC& hdc);
virtual void process_key_down(WPARAM key);
virtual void process_left_mouse_down(POINT& p);
bool is_visible();
void hide();
void show();
COLORREF get_color();
virtual
Point() = default;
};
Файл Point.cpp
#include "Point.hpp"
Point::Point(int x, int y, COLORREF color) : Location(x, y) {
m_is_visible = true;
m_color = color;
}
void Point::draw(HDC& hdc) {
if (is_visible()) {
SetPixel(hdc, get_x(), get_y(), m_color);
SetPixel(hdc, get_x() + 1, get_y(), m_color);
SetPixel(hdc, get_x(), get_y() + 1, m_color);
SetPixel(hdc, get_x() + 1, get_y() + 1, m_color);
}
}
void Point::process_key_down(WPARAM key) { }
bool Point::is_visible() {
return m_is_visible;
}
void Point::hide() {
m_is_visible = false;
}
void Point::show() {
m_is_visible = true;
}
COLORREF Point::get_color() {
return m_color;
}
void Point::process_left_mouse_down(POINT& p) { }
Файл BareTree.hpp
#pragma once
#include "Point.hpp"
class BareTree : public Point {
private:
HBRUSH m_brush;
HPEN m_pen;
protected:
bool m_is_dragging;
int m_width;
int m_height;
virtual void draw_dragging_rectangle(HDC& hdc);
public:
BareTree(int x, int y, COLORREF color);
void draw(HDC& hdc) override;
void process_left_mouse_down(POINT &p) override;
void process_key_down(WPARAM key) override;
int get_width();
int get_height();
BareTree() override;
};
Файл BareTree.cpp
#include "BareTree.hpp"
BareTree::BareTree(int x, int y, COLORREF color) : Point(x, y, color) {
m_is_dragging = false;
m_brush = CreateSolidBrush(get_color());
m_pen = CreatePen(PS_SOLID, 2, get_color());
m_width = 40;
m_height = 130;
}
int BareTree::get_width() {
return m_width;
}
int BareTree::get_height() {
return m_height;
}
void BareTree::draw(HDC& hdc) {
draw_dragging_rectangle(hdc);
if (!is_visible()) {
return;
}
SelectObject(hdc, m_brush);
SelectObject(hdc, GetStockObject(NULL_PEN));
POINT poly[3];
poly[0].x = get_x() + 10 + 8;
poly[0].y = get_y() + 50;
poly[1].x = get_x() + 8;
poly[1].y = get_y() + 100 + 30;
poly[2].x = get_x() + 20 + 8;
poly[2].y = get_y() + 100 + 30;
Polygon(hdc, poly, 3);
SelectObject(hdc, m_pen);
MoveToEx(hdc, get_x() + 18, get_y() + 60, nullptr);
LineTo(hdc, get_x() + 4, get_y() + 20);
MoveToEx(hdc, get_x() + 18, get_y() + 60, nullptr);
LineTo(hdc, get_x() + 24, get_y() + 20);
MoveToEx(hdc, get_x() + 23, get_y() + 30, nullptr);
LineTo(hdc, get_x() + 30, get_y() + 40);
MoveToEx(hdc, get_x() + 20, get_y() + 40, nullptr);
LineTo(hdc, get_x() + 10, get_y() + 4);
MoveToEx(hdc, get_x() + 16, get_y() + 20, nullptr);
LineTo(hdc, get_x() + 24, get_y() + 4);
}
void BareTree::draw_dragging_rectangle(HDC& hdc) {
if (m_is_dragging) {
SelectObject(hdc, GetStockObject(BLACK_PEN));
SelectObject(hdc, GetStockObject(NULL_BRUSH));
Rectangle(hdc, get_x(), get_y(), get_x() + m_width, get_y() + m_height);
}
}
void BareTree::process_left_mouse_down(POINT& p) {
if (p.x >= get_x() && p.x <= get_x() + m_width && p.y >= get_y() && p.y <= get_y() + m_height) {
m_is_dragging = !m_is_dragging;
}
}
void BareTree::process_key_down(WPARAM key) {
if (!m_is_dragging) {
return;
}
if (key == 'S') {
show();
}
if (key == 'H') {
hide();
}
if (key == VK_RIGHT) {
move(10, 0);
}
if (key == VK_LEFT) {
move(-10, 0);
}
if (key == VK_UP) {
move(0, -10);
}
if (key == VK_DOWN) {
move(0, 10);
}
}
BareTree::
BareTree() {
DeleteObject(m_pen);
DeleteObject(m_brush);
}
Файл Tree.hpp
#pragma once
#include "BareTree.hpp"
class Tree : public BareTree {
private:
COLORREF m_color_leaf;
HBRUSH m_brush_leaf;
public:
Tree(int x, int y, COLORREF color, COLORREF color_leaf);
void draw(HDC& hdc) override;
Tree() override;
};
Файл Tree.cpp
#include "Tree.hpp"
Tree::Tree(int x, int y, COLORREF color, COLORREF color_leaf) : BareTree(x, y, color) {
m_color_leaf = color_leaf;
m_brush_leaf = CreateSolidBrush(m_color_leaf);
}
void Tree::draw(HDC& hdc) {
draw_dragging_rectangle(hdc);
if (!is_visible()) {
return;
}
SelectObject(hdc, m_brush_leaf);
SelectObject(hdc, GetStockObject(NULL_PEN));
Ellipse(hdc, get_x(), get_y(), get_x() + 40, get_y() + 60);
BareTree::draw(hdc);
}
Tree::
Tree() {
DeleteObject(m_brush_leaf);
}
Файл AppleTree.hpp
#pragma once
#include "Tree.hpp"
class AppleTree : public Tree {
private:
COLORREF m_color_apple;
HBRUSH m_brush_apple;
public:
AppleTree(int x, int y, COLORREF color, COLORREF color_leaf, COLORREF color_apple);
void draw(HDC& hdc) override;
AppleTree() override;
};
Файл AppleTree.cpp
#include "AppleTree.hpp"
AppleTree::AppleTree(int x, int y, COLORREF color, COLORREF color_leaf, COLORREF color_apple) : Tree(x, y, color, color_leaf) {
m_color_apple = color_apple;
m_brush_apple = CreateSolidBrush(m_color_apple);
}
void AppleTree::draw(HDC& hdc) {
draw_dragging_rectangle(hdc);
if (!is_visible()) {
return;
}
Tree::draw(hdc);
SelectObject(hdc, m_brush_apple);
SelectObject(hdc, GetStockObject(NULL_PEN));
int offset_x, offset_y;
offset_x = 10;
offset_y = 12;
Ellipse(hdc, get_x() + offset_x, get_y() + offset_y, get_x() + offset_x + 8, get_y() + offset_y + 8);
offset_x = 24;
offset_y = 22;
Ellipse(hdc, get_x() + offset_x, get_y() + offset_y, get_x() + offset_x + 8, get_y() + offset_y + 8);
offset_x = 12;
offset_y = 28;
Ellipse(hdc, get_x() + offset_x, get_y() + offset_y, get_x() + offset_x + 8, get_y() + offset_y + 8);
offset_x = 28;
offset_y = 36;
Ellipse(hdc, get_x() + offset_x, get_y() + offset_y, get_x() + offset_x + 8, get_y() + offset_y + 8);
}
AppleTree::
AppleTree() {
DeleteObject(m_brush_apple);
}
Файл Fir.hpp
#pragma once
#include "BareTree.hpp"
class Fir : public BareTree {
private:
HBRUSH m_brush;
public:
Fir(int x, int y, COLORREF color);
void draw(HDC& hdc) override;
Fir() override;
};
Файл Fir.cpp
#include "Fir.hpp"
Fir::Fir(int x, int y, COLORREF color) : BareTree(x, y, color) {
m_brush = CreateSolidBrush(color);
m_width = 60;
m_height = 70;
}
void Fir::draw(HDC& hdc) {
draw_dragging_rectangle(hdc);
if (!is_visible()) {
return;
}
SelectObject(hdc, GetStockObject(NULL_PEN));
SelectObject(hdc, m_brush);
POINT poly[11];
poly[0].x = get_x() + 30;
poly[0].y = get_y();
poly[1].x = get_x() + 50;
poly[1].y = get_y() + 25;
poly[2].x = get_x() + 40;
poly[2].y = get_y() + 20;
poly[3].x = get_x() + 60;
poly[3].y = get_y() + 50;
poly[4].x = get_x() + 40;
poly[4].y = get_y() + 40;
poly[5].x = get_x() + 40;
poly[5].y = get_y() + 70;
poly[6].x = get_x() + 20;
poly[6].y = get_y() + 70;
poly[7].x = get_x() + 20;
poly[7].y = get_y() + 40;
poly[8].x = get_x();
poly[8].y = get_y() + 50;
poly[9].x = get_x() + 20;
poly[9].y = get_y() + 20;
poly[10].x = get_x() + 10;
poly[10].y = get_y() + 25;
Polygon(hdc, poly, 11);
}
Fir::
Fir() {
DeleteObject(m_brush);
}
Файл Stump.hpp
#pragma once
#include "BareTree.hpp"
class Stump : public BareTree {
private:
HBRUSH m_brush;
public:
Stump(int x, int y, COLORREF color);
void draw(HDC& hdc) override;
Stump() override;
};
Файл Stump.cpp
#include "Stump.hpp"
Stump::Stump(int x, int y, COLORREF color) : BareTree(x, y, color) {
m_brush = CreateSolidBrush(color);
m_width = 82;
m_height = 73;
}
void Stump::draw(HDC& hdc) {
draw_dragging_rectangle(hdc);
if (!is_visible()) {
return;
}
SelectObject(hdc, GetStockObject(NULL_PEN));
SelectObject(hdc, m_brush);
POINT poly[13];
poly[0].x = get_x() + 20;
poly[0].y = get_y() + 10;
poly[1].x = get_x() + 20;
poly[1].y = get_y() + 40;
poly[2].x = get_x();
poly[2].y = get_y() + 55;
poly[3].x = get_x() + 20;
poly[3].y = get_y() + 60;
poly[4].x = get_x() + 17;
poly[4].y = get_y() + 70;
poly[5].x = get_x() + 30;
poly[5].y = get_y() + 63;
poly[6].x = get_x() + 40;
poly[6].y = get_y() + 63;
poly[7].x = get_x() + 48;
poly[7].y = get_y() + 73;
poly[8].x = get_x() + 55;
poly[8].y = get_y() + 71;
poly[9].x = get_x() + 52;
poly[9].y = get_y() + 65;
poly[10].x = get_x() + 82;
poly[10].y = get_y() + 65;
poly[11].x = get_x() + 68;
poly[11].y = get_y() + 50;
poly[12].x = get_x() + 60;
poly[12].y = get_y() + 10;
Polygon(hdc, poly, 13);
}
Stump::
Stump() {
DeleteObject(m_brush);
}
Файл Axe.hpp
#pragma once
#include "Point.hpp"
class Axe : public Point {
private:
HBRUSH m_brush_axe;
HBRUSH m_brush_stick;
HPEN m_pen_string;
public:
Axe(int x, int y, COLORREF color);
void draw(HDC& hdc) override;
Axe() override;
};
Файл Axe.cpp
#include "Axe.hpp"
Axe::Axe(int x, int y, COLORREF color) : Point(x, y, color) {
m_brush_stick = CreateSolidBrush(get_color());
m_brush_axe = CreateSolidBrush(RGB(127, 127, 127));
m_pen_string = CreatePen(PS_SOLID, 1, RGB(252, 218, 191));
}
void Axe::draw(HDC& hdc) {
if (!is_visible()) {
return;
}
SelectObject(hdc, m_brush_stick);
SelectObject(hdc, GetStockObject(BLACK_PEN));
Rectangle(hdc, get_x(), get_y(), get_x() + 10, get_y() + 80);
SelectObject(hdc, m_brush_axe);
POINT poly[3];
poly[0].x = get_x();
poly[0].y = get_y() + 20;
poly[1].x = get_x() + 30;
poly[1].y = get_y();
poly[2].x = get_x() + 30;
poly[2].y = get_y() + 40;
Polygon(hdc, poly, 3);
SelectObject(hdc, m_pen_string);
MoveToEx(hdc, get_x(), get_y() + 13, nullptr);
LineTo(hdc, get_x() + 10, get_y() + 28);
MoveToEx(hdc, get_x() + 10, get_y() + 13, nullptr);
LineTo(hdc, get_x(), get_y() + 28);
}
Axe::
Axe() {
DeleteObject(m_brush_axe);
DeleteObject(m_brush_stick);
DeleteObject(m_pen_string);
}
Файл RepairKit.hpp
#pragma once
#include "Point.hpp"
class RepairKit : public Point {
private:
HBRUSH m_brush_plus;
HBRUSH m_brush_box;
public:
RepairKit(int x, int y, COLORREF color);
void draw(HDC& hdc) override;
RepairKit() override;
};
Файл RepairKit.cpp
#include "RepairKit.hpp"
RepairKit::RepairKit(int x, int y, COLORREF color) : Point(x, y, color) {
m_brush_box = CreateSolidBrush(get_color());
m_brush_plus = CreateSolidBrush(RGB(255, 0, 0));
}
void RepairKit::draw(HDC& hdc) {
if (!is_visible()) {
return;
}
int offset_y = 20;
SelectObject(hdc, m_brush_box);
SelectObject(hdc, GetStockObject(BLACK_PEN));
Rectangle(hdc, get_x(), get_y() + offset_y, get_x() + 100, get_y() + offset_y + 60);
SelectObject(hdc, m_brush_plus);
SelectObject(hdc, GetStockObject(NULL_PEN));
int width = 10;
int height = 40;
int center_x = get_x() + 50;
int center_y = get_y() + 30 + offset_y;
Rectangle(hdc, center_x - width / 2, center_y - height / 2, center_x + width / 2, center_y + height / 2);
width = 40;
height = 10;
Rectangle(hdc, center_x - width / 2, center_y - height / 2, center_x + width / 2, center_y + height / 2);
SelectObject(hdc, GetStockObject(BLACK_PEN));
MoveToEx(hdc, get_x(), get_y() + offset_y, nullptr);
LineTo(hdc, get_x() + 20, get_y());
LineTo(hdc, get_x() + 80, get_y());
LineTo(hdc, get_x() + 100, get_y() + offset_y);
}
RepairKit::
RepairKit() {
DeleteObject(m_brush_box);
DeleteObject(m_brush_plus);
}
Файл main.cpp
#include
#include
#include
#include
#include "Point.hpp"
#include "BareTree.hpp"
#include "Tree.hpp"
#include "AppleTree.hpp"
#include "Fir.hpp"
#include "Stump.hpp"
#include "Axe.hpp"
#include "RepairKit.hpp"
static BareTree* tree1 = new BareTree(0, 0, RGB(150, 75, 0));
static BareTree* tree2 = new Tree(60, 0, RGB(150, 75, 0), RGB(0, 255, 0));
static BareTree* tree3 = new AppleTree(120, 0, RGB(150, 75, 0), RGB(0, 255, 0), RGB(255, 0, 0));
static BareTree* tree4 = new Fir(180, 0, RGB(150, 75, 0));
static BareTree* tree5 = new Stump(260, 0, RGB(150, 75, 0));
static BareTree* trees[] = { tree1, tree2, tree3, tree4, tree5 };
static Point* axe = new Axe(100, 200, RGB(150, 75, 0));
static Point* repair_kit = new RepairKit(200, 200, RGB(200, 200, 200));
static TCHAR szWindowClass[] = _T("DesktopApp");
static TCHAR szTitle[] = _T("Labwork 2");
HINSTANCE hInst;
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
bool is_intersec(int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3);
int WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance,
_In_ LPSTR lpCmdLine, _In_ int nCmdShow) {
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(wcex.hInstance, IDI_APPLICATION);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(GetStockObject(WHITE_BRUSH));
wcex.lpszMenuName = NULL;
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, IDI_APPLICATION);
if (!RegisterClassEx(&wcex)) {
MessageBox(NULL, _T("Call to RegisterClassEx failed!"), szTitle, NULL);
return 1;
}
hInst = hInstance;
HWND hWnd = CreateWindowEx(WS_EX_OVERLAPPEDWINDOW, szWindowClass, szTitle,
WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
800, 600, NULL, NULL, hInstance, NULL);
if (!hWnd) {
MessageBox(NULL, _T("Call to CreateWindow failed!"), szTitle, NULL);
return 1;
}
ShowWindow(hWnd, nCmdShow);
MSG msg;
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int)msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam,
LPARAM lParam) {
PAINTSTRUCT ps;
HDC hdc;
TCHAR greeting[] = _T("Hello, Windows desktop!");
switch (message) {
case WM_KEYDOWN:
{
for (int i = 0; i < 5; i++) {
trees[i]->process_key_down(wParam);
}
if (wParam == 'C') {
int ax1 = axe->get_x();
int ay1 = axe->get_y();
int ax2 = axe->get_x() + 30;
int ay2 = axe->get_y() + 80;
int rx1 = repair_kit->get_x();
int ry1 = repair_kit->get_y();
int rx2 = repair_kit->get_x() + 100;
int ry2 = repair_kit->get_y() + 80;
for (int i = 0; i < 5; i++) {
int x1 = trees[i]->get_x();
int y1 = trees[i]->get_y();
int x2 = trees[i]->get_x() + trees[i]->get_width();
int y2 = trees[i]->get_y() + trees[i]->get_height();
if (is_intersec(x1, y1, x2, y2, ax1, ay1, ax2, ay2)) {
trees[i]->hide();
}
else if (is_intersec(x1, y1, x2, y2, rx1, ry1, rx2, ry2)) {
trees[i]->show();
}
}
}
InvalidateRect(hWnd, NULL, TRUE);
break;
}
case WM_LBUTTONDOWN:
POINT p;
GetCursorPos(&p);
ScreenToClient(hWnd, &p);
for (int i = 0; i < 5; i++) {
trees[i]->process_left_mouse_down(p);
}
InvalidateRect(hWnd, NULL, TRUE);
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
for (int i = 0; i < 5; i++) {
trees[i]->draw(hdc);
}
axe->draw(hdc);
repair_kit->draw(hdc);
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
break;
}
return 0;
}
bool is_intersec(int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3) {
return !(x0 > x3 || x1 < x2 || y0 > y3 || y1 < y2);
}
Результаты
После запуска программы откроется окно, содержащее 5 деревьев: дерево без листьев, дерево с листьями, дерево с яблоками, ель, пень. Ниже деревьев располагаются топор и аптечка:
Окно после запуска программы
Дерево с яблоками перемещено и все еще находится в режиме перемещения
Любое из деревьев можно перемещать путем перевода его в режим перемещения с помощью нажатия на него левой кнопкой мыши. Перемещение происходит путем нажатия «стрелочек» на клавиатуре, при этом находясь в режиме перемещения. Прямоугольник вокруг объекта информирует, что активен режим перемещения.
Простейшее взаимодействие между объектами реализовано следующим образом:
Проверка пересечения объектов происходит при нажатии клавиши “C” на клавиатуре. Объекты, которые касаются топора будут скрыты, а которые касаются аптечки – отображены. Если объект не касается топора или аптечки, дополнительных действий не происходит.
Дерево с яблоками касается топора. Была нажата клавиша C. Дерево было скрыто
В скрытом состоянии дерево было перемещено к аптечке. После была нажата клавиша C. Дерево было отображено
Вывод
В результате выполнения лабораторной работы были изучены понятия «наследование», «вертикальная иерархия», «веерная иерархия». На примере языка C++ и среды VisualStudio была создана вертикальная иерархия BareTree-Tree-AppleTree, веерная иерархия BareTree-Fir-Stump, освоен способ наследования классов. Было реализовано простейшее взаимодействие потомков класса BareTree с дополнительными объектами Axe и RepairKit.
Список литературы
-
Лекционные материалы по объектно-ориентированному программированию -
Дополнительный материал, предложенный на лекциях - http://radiofront.narod.ru/htm/prog/htm/winda/api/paint.html -
Документация Microsoft по созданию оконного приложения под ОС Windows на языке C++ - https://learn.microsoft.com/en-us/cpp/windows/walkthrough-creating-windows-desktop-applications-cpp?view=msvc-170