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

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: вывод изображения по нажатию кнопки  (Прочитано 23344 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Olezyk
Гость
« : 30-09-2007 17:04 » 

Скажите, пожалуйста, как сделать? есть класс-потомок от CPaintDC.  есть функция(этого класса), рисующая картинку. нужно сделать так, чтоб при нажатии кнопки, в отдельном окне вырисовывался рисунок.
Записан
MS
Помогающий

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

« Ответ #1 : 30-09-2007 17:30 » 

Olezyk, какой язык то?
Записан

Ничто так не ограничивает полёт мысли программиста, как компилятор
Olezyk
Гость
« Ответ #2 : 30-09-2007 17:33 » 

Visual C++ с использованием MFC
Записан
MS
Помогающий

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

« Ответ #3 : 30-09-2007 17:34 » 

Уууу..., извини это не ко мне, и писал бы сразу в раздел по C++
Записан

Ничто так не ограничивает полёт мысли программиста, как компилятор
Алексей++
глобальный и пушистый
Глобальный модератор

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


« Ответ #4 : 04-10-2007 09:26 » 

Olezyk, сорри за позднее реагирование...  Расскажи подробнее, что за функция, статическая ли она, что принимает внутрь, - пока не понятно, где помочь нужно Улыбаюсь
Записан

Olezyk
Гость
« Ответ #5 : 04-10-2007 15:08 » 

))) здорово, что вообще среагировал!
так вот мой класс, описывает рисование циферблата часов. там есть написаная функция вывода на экран(т е простой круг со штрихами, над ними цифры 1,2..11), входной параметр область rect rc. на форме ставлю button и при нажатии на него в области rc (это picture на панели controls) должен нарисоваться циферблат. 
Когда я пишу в OnPaint() (тот же самый текст,что и для функции обработчика), то в этой области циферблат выходит. но если я пишу в обработчике нажатия OnButton(), то при нажатии начего не происходит.
Мой класс - CTotalDC, содержит описание функции рисования и функции настройки - типа цвет фона, символов, штрихов, а также шрифта. и уже от него идут потомки, где учитывается вид циферблата, т.е круглый или квадратный.

void CScaleDlg::OnButton()
{
      CPaintDC dc(this);
      CTotalDC * pdc;
      pdc = new CCircleDC; //тот самый потомок с круглой формой
      pdc->Attach(dc);
      pdc->SetFonColor(m_FonColor); //установка цвета фона
      pdc->SetStrokeColor(m_StrokeColor); //установка цвета штриха
      pdc->SetFontColor(m_FontColor); //установка цвета шрифта
                pdc->SetFont(m_lf); //установка шрифта
      pdc->Draw(&m_PicScale); // рисование
      pdc->Detach();
      delete  pdc;
}
Что я пишу не так в OnButton()?
Вот собственно и мой вопрос Здесь была моя ладья...
Записан
Olezyk
Гость
« Ответ #6 : 04-10-2007 15:49 » 

кстати, если я пишу тот же код для вывода на принтер, используя диалог принтера, подключаю Attach(cp.GetPrinterDC()), то печатается без проблем! Улыбаюсь
есть, правда, и здесь проблемка, она из такой оперы... чтоб мой рисунок был на весь лист принтера я использую такую область.
      CRect rc;
      int nHorz = PrintDC->GetDeviceCaps(HORZRES);
      int nVert = PrintDC->GetDeviceCaps(VERTRES);
потом просто в нее вывожу рисунок
   PrintDC->Draw(&rc);
и он получается на весь лист, кроме шрифта, который очень мелкий. как выводить текст на принтер в соответствующем размере, для меня тоже пока загадка.
Очень надеюсь на помощь!...
Записан
Джон
просто
Администратор

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

« Ответ #7 : 04-10-2007 16:04 » 

Хммм. Скажем так. Ты всё пишешь не так. У тебя напрочь отсутствует теория, а без неё никуда. Какими учебничками пользуешься?

Грубо:

1.
Передача членов объекта напрямую в чужой объект - не есть гут. (ООП теория)

2.
Ф-я OnPaint для того и предназначена, чтобы отрисовывавать необходимое по ВНИМАНИЕ! сообщению винды.
Ты можешь "спровоцировать" вызов этого сообщения ф-ей Invalidate. Её можно вызывать по нажатию кнопки.

void CScaleDlg::OnButton()
{
       // изменить необходимые параметры - m_FonColor, m_PicScale, и тд
       this->Invalidate();
}

Если известен регион часов, то лучше воспользоваться ф-ей InvalidateRect. А весь свой код отрисовки запихивай обратно в OnPaint.


зы Покажи как рисуешь текст.
« Последнее редактирование: 04-10-2007 16:06 от Джон » Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"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."
Olezyk
Гость
« Ответ #8 : 04-10-2007 18:04 » 

теории у меня действительно нет. так сказать все методом тыка. в качестве учебников здоровые самоучители, например Мешков "Visual c++ и MFC", Олафсен "Visual c++ 6 и MFC". поэтому тяжело вьехать в тему. если б был конкретный рабочий пример с использованием кнопок, ввода параметров и т п, было бы легче.
Понятно о чем ты говоришь. я с помощью стандартных диалогов изменяю цвет и при нажатии, часы перерисовываются моим цветом. Но при запуске моя картинку уже есть в области, а мне надо, чтоб она возникала со всеми настроеными цветами при нажатии.

