Иллюстрированный самоучитель по Visual Studio .NET

Режимы отображения координат

Теперь покажем, как с помощью Studio .NET следует определять в классе собственные версии виртуальных функций. Мы собираемся однократно (при открытии окна) преобразовать "мировые" координаты в логические и запомнить их. Это удобно сделать внутри виртуальной функции OnlnitialUpdate, которая унаследована от класса cview. Она вызывается каркасом приложения в тот момент, когда окно еще не появилось на экране, но уже существует его Windows-описатель (HWND) и объект класса CMyView прикреплен (attached) к окну. Напомним также, что документ имеет и поддерживает динамический список всех своих представлений.

  1. В окне Class View поставьте курсор на имя класса CMyView и щелкните правой клавишей мыши.
  2. Перейдите в окно Properties, щелкнув вкладку, с помощью подсказок отыщите на панели инструментов именно этого окна кнопку Overrides и нажмите ее.
  3. Появится длинный список виртуальных функций родительских классов, которые можно переопределить в классе ему view. Найдите в нем функцию OnlnitialUpdate и выберите в правой половине таблицы действие <Add>.

Результат ищите в конце файла MyView.cpp. Внесите изменения в тело функции:

void CMyView::OnlnitialUpdate()
{
CView::OnlnitialUpdate();
// Создаем ссылку на контейнер World-координат точек
VECPTSS pts = GetDocument() › m_Points;
UINT size = pts.size ();
//====== Задаем размер контейнера логических точек
m_Points .resize (size);
for (UINT i=0; i < size;
m_Points[i] = (pts[i] * m_nLogZoom).Tolnt ();
}

Здесь мы добываем из документа World-координаты объекта, умножаем их на коэффициент m_nLogZoom и преобразуем к целому типу. Обратите внимание на использование операций и методов вновь созданного класса CDPoint и на то, что переменная pts создана и инициализирована как ссылка на контейнер точек документа. Теперь осталось изменить коды для перерисовки представления так, чтобы воспользоваться техникой масштабирования, которую мы обсудили в начале главы:

void CMyView::OnDraw(CDC* pDC)
{
CMyDoc* pDoc = GetDocument ();
ASSERT_VALID(pDoc);
//====== Узнаем размер контейнера точек
UINT nPoints = m_Points.size ();
if (! nPoints) // Уходим, если он пуст return;
// Сохраняем текущее состояние контекста pDC › SaveDC();
// Создаем перо Windows для прорисовки контура
CPen pen (PS_SOLID,2,RGB(0, 96.0));
//====== Выбираем его в контекст устройства
pDC › SelectObject (spen);
// Создаем кисть Windows для заливки внутренности
CBrush brush (RGB (240, 255, 250));
pDC › SelectObject (Sbrush);
//====== Задаем режим преобразования координат
pDC › SetMapMode(MM_ISOTROPIC);
//====== Сдвиг в логической системе
pDC › SetWindowOrg(0.0);
//====== Сдвиг в физической системе
pDC › SetViewportOrg (m_szView.cx/2, m_szView. су/2);
//====== Знаменатель коэффициента растяжения
pDC › SetWindowExt (3*m_nLogZoom, 3*m_nLogZoora);
//====== Числитель коэффициента растяжения
pDC › SetViewportExt (m_szView.cx, – m_szView.cy);
//====== Изображаем полигон
pDC › Polygon (Sra_Points [0], nPoints);
// Восстанавливаем контекст (предыдущие инструменты GDI)
pDC › RestoreDC (-1);
}

Коэффициент 3 в параметрах SetWindowExt моделирует ситуацию, когда лист ватмана в 3 раза превышает размер детали, на нем изображенной. Знак минус в параметре SetViewportExt позволяет компенсировать изменение направления оси Y при переходе из Page space в Device space. При рисовании мы используем логические (Page) координаты, которые хранятся в классе CMyView.

Если Вы заметили ошибку, выделите, пожалуйста, необходимый текст и нажмите CTRL + Enter, чтобы сообщить об этом редактору.