Добавил:
ivanov666
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Визуальное программирование на основе библиотеки MFC. Методические указания к лабораторным работам по курсу «Визуальное программирование» для студенто
.pdf
Устранение недостатка рисования
Проблема, которая существует в нашей программе, состоит в том, что
курсор должен быть перерисован каждый раз, когда указатель мыши
перемещается по экрану, следуя за мышью. Следует предпринять специальные
меры, чтобы предотвратить возвращение курсора к прежнему виду. Каждый раз
в момент рисования курсора, будь это вызвано движением мыши, или
изменением положения окон, или какими-то другими причинами, приложение
работает с сообщением WM_SETCURSOR.
Если позаботиться о том, чтобы это сообщение обрабатывалось в
соответствии с новыми требованиями, то можно добиться того, чтобы вновь
заданный курсор сохранялся при перерисовывании курсора.
Чтобы сделать это, выполним следующие шаги:
1. Добавим новую переменную к СmouseDlg. Определим ее тип как
логический BOOL и назовем переменную m_bCursor. Модификатор доступа
private.
Рис. 14. Добавление новой переменной.
21

Рис. 15. Задание свойств переменной
2. Задаем значение переменной m_bCursor при помощи следующего кода
в функции BOOL CmouseDlg::OnInitDialog() .
Код m_bCursor=FALSE;
Рис. 16. Присвоение переменной начального значения
22

3. Изменяем функцию OnKeyDown, устанавливаем значение флага
m_bCursor в состояние TRUE в том случае, если вид курсора был изменен.
Вводим код в соответствии с листингом
void CmouseDlg::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
//Здесь редактируем код нашей функции
char lsChar; // Нажатая клавиша
HCURSOR lhCursor; //какой курсор следует показать
lsChar = char(nChar); //преобразуем нажатую клавишу в букву
if (lsChar == 'A') // Нажата клавиша с буквой A
{
// Загружаем курсор в виде стрелки
lhCursor = AfxGetApp () ->LoadStandardCursor (IDC_ARROW) ;
//Устанавливаем экранный курсор
SetCursor(lhCursor);
}
if (lsChar == 'B') // Нажата клавиша с буквой B
{
// Загружаем курсор в виде I-beam
lhCursor = AfxGetApp()->LoadStandardCursor(IDC_IBEAM);
//Устанавливаем экранный курсор
SetCursor(lhCursor);
}
if (lsChar == 'C')// Нажата клавиша с буквой C
{
// Загружаем курсор в виде ручных часов
lhCursor = AfxGetApp()->LoadStandardCursor(IDC_WAIT);
//Устанавливаем экранный курсор
SetCursor(lhCursor);
}
if (lsChar == 'X')// Нажата клавиша с буквой X
{
// Загружаем курсор в виде стрелки
lhCursor = AfxGetApp()->LoadStandardCursor(IDC_ARROW);
///****Устанавливаем флаг курсора
m_bCursor=TRUE;
///****
//Устанавливаем экранный курсор
SetCursor(lhCursor) ;
OnOK();//Выходим из приложения
}
///****добавляем корректировку
23

else
{
//устанавливаем флаг курсора
m_bCursor=TRUE;
}
///****
// Здесь завершаем редактирование нашей функции
CDialog::OnKeyDown(nChar, nRepCnt, nFlags);
}
4. В класс CmouseDlg добавляем функцию для события
WM_SETCURSOR.
5. Изменяем код функции OnSetCursor в соответствии с листингом
BOOL CmouseDlg::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT
message)
{
//Здесь пишем наш код
if(m_bCursor)
return TRUE;
else
//здесь кончается наш код
return CDialog::OnSetCursor(pWnd, nHitTest, message);
}
Функция OnSetCursor нужна для того, чтобы было возвращено значение
TRUE, иначе произойдет обращение к функции, которая возвращает внешний
вид курсора к прежнему, который был у него в момент обращения к
приложению. До того момента, пока не произойдет переназначение курсора,
значение нашей логической переменной будет FALSE, и курсор будет иметь
первоначальный вид, но после того, как будет нажата клавиша,
переустанавливающая курсор, переменная примет значение TRUE, и
обращение к старому курсору будет отменено. На экране будет отображаться
курсор, который был установлен пользователем.
24

