Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: цвет CBrush  (Прочитано 24660 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« : 27-09-2003 03:04 » 

можно ли делать так ( DeleteObject() ) :

Код:
CBrush TempMakeBrushByColorCode;

//функция создаёт в TempMakeBrushByColorCode кисть по коду цвета
void CShelekToyView::MakeBrushByColorCode(UINT colorcode)
{
BYTE r=(colorcode & 0x00ff0000)>>16;
BYTE g=(colorcode & 0x0000ff00)>>8;
BYTE b=(colorcode & 0x000000ff);
//удаление предыдущих настроек
TempMakeBrushByColorCode.DeleteObject();
//новая кисть
TempMakeBrushByColorCode.CreateSolidBrush(RGB(r,g,b));
}


или подскажите как задать кисти новый цвет не удаляя её
« Последнее редактирование: 17-11-2007 16:15 от Алексей1153++ » Записан

Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #1 : 27-09-2003 06:05 » 

попробовал ещё так

Код:
CBrush *TempMakeBrushByColorCode=0;

//функция создаёт в TempMakeBrushByColorCode кисть по коду цвета
void CShelekToyView::MakeBrushByColorCode(UINT colorcode)
{
   if(TempMakeBrushByColorCode)
   {
      delete TempMakeBrushByColorCode;
      TempMakeBrushByColorCode=0;
   }
   BYTE r=. . .; BYTE g=. . .; BYTE b=. . .;
   TempMakeBrushByColorCode= new CBrush(RGB(r,g,b));
}

мне говорят: "Ресурс недоступен"

Да, у меня там вообще-то так всё завязано, может из-за этого:

Код:
void CShelekToyView::OnLButtonDown(UINT nFlags, CPoint point) 
{
   CFormView::OnLButtonDown(nFlags, point);
   CRect rect;
   int x,y;
   ////проверяем,куда попали
   //Растр?
   rect.SetRect(. . .);
   if (rect.PtInRect(point))
   {//на растре
      //вычисляем координаты клетки, по которой щелкнули
      . . .
      //смена цвета клетки растра
      CurrPict[. . .]=CurrColor;
      PrintCurrPict();
      return;
   }
}

//мышиная возня
void CShelekToyView::OnMouseMove(UINT nFlags, CPoint point)
{
   CFormView::OnMouseMove(nFlags, point);
   //если левая кнопка не нажата, то делать тут нечего
   if (!(nFlags && 1)) return;
   //левая кнопка нажата
   CRect rect;
   ////проверяем,куда попали
   . . .
   if (rect.PtInRect(point))
   {//на растре
      //левая кнопка нажата, обрабатываем
      OnLButtonDown(nFlags,point);
   }
}

//вывод клеток
void CShelekToyView{{PrintCurrPict):
{
   CDC *PictDC=this->GetDC();
   . . .
   for (i=0;i<CurrHeight;++i)
      {
      for (j=0;j<CurrWidth;++j)
      {
         MakeBrushByColorCode(CurrPict[. . .]);//передаём код цвета
         PictDC->SelectObject(*TempMakeBrushByColorCode);

         MakePenByColorCode(CurrPict[. . .]);//передаём код цвета
         PictDC->SelectObject(*TempMakePenByColorCode);

         PictDC->Rectangle(. . .);//рисуем клетку
      }
   }
. . .
   Release(PictDC);
}

//функция создаёт в TempMakeBrushByColorCode кисть по коду цвета
void CShelekToyView::MakeBrushByColorCode(UINT colorcode)
{
   if(TempMakeBrushByColorCode)
   {
      delete TempMakeBrushByColorCode;
      TempMakeBrushByColorCode=0;
   }
   BYTE r=. . .; BYTE g=. . .; BYTE b=. . .;
   TempMakeBrushByColorCode= new CBrush(RGB(r,g,b));
}

//функция создаёт в TempMakePenByColorCode кисть по коду цвета
void CShelekToyView::MakePenByColorCode(UINT colorcode)
{
   if(TempMakePenByColorCode)
   {
      delete TempMakePenByColorCode ;
      TempMakePenByColorCode =0;
   }
   BYTE r=. . .; BYTE g=. . .; BYTE b=. . .;
   TempMakePenByColorCode= new CPen(PS_SOLID,1,RGB(r,g,b));
}

то есть должно работать так: если просто щёлкаем по растру, то клетка окрашивается в выбранный цвет(это работает). Если зажали кнопку и двигаем мышь, то должны закрашиваться клетки, по которым проехали. И тут - по разному бывает, бывает несколько клеток успеют закраситься, бывает одна, а дальше - "Ресурс недоступен". Приехали.
« Последнее редактирование: 17-11-2007 16:26 от Алексей1153++ » Записан

Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #2 : 28-09-2003 05:01 » 

ладно, ставим вопрос по другому:

имеется массив DWORD с кодами цветов, которые потом могут поменяться.

при выводе прямоугольников можно делать так (можно ЛИ ?):

1) создать ещё два равных по размеру массива для CBrush и CPen, заполнить их при инициализации, а затем при необходимости менять цвет (.DeleteObject)

2) создать ещё два равных по размеру массива для CBrush* и CPen*, заполнить их при инициализации (by new), а затем при необходимости менять цвет (delete, new)
Записан

Гром
Птычк. Тьфу, птычник... Вот!
Готовлюсь к пенсии

il
Offline Offline
Пол: Мужской
Бодрый птах


« Ответ #3 : 28-09-2003 07:12 » 

Погоди дай посмотреть - я только проснулся.
Записан

А птичку нашу прошу не обижать!!!
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #4 : 28-09-2003 09:45 » 

спотыкалово происходит при выполнении
CDC *PictDC=this->GetDC();
, где для правильной работы должен быть диалог, на котором всё и рисуется
Записан

Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #5 : 29-09-2003 09:00 » 

Привет, (почти с большого будуна):
Сначала так, замечания по ходу пьессы
1. MakeBrushByColorCode(UINT colorcode) ты можешь вообще выбросить
     а) то что ты там с цветами делашь -  Я шокирован!
      см сюда :
       #define RGB(r,g,b) \
       ((COLORREF)(((BYTE)(r)|((WORD)((BYTE)(g))<<8))|(((DWORD)(BYTE)(b))<<16)))

       typedef DWORD COLORREF

       те у тебя сразу TempMakeBrushByColorCode.CreateSolidBrush(colorcode);

а посему у тебя лишний вызов функции, те ты вызываешь функцию, которая только и делает, что вызывает другую функцию(две функции).

2. Удалять GDI объекты конечно можно, но только не те которые используются,

те сначала ты говоришь

TempMakeBrushByColorCode.CreateSolidBrush()

потом

PictDC->SelectObject(&TempMakeBrushByColorCode);

а потом TempMakeBrushByColorCode.DeleteObject()

Но она у тебя выбрана!!!! И если где-то в промежутках она потребуется  - её нету, кстати у тебя не WinME случайно? Я с ней намучился, в плане ресурсов.

Поэтому обычно делают так: CBrush b; b.Create(); CBrush *pOld = (CBrush*)pDC->SelectObject(&b);

.....

pDC->SelectObject(pOld);
b.DeletObject(); - этого можно не делать, если это у тебя локальный объект - всё-равно деструктор будет вызван.


3. что у тебя за чехарда с переменной TempMakeBrushByColorCode?

то у тебя TempMakeBrushByColorCode.DeleteObject()

значит CBrush TempMakeBrushByColorCode; создаёшь объект в стеке, тогда:

delete TempMakeBrushByColorCode; !!!! - маразм

то у тебя TempMakeBrushByColorCode= new CBrush(RGB(r,g,b));

значит CBrush *TempMakeBrushByColorCode;  с последущим new - в куче

используй префикс в именах переменных m_ если это у тебч член класса, p - для указателей. Напр.:

CBrush *m_pTempMakeBrushByColorCode;

