С Новым годом! Форум программистов, компьютерный форум, киберфорум
Visual C++
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.93/89: Рейтинг темы: голосов - 89, средняя оценка - 4.93
 Аватар для RetiF
9 / 9 / 1
Регистрация: 21.12.2008
Сообщений: 43

Создание классов геометрических фигур, рисование на GDI (MFC)

03.04.2009, 16:22. Показов 17189. Ответов 8
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Нужно создать класс Shape, как некий родительский класс геометрических фигур, от которого будут наследоваться последующие конкретные классы: треугольник, прямоугольник; и нарисовать их. Далее нужно будет реализовать возможность перемещать эти фигуры, но сейчас не до этого, надо разобраться с самими классами

Читал литературу на эту тему, более или менее разобрался, делаю это на GDI. Класс Shape унаследовал от CPaintDC (и скорее всего, это бред), а надо, насколько я понимаю, от CObject

Вот что у меня пока что получилось (код приведён не весь, только нужное):

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
#include "afxwin.h"   // MFC Основные и стандартные компоненты
 
class CMainWnd : public CFrameWnd
{
public:
    CMainWnd();
    afx_msg void OnPaint(); // функция рисования в окне
    ~CMainWnd();       
private:
    DECLARE_MESSAGE_MAP(); // таблица откликов на сообщения
};
 
BEGIN_MESSAGE_MAP(CMainWnd, CFrameWnd) 
    ON_WM_PAINT()   
END_MESSAGE_MAP()
 
class Shape : public CPaintDC // класс-родитель всех фигур
{
public:
    Shape(CWnd* pWnd);
    ~Shape();
    int x, y;
};
 
Shape::Shape(CWnd* pWnd):CPaintDC(pWnd) {}
Shape::~Shape() {}
 
class RectAngle : public Shape // прямоугольник, класс-потомок от Shape
{
public:
    RectAngle(CWnd* pWnd);
    int width, height;
    void DrawRectAngle(int x, int y, int width, int height);
    ~RectAngle();
};
 
class TriAngle : public Shape // треугольник, класс-потомок от Shape
{
public:
    TriAngle(CWnd* pWnd);
    int x2, y2, x3, y3;
    void DrawTriAngle(int x, int y, int x2, int y2, int x3, int y3);
    ~TriAngle();
};
 
void RectAngle::DrawRectAngle(int x, int y, int width, int height)
{
    MoveTo(x,y);
    LineTo(x+width,y);
    LineTo(x+width,y+height);
    LineTo(x,y+height);
    LineTo(x,y);
}
 
void TriAngle::DrawTriAngle(int x, int y, int x2, int y2, int x3, int y3)
{
    MoveTo(x,y);
    LineTo(x2,y2);
    LineTo(x3,y3);
    LineTo(x,y);
}
 
RectAngle::RectAngle(CWnd* pWnd):Shape(pWnd) {}
RectAngle::~RectAngle() {}
 
TriAngle::TriAngle(CWnd* pWnd):Shape(pWnd) {}
TriAngle::~TriAngle() {}
 
void CMainWnd::OnPaint()
{
    RectAngle dc(this);
    dc.DrawRectAngle(10,10,110,85);
}
 
CMainWnd::CMainWnd()
{
    Create(NULL,"Work",WS_OVERLAPPEDWINDOW,CRect(250,200,700,500),NULL,NULL);
}
 
CMainWnd::~CMainWnd() {}
Вот какие есть вопросы и проблемы:

1) Про сам класс Shape - правильно ли было наследовать его от CPaintDC? Скорее всего нет, это получается, что я создал ещё один класс рисования

2) И поэтому при рисовании в окне я могу нарисовать либо прямоугольник, либо треугольник, потому как только один из них может получить контекст устройства, чтобы рисовать в нём. Как быть?
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
03.04.2009, 16:22
Ответы с готовыми решениями:

Рисование геометрических фигур
Доброго времени суток!!! Столкнулся с такой проблемой, сдаю сессию досрочно и нужно сдать летнюю...

Построить систему классов для описания плоских геометрических фигур
Построить систему классов для описания плоских геометрических фигур: круга, квадрата,...

Построить систему классов для описания плоских геометрических фигур
Здравствуйте. Прошу помощи) Вот сама задача Построить систему классов для описания плоских...

8
Эксперт С++
 Аватар для XuTPbIu_MuHTAu
