Модераторы: feodorv, GremlinProg, xvr, Fixin

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Двойная Буферизация 
V
    Опции темы
Kostik88
Дата 23.7.2008, 13:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 76
Регистрация: 9.5.2008

Репутация: нет
Всего: 2



Здравствуйте!

У меня такая проблема.  Я рисую график в диалоговом окне используя двойную буферизацию... вроде всё работает, по крайней мере выводится на экран.
На главном окне имеется слайдер при  движении которого график диалога должен менятся. Если использовать при этом InvalidateRect то всё неприятно мигает =( .  Может есть какойнибудь способ чтобы избежать этого мерцания?  


Вот код:

Код

 case WM_PAINT:

 


          hDC = BeginPaint(hDlg,&ps);

          GetClientRect(hDlg,&rect);

         
 hdcMem = CreateCompatibleDC(hDC);
 hbmMem = CreateCompatibleBitmap(hDC,rect.right,rect.bottom);
 hold = SelectObject(hdcMem,hbmMem);

 BitBlt(hdcMem ,0,0,rect.right,rect.bottom,hDC,0,0,SRCCOPY);// копирование фона в hdcMem

Рисую уже в hdcMem

..................................



...................................


после рисования в hdcMem Вывожу содержимое на экран
 
BitBlt(hDC,0,0,rect.right,rect.bottom,hdcMem,0,0,SRCCOPY);
 
     SelectObject(hdcMem,hold);
     DeleteObject(hbmMem);
     DeleteObject(hdcMem);




А вот что я пишу в оьработчике слайдера, чтобы изображение графика менялось в диалоге

Код


case WM_HSCROLL:
.........

if(hDialog!=NULL)    InvalidateRect(hDialog,NULL,TRUE);// вот из-за этого и мигает

break;



Спасибо!
PM MAIL   Вверх
mekhanikus
Дата 23.7.2008, 14:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Вольноопределяющийся
*


Профиль
Группа: Участник
Сообщений: 186
Регистрация: 16.6.2008
Где: Спасск-Дальний

Репутация: 1
Всего: 1



Если я правильно понял, график должен прокручиваться по горизонали?
Т.е. высота графика равна высоте окна, а ширина больше.
Я бы сделал так:
При создании окна (WM_CREATE) создавал CompatibleBitmap высотой в окно, шириной сколько надо.
Рисуем график в hdcMem.
В WM_PAINT достаточно сделать BitBlt из hdcMem в окно с нужным смещением.
В WM_HSCROLL меняем смещение и опять BitBlt.
И необязательно перерисовывать весь диалог.
PM MAIL   Вверх
Kostik88
Дата 23.7.2008, 14:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 76
Регистрация: 9.5.2008

Репутация: нет
Всего: 2



Цитата

Если я правильно понял, график должен прокручиваться по горизонали?



не совсем, слайдер распологается не на дмалоге, а на главном окне от куда и вызывается диалог графика.

Слайдер нужен для того чтобы менять значения в таблице данных по которой и строится данный график.
PM MAIL   Вверх
mekhanikus
Дата 23.7.2008, 15:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Вольноопределяющийся
*


Профиль
Группа: Участник
Сообщений: 186
Регистрация: 16.6.2008
Где: Спасск-Дальний

Репутация: 1
Всего: 1



Цитата

слайдер распологается не на дмалоге, а на главном окне от куда и вызывается диалог графика.


Нифига не понял, но все равно, не надо в WM_PAINT засовывать всю процедуру перерисовки.
Сперва нарисуй, а затем GetDC-BitBlt-ReleaseDC, и все в окошке!
Vожно даже без InvalidateRect,
PM MAIL   Вверх
Kostik88
Дата 23.7.2008, 15:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 76
Регистрация: 9.5.2008

Репутация: нет
Всего: 2



процедура перерисовки у меня располагается не в WM_PAINT, а в WM_HSCROLL.
Я сначала рисую в буфер потом вывожу на экран с помощью BitBlt, вопрос не в том как я рисую, а как мне избавиться от InvakidateRect и зменить её чемнибудь, что позволяло бы избавиться от мерцания графика при движении слайдера!

Это сообщение отредактировал(а) Kostik88 - 23.7.2008, 15:36
PM MAIL   Вверх
GremlinProg
Дата 23.7.2008, 20:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2706
Регистрация: 9.8.2005
Где: Тюмень

Репутация: 99
Всего: 106



перехвати сообщение WM_ERASEBKGND так:
Код

case WM_ERASEBKGND:
  return TRUE;

если ты рисуешь задний план, то рисуй его так же на втором буфере,
только что объяснял с чем связано моргание и как с ним бороться: http://forum.vingrad.ru/index.php?showtopi...t&p=1584779


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
Kostik88
Дата 23.7.2008, 20:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 76
Регистрация: 9.5.2008

Репутация: нет
Всего: 2



GremlinProg,  перехватл сообщение WM_ERASEBKGND , ваще хрень получилась =)

