Студопедия

КАТЕГОРИИ:


Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748)

Рисование




Обработка сообщений о нажатии кнопки мыши

 

Шаг 10. Создание обработчика нажатия кнопки мыши.

Если пользователь нажимает ЛКМ в клиентской области окна приложения, значит, он собирается рисовать, не так ли? Логично считать, что это первое нажатие задает начальную точку фигуры и ее координаты (в пикселах) мы запишем в переменную Anchor, которую мы заблаговременно описали в классе вид. При помощи мастера создайте обработчик сообщения WM_LBUTTONDOWN (не забудьте выбрать класс CPainterView на вкладке ClassView). Код обработчика отредактируйте следующим образом:

 
 

Как Вы догадались, в параметре point в обработчик передаются координаты местоположения мыши в момент нажатия ЛКМ. Эти координаты привязаны к окну вида: координата (0,0) соответствует левому верхнему углу окна вида. Никогда не удаляйте обработчик нажатия кнопки по умолчанию CView::OnLButtonDown(nFlags, point); – он все-таки не лишний и выполняет свою работу.

 

 

Шаг 11. Рисование линий.

Если пользователь нажимает ЛКМ и тем самым задает положение начальной точки фигуры, а затем перемещает мышь и отпускает кнопку, задавая положение конечной точки, то программа должна нарисовать нужную фигуру и растянуть ее от начальной до конечной точки.

Начнем с рисования линий – в этом случае, как Вы помните, должен быть установлен флаг bLineFlag. Линия должна рисоваться при отпускании кнопки мыши, поэтому добавьте в программу обработчик сообщения WM_LBUTTONUP с помощью мастера так же, как Вы это уже проделывали для сообщения WM_LBUTTONDOWN на предыдущем шаге. Так как при отпускании ЛКМ пользователь задает положение конечной точки линии, мы должны начать с запоминания координат этой точки в переменной (поле класса) DrawTo:

 
 

Казалось бы, что теперь мы должны собственно выполнить рисование линии, т.е. передать куда-нибудь координаты линии, выполнить собственно рисование и вызвать функцию Invalidate() для того, чтобы обновить содержимое окна вида с помощью метода OnDraw(). Если при этом учесть, что до рисования данной линии пользователь уже мог нарисовать множество других фигур, то надо все это рисование повторить в методе OnDraw() или в других методах. Но для этого, очевидно, надо завести себе структуры данных, в которых будет запоминаться информация обо всех нарисованных пользователем фигурах.

Одним из методов решения этой проблемы может быть применение метафайлов Windows. Кроме того, воспользуемся классом CClientDC для получения контекста устройства в любом методе, а не только в методе OnDraw(), куда он передается в качестве параметра. Этот класс является производным от CDC и позволяет просто получить контекст устройства, передав конструктору класса указатель на текущий объект класса вида:

CClientDC * pDC = new CClientDC(this);

 

Вспомним, что this в методе класса является указателем на объект класса, вызвавший данный метод. Если мы употребляем this в методе класса вид, то мы как раз и получаем указатель на объект класса вид. Теперь указатель pDC мы можем использовать в любом методе класса вид так же, как мы используем этот указатель в методе OnDraw().

Учитывая сказанное, нарисовать линию в методе CPainterView::OnLButtonUp() можно так:

 
 

Обратите внимание, что перед рисованием линии мы проверяем соответствующий флаг, в данном случае bLineFlag.

Если теперь Вы запустите приложение на выполнение, то сможете рисовать линии. Проверьте! Проверьте так же и то, что все Ваши труды по рисованию полностью теряются, если окно перерисовывается, например, перекрывается другим окном.

Шаг 12. Рисование прямоугольников.

Очевидно, что для рисования прямоугольника достаточно несколько изменить код метода OnLButtonUp():

 
 

Запустите теперь приложение на выполнение, нарисуйте линию, затем нарисуйте прямоугольник, частично перекрывающий линию. Вы заметите, что линия под прямоугольником исчезла, была стерта. Для того чтобы избежать этого эффекта, надо для прямоугольника выбрать в качестве текущей пустую кисть:

pDC->SelectStockObject(NULL_BRUSH);

 

Модифицируйте метод OnLButtonUp(), постройте приложение и протестируйте его: теперь прямоугольники не должны затирать другие изображения.

Шаг 13. Рисование эллипсов.

Доработайте метод OnLButtonUp() самостоятельно для рисования эллипсов и тестируйте его.

 

Шаг 14. Заливка фигур.

Для заливки внутреннего контура замкнутой фигуры сплошным цветом можно воспользоваться методом FloodFill(). Для заливки замкнутой области надо указать какую-либо точку внутри этой области и задать цвет границы. Метод FloodFill() заливает фигуру текущей выбранной кистью в качестве которой мы воспользуемся кистью BLACK_BRUSH.

Теперь мы уже можем доработать метод OnLButtonUp(), добавив в него, например, после рисования эллипса, следующий очевидный код:

 

Третий параметр FloodFill() – это цвет границы замкнутой области. Тестируйте приложение.

 

Шаг 15. Рисование фигур произвольной формы.

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

Рисование фигуры произвольной формы выглядит так: при нажатии ЛКМ запоминается положение начальной точки. Когда мышь перемещается в новую точку, мы рисуем линию от начальной точки до текущей и запоминаем текущую точку в качестве начальной для следующего перемещения мыши.

С помощью мастера добавьте обработчик перемещения мыши OnMouseMove() и подготовьте в нем контекст устройства:

 

Затем необходимо убедиться в том, что в текущем режиме мы должны действительно рисовать фигуру произвольной формы, т.е. проверить флаг bDrawFlag. Кроме того, рисование должно происходить только при нажатой ЛКМ. Проверить этот факт можно путем проверки значения параметра nFlags. Если в nFlags присутствует значение константы MK_LBUTTON, то ЛКМ нажата.

 

Замечание. Параметр nFlags может содержать и другие значения или их комбинации: MK_RBUTTON для ПКМ, MK_MBUTTON для средней клавиши мыши, MK_CONTROL для клавиши Ctrl и MK_SHIFT для клавиши Shift.

 

С учетом сказанного метод OnMouseMove() должен содержать такой код:

 

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

pDC->LineTo(DrawTo.x, DrawTo.y);

на

pDC->LineTo(point.x, point.y);

 




Поделиться с друзьями:


Дата добавления: 2014-12-26; Просмотров: 435; Нарушение авторских прав?; Мы поможем в написании вашей работы!


Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет



studopedia.su - Студопедия (2013 - 2024) год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! Последнее добавление




Генерация страницы за: 0.007 сек.