Форум программистов, компьютерный форум CyberForum.ru
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
antokarpo
0 / 0 / 0
Регистрация: 07.01.2013
Сообщений: 6
#1

класс холста - C++

07.01.2013, 22:36. Просмотров 461. Ответов 10
Метки нет (Все метки)

Здравствуйте всем.
Пытаюсь реализовать класс "холста" или канвы. Задумывается это как объект в виде белого прямоугольника, внутри которого будут рисоваться все нужные примитивы (линии, круги, прямоугольники и т.п.). Так вот, не могу сообразить куда прикрутить контекст устройства для этого объекта. Каким образом заставить программу понять, что данный контекст устройства привязан не к экрану, не к окну, а именно к этому прямоугольнику?

Вот то, что у меня на данный момент есть по этому вопросу:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
struct Paires {int x, int y};
 
class GCanvas
{
    public:
        GCanvas(int,int);
        virtual ~GCanvas();
 
        void Draw(HDC, int, int);
        Paires MoveTo(int,int);
        Paires LineTo(int,int);
    protected:
    private:
        int height;
        int width;
        HDC handle;
        Paires PenPos;
};
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
GCanvas::GCanvas(int w=640,int h=480)
{
    height = h;
    width = w;
    PenPos.x = 0;
    PenPos.y = 0;
}
 
GCanvas::~GCanvas()
{
    //dtor
}
 
void GCanvas::Draw(HDC hdc, int x, int y)
{
    Rectangle(hdc,x,y,x+width,y+height);
}
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
07.01.2013, 22:36
Здравствуйте! Я подобрал для вас темы с ответами на вопрос класс холста (C++):