2256 / 771 / 25
Регистрация: 27.05.2008
Сообщений: 1,496
03.04.2009, 16:48
Насколько я понял, в задании хотят независимый класс Shape. сделайте базовый класс и дайте ему вирутальный метод отрисовки,принимающий контекст GDI.Также всем фигурам свойственно иметь координаты (X,Y). Все остальное - свойство отдельных фигур. Унаследуйте классы треугольника,прямоугольника и т п от базового, переопределите метод отрисовки. После чего в главной программе можно будет создать,скажем, список или вектор Shape* и вызывать отрисовку для каждого в цикле. Поскольку функция вирутальная, вызываться будет отрисовка соответствующего объекта. Функцию отрисовки Shape можно определить чисто виртуальной,поможет при отладке.
0
 Аватар для RetiF
9 / 9 / 1
Регистрация: 21.12.2008
Сообщений: 43
04.04.2009, 02:07  [ТС]
сделайте базовый класс и дайте ему виртуальный метод отрисовки, принимающий контекст GDI
Я сразу потерялся, как это сделать?

C++
1
2
3
4
5
6
7
8
class Shape
{
public:
        int x, y; // координаты начальной точки фигуры
    Shape(int x, int y); // конструктор по умолчанию
    ~Shape(); // деструктор
       virtual void Draw(); // виртуальная функция рисования фигуры
};
Как передать контекст GDI? Рисоваться будет в CMainWnd, насколько я понимаю, значит и передавать надо его контекст? Нужно написать реализацию функции?

C++
1
2
3
4
virtual void Draw()
{
       // здесь происходит передача DC?
}
-------
Все остальное - свойство отдельных фигур. Унаследуйте классы треугольника, прямоугольника от базового
С этим понятно, у треугольника дополнительные точки, у прямоугольника ширина и высота, и так далее

-------
После чего в главной программе можно будет создать, скажем, список или вектор Shape* и вызывать отрисовку для каждого в цикле
Понимаю, что вопрос очень глупый, но расскажите подробнее, как это и что это?

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

Поправьте, если бред получился, а то я как в тёмной комнате
0
 Аватар для RetiF
9 / 9 / 1
Регистрация: 21.12.2008
Сообщений: 43
07.04.2009, 18:06  [ТС]
Вопрос и правда был глупый. Вот что получилось:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
class Shape
{
public:
    int prp_x, prp_y;
    Shape(int x, int y);
    ~Shape();
    virtual void Draw();
};
 
class RectAngle : public Shape
{   
public:
    int prp_width, prp_height;
    RectAngle(int x, int y, int width, int height);
    virtual void Draw(CWnd* pWnd, int x, int y, int width, int height);
    ~RectAngle();
};
 
Shape::Shape(int x, int y)
{
    prp_x = y;
    prp_y = x;
}
Shape::~Shape() {}
 
RectAngle::RectAngle(int x, int y, int width, int height):Shape(x, y)
{
    prp_width = width;
    prp_height = height;
}
RectAngle::~RectAngle() {}
 
void Shape::Draw() {}
 
void RectAngle::Draw(CWnd* pWnd, int x, int y, int width, int height) 
{
    CClientDC dc(pWnd);
    dc.MoveTo(x, y);
    dc.LineTo(x+width, y);
    dc.LineTo(x+width, y+height);
    dc.LineTo(x, y+height);
    dc.LineTo(x, y);
}
 
void RectAngleButton::OnLButtonDown(UINT, CPoint)
{
    RectAngle RA(40, 5, 105, 70);
    RA.Draw(this, RA.prp_x, RA.prp_y, RA.prp_width, RA.prp_height);
}
Код не весь, оставил только принципиальное
В готовой программе две кнопки, по нажатию на одну рисуется прямоугольник, по нажатию на вторую - треугольник
Захотел сделать третью кнопку - по нажатию на которую всё нарисованное стирается. Не осилил передать ей контекст главного окна, у неё в собственных параметрах конструктора уже есть такой параметр, если я не путаю
Вот здесь застрял:

C++
1
2
3
4
5
void EraseButton::OnLButtonDown(UINT, CPoint)
{
    CClientDC dc();
    Invalidate();
}
Добавлено через 23 часа 35 минут 23 секунды
C++
1
2
3
4
5
void RectAngleButton::OnLButtonDown(UINT, CPoint)
{
        RectAngle RA(40, 5, 105, 70);
        RA.Draw(this, RA.prp_x, RA.prp_y, RA.prp_width, RA.prp_height);
}
Это я получаю контекст самой этой кнопки - RectAngleButton, а не главного окна, которое CMainWnd

У меня единственная проблема, я искал в книгах, искал в сети, не нашёл. Как передать его контекст? Ведь не &CMainWnd, это ересь вообще

