Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
257-288.doc
Скачиваний:
2
Добавлен:
11.11.2019
Размер:
356.35 Кб
Скачать

288

При вычислении высоты текста необходимо определить высоту одной строки и умножить ее на количество строк. К этой величине необходимо добавить высоту верхнего поля. Для определения высоты строки необходимо узнать высоту шрифта. Эти значения хранятся в структуре TEXTMETRIC, и получить их можно с помощью функции CDC::GetTextMetrics() для шрифта, выбранного в объекте контекста устройства. В полях tmHeight и tmExternalLeading структуры TEXTMETRIC хранятся высота символа и величина междустрочного интервала. Количество строк текста в программе TextDemo определено в константе NUMLINES, а величина верхнего поля задана константой MARGIN. Таким образом, высоту текста можно вычислить с помощью оператора:

SizeTotal.cy = (TM.tmHeight + TM.tmExternalLeading) * NUMLINES + 1) + MARGIN;

где SizeTotal— структура типа SIZE; SizeTotal.cy — высота текста (прямоугольника, который ограничивает текст); TM — структура типа TEXTMETRIC.

Функция CDC::GetTextMetrics() возвращает такие значения высоты шрифта: tmHeight задает полную высоту шрифта, включая выносные элементы для букв g, j, p, q, y и диакритические значки поверх заглавных букв. Поле tmExternalLeading задает расстояние между верхом диакритического значка и низом выносного элемента с предыдущей строки. Сумма значений переменных tmHeight и tmExternalLeading задает общую высоту символа. tmInternalLeading задает расстояние между верхом диакритического значка и верхом символа. Разность между tmHeight и tmInternalLeading задает истинную высоту шрифта в пунктах.

При вычислении ширины текста вызывают функцию CDC::GetTextExtent() для получения размера каждой строки текста. Функции CDC::GetTextExtent() необходимо передать текстовую строку в качестве аргумента, и она вернет размеры в виде объекта класса CSize. Напомним, что класс CSize подобен структуре SIZE, наследует переменные cx и cy типа int и использует их для определения ширины и высоты прямоугольника. Прототип функции CDC::GetTextExtent() определен в виде:

CSize CDC::GetTextExtent(LPCTSTR lpszString, int nCount) const; Size CDC::GetTextExtent( const CString& str ) const

Первый вариант функции в качестве параметров использует указатель на строку и количество символов в строке. Во втором случае передается ссылка на объект класса CString.

Для определения количества символов в строке, т. е. длины строки, вызывают функцию CString::GetLength(). Определив строку максимальной длины, сохранив ее в переменной LineWidth и добавив ширину поля отступа, получим ширину текста, которую можно вычислить с помощью следующего оператора.

SizeTotal.cx = LineWidth + MARGIN;

где SizeTotal — структура типа SIZE; SizeTotal.cx — ширина текста (прямоугольника, который ограничивает текст).

В шрифте с переменным питчем для получения ширины символа или длины строки эту информацию использовать нельзя, так как ширина символов непостоянна. Тем не менее, функция CString::GetLength() возвращает действительную длину конкретной строки символов.

Определив размер документа, можно передать его в качестве аргумента в функцию CScrollView::SetScrollSizes():

SetScrollSizes (ММ_ТЕХТ, SizeTotal);

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

void CScrollView::ScrollToPosition( POINT pt );

Параметр pt определяет координаты точки. Возможный вызов функции:

ScrollToPosition (CPoint (0,0));

Познакомившись с методами класса CDC, которые необходимо использовать при отображении текста, продолжим разработку программы TextDemo. Вам необходимо создать код для отображения текста в окне представления выбранным шрифтом. Выводимый текст создайте в программе и представьте его массивом строк. Он должен содержать информацию об атрибутах выбранного шрифта и инкапсулироваться в объекте документа. Состав атрибутов определите в соответствии со структурами TEXTMETRIC и LOGFONT. Технология разработки этого кода рассматривается в задании 3.