Я извиняюсь, я может не совсем конкретно сформулировал вопрос) Просто мне нужно както обновлять изображение, а то у меня в окне график не меняется.... а должен, я проверял с помощью InvalidateRect, всё работает идеально, только мигает... Двойная буферизация работает, т.к. всё выводится на экран, только при смене значений(с помощью слайдера) он почемуто не хочет менятся =(. Мне просто нужна както поменять картинку чтобы при выборе других данных график менялся.
PM MAIL   Вверх
mes
Дата 23.7.2008, 21:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 1
Всего: 250



Цитата(Kostik88 @  23.7.2008,  20:51 Найти цитируемый пост)
только при смене значений(с помощью слайдера) он почемуто не хочет менятся =(. 

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

Цитата(Kostik88 @  23.7.2008,  13:48 Найти цитируемый пост)
if(hDialog!=NULL)    InvalidateRect(hDialog,NULL,TRUE);// вот из-за этого и мигает

Вызов перерисовки надо вызывать именно так.. Мигает не из за этого.. 

Цитата(Kostik88 @  23.7.2008,  20:51 Найти цитируемый пост)
GremlinProg,  перехватл сообщение WM_ERASEBKGND , ваще хрень получилась =)

Ну вот опять приходится дофантазировать чего это Вы там натворили.
 Совет перехватить очистку фона правильный и без его перехвата Вы не добьетесь нужного Вам эффекта.

Как итог :
для того чтоб избавиться от мигания нужно 
1.поставить пустой обработчик на WM_ERASEBKGND 
2. Использовать двойную буфферизацию и выводить только в WM_PAINT
3. для обновления окна вызывать InvalidateRect(..)

Если после этого  мигание останется пересмотрите свой код - однозначно что то упустили ))




--------------------
PM MAIL WWW   Вверх
Kostik88
Дата 23.7.2008, 21:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 76
Регистрация: 9.5.2008

Репутация: нет
Всего: 2



Ещё раз извеняюсь за неточный вопрос! 

 B]mes[/B],  я пытаюсь избавиться от мерцания с помощью двойной буферизации изображения а не тем что вы мне написали. Мне нужен аналог, может даже алгоритм такой чтобы найти альтернативу ф-ции InvalidateRect, и кажется в самом начале я об этом упомянул.
Цитата

 для обновления окна вызывать InvalidateRect(..)



от этого и происходит мигание!

Добавлено через 4 минуты и 9 секунд
Просто я пытался заменить InvalidateRect таким образом что я закрашивал клиентскую облась(естественно в hdcMem) какойнибудь кистью. А из обработки сообщения слайдера я посылал сообщения диалоговому окну (  if(hDialog!=NULL) SendMessage(hDialog,WM_PAINT,0,0);  ).
PM MAIL   Вверх
mes
Дата 23.7.2008, 21:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 1
Всего: 250



Цитата(Kostik88 @  23.7.2008,  21:20 Найти цитируемый пост)
от этого и происходит мигание!

Нет не от этого .. Данная функция всего лишь устанавливает область для перерисовки  и никакого вывода на ькран не делает ))
А от того что перед тем как вызвать WM_PAINT в котором Вы реализовали двойную буфферизацию, вызывается WM_ERASEBKGND
которая заливает область сводя на нет все Ваши усилия... Как бороться с этим написано в предыдущем посте..




--------------------
PM MAIL WWW   Вверх
Kostik88
Дата 23.7.2008, 21:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 76
Регистрация: 9.5.2008

Репутация: нет
Всего: 2



Спасибо всем за помощь, особенно GremlinProg. Вроде теперь график не мигает) я просто забыл убрать копирование в буфер фона.
GremlinProg, к вам ещё один вопросец. У меня в диалоге имеются кнопки, вот они жутко мигают, как бы это можно убрать?

Добавлено через 3 минуты и 44 секунды
mes, 
Цитата

вызывается WM_ERASEBKGND
которая заливает область сводя на нет все Ваши усилия... 

Мои усилия на двойную буферизацию или на закраску областью кистью? =)
PM MAIL   Вверх
mes
Дата 23.7.2008, 21:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 1
Всего: 250



Цитата(Kostik88 @  23.7.2008,  21:43 Найти цитируемый пост)
Мои усилия на двойную буферизацию или на закраску областью кистью? =) 

Ваши усилия по устранению мигания 

Цитата(Kostik88 @  23.7.2008,  21:43 Найти цитируемый пост)
 просто забыл убрать копирование в буфер фона

ну вот как видите Invalidate совсем не при чем  smile 



--------------------
PM MAIL WWW   Вверх
Kostik88
Дата 23.7.2008, 21:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 76
Регистрация: 9.5.2008

Репутация: нет
Всего: 2



Цитата

Ваши усилия по устранению мигания 



Ну не скажите... Я попробовал убрать её напрочь, двойную буферизацию всмысле, и результат не порадовал=)
PM MAIL   Вверх
mes
Дата 23.7.2008, 22:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 1
Всего: 250



Цитата(Kostik88 @  23.7.2008,  21:57 Найти цитируемый пост)
Ну не скажите... Я попробовал убрать её напрочь, двойную буферизацию всмысле, и результат не порадовал=) 

У нас разговор двух глихих получился  smile 
я говорил что как хорошо бы двойная буферизация не была бы сделана, стирание фона (WM_ERASEBKGROUND или другое небуфферизованное)   добавляет "много" мигания  smile  И никак не советовал ее убирать (двойную буфферизацию в смысле ;) )   smile 
что у нас уже оффтопик получается.. главное что все получилось! Удачи и в дальнейшем  smile 


Это сообщение отредактировал(а) mes - 23.7.2008, 22:21


--------------------
PM MAIL WWW   Вверх
Kostik88
Дата 23.7.2008, 22:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 76
Регистрация: 9.5.2008

Репутация: нет
Всего: 2



Спасибо! Теперь буду ломать голову как мигание кнопок убрать  smile 
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Системное программирование и WinAPI"
Fixin
GremlinProg
xvr
feodorv
  • Большое количество информации и примеров с использованием функций WinAPI можно найти в MSDN
  • Описание сообщений, уведомлений и примеров с использованием компонент WinAPI (BUTTON, EDIT, STATIC, и т.п.), можно найти в MSDN Control Library
  • Непосредственно, перед созданием новой темы, проверьте заголовок и удостоверьтесь, что он отражает суть обсуждения.
  • После заполнения поля "Название темы", обратите внимание на наличие и содержание панели "А здесь смотрели?", возможно Ваш вопрос уже был решен.
  • Приводите часть кода, в которой предположительно находится проблема или ошибка.
  • Если указываете код, пользуйтесь тегами [code][/code], или их кнопочными аналогами.
  • Если вопрос решен, воспользуйтесь соответствующей ссылкой, расположенной напротив названия темы.
  • Один топик - один вопрос!
  • Перед тем как создать тему - прочтите это .

На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы .


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема »


 




[ Время генерации скрипта: 0.0931 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.