Студопедия

КАТЕГОРИИ:

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

Подготовка контекста устройства для прокрутки




Запомните: действия по прокрутке учитываются лишь в контексте устройства, специально подготовленном для метода OnDraw(). При попытке создать собственный контекст устройства на базе класса CClientDCи вывести в нем строку текста возникает проблема:

CClientDC(this);

dc.TextOut(0, 0, StringData);

Она заключается в том, что созданный нами контекст устройства не был должным образом прокручен классом CScrollView и не учитывает действий пользователя с полосами прокрутки. Впрочем, эта проблема легко решается — "самостоятельный" контекст устройства (то есть отличающийся от контекста, передаваемого в качестве параметра OnDraw()) необходимо должным образом подготовить, для чего надо передать методу OnPrepareDC() объекта вида указатель на него:

      CClientDC(this);

           OnPrepareDC(&dc);

dc.TextOut(0, 0, StringData);

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

Запустите программу stroller. Теперь разные виды одного документа можно прокручивать независимо друг от друга.

Пользуясь классом CScrollView. мы организовали прокрутку вида. Возможно, вы обратиливнимание на то, что кроме класса CScrollView в AppWizard можно выбрать и другие классы. Например, наследование от классаCEditViewсделает ваш класс вида производным от класса текстового поля CEdit, aCFormView позволит построить кдасс вида на основе экранной формы. Экранные формы во многих отношениях напоминают диалоговые окна, за исключением того, что обычно они используются в качестве дочерних окон MDI, как мы убедимся на следующем примере. А сейчас мы рассмотрим пример с классом CEditView, с помощью которого можно создавать окна, обладающие рядом встроенных средств для редактирования текста.

 Использование текстового поля в качестве вида

Одной из самых актуальных проблем при написании Windows-программ является работа с текстом. Если вы хотите, чтобы пользователь мог ввести многострочный текст, отредактировать его, прокрутить, скопировать в буфер обмена или наоборот, вставить из буфера, вам придется потратить немало усилий на то, чтобы написать код приложения "с нуля". Однако классCEditView может выполнить всю необходимую работу, включая функции копирования/вставки. Данный класс создает класс вида, основанный на текстовом поле, и открывает доступ к таким командам меню, как Cutи Paste. Давайте посмотрим, как с его помощью сэкономить массу времени и усилий, а также наделить программу множеством полезных возможностей.

В AppWizard создайте новую многодокументную (MDI) программу с именем editor. В шестом окне мастера выберите базовым для класса вида программы CEditorViewкласс CEditViewи завершите создание программы. Как видно из файла editorView.h, класс вида созданного приложения является производным от CEditView:

// editorView.h : интерфейс класса CEditorView

class CEditorView : public CEditView

 {

}

Как ни удивительно, нам не придется вообще ничего делать, чтобы получить полноценную программу-редактор. В созданной программе можно вводить многострочный текст, прокручивать его, осуществлять вырезание, вставку и копирование текста с помощью команд меню или кнопок на панели инструментов, сохранять текст в файле и загружать его. На самом деле текст можно даже распечатать благодаря встроенным методам класса CEditView(): OnPreparePrinting(), OnBeginPrinting() и OnEndPrinting(). Без малейших хлопот и затрат времени мы создали полноценный текстовый редактор, способный работать с несколькими документами и видами.

На первый взгляд может показаться, что мы сталкиваемся с проблемой — что делать, если нам вдруг захочется самостоятельно выполнить какие-либо действия с текстом? Программа editor вроде бы делает все за нас, но как вмешаться в этот процесс и обработать введенный текст?

Доступ к внутренним данным редактора

Предположим, нам потребовалось добавить в меню Edit программы editor новую команду — Clear. Она должна стирать выделенный текст текущего документа. Но как реализовать новую команду, ведь нам понадобится обратиться непосредственно к данным текстового поля, накрывающего окно вида? Для этого можно воспользоваться методом GetEdltCtrlкласса CEditView.

Давайте посмотрим, как это делается. Добавьте в меню Edit новую команду Clear selected textи свяжите с ней обработчик OnEditClear():

void CEditorView::OnEditClear()

{

}

Чтобы стереть текст в поле, накрывающем окно вида, достаточно вызвать метод Clear()класса CEdit:

void CEditorView::OnEditClear()

{

GetEditCtrl().Clear();

}

 ПОДСКАЗКА: Методы класса CEdit перечислены в табл. 6.2.

Вот и все, что от нас требовалось, — теперь программа editor может обращаться к внутренним данным текстового поля и стирать выделенный текст. Таким образом, методы класса CEdit используются для работы с его внутренними данными.

Работа с элементами ActiveX

На этом этапе мы научимся работать с элементами ActiveX — управляющими компонентами, которые можно внедрять в программы, а также в Web-страницы, отображаемые с помощью броузера. Научившись создавать элементы ActiveX, мы сможем включать их в другие программы, что открывает множество полезных возможностей. Более того, их даже можно включить в палитру редактора диалоговых окон и перетаскивать непосредственно в создаваемое диалоговое окно.

Мы узнаем, как создавать элементы ActiveX и пользоваться ими как в специальной программе - "тестовом контейнере", поставляемой вместе с Visual C++, так и в других программах, написанных на Visual C++. Мы увидим, как организовать прорисовку элемента ActiveX, чтобы он выглядел так, как нам требуется.

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

Наконец, мы узнаем, как создать в элементе ActiveX методы, которые могут вызываться из других программ, и свойства (хранимые в виде внутренних переменных), значения которых могут задаваться другими программами. Элементы ActiveX могут поддерживать свои, нестандартные события, они также будут упомянуты в этом примере.

Элемент ActiveX Boxer

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

Если пользователь щелкнет в другой части, закраска переходит на нее.

Так будет работать наш первый элемент ActiveX, который, как вы вскоре убедитесь, можно включить в другую программу.

Запустите Visual C++ и начните создание программы boxer. На этот раз в диалоговом окне Newвыберите строку MFC ActiveX ControlWizard.

Создание управляющего элемента при помощи MFC ActiveX ControlWizard занимает всего два этапа. Подтвердите установки по умолчанию кнопкой Finish; Control Wizard завершает создание элемента.

Код элемента в созданном проекте содержится в файлах BoxerCtL.h и BoxerCtl.cpp. Класс элемента является производным от класса COleControl, а содержимое файла BoxerCtl.cpp отчасти напоминает код стандартного класса вида. В частности, в нем присутствует метод OnDraw(), в котором происходит отображение элемента. С него мы и начнем.

Рисование элемента ActiveX

В настоящий момент метод OnDraw() в файле BoxerCtl.cpp выглядит так:

void CBoxerCtrl::OnDraw(CDC* pdc, const CRecU rcBounds, const CRect& rcInvalid)

 {

// TODO: замените следующий фрагмент кодом рисования элемента

pdc->FillFiect(rcBounds, CBrush::FromHandIe((HBRUSH)GetStockObject(WHITE_BRUSH)));

pdc->Ellipse(rcBounds),

}

Методу OnDraw() передается прямоугольник rcBounds, в пределах которого должен быть нарисован элемент, а заранее помещенный в него код закрашивает этот прямоугольник белым цветом и рисует в нем эллипс. Мы нарисуем в элементе собственное изображение, поэтому удалите из OnDraw() строку для рисования эллипса:pdc->Ellipse(rcBounds);.

Мы разделим область элемента на четыре прямоугольника с именамиbox1-box4 и объявим их в файле BoxerCtl.h:

class CBoxerCtrl: public COleControl {

// Реализация

protected:

        CBoxerCtrl();

         CRect boxt;

        CRect box2;

        CRect box3;

        CRect box4;

В методе OnDraw() область элемента делится на четыре части, расположенные в левом верхнем, правом верхнем, левом нижнем и правом нижнем углах:

void CBoxerCtri::OnDraw(

CDC* pdc, const CRect& rcBounds, const CRect& rclnvalid) {

pdc->FillRect(rcBounds,

CBrush::FromHandle((HBRUSH)GetStockObject(WHITE_BRUSH)));

box1 = CRect(rcBounds.left, rcBounds.top, rcBounds. right/2, rcBounds.bottom/2);

box2 = CRect(rcBounds,left, rcBounds,bottom/2, rcBounds. righr/2, rcBounds.bottom);

box3 = CRect(rcBounds.right/2, rcBounds.top. rcBounds. right, rcBounds.bottom/2);

box4 = CRect (rcBounds. right/2. rcBounds.bottom/2, rcBounds. right, rcBounds.bottom);

Затем мы рисуемвсе четыре прямоугольника:

void CBoxerCtrl::OnDraw(CDC* pdc, cohst CRecU rcBounds. const CRect& rclnvalid)

{

pdc->FillRect(rcBounds,

CBrush::FromHandle((HBRUSH)GetStockObject(WHITE_BRUSH)));

box1 = CRect(rcBounds.left, rcBounds.top,

rcBounds.right/2, rcBounds.bottom/2);

box2 = CRect(rcBounds.left, rcBounds.bottom/2,

rcBounds.right/2, rcBounds.bottom);

box3 == CRect(rcBounds.right/2, rcBounds.top,

rcBounds.right, rcBounds.bottom/2);

box4 = CRect(rcBounds.right/2, rcBounds.bottom/2,

rcBounds.right, rcBounds.bottom);

        pdc->Rectangle(&box1)

        pdc->Rectangle(&box2)

        pdc->Rectangle(&box3)

         pdc->Rectangle(&box4)

}

Прямоугольники появились на экране. Следующим шагом должна стать обработка сообщений от мыши и закраска прямоугольника, на котором щелкнул пользователь.










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

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