Задание 3. Создание кода, отображающего текст

Отображаемый на экране текст сохраняется в классе документа и выводится в окно представления функцией OnDraw(). Добавляемый в функцию CTextDemoView::OnDraw()код иллюстрирует основные этапы отображения текста внутри окна представления. Если пользователь еще не выбрал команду меню Font... для определения шрифта, работа функции CTextDemoView::OnDraw() сразу завершится, потому что текст недоступен. Текст описывает атрибуты шрифта и генерируется сразу после выбора шрифта. Если шрифт не выбран в объекте контекста устройства, то используется стандартный шрифт System. Затем необходимо получить метрики текста, определить высоту символов и установить желаемые атрибуты текста. Для обновления окна представления необходимо определить размеры недействительной области окна представления, отобразить заголовок текста, попадающего в недействительную область, и строки текста, сохранные в массиве m_LineTable.

Для создания кода функции OnDraw() класса CTextDemoView выполните следующую последовательность действий.

  1. Добавьте определение константы MARGIN для сохранения значения отступа от границ окна представления. Для добавления константы откройте окно Solution Explorer. Двойным щелчком на имени файла TextDemoView.h в окне Solution Explorer откройте окно редактора кода. Добавьте оператор объявления константы MARGIN, поместив его до объявления класса CTextDemoView.

const int MARGIN = 10;

  1. В функцию CTextDemoView::OnDraw() добавьте следующие локальные переменные: ClipRect для хранения координат недействительной области, требующей перерисовки, LineHeight для определения высоты строки, TM для хранения метрики текста, Y для определения текущей вертикальной координаты при выводе текста. Поскольку эти переменные не являются членами класса представления, то их добавление осуществляется вручную в окне редактора кода. Введите следующий код в начало определения функции.

void CTextDemoView::OnDraw(CDC* pDC) { CTextDemoDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); // TODO: add draw code for native data here RECT ClipRect; int LineHeight; TEXTMETRIC TM; int Y = MARGIN; }

  1. Следующие строки, выделенные полужирным шрифтом, необходимо добавить в функцию CTextDemoView::OnDraw(). Добавленный код обеспечивает возврат из функции, если пользователь еще не выполнил команду меню Font... для выбора шрифта. Для проверки того, создан ли шрифт, используется дескриптор CGdiObject::m_hObject, содержащий дескриптор HFONT (Windows handle type), связанный с объектом шрифта. Поскольку класс CFont является производным от CGdiObject, и в классе документа определена переменная m_Font класса CFont, то доступ к дескриптору CGdiObject::m_hObject можно выполнить с использованием составного имени m_Font.m_hObject.

void CTextDemoView::OnDraw(CDC* pDC) { CTextDemoDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); // TODO: add draw code for native data here RECT ClipRect; int LineHeight; TEXTMETRIC TM; int Y = MARGIN; if (pDoc->m_Font.m_hObject == NULL) return; }

  1. Чтобы задать шрифт, используемый для отображения текста, необходимо выбрать объект шрифта в объекте контекста устройства, который создавался в классе документа. Передача объекта шрифта объекту контекста устройства обеспечит отображение текста шрифтом, описание которого соответствует сохраняемому в объекте шрифта. Для выполнения описанных действий достаточно добавить в функцию CTextDemoView::OnDraw()выделенный код.

void CTextDemoView::OnDraw(CDC* pDC) { CTextDemoDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); // TODO: add draw code for native data here RECT ClipRect; int LineHeight; TEXTMETRIC TM; int Y = MARGIN; if (pDoc->m_Font.m_hObject == NULL) return; рDC->SelectObject (&pDoc->m_Font); }

  1. Для отображения в окне представления строк текста необходимо определять координаты начальной позиции каждой строки. Для определения общей высоты строки текста функция CTextDemoView::OnDraw() вычисляет сумму значений поля tmHeight структуры TEXTMETRIC, которое определяет высоту самого высокого символа, и поля tmExternalLeading, в котором сохраняется рекомендуемый межстрочный интервал. Операторы получения метрики текста и определение высоты строки текста показаны ниже полужирным шрифтом.