Есть класс A и класс B, класс B вложен в класс A и вложен в него, как классу B получить доступ к переменным класса A просто по имени? - C++
На самом деле ничё фантастического я не прошу, ведь: template <class T> class matrix { friend class diagonal; ...

Класс таблиц баз данных и класс записей в таблице(реляционная таблица). Предусмотреть класс связей между таблицами - C++
Здравствуйте! Никак не могу продумать структуру этой программы. Проходим наследование, но я все равно не знаю, как его здесь применить. Как...

Отдельно класс данных, класс формул и главный класс - C++
Здравствуйте! У меня есть три вопроса. Первый вопрос. Скажите пожалуйста! Правильный ли это подход к созданию приложений :...

Реализовать класс родительский класс "Пара чисел" и класс-наследник "Комплексное число" - C++
Ткма работы создать класс pair (пара чисел); определить метод перемножения полей и операцию сложения пар (a,b)+(c,d) =(a+b,c+d)...

Класс, производный класс, паблик-класс - C++
Задание: Создать класс колесо, которое имеет радиус. Определить конструкторы и метод доступа. Создать класс машин, содержащий класс колесо....

Создать класс “Автомагазин”, состоящей из класса ”Марки машин”. Класс “Автомагазин ”:название магазина, адрес, телефон. Класс “ Марки машин ”: марка - C++
Создать класс “Автомагазин”, состоящей из класса ”Марки машин”. Класс “Автомагазин ”:название магазина, адрес, телефон. Класс “ Марки...

10
DU
1483 / 1129 / 45
Регистрация: 05.12.2011
Сообщений: 2,279
07.01.2013, 22:48 #2
тут речь идет о контексте, который создается в памяти и в который хочется рисовать? типа буфера вывода?
0
antokarpo
0 / 0 / 0
Регистрация: 07.01.2013
Сообщений: 6
08.01.2013, 14:01  [ТС] #3
Эмм... Речь идет о контексте устройства (deviсe context) типа HDC. Я, конечно, не в курсе как этот класс устроен, но думаю, что да, как-нибудь так он, наверно, и работает.

А вообще-то я имел ввиду что-то вроде класса TCanvas в C++ Builder'е, но только для MSVC++.

Добавлено через 4 часа 42 минуты
Поправьте меня, если что не так понимаю...

Возможно, надо члену класса handle передать контекст функцией GetDC(). Хотя, по моему это не сработает. Не могу сообразить как это реализовать. Может, можно как-то проще сделать и я все усложняю?
0
DU
1483 / 1129 / 45
Регистрация: 05.12.2011
Сообщений: 2,279
08.01.2013, 14:08 #4
ну рас вы задумали заменить классом GCanvas виндовый HDC и набор апишных функций для рисования в этот HDC,
то в классе GCanvas нужно сделать мембер HDC m_hdc; Добавить конструктор, который будет принимать HDC и иницилизировать этот m_hdc.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
GCanvas::GCanvas(HDC hdc, int w=640,int h=480)
{
    m_hdc = hdc;
    height = h;
    width = w;
    PenPos.x = 0;
    PenPos.y = 0;
}
 
GCanvas::~GCanvas()
{
    //dtor
}
 
void GCanvas::Draw(int x, int y)
{
    Rectangle(m_hdc,x,y,x+width,y+height);
}
ну а вообще затея плохая.
0
antokarpo
0 / 0 / 0
Регистрация: 07.01.2013
Сообщений: 6
08.01.2013, 14:17  [ТС] #5
Цитата Сообщение от DU Посмотреть сообщение
нужно сделать мембер HDC m_hdc;
Этот мембер у меня называется handle. Но не суть важно. Мне надо, чтобы можно было рисовать в HDC моего прямоугольника (холста), а не в HDC окна. Вот я и не могу додуматься как его туда прикрутить.

Добавлено через 1 минуту
Цитата Сообщение от DU Посмотреть сообщение
ну а вообще затея плохая.
Насчет плохой идеи я и сам понимаю. Посоветуй, как можно сделать это не заменяя HDC на GCanvas.
0
DU
1483 / 1129 / 45
Регистрация: 05.12.2011
Сообщений: 2,279
08.01.2013, 14:33 #6
я не совсем понимаю, что значит "hdc моего прямоугольника". в голову приходит только hdc, который создается в памяти и рисование идет сперва в него, а потом, в какой-то момент, нужно будет скопировать содержание этого hdc в окно (т.е. тут речь идет о буфере). если так, то вот, у меня завалялись старые файлики:

// common.h
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
#ifndef __COMMON_H__
#define __COMMON_H__
 
#include <windows.h>
 
typedef UINT64 UInt64;
typedef UINT16 UInt32;
typedef UINT16 UInt16;
 
typedef INT32 Int32;
 
// ...
 
struct Size
{
  UInt32 width;
  UInt32 height;
 
  Size()
    : width(0)
    , height(0)
  {
  }
 
  Size(UInt32 theWidth, UInt32 theHeight)
    : width(theWidth)
    , height(theHeight)
  {
  }
};
 
// ...
 
#endif
// mem_dc.h
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
#ifndef __MEM_DC_H__
#define __MEM_DC_H__
 
#include "common.h"
 
class MemDC
{
public:
  explicit MemDC(HWND hWnd = NULL);
  explicit MemDC(const Size& size, HWND hWnd = NULL);
  ~MemDC();
 
  HDC GetHDC() const;
 
  bool IsInited() const;
  Size GetSize() const;
  bool Resize(const Size& size);
  void Reset();
 
private:
  bool Init(const Size& size);
 
private:
  MemDC(const MemDC&);
  MemDC& operator = (const MemDC&);
 
private:
  HWND      m_hWnd;
  HDC       m_hMemDC;
  HBITMAP   m_hNativeBmp;
  HBITMAP   m_hBmp;
  Size      m_reservedSize;
  Size      m_size;
};
 
#endif
// mem_dc.cpp
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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
#include "mem_dc.h"
#include <cassert>
 
namespace
{
  class Cleanup
  {
  public:
    Cleanup(HDC& hDisplayDC,
            HDC& hMemDC,
            HBITMAP& hNativeBmp,
            HBITMAP& hBmp)
      : m_hDisplayDC(hDisplayDC)
      , m_hMemDC(hMemDC)
      , m_hNativeBmp(hNativeBmp)
      , m_hBmp(hBmp)
      , m_needCleanup(true)
    {
    }
 
    virtual ~Cleanup()
    {
      ReleaseDC(NULL, m_hDisplayDC);
      m_hDisplayDC = NULL;
      if (m_needCleanup)
      {
        SelectObject(m_hMemDC, m_hNativeBmp);
        DeleteObject(m_hBmp);
        DeleteDC(m_hMemDC);
        m_hMemDC = NULL;
        m_hNativeBmp = NULL;
        m_hBmp = NULL;
      }
    }
 
    void Cancel()
    {
      m_needCleanup = false;
    }
 
  private:
    Cleanup(const Cleanup&);
    Cleanup& operator = (const Cleanup&);
 
  private:
    HDC&      m_hDisplayDC;
    HDC&      m_hMemDC;
    HBITMAP&  m_hNativeBmp;
    HBITMAP&  m_hBmp;
    bool      m_needCleanup;
  };
 
} // namespace
 
MemDC::MemDC(HWND hWnd)
  : m_hWnd(hWnd)
  , m_hMemDC(NULL)
  , m_hNativeBmp(NULL)
  , m_hBmp(NULL)
{
}
 
MemDC::MemDC(const Size& size, HWND hWnd)
  : m_hWnd(hWnd)
  , m_hMemDC(NULL)
  , m_hNativeBmp(NULL)
  , m_hBmp(NULL)
{
  Resize(size);
}
 
MemDC::~MemDC()
{
  Reset();
}
 
HDC MemDC::GetHDC() const
{
  return m_hMemDC;
}
 
bool MemDC::IsInited() const
{
  return NULL != m_hMemDC;
}
 
Size MemDC::GetSize() const
{
  return m_size;
}
 
bool MemDC::Resize(const Size& size)
{
  return Init(size);
}
 
bool MemDC::Init(const Size& size)
{
  assert(size.width > 0 && size.height > 0 && "Invalid argument");
 
  const bool needJustResize = IsInited()
        && m_reservedSize.width >= size.width
        && m_reservedSize.height >= size.height
        ;
 
  if (needJustResize)
  {
    m_size = size;
    return true;
  }
 
  HDC hDisplayDC = NULL;
  HDC hMemDC = NULL;
  HBITMAP hNativeBmp = NULL;
  HBITMAP hBmp = NULL;
 
  Cleanup cleanup(hDisplayDC, hMemDC, hNativeBmp, hBmp);
 
  hDisplayDC = GetDC(m_hWnd);
  if (hDisplayDC == NULL)
  {
    return false;
  }
 
  hMemDC = CreateCompatibleDC(hDisplayDC);
  if (hMemDC == NULL)
  {
    return false;
  }
 
  hBmp = CreateCompatibleBitmap(hDisplayDC, size.width, size.height);
  if (hBmp == NULL)
  {
    return false;
  }
 
  hNativeBmp = static_cast<HBITMAP>(SelectObject(hMemDC, hBmp));
  if (hNativeBmp == NULL)
  {
    return false;
  }
 
  cleanup.Cancel();
 
  Reset();
 
  m_hMemDC       = hMemDC;
  m_hNativeBmp   = hNativeBmp;
  m_hBmp         = hBmp;
  m_reservedSize = size;
  m_size         = size;
 
  return true;
}
 
void MemDC::Reset()
{
  m_size = Size();
  m_reservedSize = Size();
 
  if (!IsInited())
  {
    return;
  }
 
  const HBITMAP hBmp = static_cast<HBITMAP>(SelectObject(m_hMemDC, m_hNativeBmp));
  m_hNativeBmp = NULL;
  if (hBmp != m_hBmp)
  {
    assert(!"Native and selected bitmap are not the same.");
    // do something
  }
 
  BOOL fSuccess = DeleteObject(m_hBmp);
  m_hBmp = NULL;
  if (!fSuccess)
  {
    assert(!"Failed to delete bitmap.");
    // do something
  }
 
  fSuccess = DeleteDC(m_hMemDC);
  m_hMemDC = NULL;
  if (FALSE == fSuccess)
  {
    assert(!"Failed to delete DC");
    // do something
  }
}

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

ну используется примерно так:

C++
1
2
3
4
5
6
7
8
9
MemDC memDC(GetDC(NULL), Size(100, 100)); // создание в памяти hdc
HDC hMemDC = memDC.getHDC();
Rectangle(hMemDC, 0, 0, 50, 50); // рисуем в hMemDC
... // тут тоже всякое рисование
 
HDC hWndDC = ...; // это мы откудато берем контекст для окна, чтобы вывести в него все то, что нарисовали в hMemDC
 
// копируем  в hWndDC то, что у нас в hMemDC
BitBlt(hWndDC, 0, 0, 100, 100, hMemDC, 0, 0);
1
antokarpo
0 / 0 / 0
Регистрация: 07.01.2013
Сообщений: 6
08.01.2013, 15:13  [ТС] #7
Спасибо. Изучу, и подумаю, как это применить. Но, на всякий случай, объясню что мне нужно другими словами. Вот возьмем стандартный Paint. Там есть такая область для рисования белого цвета. Вот мне нужен такой объект. Может быть, это нужно делать и не через HDC, а как-то по другому. Но я хочу реализовать вот эту самую область для рисования. "Все" перерыл, не могу найти литературу на тему. А курсовик застрял на начальном этапе. В общем, с миру по нитке и, надеюсь, справлюсь с этой задачей. Вот и пришел на форум, ведь он для этого и нужен.

Добавлено через 3 минуты
Забыл написать. Тружусь над графическим редактором. Поэтому и начинаю с самого нужного класса - холст или область для рисования (ну, или как там оно еще может называться).
0
DU
1483 / 1129 / 45
Регистрация: 05.12.2011
Сообщений: 2,279
08.01.2013, 15:26 #8
c win api лучше не связыватся, если кто-то не поставил идиотского условия, что нужно пренепременно win api. используйте qt чтоли. там в разы все проще.
0
antokarpo
0 / 0 / 0
Регистрация: 07.01.2013
Сообщений: 6
08.01.2013, 15:30  [ТС] #9
Да, я уже об этом слышал. Но, по Qt я мало литературы нашел (почти нисколько). Может, посоветуешь что-нибудь на русском? С Английским проблем нет, но переводить нет времени и не хочу.
0
DU
1483 / 1129 / 45
Регистрация: 05.12.2011
Сообщений: 2,279
08.01.2013, 15:40 #10
не посоветую, т.к. не значю что советовать. мне мануалов и примеров из сети хватает. и того и другого в сети полным полно.

Добавлено через 6 минут
вот в догонку постик:
Графический редактор на qt4
там в начале ссылка на исходники вроде.
короче юзайте поиск активнее.
1
antokarpo
0 / 0 / 0
Регистрация: 07.01.2013
Сообщений: 6
08.01.2013, 16:08  [ТС] #11
ну, вот до чего я на данный момент додумал свой "проект". Объявление класса:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
struct Paires {int x; int y;};
 
class GCanvas
{
    public:
        GCanvas(HDC,int,int);
        virtual ~GCanvas();
 
        void Draw(int, int);
        void MoveTo(int,int);
        void GLineTo(int,int);
    protected:
    private:
        int startX;
        int startY;
        int height;
        int width;
        HDC handle;
        Paires PenPos;
};
Реализация:
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
GCanvas::GCanvas(HDC hdc,int w=640,int h=480)
{
    handle = hdc;
    height = h;
    width = w;
    PenPos.x = 0;
    PenPos.y = 0;
}
 
GCanvas::~GCanvas()
{
    //dtor
}
 
void GCanvas::Draw(int x, int y)
{
    startX = x;
    startY = y;
    Rectangle(handle,x,y,x+width,y+height);
}
 
void GCanvas::MoveTo(int xx,int yy)
{
    PenPos.x = xx+startX;
    PenPos.y = yy+startY;
}
 
void GCanvas::GLineTo(int xx,int yy)
{
    MoveToEx(handle,PenPos.x,PenPos.y,NULL);
    LineTo(handle,xx+startX,yy+startY);
    PenPos.x = xx+startX;
    PenPos.y = yy+startY;
}
По тупому, конечно, но на то я и начинающий, чтобы на таких тупостях учиться )))

