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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Как правильно отрисовать Rectangle? убрать шлейф от прямоугольника 
:(
    Опции темы
wallstreet
Дата 25.11.2014, 16:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Добрый день.
Создаю мышкой прямоугольник с помощью функции Rectangle();
При его растягивании (увеличении) всё отрисовывается правильно, но если попытаться уменьшить его в размерах, т.е. попытаться притянуть правый нижний угол к верхнему левому, то за прямоугольником отрисовывается шлейф неудаленных граней.
Используя битовый образ при рисовании я могу конечно заливать все, что за гранями прямоугольника фоном (FillRect()), но в таком случае пропадают фигуры нарисованные ранее, а они должны оставаться.
Подскажите в каком направлении копать?

user posted image
PM MAIL   Вверх
tzirechnoy
Дата 25.11.2014, 17:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1173
Регистрация: 30.1.2009

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



Сохранять список предыдущих фигур, и каждый раз их все перерисовывать.
PM MAIL   Вверх
wallstreet
Дата 25.11.2014, 17:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Цитата(tzirechnoy @ 25.11.2014,  17:07)
Сохранять список предыдущих фигур, и каждый раз их все перерисовывать.

Принято! Попробую, отпишусь об ощущениях smile
PM MAIL   Вверх
wallstreet
Дата 26.11.2014, 15:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Пробовал сохранять параметры объекта и потом перерисовывать, рисует но сильно криво при WM_MOUSEMOVE, которое провоцирует перерисовывать  достаточно быстро.
Сейчас пробую сохранять хендлы контекстов прошлых образов в контейнер, но не знаю как достать из них координаты для отрисовки на экран или необходимо сохранять их вместе с хендлом?

PM MAIL   Вверх
baldina
Дата 26.11.2014, 15:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

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



а зачем перерисовывать при WM_MOUSEMOVE?
PM MAIL   Вверх
wallstreet
Дата 26.11.2014, 16:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Цитата(baldina @ 26.11.2014,  15:51)
а зачем перерисовывать при WM_MOUSEMOVE?

логика отрисовки предполагает, что левый верхний угол определяется при нажатии левой кнопки мыши, а потом текущие координаты мыши (при нажатой левой кнопке) являются правым нижним углом.
Так вот при растягивании прямоугольника необходимо отображать процесс на экране. 
Может быть я неправильно выразился, но рисую я только в WM_PAINT, а в WM_MOUSEMOVE я закрашиваю фон образа в памяти (FillRect()) рисую новую фигуру в память (Rectangle()) и обозначаю область экрана для перерисовки (InvalidateRect())

PM MAIL   Вверх
tzirechnoy
Дата 26.11.2014, 16:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1173
Регистрация: 30.1.2009

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



А что такое "сильно криво"?

Ну и, если у Вас действительно меняется картинка по WM_MOUSEMOVE -- то и рисовать имеет смысл прямо в обработчике, без InvalidateRect.
PM MAIL   Вверх
baldina
Дата 26.11.2014, 16:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

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



Цитата(wallstreet @  26.11.2014,  16:12 Найти цитируемый пост)
Так вот при растягивании прямоугольника необходимо отображать процесс на экране. 
Может быть я неправильно выразился, но рисую я только в WM_PAINT, а в WM_MOUSEMOVE я закрашиваю фон образа в памяти (FillRect()) рисую новую фигуру в память (Rectangle()) и обозначаю область экрана для перерисовки (InvalidateRect())

при динамической отрисовке обычно не перерисовывают экран при движении мыши, а рисуют новый объект в режиме XOR два раза - со старыми координатами и с новыми. XOR, примененный дважды, восстанавливает исходное изображение.

Добавлено через 1 минуту и 42 секунды
тут посмотрите
PM MAIL   Вверх
tzirechnoy
Дата 26.11.2014, 16:49 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1173
Регистрация: 30.1.2009

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



Цитата
при динамической отрисовке обычно не перерисовывают экран при движении мыши, а рисуют новый объект в режиме XOR два раза - со старыми координатами и с новыми. XOR, примененный дважды, восстанавливает исходное изображение.


Многие графические API этого ужэ попросту не гарантируют.

По факту -- игрушки прекратили так делать где-то в середине 90-х, с каких-то (разных, XOR -- не единственная) технологий восстановления изменений перешли на полную перерисовку. Сейчас ещё, можэт, и можно найти различные графические редакторы и CADы, которые пытаются стирать свои спрайты по одному -- но в основном их как раз можно вычислить по всяким артэфактам на границах элементов, удаляемым полной перерисовкой. В общем, пытаться восстановить изменения -- тяжёлое дело и весьма неблагодарное.
PM MAIL   Вверх
baldina
Дата 26.11.2014, 17:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

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



зависит от задачи. человек учится, пусть начнет с простого.  зачем ему для отображения rubberline в перерисовывать всю сцену? хорошо работающие решения с полной перерисовкой сцены требуют определенных архитектурных усилий и более продвинутых способов, чем базовый gdi.
PM MAIL   Вверх
tzirechnoy
Дата 26.11.2014, 17:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1173
Регистрация: 30.1.2009

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



Цитата
 человек учится, пусть начнет с простого. 


Будь это просто -- как раз это был бы основной метод. Но это как раз сложно (хотя зачастую и быстрее работает).

Это сообщение отредактировал(а) tzirechnoy - 26.11.2014, 17:53
PM MAIL   Вверх
Pavia
Дата 26.11.2014, 19:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



xor не пользуются. По одной простой причине так как такую рамку не всегда хорошо видно. Она хорошо работает только когда фон белый и рамка черная. Или наоборот черный фон белая рамка. А для других цветов данный подход работает плохо.

В продвинутых редакторах сейчас меняют яркость или контрастность картинке вне рамке. 

Использование масок тоже не годится. Так как медленнее или соизмерима с перерисовка всего. 

PM MAIL   Вверх
Dem_max
Дата 28.11.2014, 11:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1780
Регистрация: 12.4.2007

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



Вот тебе пример
http://msdn.microsoft.com/en-us/library/wi...4(v=vs.85).aspx

Можешь в этом коде заменить Rectangle на DrawFocusRect(hdc, &rc);
либо добавить SelectObject(hdc, hpenDot);

Код

            if ((wParam && MK_LBUTTON) 
                    && !fDragRect) 
            {
                // Set the mix mode so that the pen color is the  
                // inverse of the background color. The previous  
                // rectangle can then be erased by drawing  
                // another rectangle on top of it.  
 
                hdc = GetDC(hwnd); 
                SetROP2(hdc, R2_NOTXORPEN); 
      SelectObject(hdc, hpenDot);


Это сообщение отредактировал(а) Dem_max - 28.11.2014, 12:08


--------------------
Американские программисты долго не могли понять, почему русские при зависании Windоws всё время повторяют "Твой зайка написал" ("Yоur bunnу wrоte")
PM MAIL   Вверх
GremlinProg
Дата 29.11.2014, 13:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(wallstreet @  26.11.2014,  17:33 Найти цитируемый пост)
рисует но сильно криво при WM_MOUSEMOVE, которое провоцирует перерисовывать  достаточно быстро.

полагаю, тут следует уже прикладывать Ваш код, т.к. на перерисовку прямоугольников особых нагрузок быть не должно, даже с частотой WM_MOUSEMOVE (которая, кстати, не такая уж и большая, если разобраться) если только в алгоритме нет "течи" или сама перерисовка проводится с какими-то нарушениями оконной идеологии WinAPI.


--------------------
"Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины."
PM WWW ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "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.0561 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


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

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