void CTextDemoView::OnDraw(CDC* pDC) { CTextDemoDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); // TODO: add draw code for native data here RECT ClipRect; int LineHeight; TEXTMETRIC TM; int Y = MARGIN; //если шрифт не выбран, то возврат if (pDoc->m_Font.m_hObject == NULL) return; //выбор шрифта в контексте устройства рDC->SelectObject (&pDoc->m_Font); //получение метрики текста pDC->GetTextMetrics(&TM); LineHeight = TM.tmHeight + TM.tmExternalLeading; }

  1. В диалоговом окне Font можно выбрать цвет шрифта, который сохраняется в переменной m_Color класса документа. Для установки цвета текста значение переменной m_Color надо передать в функцию СDC::SetTextColor(). При отображении текста можно использовать окраску фона. Установка режима фоновой окраски осуществляется функцией СDC::SetBkMode(). Напомним, что значение TRANSPARENT аргумента функции СDC::SetBkMode() означает, что символы отображаются поверх цвета фона окна представления. Для реализации цветового представления текста добавьте вызов следующих функций:

void CTextDemoView::OnDraw(CDC* pDC) { CTextDemoDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); // TODO: add draw code for native data here RECT ClipRect; int LineHeight; TEXTMETRIC TM; int Y = MARGIN; //если шрифт не выбран, то возврат if (pDoc->m_Font.m_hObject == NULL) return; //выбор шрифта в контексте устройства рDC->SelectObject (&pDoc->m_Font); //получение метрики текста pDC->GetTextMetrics(&TM); LineHeight = TM.tmHeight + TM.tmExternalLeading; //установка атрибутов текста pDC->SetTextColor(pDoc->m_Color); pDC->SetBkMode(TRANSPARENT); }

  1. Перерисовка окна представления выполняется в случае формирования его недействительной области. Для определения ее размеров вызовите функцию CDC::GetClipBox(). В качестве аргумента передайте указатель на прямоугольную область, размеры которой определяются. В функцию CTextDemoView::OnDraw() добавьте оператор определения координат недействительной области. Кроме этого, добавьте код, который обеспечивает отображение каждой строки текста в пределах окна представления. Для этого используйте функцию CDC::TextOut(). Количество выводимых строк хранится в константе NUMLINES. Для вывода каждой новой строки текста изменяется вертикальная координата ее отображения. Добавленный код представлен ниже полужирным шрифтом.

void CTextDemoView::OnDraw(CDC* pDC) { CTextDemoDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); // TODO: add draw code for native data here RECT ClipRect; int LineHeight; TEXTMETRIC TM; int Y = MARGIN; //если шрифт не выбран, то возврат if (pDoc->m_Font.m_hObject == NULL) return; //выбор шрифта в контексте устройства рDC->SelectObject (&pDoc->m_Font); //получение метрики текста pDC->GetTextMetrics(&TM); LineHeight = TM.tmHeight + TM.tmExternalLeading; //установка атрибутов текста pDC->SetTextColor(pDoc->m_Color); pDC->SetBkMode(TRANSPARENT); //получение координат недействительной области pDC->GetClipBox (&ClipRect); // отображение строки заголовка pDC->TextOut (MARGIN, Y,"FONT PROPERTIES"); // отображение строк текста for (int Line = 0; Line < NUMLINES; ++Line) { Y += LineHeight; if (Y + LineHeight >= ClipRect.top && Y <= ClipRect.bottom) pDC->TextOut (MARGIN, Y, pDoc->m_LineTable [Line]); } }

  1. Сохраните программу, постройте и запустите ее.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]