Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Visual C++/MFC/WTL > График через таймер


Автор: Coocky 30.1.2005, 10:37
Вот столкнулся с проблемой..Нужно ,что б рисовалась синусоида постоянно ,нк в таймере,и изменялась в зависимости от данных.Типа осцилографа smile
Только как мне засунуть обработчик WM_TIMER в обработчик WM_PAINT,для корректной работы smile

Автор: alien_by 31.1.2005, 12:17
Ты просто в WM_PAINT отрисовывай то состояние графика, которое было в момент прихода WM_PAINT. Т.к. если таймер у тебя будет тикать достаточно часто, то WM_PAINT тебе нужно обрабатывать, только для того, чтобы небыло никаких артефактов при перетаскивании.

Т.е. простой примерчик, пусть график зависит только от времени...

Код

....
// Переменная времени
double m_dfTime;
....

void MyWnd::OnPaint()
{
    .....
    drawSinusoid(m_dfTime, ...);
}

void MyWnd::OnTimer()
{
    .....
    drawSinusoid(++m_dfTime, ...);
}

Автор: Adil' 31.1.2005, 13:28
alien_by все верно, только за одним исключением smile вся отрисовка должна быть в OnPaint, а в OnTimer лучше лиший раз не рисовать, а просто посылать окну WM_PAINT c прямоугольником отрисовки, соответствующим прямоугольнику графика. Можно для этого вызывать InvalidateRect.

Автор: Coocky 31.1.2005, 13:39
alien_by
Я немного не пойму.А где обновление графика?


Добавлено @ 13:40
Adil
Я б давно реализовал эту идею ,если б не мерцание экрана smile

Автор: Coocky 31.1.2005, 14:19
Але!Спецы!

Автор: Adil' 31.1.2005, 15:42
Цитата(Coocky @ 31.1.2005, 13:39)
Я немного не пойму.А где обновление графика?
Насколько я понял - в drawSinusoid(m_dfTime, ...);


Цитата(Coocky @ 31.1.2005, 13:39)
Я б давно реализовал эту идею ,если б не мерцание экрана
А причем здесь эта идея и мерцание экрана? Экран мерцать будет и в способе alien_by - тут главное как реализована сама отрисовка.

Автор: alien_by 31.1.2005, 17:08
Цитата
ien_by все верно, только за одним исключением smile вся отрисовка должна быть в OnPaint

Согласен. smile

Цитата
Я б давно реализовал эту идею ,если б не мерцание экрана


Мерцание, можно убрать следующими способами.
1. Если работа по отрисовке слишком громоздкая, то можно уменьшить частоту тиков таймера.
2. Вызывать функцию InvalidateRect или InvalidateRgn не с параметром NULL (который указывает, что нужно перерисовать всё), а с конкретным ректом или регионом (лучше всё таки ректом smile ) который нужно перерисовать.
3. Сделать функцию отрисовки более "интеллектуальной", в см. не тупо перерисовывающей график при каждом вызове, а анализирующей было ли изменение данных, повлекшее измененние представления.
4. И самый эффективный способ на мой взгляд - не выводить информацию прямо в контекст устройства, а создавать новый compatible контекст в памяти, рисовать всё что надо в него, а затем с помощью функции bitBlt переносить весь рисунок в свой основной контекст как битмап!!!

Автор: Nastya 31.1.2005, 22:49
Все ресуешь в Paint, а в таймере вызывашь InvalidateRect - он вызывает перерисовку, а следовательно и WM_PAINT для того прямоугольника. который ты передал.
Но тут может появится мерцание, если появится напиши, объясню как боротся. а лучше кусочек кода дай.
Параметры для перересовке, соответственно объялеешь как методы класса а не как локальные в фунциях. ну это думаю ясно smile

Автор: Coocky 1.2.2005, 09:13
Цитата
И самый эффективный способ на мой взгляд - не выводить информацию прямо в контекст устройства, а создавать новый compatible контекст в памяти, рисовать всё что надо в него, а затем с помощью функции bitBlt переносить весь рисунок в свой основной контекст как битмап!!!

И что не будет мерцания?

Автор: S.A.P. 1.2.2005, 09:42
Coocky мерцание будет по любому. Особенно если частота обновления высока. Мерцание возникает в том случае, если картинка не успевает до конца прорисоваться, до следующей прорисовки или прорисока настолько редка, что заметна человеческим глазом. Я как то делал подобное на QT. Могу сказать, что графика там достаточно оптимизированна. Можно еще попробовать DirectX...

Как оптимизировать GDI... Тут хорошо бы показать код, которым ты выводишь картинку. Могу предположить, что перед перерисовкой картинка стирается и заново рисуется, причем вся, а надо только стирать саму синусоиду.

Как стереть только синусоиду? Тут я пока остановлюсь...... smile

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)