4. PictDC->SelectObject(*TempMakeBrushByColorCode); !!!!

если у тебя указатель, то передаешь только указатель
PictDC->SelectObject(TempMakeBrushByColorCode);

если объект, то передаёшь его адрес
PictDC->SelectObject(&TempMakeBrushByColorCode);
хотя это конечно могла быть и опечатка - я не знаю - ты из кода выдирал, или просто начипятал.  Если у тебя в коде такое - то исправляй.

Ну а про остальное... А не BMP(DIB) формат ли ты собрался изобретать? Ага

Очень похоже, Только зачем тебе массивы кистей и ручек Я шокирован!  это ж сколько ресурсов надо? Тебе нужны только данные для каждого элемента матрицы, которые потом используются в функции рисования. по сути (X,Y, COLORREF)

Думаю - меняй концепт.
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Serega
Гость
« Ответ #6 : 29-09-2003 10:26 » 

хранить таблицу кистей можно, ресурсы при этом не съедаются (разве что память)
а работать с обьектами GDI можно примерно так
Код:
template <class GDIObject>
class GDIObjectSelecter
{
CDC* dc;
GDIObject* oldObject;
public:
GDIObjectSelecter(CDC* pDC, GDIObject& newObject) : dc(pDC)
{
oldObject = dc->SelectObject(&newObject);
}
~GDIObjectSelecter()
{
dc->SelectObject(oldObject);
}
CDC* operator->()
{
return dc;
}
};

typedef GDIObjectSelecter<CBrush> BrushSelecter;
typedef GDIObjectSelecter<CFont>  FontSelecter;

а используем так
Код:
std::vector<CBrush> brushes;

void Paint()
{
CDC* pDC = GetDC();
...
BrushSelecter(pDC,brushes[currentColor])->RoundRect(rect, CPoint(10,10));
...
}
« Последнее редактирование: 17-11-2007 16:31 от Алексей1153++ » Записан
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #7 : 29-09-2003 11:41 » 

Серёга, я память и имел ввиду. Потом, число открытых хэндлов всё-таки не безгранично, зависит от памяти. И (не помню точно) по-моему на 95 совсем с ними плохо.

Но самое главное - я противник принципа: "Зачем делать просто, если можно сделать сложнее?". Если у нас белый квадрат размером 100х100 а в неём чёрный квадрат размером 10х10, то таким образом получаем 9900 кистеё и 100 карандашей!
А надо только 2.
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Serega
Гость
« Ответ #8 : 29-09-2003 12:39 » 

У меня возникает впечатление что ты плохо понимаешь что написано
Написан врапер для обьектов GDI, который следит за освобождением ресурсов
Создание обьекта GDI (например CBrush) само по себе требует только памяти для его размещения, вот если мы хотим его использовать при рисовании, тогда другое дело, врапер какраз нужен чтобы сразу же после рисования освоботить ресурс
А вообще я приверженец принципа: "зачем что-то делать если можно немного подумать и все станет просто" Отлично
Каким образом ты получил 9900 кистей и 100 карандашей я не понял (недалекий я наверно =)
Я бы нарисовал белый квадрат а в нем черный, но видимо это сложно, надо сделать проще Отлично
Не стоит настолько серьезно относиться к примерам, ведь это только примеры

P.S. возможно написал немножко жестко, извини если чем обидел
Записан
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #9 : 29-09-2003 14:01 » 

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

Но "ближе к телу":

Лёха писал:
2) создать ещё два равных по размеру массива для CBrush* и CPen*, заполнить их при инициализации (by new), а затем при необходимости менять цвет (delete, new)

это как? вот отсюда и пляшу, я так понял для каждой точки своя кисть и свой карандаш. А ты подкрепил - "хранить таблицу кистей можно".

Отсюда и 9900 кистей для фона и 100 пэнов для каждой точки, если быть точнее то 10000 кистей и 10000 пэнов для 100 на 100.

