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

Класс для просмотра изображений

Функция SetScrollSizes одновременно с размерами задает и режим преобразования координат. Самым неприятным и непонятным моментом в наследовании от класса CScrollView является то, что функция SetScrollSizes не позволяет задавать режимы MM_ISOTROPIC и MM_ANISOTROPIC, которые позволяют, как вы помните работать с формулами. Этот недостаток MFC широко дискутировался как в MSDN, так и на одном из самых популярных сайтов для программистов – www.CodeGuru.com. Там же вы можете обнаружить некоторые решения этой проблемы. Измените конструктор класса. В момент своего рождения объект класса CRightView должен подготовиться к работе с окнами, управляемыми классом CWndGeom. К тому моменту, когда ему понадобится создать серию таких окон, их тип (класс окон в смысле структуры типа WNDCLASS) уже должен быть известен системе.

Примечание
Прекрасное решение дал Brad Pirtle, и вы можете найти его в одном из разделов CodeGuru, включив поиск по имени. Он создал свой класс CZoomView (производный от CScrolLView), в котором заменил функцию SetScrollSizes на другую – SetZoomSizes, а также переопределил (overrode) виртуальную функцию OnPrepareDC, родительская версия которой обнаруживает и запрещает попытку использовать формульные режимы. В своей версии OnPrepareDC он обходит вызов родительской версии, то есть версии CSrollView, и вместо этого вызывает "дедушкину" версию CView::OnPrepareDC, которая терпимо относится к формульным режимам. Этот пример, на мой взгляд, очень убедительно демонстрирует гибкость объектно-ориентированного подхода при разработке достаточно сложных приложений
.

CRightView::CRightView() {
m_szltem = CSize (200.150); // Размеры картинки
m_szMargin = CSize (20.20); // Размеры полей
try
{
//====== Попытка зарегистрировать класс окон
m_WndClass=AfxRegisterWndClass(CS_VREDRAWICS_HREDRAW,
::LoadCursor(GetModuleHandle(0),(char*)IDC_MYHAND), (HBRUSH)
CreateSolidBrush(GetSysColor(COLOR_INFOBK)));
}
catch (CResourceException* pEx)
{
AfxMessageBox(_T("Класс уже зарегистрирован")); pEx › Delete ();
}
}

В конструкторе класса CRightView происходит попытка зарегистрировать новый класс окон. Обычно отказов здесь не бывает, но технология требует проверить наличие сбоя, поэтому включаем механизм обработки исключений (try-catch). Мы хотим добиться особого поведения окон с картинками, поэтому зададим для них свою форму курсора и свой цвет фона. Цвет фона выбирается из того набора, который предоставляет система (см. справку по функции GetSysColor), а курсор создали сами.

Дело в том, что системный курсор, идентифицируемый как iDC_HAND, работает не во всех версиях Windows. Если вы работаете в среде Windows 2000, то можете заменить в параметре функции LoadCursor вызов GetModuleHandle (0) на 0, а идентификатор IDC_MYHAND на IDC_HAND и работать с системным курсором. В этом случае ресурс курсора IDC_MYHAND окажется лишним и его можно удалить.

В данный момент мы предполагаем, что в классе документа уже создан динамический контейнер m_Shapes объектов класса CPolygon, каждый элемент которого соответствует данным, полученным в результате чтения документов, обнаруженных в текущем каталоге. Теперь приступим к разработке самой сложной функции в составе класса CRightView, которая должна:

  1. Пройти по всему перечню объектов m_shapes класса CPolygon.
  2. Вычислить исходя из текущего размера окна количество рядов и колонок мини-окон с изображениями полигонов.
  3. Создать для каждого из них окно, управляемое классом CWndGeom.

Дальше события развиваются автоматически. После создания окна cwndGeom система пошлет ему сообщение WM_PAINT, в обработке которого надо создать и настроить контекст устройства мини-окна, а затем вызвать функцию Draw для того полигона из контейнера m_Shapes, индекс которого соответствует индексу окна CWndGeom. Каждый полигон рисует себя сам в заданном ему в качестве параметра контексте устройства.

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