Рис. 17. Изменение рисующего курсора
Пример 2
Как можно изменить тип рисуемой линии так, чтобы можно было
рисовать более толстую линию и другим цветом?
В процессе рисования на экране с использованием стандартных команд
контекстных устройств мы используем средство, называемое ручкой (реn), и
рисуем во многом так, как это делается на обычном листе бумаги. Для того,
чтобы линия стала толще и цвет ее изменился, необходимо сменить ручку. Для
осуществления этого можно ввести дополнительный код в функцию
OnMouseMove в том месте, где получается контекст устройства. Следующий
код позволит рисовать толстой ручкой красного цвета:
void CmouseDlg::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
//ПИШЕМ НАШ КОД ЗДЕСЬ
// проверка того,нажата ли левая кнопка
if ((nFlags & MK_LBUTTON) == MK_LBUTTON)
// получаем контекст устройства
{ CClientDC dc(this);
// Добавляем код в функцию
// Создаем новую ручку
CPen lpen(PS_SOLID,16,RGB(255,0,0));
// Используем новую ручку
25

dc.SelectObject(&lpen);
//Рисуем линию между начальным положением и текущим
//положением мыши
dc.MoveTo(m_iPrevX,m_iPrevY) ;
dc.LineTo(point.x,point.y) ;
//Сохраняем текущее положение в переменных первоначального
положения //для следующего шага
m_iPrevX=point.x;
m_iPrevY=point.y;
}
// Здесь заканчивается наш код
/////////////////////////////////////////////////////////////////////////////////
CDialog::OnMouseMove(nFlags, point);
}
Варианты заданий для лабораторной работы № 1:
Вариант 1. Расширьте возможности функции OnKeyDown так, чтобы в
ней были использованы следующие стандартные виды курсора: IDC__CROSS,
IDC__SIZEALL, IDC__SIZENESW.
Вариант 2. Расширьте возможности функции OnKeyDown так, чтобы в
ней были использованы следующие стандартные курсоры: IDC_CROSS,
IDC_UPARROW, IDC_SIZEALL.
Вариант 3. Расширьте возможности функции OnKeyDown так, чтобы в
ней были использованы следующие стандартные курсоры: IDC_SIZENWSE,
IDC_SIZENESW, IDC_SIZEWE,IDC_SIZENS.
Вариант 4. Расширьте возможности функции OnKeyDown так, чтобы в
ней были использованы следующие стандартные курсоры: IDC_NO,
IDC_APPSTARTING, IDC_HELP.
Вариант 5. Реализуйте возможность рисования картинкой эллипса
(рисование выполняется функцией dc.Ellipse(x1,y1,x2,y2). Рисование должно
выполняться с помощью вызова данной функции, вместо вызова функции
рисования точки (см. первый вариант примера).
26

x2,y2
x3,y3
x4,y4
x2,y2
x1,y1
x3,y3
x4,y4
x2,y2
x1,y1
Рис. 18. Образец в виде эллипса
Вариант 6. Реализуйте возможность рисования картинкой сегмента
(рисование выполняется функцией dc.Chord(x1,y1,x2,y2,x3,y3,x4,y4).
Получается замкнутая дуга, конечные точки которой соединены линией с
координатами x3,y3,x4,y4 Рисование должно выполняться с помощью вызова
данной функции (см. вариант 5).
Рис. 19. Образец в виде сегмента
Вариант 7. Реализуйте возможность рисования картинкой сектора
(рисование выполняется функцией dc.Pie(x1,y1,x2,y2,x3,y3,x4,y4). Концы
сектора обозначаются точками x3,y3,x4,y4) Рисование должно выполняться с
помощью вызова данной функции (см. вариант 5).
Рис. 20. Образец в виде сектора
27

Вариант 8. Реализуйте возможность рисования картинкой круга
Рисование состоит из объявления массива
вершин, заполнения этого массива
координатами, и вызова функции
рисования ломаной линии. Рисование
должно выполняться с помощью вызова
данной функции (см. вариант 5).
(рисование выполняется функцией dc.Ellipse(x1,y1,x2,y2) с равными
полуосями) Рисование должно выполняться с помощью вызова данной
функции (см. вариант 5).
Вариант 9. Реализуйте возможность рисования картинкой дуги
(рисование выполняется функцией dc.Arc(x1,y1,x2,y2,x3,y3,x4,y4) – параметры
аналогичны сегменту) Рисование должно выполняться с помощью вызова
данной функции (см. вариант 5).
Вариант 10. Реализуйте возможность рисования картинкой
прямоугольника (рисование выполняется функцией
dc.Rectangle(x1,y1,x2,y2,x3)) Рисование должно выполняться с помощью вызова
данной функции (см. вариант 5).
Вариант 11. Реализуйте возможность рисования картинкой
закругленного прямоугольника (рисование выполняется функцией
dc.RoundRect(x1,y1,x2,y2,x3,r1,r2) где r1, r2 – закругления). Рисование должно
выполняться с помощью вызова данной функции (см. вариант 5).
Вариант 12. Реализуйте возможность рисования картинкой квадрата
(рисование выполняется функцией dc.Rectangle(x1,y1,x2,y2,x3) с одинаковыми
сторонами) Рисование должно выполняться с помощью вызова данной функции
(см. вариант 5).
Вариант 13. Реализуйте возможность рисования картинкой треугольника
с помощью ломаной линии.
POINT poly[4];
poly[0].x=x1; poly[0].y=y1;
poly[1].x=x2; poly[1].y=y2;
poly[2].x=x3; poly[2].y=y3;
poly[3].x=x4; poly[3].y=y4;
dc.Polyline(poly,4);
28

Рис. 22. Образец в виде звезды.
Рис. 23. Образец в виде
четырехугольной звезды.
x1,y1
x2,y2
x3,y3
x4,y4
Рис. 21. Образец в виде треугольника
Вариант 14. Реализуйте возможность рисования картинкой пятиконечной
звезды (рисование выполняется с помощью ломаной линии см. вариант 13).
Рисование должно выполняться с помощью вызова данной функции.
Вариант 15. Реализуйте возможность рисования картинкой
четырехконечной звезды (рисование выполняется с помощью ломаной линии
см. вариант 13). Рисование должно выполняться с помощью вызова данной
функции.
29

Лабораторная работа № 2
Тема: Использование Меню
Интерфейс приложений Windows составляют меню, диалоговые окна и
размещаемые на них элементы управления. Все они являются ресурсами, для
разработки и настройки которых применяются соответствующие редакторы
ресурсов.
Меню представляет собой сгруппированный набор команд, с помощью
которых можно выполнять требуемые действия при выполнении приложения.
Первыми из стилей меню были ниспадающие и каскадные меню. В этих
меню все категории были перечислены в одном ряду, расположенном в верхней
части окна приложения. Если пользователь выбирает какую-либо категорию,
соответствующее ей меню вываливается, открывая вниз окно, содержащее
список функций меню, которые могут быть активированы пользователем.
Усложненным вариантом такого меню является каскадное меню, в котором
появляется дополнительно окно для функций основного списка меню, и в
дополнительном окне можно осуществить выбор перечисленных в нем
действий. Это дополнительное окно появляется сбоку (справа) от выбранной в
вывалившемся окне функции.
Был создан еще один тип меню - контекстное меню. Это меню появляется
где-либо в окне приложения и может появиться в любом его месте. Этот тип
меню носит название контекстного меню, потому что тип всплывающего меню
зависит от того, над какой частью окна приложения, над каким объектом
расположен курсор мыши в момент вызова такого меню.
Цель работы: Создание Windows приложения в среде Visual Studio 2010.
Приобретение навыков разработки меню в приложениях Visual C++2010.
30
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]
