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

257

{ char temp[100]; sprintf(temp, "Paper size: %g\" x %g\".", (double)dlg.m_psd.ptPaperSize.x / 1000.0, // (double)dlg.m_psd.ptPaperSize.y / 1000.0); AfxMessageBox(temp); } }

Параметр формата бумаги по умолчанию измеряется в тысячных долях дюйма.

14. Скомпонуйте, запустите и протестируйте программу. Вы получите окно как на рис. 7.20.

Рис. 7.20. Окончательный вид главного окна программы TabDemo с добавленным меню View

Подведение итогов

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

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

  • Диалоговое окно с вкладками позволяет отображать несколько страниц взаимосвязанных элементов управления в одном диалоговом окне.

  • Для управления диалоговым окном с вкладками необходимо создать экземпляр класса CPropertySheet (или класса, порождаемого от него). Чтобы управлять каждой отображаемой страницей, необходимо создать объект класса, порождаемого от класса CPropetyPage. Каждый объект страницы связан с созданным в редакторе диалоговых окон шаблоном диалогового окна и добавляется к объекту CPropertySheet при вызове функции CPropertySheet::AddPage().

  • Чтобы отобразить диалоговое окно с вкладками, следует вызвать функцию CPropertySheet::DoModal().

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

  • Все стандартные диалоговые окна являются производными от базового класса CCommonDialog

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

Глава 8. Вывод текстовой информации и использование шрифтов

В этой главе рассматриваются вопросы:

  • установка и сохранение атрибутов шрифта;

  • отображение текста выбранным шрифтом;

  • отображение текста стандартным шрифтом;

  • поддержка средств прокрутки при отображении текста.

Атрибуты шрифтов и диалоговое окно их выбора

Мы рассмотрим программу TextDemo, демонстрирующую отображение строк текста внутри окна представления, используя для этого разные шрифты, которые можно выбирать в стандатном диалоговом окне Font (рис. 8.1).

Рис. 8.1. Стандартное диалоговое окно Font

Под шрифтом понимают набор печатных символов определенной гарнитуры, размера и начертания (курсивное, полужирное и т.п.). Шрифт включает символы букв и знаков. Размер шрифта измеряется в пунктах. Пункт — это наименьшая единица в типографской системе мер, равная 0,376 мм. 72 пункта составляют один дюйм.

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

Диалоговое окно Font — это одно из стандартных диалоговых окон, предоставляемых Windows. Диалоговое окно Font отображается при создании локального объекта класса CFontDialog и последующем вызове функции CFontDialog::DoModal(). Для создания объекта CFontDialog используют конструктор класса CFontDialog, прототип которого приводится ниже.

CFontDialog( LPLOGFONT lplfInitial = NULL, DWORD dwFlags = CF_EFFECTS | CF_SCREENFONTS, CDC* pdcPrinter = NULL, CWnd* pParentWnd = NULL );

Конструктор может иметь следующие параметры: lplfInitial— указатель на структуру LOGFONT, хранящую информацию о шрифте; dwFlags — комбинация флагов для инициализации диалогового окна Font; pdcPrinter — указатель на объект контекста принтера; pParentWnd — указатель на родительское окно или окно владельца диалогового окна Font.

Класс CFontDialog инкапсулирует переменную-член m_cf, которая является структурой типа CHOOSEFONT, хранящей характеристики диалогового объекта, и объявлена таким образом:

CHOOSEFONT m_cf;

Перед отображением диалогового окна с помощью функции CFontDialog::DoModal() его можно инициализировать, установив значение полей структуры CFontDialog::m_cf. Структура типа CHOOSEFONT имеет такие поля:

typedef struct tagCHOOSEFONTW { DWORD lStructSize; //длина структуры в байтах HWND hwndOwner; //дескриптор окна-владельца HDC hDC; //дескриптор контекста принтера LPLOGFONT lpLogFont; //указатель на структуру LOGFONT INT iPointSize; //размер выбранного шрифта в //единицах 1/10 пункта DWORD Flags; //флаги инициализации диалогового окна DWORD rgbColors; //цвет шрифта по умолчанию LPARAM lCustData; //зависимые от приложения данные LPCTSTR lpTemplateName; //указатель на имя ресурса //шаблона диалогового окна HINSTANCE hInstance; //дескриптор приложения LPTSTR lpszStyle; //указатель на буфер, содержащий //стиль данных WORD nFontType; //тип выбранного шрифта INT nSizeMin; //минимальный размер шрифта INT nSizeMax; //максимальный размер шрифта } CHOOSEFONT;

Напомним, что функция CFontDialog::DoModal() возвращает значение IDOK, если диалоговое окно закрыть нажатием кнопки OK. Если отменить диалоговое окно, то функция CFontDialog::DoModal() возвратит значение IDCANCEL, что должно привести к выходу из функции, вызывающей CFontDialog::DoModal(). Следующие операторы позволяют создать объект диалогового окна и отобразить его:

CFontDialog FontDialog; if (FontDialog.DoModal () != IDOK) return; //отменить диалоговое окно

После закрытия диалогового окна можно использовать значения полей структуры CFontDialog::m_cf для получения информации о размере, цвете, типе выбранного шрифта. Особый интерес представляет указатель m_cf.lpLogFont на структуру LOGFONT, которую можно использовать для создания логического шрифта. Для этого класс CFontDialog инкапсулирует еще одну переменную-член m_lf, которая является структурой типа LOGFONT:

LOGFONT m_lf;

Все атрибуты шрифта задаются в полях структуры LOGFONT.

typedef struct tagLOGFONT { LONG lfHeight; //высота шрифта LONG lfWidth; //средняя ширина шрифта LONG lfEscapement; //ориентация — угол наклона строки //относительно горизонтальной оси в десятых долях градуса LONG lfOrientation; //наклон символов относительно //горизонтальной оси LONG lfWeight; //толщина шрифта BYTE lfItalic; //курсивное начертание BYTE lfUnderline; //подчеркивание символов BYTE lfStrikeOut; //зачеркивание символов BYTE lfCharSet; //набор символов BYTE lfOutPrecision; //степень соответствия физического //шрифта заданным установкам BYTE lfClipPrecision; //точность отсечения BYTE lfQuality; //качество BYTE lfPitchAndFamily; //межсимвольный интервал и семейство TCHAR lfFaceName[LF_FACESIZE]; //название гарнитуры шрифта } LOGFONT;

Значения многих полей структуры LOGFONT определяются константами. Так, например, в поле m_lf.lfCharSet хранится тип набора символов, задаваемый константами, значения которых приведены ниже:

ANSI_CHARSET

BALTIC_CHARSET

CHINESEBIG5_CHARSET

DEFAULT_CHARSET

EASTEUROPE_CHARSET

GB2312_CHARSET

GREEK_CHARSET

HANGUL_CHARSET

MAC_CHARSET

OEM_CHARSET

RUSSIAN_CHARSET

SHIFTJIS_CHARSET

SYMBOL_CHARSET

TURKISH_CHARSET

VIETNAMESE_CHARSET

Структура типа LOGFONT используется для инициализации объекта шрифта и хранит описание требуемого шрифта. Если выбрать объект шрифта из объекта контекста устройства, то при отображении текста будет использоваться шрифт, который более всего близок к описанию. Для поля m_lf.lfOutPrecision определены следующие константы (табл. 8.1), которые задают степень соответствия выбранного в диалоговом окне и реально существующего в данной системе шрифтов.

Т а б л и ц а 8.1

Константы соответствия выбранного шрифта и имеющегося в наличии

Значение

Описание

OUT_DEFAULT_PRECIS

Стандартный режим

OUT_DEVICE_PRECIS

При наличии нескольких шрифтов с одинаковым названием выбирается аппаратный шрифт.

OUT_OUTLINE_PRECIS

Выбирается шрифт TrueType или другой контурный шрифт.

OUT_RASTER_PRECIS

Выбирает растровый шрифт при наличии множества шрифтов с тем же названием.

OUT_TT_ONLY_PRECIS

Выбираются только TrueType шрифты. Если таких шрифтов нет, то он выбирается по умолчанию.

OUT_TT_PRECIS

При наличии нескольких шрифтов с одинаковым названием выбирается контурный (TrueType) шрифт

В случае выхода символов за пределы области вывода они усекаются. Способ усечения определяется константами, значения которых задаются для поля m_lf.lfClipPrecision и приводятся в табл. 8.2.

Т а б л и ц а 8.2

Константы способа усечения букв при выходе их за границы области вывода

Значение

Описание

CLIP_DEFAULT_PRECIS

Стандартный режим

CLIP_CHARACTER_PRECIS

Отсекается весь символ

CLIP_STROKE_PRECIS

Отсекается часть символа с точностью до штриха.

CLIP_EMBEDDED

Используется внедренный только для чтения шрифт

CLIP_LH_ANGLES

Когда используется это значение, угол поворота шрифта зависит от лево- или правосторонней системы координат-

Качество шрифта при печати определяется константами, значение которых задаются для поля m_lf.lfQuality и приводится в табл. 8.3.

Т а б л и ц а 8.3

Качество шрифта при печати

Значение

Описание

DEFAULT_QUALITY

Вид шрифта не имеет значения

DRAFT_QUALITY

Качество вывода играет минимальную роль, допускается масштабирование растровых шрифтов

PROOF_QUALITY

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

Шрифты могут иметь фиксированную или переменную ширину литер. В поле m_lf.lfPitchAndFamily в двух младших битах задается межсимвольный интервал, который определяется такими константами: DEFAULT_PITCH — интервал не известен или не имеет значения; FIXED_PITCH — фиксированный интервал; VARIABLE_PITCH — переменный интервал, что характерно для пропорциональных шрифтов. В четырех старших битах поля m_lf.lfPitchAndFamily определяется семейство, к которому относится шрифт. Возможные константы для данного поля приведены в табл. 8.4.

Т а б л и ц а 8.4

Значения констант, определяющих семейство шрифтов

Значение

Описание

FF_DECORATIVE

Декоративный шрифт

FF_DONTCARE

Семейство не известно или не имеет значения

FF_MODERN

Шрифт с постоянной шириной символа с засечками или без них.

FF_ROMAN

Шрифт с засечками с переменной шириной символов

FF_SCRIPT

Шрифт, напоминающий рукописный

FF_SWISS

Шрифт без засечек с переменной шириной символов

Для инициализации объекта шрифта необходимо создать объект класса CFont. Для этого используется конструктор CFont(). После создания объекта класса CFont не обходимо инициализировать шрифт с помощью функций CGdiObject::DeleteObject() и CFont::CreateFontIndirect(). Прототипы функций такие:

BOOL CGdiObject::DeleteObject(); BOOL CFont::CreateFontIndirect(const LOGFONT* lpLogFont );

указатель на структуру LOGFONT передается в качестве аргумента в функцию CFont::CreateFontIndirect().

Обращение к функции CGdiObject::DeleteObject() удаляет существующую информацию о шрифте из объекта шрифта. Для этого данный объект предварительно инициализируется предшествующим вызовом функции, обрабатывающей командное сообщение в результате выбора команды меню Font.... Если объект шрифта не был предварительно инициализирован, то вызов функции CGdiObject::DeleteObject() бесполезен, но безопасен. Передача структуры LOGFONT в функцию CFont::CreateFontIndirect() инициализирует (возможно, повторно) объект шрифта описанием вновь выбранного шрифта. После вызова функции CFont::CreateFontIndirect() информация о шрифте хранится внутри объекта шрифта, который можно выбрать в объекте контекста устройства и, как следствие, отобразить текст с использованием соответствующего шрифта.

Инициализировать объект шрифта также можно с помощью функции CFont::CreateFont(), имеющей такой прототип:

BOOL CFont::CreateFont( int nHeight, int nWidth, int nEscapement, int nOrientation, int nWeight, BYTE bItalic, BYTE bUnderline, BYTE cStrikeOut, BYTE nCharSet, BYTE nOutPrecision, BYTE nClipPrecision, BYTE nQuality, BYTE nPitchAndFamily, LPCTSTR lpszFacename );

В список параметров этой функции входят поля структуры LOGFONT.

Каждый раз после инициализации объекта шрифта вызовом функции CFont::CreateFontIndirect() или CFont::CreateFont() можно получить текущую информацию о шрифте, записанную в соответствующем объекте шрифта. Для этого следует вызвать функцию CGdiObject::GetObject(), копирующую эту информацию в структуру LOGFONT. Прототип функции такой:

int CGdiObject::GetObject( int nCount, LPVOID lpObject ) const;

Функция имеет такие параметры: nCount — количество копируемых байтов; lpObject — указатель на буфер, получающий информацию. В качестве буфера используются структуры LOGFONT, LOGBRUSH, LOGPEN и др.

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

Функция CFontDialog::GetCurrentFont() заполняет структуру LOGFONT и позволяет получить все атрибуты выбранного шрифта. Прототип функции такой:

void CFontDialog::GetCurrentFont( LPLOGFONT lplf );

Функция CFontDialog::GetFaceName() возвращает имя выбранного шрифта и имеет такой прототип:

CString CFontDialog::GetFaceName() const;

Функция CFontDialog::GetSize() возвращает размер шрифта. Напомним, что размер шрифта определяется как десятая часть пункта. Прототип функции:

int CFontDialog::GetSize() const;

Функция CFontDialog::GetColor() возвращает цвет шрифта в виде RGB палитры

COLORREF CFontDialog::GetColor() const;

Для определения толщины шрифта используется функция CFontDialog::GetWeight(), для которой существует прототип:

int CFontDialog::GetWeight() const;

Некоторые функции устанавливают факт наличия определенного начертания и эффектов, например, функция CFontDialog::IsBold() проверяет, выбрано ли начертание полужирное или нет.

BOOL CFontDialog::IsBold() const;

Для определения высоты и ширины символов используются логические единицы (logical units). Значение логической единицы определяется режимом отображения (mapping mode). Соответствие между режимом отображения и логической единицей представлено в табл. 8.5.

Т а б л и ц а 8.5

Режимы отображения и логические единицы

Режим отображения

Логические единицы

MM_TEXT

1 пиксел

MM_HIMETRIC

0,01 мм

MM_LOENGLISH

0,01 дюйма

MM_ISOTROPIC

Определяется пользователем

MM_ANISOTROPIC

Определяется пользователем

MM_HIENGLISH

0,001 дюйма

MM_LOMETRIC

0,1 мм

MM_TWIPS

1/1440 дюйма

В режиме MM_ISOTROPIC поддерживается коэффициент пропорциональности (aspect ratio) 1:1, и он используется в тех случаях, когда необходимо точно передать форму изображения. В режиме MM_ANISOTROPIC масштабные множители по осям x и y изменяются независимо друг от друга.

Рис.8.2. Характеристики символа, сохраняемые в структуре TEXTMETRIC

Для хранения атрибутов активного шрифта устройства, т.е. такого, который действительно доступен для любого устройства вывода, используется структура TEXTMETRIC. Все размеры хранятся в логических единицах, т.е. они зависят от текущего режима отображения в объекте контекста устройства. На рис. 8.2 показаны некоторые поля структуры TEXTMETRIC, содержащие размеры символов.

Теперь рассмотрим объявление полей структуры TEXTMETRIC:

typedef struct tagTEXTMETRIC { LONG tmHeight; //высота символов LONG tmAscent; //подъем символа относительно базовой линии LONG tmDescent; //спуск символа относительно базовой линии LONG tmInternalLeading; //количество лидирующих пробелов //внутри границ, определенных высотой символа LONG tmExternalLeading; //междустрочный интервал LONG tmAveCharWidth; //средняя ширина символа LONG tmMaxCharWidth; //максимальная ширина символа LONG tmWeight; //толщина шрифта LONG tmOverhang; //дополнительная ширина строки LONG tmDigitizedAspectX; //горизонтальное положение //устройства, для которого разработан шрифт LONG tmDigitizedAspectY;//вертикальное положение устройства BCHAR tmFirstChar; //значение первого символа шрифта BCHAR tmLastChar; //значение последнего символа шрифта BCHAR tmDefaultChar; //значение символа подстановки вместо //отсутствующего в шрифте BCHAR tmBreakChar; //значение символа для определения конца //слова для выравнивания текста BYTE tmItalic; //курсивный шрифт BYTE tmUnderlined; //подчеркнутый шрифт BYTE tmStruckOut; //зачеркнутый шрифт BYTE tmPitchAndFamily; //межсимвольный интервал и семейство BYTE tmCharSet; //номер набора символов } TEXTMETRIC;

Получить информацию, хранящуюся в структуре TEXTMETRIC, можно с помощью функции CDC::GetTextMetrics(), параметром которой является указатель на структуру TEXTMETRIC. Функция предоставляет полное описание используемого шрифта, применяемого при отображении текста. Прототип функции следующий:

BOOL CDC::GetTextMetrics( LPTEXTMETRIC lpMetrics ) const;

Для отображения текста необходим объект контекста устройства. При создании объекта контекста устройства, связанного с окном представления, используется конструктор класса CClientDC. Параметром конструктора является указатель на объект CWnd класса окна, к клиентской области которого обращается объект контекста устройства.

CClientDC( CWnd* pWnd );

Получение доступа к объекту представления, связанного с объектом документа, обеспечивают функции GetFirstViewPosition() и GetNextView() класса CDocument. Документ может иметь более одного ассоциированного с ним представления, которые организованы в коллекции объектов. Функцию GetFirstViewPosition() класса CDocument вызывают для получения индекса объекта представления этой коллекции. Полученный индекс объекта представления передается в качестве аргумента в функцию CDocument::GetNextView(). Функция CDocument::GetNextView() возвращает указатель на объект представления и устанавливает значение аргумента, равное индексу следующего объекта представления в списке объектов или нулю, если другие представления отсутствуют. Таким образом, эти две функции позволяют обращаться ко всем ассоциированным с документом представлениям. Их прототипы:

virtual POSITION CDocument::GetFirstViewPosition(); virtual CView* CDocument::GetNextView( POSITION& rPosition );

Шрифт можно использовать после его выбора в созданном объекте контекста устройства. Для выбора объекта используют функцию CDC::SelectObject(), параметром которой является указатель на объект шрифта. Прототип функции приводится ниже.

virtual CFont* CDC::SelectObject( CFont* pFont );

Если выбирать объект шрифта из объекта контекста устройства, то при отображении текста будет использоваться шрифт, который более всего близок к описанию. Значения, присваиваемые функцией CDC::GetTextMetrics()полям структуры TEXTMETRIC, задают шрифт, используемый для отображения текста, который фактически доступен в данной системе.

После выбора атрибутов шрифта в диалоговом окне и изменения объекта документа необходимо обновить все объекты представлений. Напомним, что обновление объектов представлений осуществляется в результате такой последовательности вызовов функций: CDocument::UpdateAllViews(), CView::OnUpdate() (вызывается по умолчанию), CTextDemoView::OnDraw(). Напомним прототипы этих функций.

void CDocument::UpdateAllViews(CView* pSender, LPARAM lHint = 0L, CObject* pHint = NULL );

virtual void CView::OnUpdate( CView* pSender, LPARAM lHint, CObject* pHint );

virtual void CView::OnDraw( CDC* pDC ) = 0;

Параметры этих функций имеют следующий смысл: pSender определяет указатель на объект представления, который изменяет документ; lHint содержит информацию об изменениях документа и pHint является указателем на объект, сохраняющий изменения. Если в качестве аргумента в функцию CDocument::UpdateAllViews() передать значение NULL, то все представления будут обновлены. Параметр pDC функции CView::OnDraw() определяет указатель на объект контекста устройства.

Рассмотренные выше функции будут использованы при выполнении заданий, с помощью которых реализуется сохранение выбранных в диалоговом окне Font атрибутов шрифта с целью их дальгнейшего использования при выводе текста в окне представления.

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