Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
65-96.doc
Скачиваний:
5
Добавлен:
11.11.2019
Размер:
340.99 Кб
Скачать

Задание 3. Ограничение перемещения курсора в окне представления областью рисунка

  1. Переопределите виртуальную функцию OnInitialUpdate() в классе представления программы. Для этого в окне Class View выделите класс CMуPaintVew. Откройте окно свойств (Properties). Щелкните на кнопке Overrides (Переопределения) для получения списка виртуальных функций. Выберите функцию OnInitialUpdate(), а для нее команду <Add> OnInitialUpdate.

class CMуPaintView : public CScrollView { //. . . virtual void OnInitialUpdate (); //. . . };

  1. Добавьте следующий код в определение функции OnInitialUpdate() в файле MуPaintView.cpp. Горизонтальные и вертикальные размеры рисунка записываются в структуру SIZE. В текущей версии программы MуPaint размер рисунка установлен постоянным: 300 пикселов в ширину и 400 – в высоту.

void CMуPaintView::OnInitialUpdate() { CView::OnInitialUpdate (); // TODO: Add your specialized code here and/or call the base //class SIZE Size = {300, 400}; SetScrollSizes (MM_TEXT, Size); }

  1. Добавим в программу средства, предотвращающие рисование линий вне области рисунка для обеспечения корректной работы прокрутки. Сначала добавьте в функцию CMуPaintView::OnDraw() операторы, позволяющие при каждой перерисовке окна представления задавать внизу и справа ограничивающие линии, показывающие пользователю границы рисунка. Добавьте строки, выделенные полужирным шрифтом, в функцию CMуPaintView::OnDraw() в файл MуPaintView.cpp.

void CMуPaintView::OnDraw(CDC* pDC) { CMуPaint Doc* pDoc = GetDocument(); ASSERT_VALID(pDoc); // TODO: add draw code for native data here CSize ScrollSize = GetTotalSize(); pDC->MoveTo(ScrollSize.cx, 0); pDC->LineTo(ScrollSize.cx, ScrollSize.cy); pDC->LineTo(0, ScrollSize.cy); int Index = pDoc->GetNumLines(); while (Index--) pDoc->GetLine(Index)->Draw(pDC); }

Функция CScrollView::GetTotalSize() возвращает объект класса CSize с размерами рисунка, заданными при вызове функции CScrollView::SetScrollSizes(). Затем размеры рисунка в виде значений его ширины и высоты используются для отображения линий, ограничивающих рисунок справа и снизу.

  1. В обработчик CMуPaintView::OnLButtonDown() сообщений, возникающих при нажатии левой кнопки мыши, добавьте операторы, предотвращающие рисование линий вне области рисунка. Для этого перепишите функцию CMуPaintView::OnLButtonDown() в файле MуPaintView.cpp (новые или измененные строки выделены полужирным шрифтом, а строки, которые стали не нужными, закомментированы).

void CMуPaintView::OnLButtonDown (UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default CClientDC ClientDC (this); OnPrepareDC (&ClientDC); ClientDC.DPtoLP (&point); //проверка нахождения курсора внутри области окна //представления CSize ScrollSize = GetTotalSize(); //область рисунка CRect ScrollRect(0, 0, ScrollSize.cx, ScrollSize.cy); if(!ScrollRect.PtInRect (point)) return; //сохранение позиции курсора, захват мыши, //установка флага перемещения m_PointOrigin = point; m_PointOld = point; SetCapture (); m_Dragging = 1; //ограничение перемещения курсора мыши в области рисунка ClientDC.LPtoDP (&ScrollRect); CRect ViewRect; //окно представления GetClientRect (&ViewRect); CRect IntRect; //общая область для окна представления //и области рисунка IntRect.IntersectRect(&ScrollRect, &ViewRect); ClientToScreen (&IntRect); ::ClipCursor (&IntRect); // RECT Rect; // GetClientRect (&Rect); // ClientToScreen (&Rect); // ::ClipCursor (&Rect); CView::OnLButtonDown (nFlags, point); }

Так как классу представления передается сообщение мыши, то ее курсор должен находиться внутри окна представления, при этом он может находиться вне области рисунка. Чтобы удостовериться в том, что курсор находится в области рисунка, определяется объект ScrollRect, являющийся экземпляром MFC-класса CRect, и ему присваиваются размеры рисунка, возвращаемые функцией CScrollView::GetTotalSize(). Затем вызывается функция CRect::PtInRect() для объекта ScrollRect, и ей передаются координаты курсора.

Рис. 4.6. Область перемещения курсора: рисунок меньше окна представления (а); рисунок больше окна представления (б).

В добавленном фрагменте программы вызывается функция CDC::LPtoDP() для преобразования логических координат рисунка, сохраняемых в объекте ScrollRect, в координаты устройства. Затем определяется объект ViewRect класса CRect, которому присваиваются координаты окна представления, возвращаемые функцией CWnd::GetClientRect(). Далее определяется объект IntRect класса CRect и вызывается функция CRect::IntersectRect() для задания ему координат пересечения области рисунка и окна представления. Следующая функция CWnd::ClientToScreen() преобразует значение IntRect, которое представлено логическими координатами прямоугольника, в координаты устройства (экрана) и передает их в функцию ::ClipCursor(). Глобальная функция ::ClipCursor() ограничивает перемещение курсора прямоугольной областью, указатель на которую передается ей в качестве параметра. Области ограничения показаны на рис. 4.6.

На рис. 4.6 проиллюстрирована работа программы MуPaint в случае, когда рисунок меньше окна представления, и показаны линии, обозначающие границы рисунка. Когда рисунок полностью помещается внутри окна представления (рис.4.6, а), MFC скрывает полосы прокрутки. Они появятся вновь, если размер окна уменьшить таким образом, чтобы рисунок не помещался внутри него (рис.4.6, б).

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]