рисую текст так:
void CTotalDC::DrawText(int iXCenter, int iYCenter, int iRadius,double phi, char *txt, COLORREF txtColor)
{
   int x, y;
   x = iXCenter - (0.9*iRadius)*cos(phi*PI/180);
   y = iYCenter - (0.9*iRadius)*sin(phi*PI/180);

   CFont * pOldFont = SelectObject(&m_Font);
   SelectObject(&m_Font);

   SetBkMode(TRANSPARENT);
   SetTextColor(txtColor);

   CRect rc (0,0,0,0);
   CString strtxt = txt;
   CDC::DrawText(strtxt, &rc, DT_CALCRECT);
   rc.OffsetRect(x - rc.Width()/2, y - rc.Height()/2);
   CDC::DrawText(strtxt, &rc, DT_CENTER | DT_VCENTER);

   SelectObject(pOldFont);
}
затем просто вызываю
   DrawText(iXCenter,iYCenter,iRadius,0,"12", m_FontColor);
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

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


« Ответ #9 : 04-10-2007 18:22 » 

Olezyk, класс CTotalDC тут , в принципе, не нужен.  А объект класса CPaintDC можно создавать только в обработчике OnPaint и нигде ещё!

в обработчике OnPaint -
Код:
void CScaleDlg::OnPaint() 
{
      CPaintDC dc(this);

//рисуешь на контексте dc
//...

}

если всё ещё тебе нужен твой класс CTotalDC , то, возможно, ты не всё ТЗ рассказал нам Улыбаюсь
Записан

Olezyk
Гость
« Ответ #10 : 04-10-2007 18:41 » 

Улыбаюсь естественно это не все ТЗ, там еще ого(!) чего делать.
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

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


« Ответ #11 : 04-10-2007 18:46 » 

Olezyk, ого нам не нужно знать Улыбаюсь , нужно только насчёт рисования и что ты хочешь сделать, а ещё
CTotalDC - от чего он произведён ?
Записан

Olezyk
Гость
« Ответ #12 : 04-10-2007 19:01 » 

CTotalDC потомок CDC.
хочу чтоб картинка появлялась не сразу при запуске, а только по нажатию кнопки. и на принтере мой шрифт тоже как-то масштабировался.
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

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


« Ответ #13 : 04-10-2007 19:10 » 

Olezyk,

хочу чтоб картинка появлялась не сразу при запуске, а только по нажатию кнопки.

это довольно просто сделать - заведи в качестве флага член-переменную bool в классе диалога (я так понял, у тебя в диалоге происходит дело?), В конструкторе диалога сбрасываешь флаг в false  , а в обработчике кнопки взводишь флаг. А в OnPaint пишешь
Код:
void CScaleDlg::OnPaint() 
{
      CPaintDC dc(this);

      if(m_bNeedPaint)
      {
            //рисуешь
            //...
      }
}
« Последнее редактирование: 04-10-2007 19:16 от Алексей1153++ » Записан

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

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


« Ответ #14 : 04-10-2007 19:14 » 

>> и на принтере мой шрифт тоже как-то масштабировался.

это не к принтеру вопрос, если идёт речь о подгонке размера текста к неким границам, вопрос к тому, чтобы определить границы текста и подобрать размер шрифта, когда выводишь на контекст. А с принтером - я не подскажу, не сталкивался...
Записан

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

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

« Ответ #15 : 05-10-2007 11:46 » 

1. Читай теорию по Device Context (DC)

2.  это так по ходу

   CFont * pOldFont = SelectObject(&m_Font);
   SelectObject(&m_Font);


3. Зачем тебе нужны классы наследники от CDC? Схема очень простая - у тебя есть одно окно (CScaleDlg), у которого есть девайс контекст. Есть некий объект (CCircle), который содержит данные и ф-ции работы с этими данными. Те он знает ЧТО и КАК надо рисовать. А ГДЕ рисовать ему сообщает окно родитель - передаёт в его ф-ю рисования ссылку на свой ДС. Вот и всё. Примерно так:




Это просто тебе совет переделать всё пока не поздно. Позже, когда у тебя будет (может быть) ещё куча таких объектов всё это будет очень здорово "моргать" и тебе надо будет сделать двойной буфер. Тогда ты со своими ДС-детьми запаришься.

4. Для принтера тебе надо управлять размером шрифта - m_Font. Ты можешь спросить принтер с каким разрешением он печатает и пересчитать размер шрифта. Можно конечно изменять размеры всего ДС, но тогда при увеличении будет происходить потеря качества. Ну примерно как битмап просто взять да растянуть. А вобще-то если хочешь грамотно сделать, то тогда все твои ф-ции отрисовки должны учитывать разрешение ДС и получать его в качестве параметра. Я в таких случаях отдаю предпочтение gdi+ - в этой библиотеке есть куча функций для всевозможных трансформаций и координатных систем. Установив одну координатную систему ты всегда получишь один и тот же результат и на экране, и на принтере.

* ss1.gif (2.63 Кб - загружено 4793 раз.)
« Последнее редактирование: 05-10-2007 11:56 от Джон » Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"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."
Olezyk
Гость
« Ответ #16 : 06-10-2007 14:53 » 

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

Изучаю сейчас gdi...
я так понимаю, чтобы у меня все было в единой системе, например в мм, использовать надо
SetMapMode(MM_LOMETRIC)
Записан
Джон
просто
Администратор

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

« Ответ #17 : 06-10-2007 16:12 » 

1. Эти классы могуть просто generic. Я понимаю что тебе Attach нравится. Ага Ну как хочешь. Моё дело предложить, твоё - отказаться.

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."
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines