Студопедия КАТЕГОРИИ: АвтоАвтоматизацияАрхитектураАстрономияАудитБиологияБухгалтерияВоенное делоГенетикаГеографияГеологияГосударствоДомЖурналистика и СМИИзобретательствоИностранные языкиИнформатикаИскусствоИсторияКомпьютерыКулинарияКультураЛексикологияЛитератураЛогикаМаркетингМатематикаМашиностроениеМедицинаМенеджментМеталлы и СваркаМеханикаМузыкаНаселениеОбразованиеОхрана безопасности жизниОхрана ТрудаПедагогикаПолитикаПравоПриборостроениеПрограммированиеПроизводствоПромышленностьПсихологияРадиоРегилияСвязьСоциологияСпортСтандартизацияСтроительствоТехнологииТорговляТуризмФизикаФизиологияФилософияФинансыХимияХозяйствоЦеннообразованиеЧерчениеЭкологияЭконометрикаЭкономикаЭлектроникаЮриспунденкция |
Определение параметров шрифта по структуре TEXTMETRIC
Наш курсор будет создан в методеOnDraw(). Прежде всего мы создадим в объекте вида логическую переменную с именем CaretCreated, по которой можно будет определить, был ли курсор создан ранее: // caretsView.h: интерфейс класса CCaretsView class CCaretsView: public CView { protected: // создание только при сериализации CCaretsView(); DECLARE_DYNCREATE(CCaretsView) boolean CaretCreated; } ПОДСКАЗКАЛогические переменные, также называемые флагами, могут принимать всего два значения: "истина" (true) и "ложь" (false). После того как в конструкторе вида переменной CaretCreated было присвоено значение false:
CcaretsView::CcaretsView() { CaretCreated = false; }
в методе OnDraw() необходимо проверить, был ли создан курсор: void CCaretsView::OnDraw(CDC* pDC) { CaretsDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); if(!CaretCreated){ } Если курсор еще не создан, необходимо сделать это. Сначала выберем размер курсора. Необходимую информацию можно взять из структуры TEXTMETRIC, но сначала следует вызвать метод GetTextMetrics(). Метод GetTextMetrlcs() заполняет структуру типа TEXTMETRIC, которая состоит из следующих полей: typedef struct tagTEXTMETRIC { LONG tmHeight; LONG tmAscent; LONG tmDescent; LONG tmInternalLeading; LONG tmExternalLeading; LONG tmAveCharWidth; LONG trnMaxCharWidth; LONG tmWeight; LONG tmOverhang; LONG ImDigitizedAspectX; LONG mDigitizedAspectY; BCHAR tmFirstChar; BCHAR tmLastChar; BCHAR tmDefaultChar; BCHAR tmBreakChar; BYTE tmltalic; BYTE tmUnderlined; BYTE tmStruckOut; BYTE tmPitchAndFamily; BYTE tmCharSet; } TEXTMETRIC; В нашей программе структура типа TEXTMETRICс именем textmetric заполняется так: void CCaretsView::OnDraw(CDC* pDC) { CCaretsDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); if(CaretCreated){ TEXTMETRIC textmetric; pDC->GetTextMetrics(&textmetric); } } Все готово к созданию курсора. Его высота будет равна высоте символов (textmetric.tmHeight), а ширина— 1/8 средней ширины символа (textmetric.tmAveCharWidth/8). Для создания курсора мы воспользуемся методомCreateSolidCaret(): void CCaretsView::OnDraw(CDC* pDC) { CCaretsDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); if(CaretCreated){ TEXTMETRIC textmetric; pDC->GetTextMetrics(&textmetric); CreateSolidCaret(textmetric.tmAveCharWidth/8, textmetric.tmHeight); } } ПОДСКАЗКА:Кроме метода CreateSolidCaret()существует также метод CreateGrayCaret() для создания затушеванного, "серого" курсора. Помимо этого, для работы с курсорами предназначены методы ShowCaret(), SetCaretPos() и HideCaret(). Приведенный выше фрагмент создает курсор и включает его в объект вида. Но прежде чем работать с курсором, необходимо задать его положение методом SetCaretPos(). Установка положения курсора Положение курсора будет храниться в новом объекте класса CPointс именем CaretPosition. Класс CPointсодержит две переменные, х и у, в которых хранятся значения координат: // caretsView.h : интерфейс класса CCaretsView class CCaretsView : public CView { protected: // создание только при сериализации CCaretsView(); DECLARE_DYNCREATE(CCaretsView) CPoint CaretPosition; boolean CaretCreated; } Только что созданный курсор помещается в точку с координатами (0, 0). В методеOnDraw()это делается так: void CCaretsView::OnDraw(CDC* pDC) { CCaretsDoc* pDoc = GetDocumentO; ASSERT_VALID(pDoc); if(CaretCreated){ TEXTMETRIC textmetric; pDC->GetTextMetrics(&textmetric); CreateSolidCaret(textmetric.tmAveCharWidth/8, textmetric.tmHeight); CaretPosition.x = CaretPosition.у = 0; } } ПОДСКАЗКА: Обратите внимание на удобную сокращенную форму записи, которая позволяет в C++ присвоить одинаковое значение сразу нескольким переменным: x=y=z=1;. 3атем мы задаем позицию курсора методом SetCaretPos(), отображаем курсор на экране (ShowCaret()) и устанавливаем значение флага CaretCreated в true: void CCaretsView::OnDraw(CDC* pDC) { CCaretsDoc* pDoc = GetDocumentO; ASSERT_VALID(pDoc); if(CaretCreated){ TEXTMETRIC textmetric; pDC->GetTextMetrics(&textmetric); CreateSolidCaret(textmetric.tmAveCharWidth/8, textmetric.tmHeight); CaretPosition.x = CaretPosition.у = 0; SetCaretPos(CaretPosition);. ShowCaret(); CaretCreated = true; } } После выполнения этой части программы курсор появляется на экране. Нам удалось создать свой собственный мерцающий и вполне работоспособный курсор. Теперь необходимо организовать перемещение курсора по мере ввода текста; курсор всегда должен находиться там, где окажется следующий символ. Сначала отобразим текст, введенный пользователем: void CCaretsView::OnDraw(CDC* pDC) { CCaretsDoc* pDoc = GetDocumentO; ASSERT_VALID(pDoc); if(CaretCreated){ TEXTMETRIC textmetric; pDC->GetTextMetrics(&textmetric); CreateSolidCaret(textmetric.tmAveCharWidth/8, textmetric.tmHeight); CaretPosition.x = CaretPosition.у = 0; SetCaretPos(CaretPosition);. ShowCaret(); CaretCreated = true; } pDC->TextOut(0, 0, pDoc->StringData);
} Затем нужно переместить курсор в конец строки, но предварительно необходимо выяснить, где она кончается. Для этого мы заполним объект класса CSizeс именем size, для чего вызовем метод GetTextExtent(): void CCaretsView::OnDraw(CDC* pDC) { CCaretsDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); pDC->TextOut(0, 0, pDoc->StringData); CSize size = pDC->GetTextExtent(pDoc->StringData); Прежде чем выводить курсор в конце строки, мы с помощью метода HideCaret()скроем его: void CCaretsView::OnDraw(CDC* pDC) { CCaretsDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); pDC->TextOut(0, 0, pDoc->StringData); CSize size = pDC->GetTextExtent(pDoc->StringData); HideCaret(); } ВНИМАНИЕ: Если не скрыть курсор перед перемещением, его изображение может остаться на прежнем месте. Затем переменной хобъекта CaretPositionприсваивается координата конца текстовой строки на экране: void CCaretsView::OnDraw(CDC* pDC) { CCaretsDoc* pOoc = GetDocument(); ASSERT_VALID(pDoc); pDC->TextOut(0, 0, pDoc->StringData); CSize size = pDC->GetTextExtent(pDoc->StringData); HideCaret(); CaretPosition.x = size.ex; } Наконец, мы перемещаем курсор в новое положение и сновавыводим его на экран: void CCaretsView::OnDraw(CDC* pDC) { CCaretsDoc* pDoc = GetDocument(); ASSERT.VALID(pDoc); pDC->TextOut(0, 0. pDoc->StringData); CSize size = pDC->GetTextExtent(pDoc->StringData); HideCaret(); CaretPosition.x = size.ex; SetCaretPos(CaretPosition); ShowCaret(); } Запустите программу. Как видите, курсор постоянно находится в конце строки. Программа carets прекрасно работает, а мы научились работать с курсором. Тем не менее, необходимо учесть еще одно обстоятельство. Когда пользователь щелкает мышью внутри другого окна и передает в него фокус, мы должны скрыть мигающий курсор, как это принято в программах для Windows. Именно этим мы сейчас и займемся. |
||
Последнее изменение этой страницы: 2018-04-12; просмотров: 469. stydopedya.ru не претендует на авторское право материалов, которые вылажены, но предоставляет бесплатный доступ к ним. В случае нарушения авторского права или персональных данных напишите сюда... |