Добавлено через 21 час 49 минут 59 секунд
Внезапно обнаружил - AfxGetApp()->m_pMainWnd
А ещё оказалось, что Invalidate ничего не стирает. Использовал FloodFill:
C++
1
2
3
4
5
6
void EraseButton::OnLButtonDown(UINT, CPoint) // обработчик нажатия кнопки
{
    CClientDC dc(AfxGetApp()->m_pMainWnd); // получить контекст Главного окна
    dc.FloodFill(0,0,NULL);                // заполнить его всё цветом фона (стереть всё)
 
}
1
 Аватар для RetiF
9 / 9 / 1
Регистрация: 21.12.2008
Сообщений: 43
12.04.2009, 17:07  [ТС]
А как теперь это сделать с OnPaint?

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class CMainWnd : public CFrameWnd          
{
public:
        CMainWnd();
    afx_msg void OnPaint();
    ~CMainWnd();
private:
    DECLARE_MESSAGE_MAP();
};
 
BEGIN_MESSAGE_MAP(CMainWnd, CFrameWnd)
    ON_WM_PAINT()   
END_MESSAGE_MAP()
 
void CMainWnd::OnPaint()
{
        
}
По нажатию на кнопку должно передаваться сообщение, что нужно вызвать функцию рисования, насколько я понимаю. Как это реализовать?
0
 Аватар для RetiF
9 / 9 / 1
Регистрация: 21.12.2008
Сообщений: 43
17.04.2009, 21:07  [ТС]
На обработчики нажатия кнопок нужно было поставить изменение глобальных переменных, а в OnPaint при условии изменения переменной - вызов функции рисования

Оттакая штука получилась: http://img5.imageshost.ru/imgs... 59311a.png

Программу закончил, исходник приаттачил, вдруг кому-то понадобится
Вложения
Тип файла: zip work.zip (3.5 Кб, 3106 просмотров)
2
0 / 0 / 0
Регистрация: 14.02.2012
Сообщений: 6
14.02.2012, 01:28
class CMainWnd : public CFrameWnd
Честно говоря я не очен понял как оно у вас заработало? Мне выдает кучу ошибок. И хотелось бы узнать а где описание класса CFrameWnd?
0
 Аватар для RetiF
9 / 9 / 1
Регистрация: 21.12.2008
Сообщений: 43
14.02.2012, 09:12  [ТС]
Я не помню уже совершенно, сейчас посмотрел на своё творение и содрогнулся
Нашёл его в завалах, скомпиленный .exe запустился, хоть и криво работает, а компилить нету желания и Студии
А что, "class CMainWnd : public CFrameWnd" - это что-то плохое?
0
0 / 0 / 0
Регистрация: 14.02.2012
Сообщений: 6
15.02.2012, 22:05
"class CMainWnd : public CFrameWnd" нет это не плохое)))это как я понял создание окна. Между прочем у вас не плохо оформлен код. Хоть и криво как вы говорите. Прост класс CFrameWnd у меня пишет на студии что не найден. Но по мойму надо прописать:
#pragma comment(lib, "GdiPlus.lib")
и #include <windows.h>
в StdAfx.cpp. в Header Files
и #include <GdiPlus.h>
using namespace Gdiplus; в StdAfx.cpp.в Source Files.У меня VC2008
Но я еще не специалист только осваиваю.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
15.02.2012, 22:05
Помогаю со студенческими работами здесь

Построить систему классов для описания плоских геометрических фигур
Всем привет. Помогите пожалуйста сделать программу, ото совсем не получается и еще скоро курсовая. ...

Построить систему классов для описания плоских геометрических фигур
C++ Построить систему классов для описания плоских геометрических фигур: круга, квадрата,...

Построить систему классов для описания плоских геометрических фигур
Ребята смотрите дана така задача: Построить систему классов для описания плоских геометрических...

Многофайловая система классов для описания плоских геометрических фигур
Помогите пожалуйста составить по данной программе многофайловую систему,а то у меня не получается...

Иерархия классов для геометрических фигур
Здравствуйте, нужно Создать иерархию классов на примере геометрических фигур, которая должна...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
9
Ответ Создать тему
Новые блоги и статьи
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Programma_Boinc 28.12.2025
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост. Налог на собак: https:/ / **********/ gallery/ V06K53e Финансовый отчет в Excel: https:/ / **********/ gallery/ bKBkQFf Пост отсюда. . .
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Нашел на реддите интересную статью под названием Anyone know where to get a free Desktop or Laptop? Ниже её машинный перевод. После долгих разбирательств я наконец-то вернула себе. . .
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Рецензия / Мнение/ Перевод Нашел на реддите интересную статью под названием The Thinkpad X220 Tablet is the best budget school laptop period . Ниже её машинный перевод. Thinkpad X220 Tablet —. . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru