Шаг 57.
Среда программирования Visual C++.
Прокрутка в представлении

    На этом шаге мы рассмотрим реализацию прокрутки в виде документа.

    Вывод графической информации в логическое устройство ограничен только доступным диапазоном координат. В приложениях для Windows 95 и Windows 98 графические координаты изменяются в пределах от -32768 до +32767. В режиме МM_LOENGLISH этот диапазон соответствует физической области рисования, имеющей площадь примерно 280 квадратных метров. Это намного больше любого мыслимого устройства вывода.

    В окнах, которые не вмещают всю выводимую информацию, следует предусмотреть полосы прокрутки. Кроме того, полосы прокрутки должны появляться при изменении размеров окна и в случае, когда рамка окна обрезает рабочую область.

    Можно самостоятельно организовать прокрутку в любом классе представления, применяя CWnd-функции прокрутки и обрабатывая сообщения WM_VSCROLL и WM_HSCROLL. Однако намного проще реализовать прокрутку средствами класса CScrollView, поскольку в нем предусмотрено:

    Познакомимся со средствами прокрутки класса CScrollView.

    Обратите внимание, что хотя прокрутка и выполняется автоматически, но в ее реализации имеются недостатки. На рисунке 1 показано, что правая часть строк уже не просматривается, а горизонтальная полоса прокрутки еще не появилась. Хотя, казалось бы, полосы прокрутки должны появляться на экране сразу же после того, как край рамки обрезает выводимые в окно данные. И хотя при дальнейшем сужении окна горизонтальная полоса прокрутки появляется, но она не позволяет увидеть всю строку.

    Причина тому - не задан логический размер и режим сопоставления координат для прокрутки представления. Когда AppWizard включает в создаваемое приложение класс, производный от CScrollView, он добавляет в перегруженный метод CView::OnInitialUpdate() следующий код:

	CSize sizeTotal;
	// TODO: calculate the total size of this view
	sizeTotal.cx = sizeTotal.cy = 100;
	SetScrollSizes(MM_TEXT, sizeTotal);

    Функция CScrollView::SetScrollSizes() задает логический размер и режим сопоставления координат для прокрутки вида. Meтод OnInitialUpdate() по умолчанию устанавливает окна для вида размером 100 на 100 логических единиц. В режиме ММ_ТEXT это соответствует экранной области просмотра размером 100 на 100 пикселей, или примерно одному квадратному дюйму поверхности монитора с разрешением 800 на 600. У функции SetScrollSizes() есть еще два параметра: размер строки и размер страницы. Первый - это величина горизонтальной и вертикальной прокрутки в любом направлении при щелчке стрелки полосы прокрутки. Второй - это шаг прокрутки при щелчке любой области полосы прокрутки, но не ее стрелки. Значения этих двух параметров рассчитываются по умолчанию исходя из общего размера окна.

    Когда окно приложения MуAрр достаточно велико, виден весь текст. Если сжать окно так, чтобы его размер стал меньше значения установленного в функции SetScrollSizes(), то появится полоса прокрутки. Масштаб и позиция движка в полосе прокрутки также вычисляются в соответствии с установленным размером прокрутки. Поэтому в экспериментах со стандартным поведением прокрутки в приложении МуАрр нельзя путем прокрутки увидеть данные, находящиеся вне логической области окна размерами 100 на 100.

    При установке в приложении с архитектурой "документ/вид" простой прокрутки для представления нужно выбрать размер логической области графического представления данных документа. Затем надо определить режим сопоставления координат, подходящий для масштабирования изображения на устройстве вывода, и задать значения, передаваемые SetScrollSizes() при ее вызове в функции ОnInitialUpdate() класса представления. В следующем фрагменте кода показано, как установить для вида размер 8,5 на 11 дюймов.

  sizeTotal.cx = 850; 
  sizeTotal.cy = 1100; 
  SetScrollSizes(MM_LOENGLISH, sizeTotal);

    Этот метод годится при задании фиксированного размера данных приложения. Однако в таком приложении, как, например, текстовый редактор, не существует ограничений на длину документа. При добавлении новых строк текста придется изменять размер логической окна и пересчитывать масштаб полосы прокрутки, то есть всякий раз вызывать SetScrollSizes() при изменении объема данных в документе.

    В следующем примере в функции SetScrollSizes() откорректируем вид CMyAppView: полоса прокрутки должна появляться пhb выходе отображаемых данных за рамку окна. Функция SetScrollSizes() будет вызываться из функции рисования, чтобы размеры прокрутки вычислялись исходя из длины выводимой строки. Кроме того, в этой функции будет устанавливаться режим MM_LOENGLISH, обеспечивающий одинаковый вывод как на экран, так и на принтер.

    Текст измененного приложения можно взять здесь (61,4 Кб).

    На следующем шаге мы рассмотрим рисование в контексте устройства.




Предыдущий шаг Содержание Следующий шаг