Идея сохранения оригинальных ресурсов с шаблонным классом бесспорно красива. A освобождение произойдёт автоматически в конце OnPaint(). Так что у тебя тут никакого освобождения нету.

Речь идёт о std::vector<CBrush> brushes; хотя если честно, то вторую часть твоего кода я не понял совсем. Или вернее именно вот это " std::vector<CBrush> brushes; "

Может лучше так?:
BrushSelecter(pDC,CBrush(currentColor))->RoundRect(rect, CPoint(10,10));
думаю ты это хотел написать

Но мне в данном случае это не важно, а важно именно "std::vector<CBrush> brushes;" Это к чему? Как будет проиннициаллизировано? И как удалено?

Зачем содавать массивы GDI объектов?

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

Хотя подожди - есть идея - ты что понимаешь под "освобождением ресурсов"?
Наверное, что ресурс больше не задействован и может быть удалён? Я в виду имею освобождение системных ресурсов - памяти. Если это так, то ... Ну дык,
что я ещё могу сказать
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Serega
Гость
« Ответ #10 : 29-09-2003 17:07 » 

На самом деле просто не удобно писать что-то вроде

CBrush* oldBrush = pDC->SelectObject(CBrush(...));
...
pDC->SelectObject(oldBrush);

особенно если кисти часто менять

об этом речь, а не о массивах GDI обьектов
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #11 : 29-09-2003 17:23 » 

Привет, однако!
Ух, Джонни, загрузил!!!

я не могу объяснить в умных словах, давай скину на мыло проект, лови, там комментарии, если что коряво написано - спрашивай

все "подозрительные" процедуры - после "//?Не понялНе понялНе понялНе понялНе понялНе понялНе понялНе понялНе понялНе понялНе понялНе понялНе понялНе понялНе понялНе понялНе понялНе понялНе понялНе понялНе понял"

ругай сильнее - я учусь :?   Отлично
Записан

Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #12 : 30-09-2003 12:55 » 

Привет,

Лёха, проектом твоим займусь позже. Если всё нормально будет - сегодня вечером. А ты пока присмотрись, к STL - Серёга, вон и статью написал. Клёвая эт штука!

Серёга, на самом деле всё не так просто (сложно). Обычно, стараются сохранить оригинальные параметры девайс конткста, те которые были напр. до вызова функции, а в конце действия функции восстановить их. Кто его знает, кто там DC занимался до нас. Поэтому в данном случае твой вариант с многократным вызовом

BrushSelecter(...)->

не прокатит, в итоге будет восстановлена предпоследняя, НО НАША, кисть.
или, чтоб таки достичь этого, тебе придётся сохранять все промежуточные кисти,
а потом удалять их в обратном порядке.

Но это всё фигня! Мне твой пример всё-равно понравился, как доказательство красоты использования шаблонов и STL.

Кстати, я не нашёл форума по обсуждению твоей статьи. Поэтому пишу тут. Надо бы как-нить код исправить, или хотя бы на первых порах, пометочку сделать, типа "см. HTML код". А то ведь некоторые так и вставят код.

К сожаления у меня нет достаточно времени, самому статьи писать. Поэтому - твоя статья классное начинание. Помню как сам, когда с STL разобирался, искал описание. Если нужна поддержка, или потребуется помощь - всегда пожалуйста.
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Serega
Гость
« Ответ #13 : 30-09-2003 14:09 » 

Мне очень приятно что есть люди, настолько интересующиеся программированием

врезультате выполнения кода
Код:
BrushSelecter(...)->...
будет восстановлена предыдущая кисть, собственно для этого и писалось =)
« Последнее редактирование: 20-11-2007 15:44 от Алексей1153++ » Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #14 : 30-09-2003 17:40 » 

вот ещё вопросы:

 :arrow: 1) то есть, когда я делал так:

CPen TempPen(PS_SOLID,1,RGB(r,g,b));
PictDC->SelectObject(TempPen);

а не так

CPen TempPen(PS_SOLID,1,RGB(r,g,b));
PictDC->SelectObject(&TempPen);