Добавлено через 20 минут
Цитата Сообщение от DU Посмотреть сообщение
вот в догонку постик:
Графический редактор на qt4
там в начале ссылка на исходники вроде.
По той ссылке уже ничего нет ((( Может, сайт переехал, или страницу удалили. Печально.
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
08.01.2013, 16:08
Привет! Вот еще темы с ответами:

Абстрактный класс CGraphicsObject, его наследник - базовый класс CPoint, и класс - наследник от CPoint - C++
Всем доброй ночи! Очень нужна помощь и по мере возможности разъяснения на темы: абстрактный класс в задании(что он из себя представляет и...

Создать класс Элемент списка (Node), а затем класс Список (List) - C++
Задание: Создать класс Элемент списка (Node), а затем класс Список (List). В зависимости от варианта список должен быть одно или...

Класс домов и класс улиц для учета поступлений квартплаты. Массив - C++
Задание: вырезано Файл StdAfx.h #pragma once #include &quot;targetver.h&quot; #include &lt;stdio.h&gt;

Реализовать класс Goods используя для представления цены класс Money - C++
Реализовать класс Goods (пункт 1 ), используя для представления цены класс Money с пункта 2 Реализовать метод уценки товара, уменьшая цену...


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

Или воспользуйтесь поиском по форуму:
11
Yandex
Объявления
08.01.2013, 16:08
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru