Студопедия

КАТЕГОРИИ:

АвтоАвтоматизацияАрхитектураАстрономияАудитБиологияБухгалтерияВоенное делоГенетикаГеографияГеологияГосударствоДомЖурналистика и СМИИзобретательствоИностранные языкиИнформатикаИскусствоИсторияКомпьютерыКулинарияКультураЛексикологияЛитератураЛогикаМаркетингМатематикаМашиностроениеМедицинаМенеджментМеталлы и СваркаМеханикаМузыкаНаселениеОбразованиеОхрана безопасности жизниОхрана ТрудаПедагогикаПолитикаПравоПриборостроениеПрограммированиеПроизводствоПромышленностьПсихологияРадиоРегилияСвязьСоциологияСпортСтандартизацияСтроительствоТехнологииТорговляТуризмФизикаФизиологияФилософияФинансыХимияХозяйствоЦеннообразованиеЧерчениеЭкологияЭконометрикаЭкономикаЭлектроникаЮриспунденкция

Независимая прокрутка видов




Научившись поддерживать несколько видов, давайте посмотрим, как прокручивать окна видов, чтобы пользователь мог просматривать в них разные части документа. 

При помощи AppWizard создайте новую многодокументную (MDI) программу с именем scroller. Однако базовым классом для нашего класса вида в новом примере будет уже не стандартный класс MFC CView, a CScrollView. Он выполняет почти всю работу, связанную с прокруткой (с минимальными дополнениями с нашей стороны). Чтобы выбрать этот класс в качестве базового для класса вида нашей программы CScrollerView, выберите последний пункт из списка в шестом окне AppWizard.

Затем выберите класс CScrollView из спискаBase classв нижней части того же окна. Завершите создание программы кнопкой Finish.

В результате класс CScrollView становится базовым для класса вида нашей программы, и в этом нетрудно убедиться, взглянув на объявление класса вида в файле scrollerView.h. Не путайте стандартный класс MFC CScrollView с CScrollerView, классом вида приложения scroller:

// scrollerView.h: интерфейс класса CScrollerView

class CScrollerView: public CScrollView

{

.

.

.

}

 Методы класса CScrollView перечислены в табл. 11.1.

Таблица 11.1. Методы класса CScrollView

Метод Назначение
CScrollView Конструирует объект класса CScrollView
FillOutsideRect Заполняет участок вида за пределами прокручиваемой области
GetDeviceScrollPosition Получает текущую позицию прокрутки в единицах устройства
GetDeviceScrollSizes Получает текущий координатный режим, общий размер и размеры строки и страницы для прокручиваемого
GetScrollPosition Получает текущую позицию прокрутки в логических единицах
GetTotalSize Получает общий размер прокручиваемого вида в логических единицах
ResizeParentToFit Ставит размер кадра прокрутки в зависимость от размера вида
ScrollToPosition   Прокручивает вид до конкретной позиции, заданной в логических единицах
SetScaleToFitSize  Переводит прокручиваемый вид в режим масштабирования с заполнением"
SetScrollSizes    Задает текущий координатный режим, общий размер и размеры для горизонтальной и вертикальной прокрутки   

Затем добавьте в созданную программу код, использованный нами в предыдущем примере multiview для ввода пользователем текста. Другими словами, создайте в документе объект StringDataкласса CStringдля хранения текста и в методе вида OnChar()напишите метод для сохранения очередного символа, вводимого пользователем:

void CScrollerView::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)

{    

CScrollerDoc* pDoc=GetDocument();

ASSERT_VALID(pDoc):       

pDoc->StringData += nChar;         

Invalidate():  

 pDoc->UpdateAllViews(this, 0L, NULL); 

pDoc->SetModifiedFlag();         

CScrollView::OnChar(nChar, nRepCnt, nFlags);  

}   

Пока программа scrollerничем не отличается от multiview— пользователь может одновременно создать несколько документов и работать с ними, а также открыть несколько видов для любого из них. Настало время внести различия — добавить в программу scroller возможность прокрутки.

Организация прокрутки вида

Подготовка вида к прокрутке проходит в несколько этапов, но мы рассмотрим этот процесс в самых общих чертах. Прежде всего необходимо определить, какой размер (в пикселях) будет иметь весь документ, если целиком вывести его на экран. Прокрутка возможна лишь в том случае, если класс CScrollView знает размеры документа. В дальнейшем каждый вид будет действовать как самостоятельное окно внутри этого документа и прокручивать содержимое документа (как по горизонтали, так и по вертикали). Все подробности работы пользователя с полосой прокрутки класс CScrollView берет на себя.

Определение размера документа

Чтобы узнать размер всего документа, мы добавим в объект документа новый объект класса CSize, который будет называться m_size:

// scrollerDoc.h: интерфейс класса CScrollerDoc

class CScrollerDoc: public.CDocument

{

protected: // создание только при сериализации CScrollerDoc();

    DECLARE_DYNCREATE(CScrollerDoc)

     CSize m_size;

}

Новая переменная документа объявлена как защищенная, поэтому мы также добавим методGetDocSize(), в котором ей будет присваиваться необходимое значение:

// scrollerDoc.h: интерфейс класса CScrollerDoc

class CScrollerDoc: public CDocument

 {

protected: // создание только при сериализации CScrollerDoc();

    DECLARE_DYNCREATE(CScrollerDoc)

     CSize m_size;

// Атрибуты public:

CString StringData;

// Операции public:

CSize GetDocSize() {return m_size;}

}

Наконец, мы инициализируем m_size в конструкторе документа значением, допустим, в 1000х1000 пикселей:

CScrollerDoc::CScrollerDoc()

{

        m_size = CSize(1000, 1000);

StringData ="";

}

ПОДСКАЗКА: Хотя в данном примере для документа выбран произвольный размер (1000х1000 пикселей), вы можете получить фактические размеры документа такими методами, как GetTextExtent()или GetTextMetrics(), и задать в конструкторе реальные размеры документа.

Хотя мы задали размеры документа в экранных пикселях, классу CScrollView об этом еще ничего не известно. Необходимо сообщить виду размеры документа, вызывая метод SetScrollSizes().

На самом деле AppWizard заранее поместил вызов SetScrollSizes() в метод OnInitialUpdate() нашего вида, хотя в нем по умолчанию задается размер всего лишь в 100х100 пикселей:     

void CScrolierView::OnInitialUpdate()      

{  

CScrollView: :OnInitialUpdate();        

CSize sizeTotal;        

// TODO: вычислите общий размер вида

          sizeTotal.сx = sizeTotal.су = 100;

 SetScrollSizes(MM_TEXT. sizeTotal);

}

Параметр ММ_ТЕХТ метода SetScrollSlze() говорит о том, что значения заданы в экранных пикселях. Мы изменим этот фрагмент и включим в него фактические размеры документа (которые определяются с помощью нового метода GetDocSize()):

void CScrollerView::OnInitialUpdate()

{

CScrollView ::OnInitialUpdate();

           CSize sizeTotal;

            CScrollerDoc* pDoc == GetDocument();

           ASSERT_VALID(pDoc);

            sizeTotal.cx = pDoc->GetDocSize().cx;

           sizeTotal.cy = pDoc->GetDocSize().cy;

           SetScrollSizes(MM_TEXT, sizeTotal);

}

ПРИМЕЧАНИЕ: Если размеры документа изменятся в тот момент, когда с ним работает пользователь, снова вызовите SetScrollSize() чтобы сообщить виду о новом размере документа и обеспечить его правильную прокрутку.

Теперь ничто не мешает нам отобразить введенную пользователем строку в методе OnDraw():

 void CScrollerView::OnDraw(CDC* pDC)

        {

        CScrollerDoc* pDoc = GetDocument();

         ASSERT_VALID(pDoc);

         pDC->TextOut(0, 0, pDoc->StringData);

          }

При прокрутке внутренние методы класса CScrollView изменяют положение начала координат в контексте устройства метода OnDraw(), перемещая его в направлении, противоположном направлению прокрутки. Это означает, что нам остается лишь отобразить текст в передаваемом контексте устройства. Класс CScrollView заранее готовит контекст и автоматически прокручивает его в соответствии с действиями пользователя.










Последнее изменение этой страницы: 2018-04-12; просмотров: 278.

stydopedya.ru не претендует на авторское право материалов, которые вылажены, но предоставляет бесплатный доступ к ним. В случае нарушения авторского права или персональных данных напишите сюда...