я делал, мягко говоря, грубо выражаясь ошибку? :oops:
а почему компилятор пропускал?

 :arrow: 2) когда произошло

CPen TempPen(PS_SOLID,1,RGB(r,g,b));
PictDC->SelectObject(&TempPen);

ТОЛЬКО передаётся адрес, а необходимые свойства читаются через него из кисти, а если кисть убили, то адрес становится на ничто, и тогда -"ресурс недоступен", я так догнал или нет?

 :arrow: 3)где статья?
Записан

Гром
Птычк. Тьфу, птычник... Вот!
Готовлюсь к пенсии

il
Offline Offline
Пол: Мужской
Бодрый птах


« Ответ #15 : 30-09-2003 20:00 » 

Статья на сайте - где ж еще Улыбаюсь
Записан

А птичку нашу прошу не обижать!!!
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #16 : 01-10-2003 01:38 » 

у меня получилось! (с)  Отлично  Отлично  Отлично

Джон, спасибо, очень помог (как и всегда)!

в проге осталось доделать undo/save/load и  ST v3.0 готов!
Записан

Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #17 : 01-10-2003 08:40 » 

Привет, я до твоего прокта так вчера и не добрался Жаль. Но раз всё работает, то поздравляю - всегда лучше учиться на своих ошибках, чем исправлять мои  Ага

1. На самом дела всё просто. Ошибки нет.
SelectObject() перегруженная функция (overloaded) т.е. есть 7 видов этой функции. Возьмём например кисть:

CBrush* SelectObject (CBrush* pBrush) в качестве параметра указатель на кисть

но! class CBrush : public CGdiObject

а все MFC CGdiObject способны "автоматически преобразовываться" ( по умному у них есть оператор преобразования типа например для кисти HBRUSH() ) в HGDIOBJ,  это переллестное свойство позволяет использовать их в API функциях напрямую:

CBrush br();
br.Create...
SelectObject(hDC,br);

есть так-же ещё такой вид SelectObject
HGDIOBJ SelectObject (HGDIOBJ)

Поэтому, когда ты вызываешь:
PictDC->SelectObject(TempPen); работает SelectObject (HGDIOBJ)
а когда
PictDC->SelectObject(&TempPen); работает SelectObject (CPen*)

Земля опять круглая!

Я просто обратил твоё внимание на тип передаваемых параметров.
Есть функции, которые требуют адрес объекта
func(&object) тогда, если:
ObjectType *pObject = new ObjectType();

передача выглядит след образом:

func(рОbject) - правильно, указатель и есть по сути адрес объекта в куче
func(*рОbject) - неправильно, это сам объект, который лежит по укзателю

если:
ObjectType Object;
то
func(Оbject) - правильно, в этом случае функция сама получит адрес
func(*рОbject) - неправильно, это будет адрес указателя - если такое вообще возможно!

2. Совершенно в дырочку! Отлично

3. На первой странице в разделе "Свежачок" - STL и шаблоны
только будь осторожен с кодом - на странице он выглядит неправильно - потому, что в шаблонах используются "<"   ">" и они проглатываются. Поэтому открывай HTML код и смотри там. Там всё правильно.

Так с твоим проектом разбираться или уже всё хокей?
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #18 : 01-10-2003 09:38 » 

Попал значит! Отлично
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #19 : 03-10-2003 10:25 » 

Джон, помнишь про Страуструпа разговор был? Он сколько весит?   Улыбаюсь

у меня ящик на 20 метров
Записан

Anonymous
Гость
« Ответ #20 : 04-10-2003 00:02 » 

Да, помню. Даже что отвечал помню:

https://forum.shelek.ru/index.php/topic,858.0.html
Ага

Поточнее адрес:
http://anatolix.naumen.ru/cppbooks.htm
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #21 : 04-10-2003 05:04 » 

на сайте не нашел Жаль
скачал из

http://anatolix.naumen.ru/cppbooks.htm

по английски

весит 2.9 M
Записан

Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines